OrderIAWP/AJAX/AJAX.php000064400000011146147600331220007264 0ustar00requires_pro()) { \add_action('wp_ajax_' . $this->action_name(), [$this, 'intercept_ajax']); } } /** * Classes must define an action name for the ajax request * * The required nonce for the ajax request will be the action name with a "_nonce" postfix * Example: "iawp_delete_data" require a "iawp_delete_data_nonce" nonce field * * @return string */ protected abstract function action_name() : string; /** * Classes must define an action callback to run when an ajax request is made * * @return void */ protected abstract function action_callback() : void; /** * This is the direct handler for ajax requests. * Permissions and nonce values are checked before executing the ajax action_callback function. * * @return void */ public function intercept_ajax() : void { // Todo - Should this be can_edit() instead? $is_not_migrating = $this->allowed_during_migrations() || !Migrations\Migrations::is_migrating(); $valid_fields = !$this->missing_fields(); $can_view = Capability_Manager::can_view(); \check_ajax_referer($this->action_name(), 'nonce'); if ($is_not_migrating && $valid_fields && $can_view) { Server::increase_max_execution_time(); $this->action_callback(); } else { \wp_send_json_error(['errorMessage' => 'Unable to process IAWP AJAX request'], 400); } \wp_die(); } public function get_action_signature() : array { $shorthand_name = $this->action_name(); if (\strpos($this->action_name(), "iawp_") === 0) { $shorthand_name = \substr($this->action_name(), 5); } return [$shorthand_name => ['action' => $this->action_name(), 'nonce' => \wp_create_nonce($this->action_name())]]; } /** * Classes can define a set of required fields for an ajax request * * @return array */ protected function action_required_fields() : array { return []; } /** * Override method to allow the AJAX request to run during migrations * * @return bool false by default */ protected function allowed_during_migrations() : bool { return \false; } protected function requires_pro() : bool { return \false; } /** * Get a field value. This method supports text and arrays. Returns array if no field found. * * @param $field * * @return array|string|null */ protected function get_field($field) { if (!\array_key_exists($field, $_POST)) { return null; } $type = \gettype($_POST[$field]); if ($type == 'array') { if ($this->array_is_list($_POST[$field])) { return \rest_sanitize_array($_POST[$field]); } else { return \rest_sanitize_object($_POST[$field]); } } else { return \stripslashes(\sanitize_text_field($_POST[$field])); } } protected function get_int_field($field) : ?int { if (!\array_key_exists($field, $_POST)) { return null; } $type = \gettype($_POST[$field]); if ($type === 'int') { return $_POST[$field]; } elseif ($type === 'string') { return \ctype_digit($_POST[$field]) ? (int) $_POST[$field] : null; } else { return null; } } protected function get_boolean_field($field) : ?bool { if (!\array_key_exists($field, $_POST)) { return null; } $type = \gettype($_POST[$field]); if ($type === 'string') { return $_POST[$field] === 'true'; } else { return null; } } // This is the recommended polyfill: https://wiki.php.net/rfc/is_list private function array_is_list(array $array) : bool { $expectedKey = 0; foreach ($array as $i => $_) { if ($i !== $expectedKey) { return \false; } $expectedKey++; } return \true; } private function missing_fields() : bool { foreach ($this->action_required_fields() as $required_field) { if (!\array_key_exists($required_field, $_POST)) { return \true; } } return \false; } } IAWP/AJAX/AJAX_Manager.php000064400000005103147600331220010712 0ustar00instances[] = new \IAWP\AJAX\Archive_Link(); $this->instances[] = new \IAWP\AJAX\Click_Tracking_Cache_Cleared(); $this->instances[] = new \IAWP\AJAX\Configure_Pruner(); $this->instances[] = new \IAWP\AJAX\Set_WooCommerce_Statuses_To_Track(); $this->instances[] = new \IAWP\AJAX\Copy_Report(); $this->instances[] = new \IAWP\AJAX\Create_Campaign(); $this->instances[] = new \IAWP\AJAX\Create_Report(); $this->instances[] = new \IAWP\AJAX\Delete_Campaign(); $this->instances[] = new \IAWP\AJAX\Delete_Data(); $this->instances[] = new \IAWP\AJAX\Delete_Link(); $this->instances[] = new \IAWP\AJAX\Delete_Report(); $this->instances[] = new \IAWP\AJAX\Dismiss_Notice(); $this->instances[] = new \IAWP\AJAX\Edit_Link(); $this->instances[] = new \IAWP\AJAX\Export_Campaigns(); $this->instances[] = new \IAWP\AJAX\Export_Clicks(); $this->instances[] = new \IAWP\AJAX\Export_Devices(); $this->instances[] = new \IAWP\AJAX\Export_Geo(); $this->instances[] = new \IAWP\AJAX\Export_Pages(); $this->instances[] = new \IAWP\AJAX\Export_Referrers(); $this->instances[] = new \IAWP\AJAX\Export_Reports(); $this->instances[] = new \IAWP\AJAX\Filter(); $this->instances[] = new \IAWP\AJAX\Import_Reports(); $this->instances[] = new \IAWP\AJAX\Migration_Status(); $this->instances[] = new \IAWP\AJAX\Preview_Email(); $this->instances[] = new \IAWP\AJAX\Real_Time_Data(); $this->instances[] = new \IAWP\AJAX\Rename_Report(); $this->instances[] = new \IAWP\AJAX\Reset_Analytics(); $this->instances[] = new \IAWP\AJAX\Save_Report(); $this->instances[] = new \IAWP\AJAX\Set_Favorite_Report(); $this->instances[] = new \IAWP\AJAX\Sort_Links(); $this->instances[] = new \IAWP\AJAX\Sort_Reports(); $this->instances[] = new \IAWP\AJAX\Test_Email(); $this->instances[] = new \IAWP\AJAX\Update_Capabilities(); $this->instances[] = new \IAWP\AJAX\Update_User_Settings(); } public function get_action_signatures() : array { $action_signatures = []; foreach ($this->instances as $instance) { $action_signatures = \array_merge($action_signatures, $instance->get_action_signature()); } return $action_signatures; } } IAWP/AJAX/Archive_Link.php000064400000002522147600331220011075 0ustar00get_field('id'); $link_rule = Click_Tracking\Link_Rule::find($id); if (\is_null($link_rule)) { \wp_send_json_error([]); } \delete_option('iawp_click_tracking_cache_cleared'); $link_rule->toggle_active(); Illuminate_Builder::new()->from(Tables::link_rules())->where('is_active', '=', $link_rule->is_active() ? 1 : 0)->increment('position'); Illuminate_Builder::new()->from(Tables::link_rules())->where('link_rule_id', '=', $link_rule->id())->update(['position' => 0]); // Send response $response = \IAWPSCOPED\iawp_blade()->run('click-tracking.link', ['link' => $link_rule->to_array(), 'types' => Click_Tracking::types(), 'extensions' => Click_Tracking::extensions(), 'protocols' => Click_Tracking::protocols()]); echo \wp_json_encode($response); } } IAWP/AJAX/Click_Tracking_Cache_Cleared.php000064400000000714147600331220014111 0ustar00get_field('pruningCutoff'); $is_confirmed = $this->get_boolean_field('isConfirmed'); $pruning_scheduler = new Pruning_Scheduler(); if ($cutoff !== 'disabled' && !$is_confirmed) { \wp_send_json_error(['confirmationText' => $pruning_scheduler->get_pruning_description($cutoff)]); } $was_updated = $pruning_scheduler->update_pruning_cutoff($cutoff); if ($was_updated && $pruning_scheduler->is_enabled()) { Pruner::prune(); } if ($was_updated) { \wp_send_json_success(['isEnabled' => $pruning_scheduler->is_enabled(), 'statusMessage' => $pruning_scheduler->status_message()]); } else { \wp_send_json_error([]); } } } IAWP/AJAX/Copy_Report.php000064400000004120147600331220011000 0ustar00get_existing_report_options(); if (\is_null($existing_report_options)) { \wp_send_json_error(); } $new_report_id = Illuminate_Builder::new()->from($reports_table)->insertGetId($existing_report_options); $report_options_parser = Report_Options_Parser::from_json($_POST['changes']); if (\count($report_options_parser->get_options_for_updating()) > 0) { Illuminate_Builder::new()->from($reports_table)->where('report_id', '=', $new_report_id)->update($report_options_parser->get_options_for_updating()); } $row = Illuminate_Builder::new()->from($reports_table)->where('report_id', '=', $new_report_id)->first(); $report = new Report($row); \wp_send_json_success(['url' => $report->url()]); } private function get_existing_report_options() : ?array { if (\strlen($this->get_field('id')) === 0) { return ['name' => $this->get_field('name'), 'type' => $this->get_field('type')]; } $reports_table = Query::get_table_name(Query::REPORTS); $existing_report = Illuminate_Builder::new()->from($reports_table)->where('report_id', '=', $this->get_field('id'))->first(); if (\is_null($existing_report)) { return null; } $existing_report = (array) $existing_report; unset($existing_report['report_id']); $existing_report['name'] = $this->get_field('name'); return $existing_report; } } IAWP/AJAX/Create_Campaign.php000064400000001553147600331220011544 0ustar00create_campaign(Security::string(\trim($this->get_field('path'))), Security::string(\trim($this->get_field('utm_source'))), Security::string(\trim($this->get_field('utm_medium'))), Security::string(\trim($this->get_field('utm_campaign'))), Security::string(\trim($this->get_field('utm_term'))), Security::string(\trim($this->get_field('utm_content')))); \wp_send_json_success(['html' => $html]); } } IAWP/AJAX/Create_Report.php000064400000001177147600331220011302 0ustar00 'New Report', 'type' => $this->get_field('type')]); \wp_send_json_success(['url' => $report->url()]); } } IAWP/AJAX/Delete_Campaign.php000064400000000732147600331220011541 0ustar00get_field('campaign_url_id')); \wp_send_json_success([]); } } IAWP/AJAX/Delete_Data.php000064400000001737147600331220010701 0ustar00get_field('confirmation'); $valid = \strtolower($confirmation) == 'delete all data'; if (!$valid) { \wp_send_json_error([], 400); } $database_manager = new Database_Manager(); $database_manager->delete_all_data(); $geo_database_manager = new Geo_Database_Manager(); $geo_database_manager->delete(); Capability_Manager::reset_capabilities(); \deactivate_plugins(\IAWP_PLUGIN_FILE); \wp_send_json_success(['redirectUrl' => \admin_url()]); } } IAWP/AJAX/Delete_Link.php000064400000003064147600331220010720 0ustar00get_int_field('id'); if (\is_null($link_rule_id)) { \wp_send_json_error([], 400); } // Delete the link Illuminate_Builder::new()->from(Tables::link_rules())->where('link_rule_id', '=', $link_rule_id)->delete(); // Delete the linked clicks Illuminate_Builder::new()->from(Tables::clicked_links())->where('link_rule_id', '=', $link_rule_id)->delete(); // Delete the clicks $clicked_links_table = Tables::clicked_links(); Illuminate_Builder::new()->from(Tables::clicks(), 'clicks')->leftJoin("{$clicked_links_table} AS clicked_links", "clicks.click_id", '=', "clicked_links.click_id")->whereNull('clicked_links.click_id')->delete(); // Delete the click targets $clicks_table = Tables::clicks(); Illuminate_Builder::new()->from(Tables::click_targets(), 'click_targets')->leftJoin("{$clicks_table} AS clicks", "click_targets.click_target_id", '=', "clicks.click_target_id")->whereNull('clicks.click_target_id')->delete(); \wp_send_json_success(['id' => $link_rule_id]); } } IAWP/AJAX/Delete_Report.php000064400000003166147600331220011301 0ustar00from($reports_table)->where('report_id', '=', $this->get_field('id'))->first(); if (\is_null($existing_report)) { \wp_send_json_error(); } $report = new Report((object) ['type' => $existing_report->type]); $report_finder = new Report_Finder(); $reports = $report_finder->by_type($existing_report->type); $report_index = 0; foreach ($reports as $index => $report) { if ($report->id() === $existing_report->report_id) { $report_index = $index; } } if (\array_key_exists($report_index + 1, $reports)) { $report = $reports[$report_index + 1]; } elseif ($report_index > 0 && \array_key_exists($report_index - 1, $reports)) { $report = $reports[$report_index - 1]; } Illuminate_Builder::new()->from($reports_table)->where('report_id', '=', $this->get_field('id'))->delete(); \wp_send_json_success(['url' => $report->url()]); } } IAWP/AJAX/Dismiss_Notice.php000064400000001573147600331220011460 0ustar00get_field('id'); if ($id == 'iawp_need_clear_cache') { \update_option('iawp_need_clear_cache', \false, \true); } elseif ($id == 'iawp_show_gsg') { \update_option('iawp_show_gsg', '0', \true); } elseif ($id == 'iawp_clicks_sync_notice') { \update_option('iawp_clicks_sync_notice', \true, \true); } elseif ($id == 'enable-logged-in-tracking') { \update_option('iawp_logged_in_tracking_notice', \true, \true); } return; } } IAWP/AJAX/Edit_Link.php000064400000005467147600331220010414 0ustar00get_int_field('id'); $link_properties = ['name' => $this->get_field('name'), 'type' => $this->get_field('type'), 'value' => $this->get_field('value')]; // Validate foreach ($link_properties as $key => $value) { $error = Link_Validator::validate($key, $value, $link_properties['type']); if ($error) { \wp_send_json_error(['error' => $error, 'property' => $key]); } } // Sanitize $link_properties['name'] = \sanitize_text_field($link_properties['name']); $link_properties['type'] = \sanitize_text_field($link_properties['type']); if ($link_properties['type'] == 'domain') { $link_properties['value'] = Link_Validator::sanitize_domain($link_properties['value']); } elseif ($link_properties['type'] == 'subdirectory') { $link_properties['value'] = Link_Validator::sanitize_subdirectory($link_properties['value']); } else { $link_properties['value'] = \sanitize_text_field($link_properties['value']); } $link_rule = null; if (\is_int($link_id)) { $link_rule = Click_Tracking\Link_Rule::find($link_id); if ($link_rule->type() !== $link_properties['type'] || $link_rule->value() !== $link_properties['value']) { \delete_option('iawp_click_tracking_cache_cleared'); } } else { \delete_option('iawp_click_tracking_cache_cleared'); } if ($link_rule) { Illuminate_Builder::new()->from(Tables::link_rules())->where('link_rule_id', '=', $link_id)->update($link_properties); } else { $link_properties['created_at'] = (new \DateTime())->format('Y-m-d H:i:s'); $link_id = Illuminate_Builder::new()->from(Tables::link_rules())->insertGetId($link_properties); } // Fetch a fresh copy $link_rule = Click_Tracking\Link_Rule::find($link_id); \wp_send_json_success(['shouldShowCacheMessage' => \get_option('iawp_click_tracking_cache_cleared') === \false, 'html' => \IAWPSCOPED\iawp_blade()->run('click-tracking.link', ['link' => $link_rule->to_array(), 'types' => Click_Tracking::types(), 'extensions' => Click_Tracking::extensions(), 'protocols' => Click_Tracking::protocols()])]); } } IAWP/AJAX/Export_Campaigns.php000064400000001335147600331220012003 0ustar00csv($campaigns->rows()); echo $csv->to_string(); } } IAWP/AJAX/Export_Clicks.php000064400000001365147600331220011314 0ustar00sanitize_sort_parameters()); $csv = $table->csv($clicks->rows()); echo $csv->to_string(); } } IAWP/AJAX/Export_Devices.php000064400000001222147600331220011456 0ustar00csv($device_types->rows()); echo $csv->to_string(); } } IAWP/AJAX/Export_Geo.php000064400000001154147600331220010612 0ustar00csv($geos->rows()); echo $csv->to_string(); } } IAWP/AJAX/Export_Pages.php000064400000001166147600331220011142 0ustar00csv($resources->rows()); echo $csv->to_string(); } } IAWP/AJAX/Export_Referrers.php000064400000001216147600331220012036 0ustar00csv($referrers->rows()); echo $csv->to_string(); } } IAWP/AJAX/Export_Reports.php000064400000001726147600331220011543 0ustar00get_field('ids'); if (\count($ids) === 0) { \wp_send_json_error([], 400); } $report_finder = new Report_Finder(); $reports = $report_finder->by_ids($ids); $reports_array = \array_map(function ($report) { return $report->to_array(); }, $reports); \wp_send_json_success(['json' => \json_encode(['plugin_version' => '2.9.7', 'database_version' => '39', 'export_version' => '1', 'reports' => $reports_array])]); } } IAWP/AJAX/Filter.php000064400000012004147600331220007760 0ustar00get_date_range(); $is_new_date_range = $this->get_field('is_new_date_range') === 'true'; $filters = $this->get_field('filters') ?? []; $sort_column = $this->get_field('sort_column') ?? null; $sort_direction = $this->get_field('sort_direction') ?? null; $group = $this->get_field('group') ?? null; $as_csv = $this->get_field('as_csv') ?? \false; $is_new_group = $this->get_field('is_new_group') === 'true'; $chart_interval = $is_new_date_range ? Intervals::default_for($date_range->number_of_days()) : Intervals::find_by_id($this->get_field('chart_interval')); $page = \intval($this->get_field('page') ?? 1); $number_of_rows = $page * \IAWPSCOPED\iawp()->pagination_page_size(); $table_type = $this->get_field('table_type'); $is_geo_table = $table_type === 'geo'; $table_class = Env::get_table(); /** @var Table $table */ $table = new $table_class($group, $is_new_group); $filters = $table->sanitize_filters($filters); $sort_configuration = $table->sanitize_sort_parameters($sort_column, $sort_direction); $rows_class = $table->group()->rows_class(); $statistics_class = $table->group()->statistics_class(); if ($as_csv) { $rows_query = new $rows_class($date_range, null, $filters, $sort_configuration); $rows = $rows_query->rows(); $csv = $table->csv($rows, \true); echo $csv->to_string(); return; } if ($is_geo_table) { $rows_query = new $rows_class($date_range, null, $filters, $sort_configuration); } else { $rows_query = new $rows_class($date_range, $number_of_rows, $filters, $sort_configuration); } $rows = $rows_query->rows(); if (empty($filters)) { /** @var Statistics $statistics */ $statistics = new $statistics_class($date_range, null, $chart_interval); } else { $statistics = new $statistics_class($date_range, $rows_query, $chart_interval); } $total_number_of_rows = $statistics->total_number_of_rows(); if ($is_geo_table) { $chart = new Chart_Geo($rows, $date_range->label()); $rows = \array_slice($rows, 0, $number_of_rows); } else { $chart = new Chart($statistics); } $table->set_statistics($statistics); $quick_stats = new Quick_Stats($statistics); \wp_send_json_success(['rows' => $table->get_rendered_template($rows, \true, $sort_configuration->column(), $sort_configuration->direction()), 'table' => $table->get_rendered_template($rows, \false, $sort_configuration->column(), $sort_configuration->direction()), 'totalNumberOfRows' => $total_number_of_rows, 'chart' => $chart->get_html(), 'stats' => $quick_stats->get_html(), 'label' => $date_range->label(), 'isLastPage' => \count($rows) < \IAWPSCOPED\iawp()->pagination_page_size() * $page, 'columns' => $table->visible_column_ids(), 'columnsHTML' => $table->column_picker_html(), 'groupId' => $table->group()->id(), 'filters' => $filters, 'filtersTemplateHTML' => $table->filters_template_html(), 'filtersButtonsHTML' => $table->filters_condition_buttons_html($filters), 'chartInterval' => $chart_interval->id()]); } /** * Get the date range for the filter request * * The date info can be supplied in one of two ways. * * The first is to provide a relative_range_id which is converted into start, end, and label. * * The second is to provide explicit start and end fields which will be used as is. * * @return Date_Range */ private function get_date_range() : Date_Range { $relative_range_id = $this->get_field('relative_range_id'); $exact_start = $this->get_field('exact_start'); $exact_end = $this->get_field('exact_end'); if (!\is_null($exact_start) && !\is_null($exact_end)) { try { $start = new DateTime($exact_start, Timezone::site_timezone()); $end = new DateTime($exact_end, Timezone::site_timezone()); return new Exact_Date_Range($start, $end); } catch (Throwable $e) { // Do nothing and fall back to default relative date range } } return new Relative_Date_Range($relative_range_id); } } IAWP/AJAX/Import_Reports.php000064400000001507147600331220011531 0ustar00get_options_for_creating()); } \wp_send_json_success([]); } } IAWP/AJAX/Migration_Status.php000064400000002221147600331220012027 0ustar00 Migrations\Migrations::is_migrating()]; if (\get_option('iawp_migration_error', null) && \get_option('iawp_migration_error_query', null)) { $response['errorHtml'] = \IAWPSCOPED\iawp_blade()->run('interrupt.migration-error', ['plugin_version' => \IAWP_VERSION, 'migration_db_version' => \intval(\get_option('iawp_db_version', 0)) + 1, 'migration_step' => \intval(\get_option('iawp_last_finished_migration_step', 0)) + 1, 'migration_error' => \get_option('iawp_migration_error', null), 'migration_error_query' => \get_option('iawp_migration_error_query', null)]); } \wp_send_json_success($response); } } IAWP/AJAX/Preview_Email.php000064400000001222147600331220011263 0ustar00get_field('colors'))); $email = \IAWPSCOPED\iawp()->email_reports->get_email_body($colors); \wp_send_json_success(['html' => $email]); } } IAWP/AJAX/Real_Time_Data.php000064400000000712147600331220011330 0ustar00get_real_time_analytics()); } } IAWP/AJAX/Rename_Report.php000064400000001570147600331220011303 0ustar00get_field('name')); if (\strlen($name) === 0) { \wp_send_json_error([], 400); } Illuminate_Builder::new()->from($reports_table)->where('report_id', '=', $this->get_field('id'))->update(['name' => $name]); \wp_send_json_success(['name' => $name]); } } IAWP/AJAX/Reset_Analytics.php000064400000001322147600331220011625 0ustar00get_field('confirmation'); $valid = \strtolower($confirmation) == 'reset analytics'; if (!$valid) { \wp_send_json_error([], 400); } $manager = new Database_Manager(); $manager->reset_analytics(); \wp_send_json_success([]); } } IAWP/AJAX/Save_Report.php000064400000001644147600331220010774 0ustar00get_options_for_updating()) > 0) { Illuminate_Builder::new()->from($reports_table)->where('report_id', '=', $this->get_field('id'))->update($report_options_parser->get_options_for_updating()); } } } IAWP/AJAX/Set_Favorite_Report.php000064400000002261147600331220012464 0ustar00get_field('id'); $type = $this->get_field('type'); if (!\is_null(Report_Finder::by_id($id))) { \delete_user_meta(\get_current_user_id(), 'iawp_favorite_report_id'); \delete_user_meta(\get_current_user_id(), 'iawp_favorite_report_type'); \update_user_meta(\get_current_user_id(), 'iawp_favorite_report_id', $id); \wp_send_json_success([]); } if (Report::is_valid_report_type($type)) { \delete_user_meta(\get_current_user_id(), 'iawp_favorite_report_id'); \delete_user_meta(\get_current_user_id(), 'iawp_favorite_report_type'); \update_user_meta(\get_current_user_id(), 'iawp_favorite_report_type', $type); \wp_send_json_success([]); } \wp_send_json_error([], 400); } } IAWP/AJAX/Set_WooCommerce_Statuses_To_Track.php000064400000001747147600331220015262 0ustar00get_field('statusesToTrack'); $reset_to_default = $this->get_boolean_field('resetToDefault'); $status_manager = new WooCommerce_Status_Manager(); if ($reset_to_default) { $status_manager->reset_tracked_statuses(); $status_manager->update_order_records_based_on_tracked_statuses(); } elseif (\is_array($statuses_to_track)) { $status_manager->set_tracked_statuses($statuses_to_track); $status_manager->update_order_records_based_on_tracked_statuses(); } \wp_send_json_success(['statusesToTrack' => $status_manager->get_statuses()]); } } IAWP/AJAX/Sort_Links.php000064400000001550147600331220010626 0ustar00get_field('ids') as $index => $id) { Illuminate_Builder::new()->from(Tables::link_rules())->where('link_rule_id', '=', $id)->update(['position' => $index]); } \wp_send_json_success(); } } IAWP/AJAX/Sort_Reports.php000064400000002115147600331220011202 0ustar00from($reports_table)->where('type', '=', $this->get_field('type'))->update(['position' => null]); foreach ($this->get_field('ids') as $index => $id) { Illuminate_Builder::new()->from($reports_table)->where('type', '=', $this->get_field('type'))->where('report_id', '=', $id)->update(['position' => $index]); } \wp_send_json_success(); } } IAWP/AJAX/Test_Email.php000064400000001045147600331220010564 0ustar00email_reports->send_email_report(\true); echo \rest_sanitize_boolean($sent); } } IAWP/AJAX/Update_Capabilities.php000064400000001107147600331220012430 0ustar00get_field('capabilities'); Capability_Manager::edit_all_capabilities($capabilities); \update_option('iawp_white_label', $this->get_boolean_field('white_label'), \true); } } IAWP/AJAX/Update_User_Settings.php000064400000001040147600331220012631 0ustar00get_boolean_field('is_sidebar_collapsed'); if (\is_bool($is_sidebar_collapsed)) { \update_user_meta(\get_current_user_id(), 'iawp_is_sidebar_collapsed', $is_sidebar_collapsed); } \wp_send_json_success([]); } } IAWP/Admin_Page/Admin_Page.php000064400000004057147600331220011771 0ustar00run('interrupt.migration-is-running'); return; } $options = Dashboard_Options::getInstance(); $tab = (new Env())->get_tab(); ?>
run('partials.sidebar', ['favorite_report' => Report_Finder::get_favorite(), 'report_finder' => new Report_Finder(), 'is_white_labeled' => Capability_Manager::show_white_labeled_ui(), 'can_edit_settings' => Capability_Manager::can_edit(), 'is_dark_mode' => \get_option('iawp_dark_mode')]); } ?>
render_page(); ?>
get_date_range(); $tab = (new Env())->get_tab(); if ($tab === 'views') { $table = new Table_Pages(); $statistics_class = $table->group()->statistics_class(); $statistics = new $statistics_class($date_rage, null, $options->chart_interval()); $stats = new Quick_Stats($statistics); $chart = new Chart($statistics); $this->interface($table, $stats, $chart); } elseif ($tab === 'referrers') { $table = new Table_Referrers(); $statistics_class = $table->group()->statistics_class(); $statistics = new $statistics_class($date_rage, null, $options->chart_interval()); $stats = new Quick_Stats($statistics); $chart = new Chart($statistics); $this->interface($table, $stats, $chart); } elseif ($tab === 'geo') { $table = new Table_Geo($options->group()); $statistics_class = $table->group()->statistics_class(); $statistics = new $statistics_class($date_rage, null, $options->chart_interval()); $stats = new Quick_Stats($statistics); $table_data_class = $table->group()->rows_class(); $geo_data = new $table_data_class($date_rage); $chart = new Chart_Geo($geo_data->rows()); $this->interface($table, $stats, $chart); } elseif ($tab === 'campaigns') { $table = new Table_Campaigns(); $statistics_class = $table->group()->statistics_class(); $statistics = new $statistics_class($date_rage, null, $options->chart_interval()); $stats = new Quick_Stats($statistics); $chart = new Chart($statistics); $this->interface($table, $stats, $chart); } elseif ($tab === 'clicks') { $table = new Table_Clicks(); $statistics_class = $table->group()->statistics_class(); $statistics = new $statistics_class($date_rage, null, $options->chart_interval()); $stats = new Quick_Stats($statistics); $chart = new Chart($statistics); $this->interface($table, $stats, $chart); } elseif ($tab === 'devices') { $table = new Table_Devices($options->group()); $statistics_class = $table->group()->statistics_class(); $statistics = new $statistics_class($date_rage, null, $options->chart_interval()); $stats = new Quick_Stats($statistics); $chart = new Chart($statistics); $this->interface($table, $stats, $chart); } elseif ($tab === 'real-time') { (new Real_Time())->render_real_time_analytics(); } } private function interface(Table $table, $stats, $chart) { $options = Dashboard_Options::getInstance(); $sort_configuration = $table->sanitize_sort_parameters($options->sort_column(), $options->sort_direction()); ?>
run('partials.report-header', ['report' => (new Report_Finder())->current(), 'can_edit' => Capability_Manager::can_edit()]); ?> output_report_toolbar(); ?>
get_html(); ?> get_html(); ?> get_table_toolbar_markup(); ?> get_table_markup($sort_configuration->column(), $sort_configuration->direction()); ?>
'; echo \esc_html_x('Geolocation data powered by', 'Following text is a noun: DB-IP', 'independent-analytics') . ' ' . 'DB-IP.'; echo ''; } ?>
has_conflict()) { echo \IAWPSCOPED\iawp_blade()->run('notices.notice', ['notice_text' => $plugin_conflict_detector->get_error(), 'button_text' => \false, 'id' => 'plugin-conflict', 'notice' => 'iawp-error', 'url' => 'https://independentwp.com/knowledgebase/tracking/secure-rest-api/']); } elseif (\IAWPSCOPED\iawp_is_pro() && \is_plugin_active('better-wp-security/better-wp-security.php')) { $settings = \get_option('itsec-storage'); if (\array_key_exists('system-tweaks', $settings)) { if (\array_key_exists('plugins_php', $settings['system-tweaks'])) { if ($settings['system-tweaks']['plugins_php']) { echo \IAWPSCOPED\iawp_blade()->run('notices.notice', ['notice_text' => \__('The "Solid Security" plugin is disabling PHP execution in the plugins folder, and this is preventing click tracking from working. Please visit the Security > Settings page, click on the Advanced section, click on System Tweaks Settings, uncheck the "Disable PHP Plugins" option, and then save.', 'independent-analytics'), 'button_text' => \false, 'id' => 'plugin-conflict', 'notice' => 'iawp-error', 'url' => 'https://independentwp.com/knowledgebase/click-tracking/allow-php-execution-plugins-folder/']); } } } } if (\get_option('iawp_need_clear_cache')) { echo \IAWPSCOPED\iawp_blade()->run('notices.notice', ['notice_text' => \__('Please clear your cache to ensure tracking works properly.', 'independent-analytics'), 'button_text' => \__('I\'ve cleared the cache', 'independent-analytics'), 'id' => 'iawp_need_clear_cache', 'notice' => 'iawp-warning', 'url' => 'https://independentwp.com/knowledgebase/common-questions/views-not-recording/']); } $requires_logged_in_tracking = $plugin_conflict_detector->plugin_requiring_logged_in_tracking(); $show_logged_in_tracking_notice = $requires_logged_in_tracking && !\get_option('iawp_track_authenticated_users') && !\get_option('iawp_need_clear_cache') && !\get_option('iawp_logged_in_tracking_notice'); if ($show_logged_in_tracking_notice) { echo \IAWPSCOPED\iawp_blade()->run('notices.notice', ['notice_text' => '' . \sprintf(\_x('%s compatibility:', 'Variable is the name of a plugin', 'independent-analytics'), $requires_logged_in_tracking) . ' ' . \__('We recommend you enable tracking for logged-in visitors.', 'independent-analytics'), 'button_text' => \__('Dismiss', 'independent-analytics'), 'id' => 'enable-logged-in-tracking', 'notice' => 'iawp-warning', 'url' => 'https://independentwp.com/knowledgebase/tracking/how-to-track-logged-in-visitors/']); } if (\IAWPSCOPED\iawp_db_version() > 0 && !Database::has_correct_database_privileges()) { echo \IAWPSCOPED\iawp_blade()->run('notices.notice', ['notice_text' => \__('Your site is missing the following critical database permissions:', 'independent-analytics') . ' ' . \implode(', ', Database::missing_database_privileges()) . '. ' . \__('There is no issue at this time, but you will need to enable the missing permissions before updating the plugin to a newer version to ensure an error is avoided. Please click this link to read our tutorial:', 'independent-analytics'), 'button_text' => \false, 'id' => 'missing-permissions', 'notice' => 'iawp-error', 'url' => 'https://independentwp.com/knowledgebase/common-questions/missing-database-permissions/']); } if (Env::get_tab() === 'clicks') { if (!\get_option('iawp_clicks_sync_notice')) { echo \IAWPSCOPED\iawp_blade()->run('notices.notice', ['notice_text' => \__('Click data syncs every 60 seconds. Please allow for this delay when testing clicks on new links.', 'independent-analytics'), 'button_text' => \__('Dismiss', 'independent-analytics'), 'id' => 'iawp_clicks_sync_notice', 'notice' => 'iawp-warning', 'url' => 'https://independentwp.com/knowledgebase/click-tracking/click-tracking-update-process/']); } } } ?>
has_conflict() && (Env::get_tab() !== 'clicks' || Env::get_tab() === 'clicks' && \get_option('iawp_clicks_sync_notice'))) { echo \IAWPSCOPED\iawp_blade()->run('notices.getting-started'); } } } IAWP/Admin_Page/Campaign_Builder_Page.php000064400000000401147600331220014113 0ustar00render_campaign_builder(); } } IAWP/Admin_Page/Click_Tracking_Page.php000064400000000767147600331220013614 0ustar00' . \esc_html__('You do not have permission to edit the click tracking settings.', 'independent-analytics') . '

'; } } } IAWP/Admin_Page/Settings_Page.php000064400000000733147600331220012536 0ustar00settings->render_settings(); } else { echo '

' . \esc_html__('You do not have permission to edit the settings.', 'independent-analytics') . '

'; } } } IAWP/Admin_Page/Support_Page.php000064400000000734147600331220012413 0ustar00run('support'); } else { echo '

' . \esc_html__('You do not have permission to view this page.', 'independent-analytics') . '

'; } } } IAWP/Admin_Page/Updates_Page.php000064400000001226147600331220012341 0ustar00run('updates'); $this->update_latest_update_viewed(); } else { echo '

' . \esc_html__('You do not have permission to view this page.', 'independent-analytics') . '

'; } } private function update_latest_update_viewed() { \update_option('iawp_last_update_viewed', \IAWP_VERSION, \true); } } IAWP/Click_Tracking/Click.php000064400000007666147600331220011726 0ustar00protocol = $this->extract_protocol_from_href($record['href']); $this->value = $this->extract_target_value_from_href($record['href']); $this->href = $record['href']; $this->classes = $record['classes']; $this->resource_id = $record['resource_id']; $this->visitor_id = $record['visitor_id']; $this->created_at = $record['created_at']; } /** * Update the database * * @return void */ public function track() : void { $link_rules = \IAWP\Click_Tracking\Link_Rule_Finder::new($this->protocol, $this->href, $this->classes)->links(); if ($link_rules->isEmpty()) { return; } $click_target = $this->get_click_target(); $view_id = $this->get_view_id(); if (\is_null($view_id)) { return; } $click_id = Illuminate_Builder::new()->from(Tables::clicks())->insertGetId(['click_target_id' => $click_target->click_target_id, 'view_id' => $view_id, 'created_at' => $this->created_at->format('Y-m-d H:i:s')]); $link_rules->each(function ($link_rule) use($click_id) { Illuminate_Builder::new()->from(Tables::clicked_links())->insertGetId(['click_id' => $click_id, 'link_rule_id' => $link_rule->id()]); }); } private function extract_protocol_from_href(?string $href) : ?string { if (\is_null($href)) { return null; } if (Str::startsWith($href, ['tel:', 'mailto:'])) { return Str::before($href, ':'); } return null; } private function extract_target_value_from_href(?string $href) : ?string { if (\is_null($href)) { return null; } if (Str::startsWith($href, ['tel:', 'mailto:'])) { return Str::after($href, ':'); } return $href; } private function get_click_target() : object { $select_query = Illuminate_Builder::new()->from(Tables::click_targets())->where('target', '=', $this->value)->when(\is_null($this->protocol), function (Builder $query) { $query->whereNull('protocol'); })->when(\is_string($this->protocol), function (Builder $query) { $query->where('protocol', '=', $this->protocol); }); $target = $select_query->first(); if (\is_object($target)) { return $target; } Illuminate_Builder::new()->from(Tables::click_targets())->insertOrIgnore(['target' => $this->value, 'protocol' => $this->protocol]); return $select_query->first(); } private function get_view_id() : ?int { $sessions_table = Tables::sessions(); $view_id = Illuminate_Builder::new()->from(Tables::views(), 'views')->join("{$sessions_table} AS sessions", 'views.session_id', '=', 'sessions.session_id')->where('views.resource_id', '=', $this->resource_id)->where('sessions.visitor_id', '=', $this->visitor_id)->where('views.viewed_at', '<=', $this->created_at->format('Y-m-d H:i:s'))->orderByDesc('views.viewed_at')->limit(1)->value('views.id'); // There's a small chance that view_id is a string instead of an int. In that case, // it should be converted to a string. // https://github.com/andrewjmead/independent-analytics/issues/1335 if (\is_string($view_id)) { return (int) $view_id; } if (\is_int($view_id)) { return $view_id; } return null; } public static function new(array $record) : ?self { return new self($record); } } IAWP/Click_Tracking/Click_Processing_Job.php000064400000006030147600331220014674 0ustar00get_click_data_file(); if ($click_data_file === null) { return; } $job_file = $this->create_job_file($click_data_file); if ($job_file === null) { return; } $job_handle = \fopen($job_file, 'r'); if ($job_handle === \false) { return; } // The first line for the PHP file is an exit statement to keep the contents private. This // should be skipped when parsing the file. if (\pathinfo($job_file, \PATHINFO_EXTENSION) === 'php') { \fgets($job_handle); // Skip first line } while (($json = \fgets($job_handle)) !== \false) { $event = \json_decode($json, \true); $event['href'] = Security::string($event['href']); $event['classes'] = Security::string($event['classes']); if (\is_null($event)) { continue; } $payload_validator = Payload_Validator::new($event['payload'], $event['signature']); if (!$payload_validator->is_valid() || \is_null($payload_validator->resource())) { continue; } $click = \IAWP\Click_Tracking\Click::new(['href' => $event['href'], 'classes' => $event['classes'], 'resource_id' => $payload_validator->resource()['id'], 'visitor_id' => Visitor::fetch_visitor_id_by_hash($event['visitor_token']), 'created_at' => \DateTime::createFromFormat('U', $event['created_at'])]); $click->track(); } \fclose($job_handle); \unlink($job_file); } private function get_click_data_file() : ?string { $text_file = Str::finish(\sys_get_temp_dir(), \DIRECTORY_SEPARATOR) . "iawp-click-data.txt"; if (\is_file($text_file)) { return $text_file; } $php_file = \IAWPSCOPED\iawp_path_to('iawp-click-data.php'); if (\is_file($php_file)) { return $php_file; } return null; } private function create_job_file(string $file) : ?string { if (!\is_file($file)) { return null; } $job_id = \rand(); $extension = \pathinfo($file, \PATHINFO_EXTENSION); $job_file = Str::finish(\dirname($file), \DIRECTORY_SEPARATOR) . "iawp-click-data-{$job_id}.{$extension}"; \rename($file, $job_file); if (!\is_file($job_file)) { return null; } return $job_file; } } IAWP/Click_Tracking/Config_File_Manager.php000064400000003573147600331220014470 0ustar00 \IAWPSCOPED\iawp_is_pro(), 'visitor_token_salt' => Salt::visitor_token_salt()]; if (\is_string(Request::custom_ip_header())) { $data['custom_ip_header'] = Request::custom_ip_header(); } $contents = "\n"; $contents .= \json_encode($data); \file_put_contents(self::config_file_path(), $contents); } /** * For a couple releases, click tracking files were in the uploads folder. This method is responsible for * cleaning them up if they are still there. * * @return void */ private static function remove_legacy_files() : void { self::delete_file(\IAWPSCOPED\iawp_upload_path_to('/iawp-click-endpoint.php')); self::delete_file(\IAWPSCOPED\iawp_upload_path_to('/iawp-click-config.php')); self::delete_file(\IAWPSCOPED\iawp_upload_path_to('/iawp-click-data.php')); } private static function config_file_path() : string { return \IAWPSCOPED\iawp_path_to('/iawp-click-config.php'); } private static function delete_file(string $file) : void { if (\is_file($file)) { \unlink($file); } } } IAWP/Click_Tracking/Link_Rule.php000064400000004125147600331220012550 0ustar00is_active)) { $attributes->is_active = (int) $attributes->is_active; } $this->attributes = $attributes; } public function id() : int { return $this->attributes->link_rule_id; } public function name() : string { return $this->attributes->name; } public function type() : string { return $this->attributes->type; } public function value() : string { return $this->attributes->value; } public function toggle_active() : bool { $new_is_active = !$this->is_active() ? 1 : 0; $records_updated = Illuminate_Builder::new()->from(Tables::link_rules())->where('link_rule_id', '=', $this->id())->update(['is_active' => $new_is_active]); if ($records_updated === 1) { $this->attributes->is_active = $new_is_active; return \true; } else { return \false; } } public function is_active() : bool { return $this->attributes->is_active === 1; } public function to_array() : array { $array = (array) $this->attributes; // Rename id $array['id'] = $array['link_rule_id']; unset($array['link_rule_id']); // Convert is_active to a boolean $array['is_active'] = $array['is_active'] === 1 ? \true : \false; return $array; } public static function find(int $id) : ?self { $link_rule = Illuminate_Builder::new()->from(Tables::link_rules())->where('link_rule_id', '=', $id)->first(); if (\is_null($link_rule)) { return null; } return new self($link_rule); } } IAWP/Click_Tracking/Link_Rule_Finder.php000064400000010455147600331220014042 0ustar00protocol = $protocol; $this->href = $href; $this->classes = $classes; } public function links() : ?Collection { return self::get_database_records()->filter(function ($link_rule) { return $link_rule->is_active(); })->filter(function ($link_rule) { return $this->is_match($link_rule); })->values(); } private function is_match($link_rule) : bool { switch ($link_rule->type()) { case 'class': return $this->is_matching_class($link_rule); case 'domain': return $this->is_matching_domain($link_rule); case 'extension': return $this->is_matching_extension($link_rule); case 'subdirectory': return $this->is_matching_subdirectory($link_rule); case 'protocol': return $this->is_matching_protocol($link_rule); default: return \false; } } private function is_matching_class($link_rule) : bool { if ($this->classes === "") { return \false; } return Collection::make(\explode(' ', $this->classes))->contains(function ($value, $key) use($link_rule) { return $link_rule->value() === $value; }); } private function is_matching_domain($link_rule) : bool { if (\is_null($this->href)) { return \false; } $url = new URL($this->href); if (!$url->is_valid_url()) { return \false; } return $link_rule->value() === $url->get_domain(); } private function is_matching_extension($link_rule) : bool { if (\is_null($this->href)) { return \false; } $url = new URL($this->href); if (!$url->is_valid_url()) { return \false; } return $link_rule->value() === $url->get_extension(); } private function is_matching_subdirectory($link_rule) : bool { if (\is_null($this->href)) { return \false; } $url = URL::new($this->href); $site_url = URL::new(\get_site_url()); if (!$url->is_valid_url() || $url->get_domain() !== $site_url->get_domain()) { return \false; } $path = $url->get_path(); $path_parts = Collection::make(\explode('/', $path))->filter()->values(); if ($path_parts->isEmpty()) { return \false; } return $link_rule->value() === $path_parts->first(); } private function is_matching_protocol($link_rule) : bool { if (\is_null($this->href)) { return \false; } return $this->protocol === $link_rule->value(); } public static function new(?string $protocol, ?string $href, string $classes) : self { return new self($protocol, $href, $classes); } public static function link_rules() : Collection { return self::get_database_records(); } public static function active_link_rules() : Collection { return self::get_database_records()->filter(function ($link_rule) { return $link_rule->is_active(); }); } public static function inactive_link_rules() : Collection { return self::get_database_records()->filter(function ($link_rule) { return !$link_rule->is_active(); }); } private static function get_database_records() : Collection { if (\is_null(static::$database_records)) { $records = Illuminate_Builder::new()->from(Tables::link_rules())->orderBy('position')->orderByDesc('created_at')->get(); static::$database_records = $records->map(function ($link_rule) { return new \IAWP\Click_Tracking\Link_Rule($link_rule); }); } return static::$database_records; } } IAWP/Custom_WordPress_Columns/Views_Column.php000064400000006267147600331220015422 0ustar00 'integer', 'single' => \true, 'default' => 0, 'show_in_rest' => \true]); \add_filter("manage_edit-{$post_type_slug}_sortable_columns", [self::class, 'enable_sorting']); } } public static function set_column_header(array $columns, string $post_type = null) : array { // manage_pages_columns doesn't set the $post_type argument, so checking is_null() works for it if (\is_null($post_type) || \in_array($post_type, self::post_type_slugs())) { $columns[self::$meta_key] = \__('Views', 'independent-analytics') . ' (Independent Analytics)'; } return $columns; } public static function echo_cell_content($column_id, $post_id) : void { if ($column_id === self::$meta_key) { $total_views = \intval(\get_post_meta($post_id, self::$meta_key, \true)); echo Number_Formatter::decimal($total_views); } } public static function enable_sorting(array $columns) : array { $columns[self::$meta_key] = [self::$meta_key, 'DESC']; return $columns; } public static function configure_sorting($query) : void { // Limit to admin menus if (!\is_admin() || !$query->is_main_query() || \wp_doing_ajax() || \wp_doing_cron()) { return; } $order_by = $query->get('orderby'); if ($order_by === self::$meta_key) { $meta_query = ['relation' => 'OR', ['key' => self::$meta_key, 'compare' => 'NOT EXISTS'], ['key' => self::$meta_key]]; $query->set('meta_query', $meta_query); $query->set('orderby', 'meta_value_num'); } } private static function post_type_slugs() : array { $built_in_post_type_slugs = ['post', 'page']; $post_type_slugs = \get_post_types(['public' => \true, '_builtin' => \false]); $slugs = \array_merge($built_in_post_type_slugs, $post_type_slugs); $disallowed = ['elementor_library', 'e-landing-page']; return \array_diff($slugs, $disallowed); } } IAWP/Data_Pruning/Pruner.php000064400000011625147600331220011646 0ustar00cutoff_date = (new \IAWP\Data_Pruning\Pruning_Scheduler())->get_pruning_cutoff_as_datetime(); } private function run() { if (\is_null($this->cutoff_date)) { return; } $db = Illuminate_Builder::get_connection(); $db->transaction(function () { $sessions_table = Query::get_table_name(Query::SESSIONS); Illuminate_Builder::new()->from($sessions_table)->where('created_at', '<', $this->cutoff_date->format('Y-m-d\\TH:i:s'))->delete(); // Delete orphaned views $views_table = Query::get_table_name(Query::VIEWS); $this->delete_session_orphans($views_table, 'session_id'); // Delete orphaned form submissions $form_submissions_table = Query::get_table_name(Query::FORM_SUBMISSIONS); $this->delete_session_orphans($form_submissions_table, 'session_id'); // Delete orphaned WooCommerce orders $orders_table = Query::get_table_name(Query::ORDERS); $this->delete_view_orphans($orders_table, 'view_id', 'id'); // Delete orphaned visitors $visitors_table = Query::get_table_name(Query::VISITORS); $this->delete_session_orphans($visitors_table, 'visitor_id'); // Delete orphaned resources $resources_table = Query::get_table_name(Query::RESOURCES); $this->delete_view_orphans($resources_table, 'id', 'resource_id'); // Delete orphaned referrers $referrers_table = Query::get_table_name(Query::REFERRERS); $this->delete_session_orphans($referrers_table, 'id', 'referrer_id'); // Delete orphaned forms $forms_table = Query::get_table_name(Query::FORMS); Illuminate_Builder::new()->from($forms_table, 'orphans')->leftJoin("{$form_submissions_table} AS form_submissions", "orphans.form_id", '=', "form_submissions.form_id")->whereNull('form_submissions.form_id')->delete(); // Delete orphaned device browsers $device_browsers_table = Query::get_table_name(Query::DEVICE_BROWSERS); $this->delete_session_orphans($device_browsers_table, 'device_browser_id'); // Delete orphaned device oss $device_oss_table = Query::get_table_name(Query::DEVICE_OSS); $this->delete_session_orphans($device_oss_table, 'device_os_id'); // Delete orphaned device types $device_types_table = Query::get_table_name(Query::DEVICE_TYPES); $this->delete_session_orphans($device_types_table, 'device_type_id'); // Don't touch cities or countries for now // This would be a very different custom query as cities reference countries // Delete orphaned campaigns $campaigns_table = Query::get_table_name(Query::CAMPAIGNS); $this->delete_session_orphans($campaigns_table, 'campaign_id'); // Delete orphaned clicks $this->delete_view_orphans(Tables::clicks(), 'view_id', 'id'); // Delete orphaned clicked links $clicks_table = Tables::clicks(); Illuminate_Builder::new()->from(Tables::clicked_links(), 'orphans')->leftJoin("{$clicks_table} AS clicks", "orphans.click_id", '=', "clicks.click_id")->whereNull('clicks.click_id')->delete(); // Delete orphaned click targets Illuminate_Builder::new()->from(Tables::click_targets(), 'orphans')->leftJoin("{$clicks_table} AS clicks", "orphans.click_target_id", '=', "clicks.click_target_id")->whereNull('clicks.click_id')->delete(); }); \delete_option('iawp_beginning_of_time'); } private function delete_session_orphans(string $table, string $column, ?string $sessions_column = null) : int { $sessions_table = Query::get_table_name(Query::SESSIONS); $sessions_column = $sessions_column ?? $column; return Illuminate_Builder::new()->from($table, 'orphans')->leftJoin("{$sessions_table} AS sessions", "orphans.{$column}", '=', "sessions.{$sessions_column}")->whereNull('sessions.session_id')->delete(); } private function delete_view_orphans(string $table, string $column, ?string $views_column = null) : int { $views_table = Query::get_table_name(Query::VIEWS); $views_column = $views_column ?? $column; return Illuminate_Builder::new()->from($table, 'orphans')->leftJoin("{$views_table} AS views", "orphans.{$column}", '=', "views.{$views_column}")->whereNull('views.id')->delete(); } public static function register_hook() { \add_action('iawp_prune', function () { self::prune(); }); } public static function prune() { $pruner = new self(); $pruner->run(); } } IAWP/Data_Pruning/Pruning_Scheduler.php000064400000013217147600331220014012 0ustar00is_enabled()) { return null; } return $this->convert_cutoff_to_date($this->get_pruning_cutoff()); } public function status_message() : ?string { if (!$this->is_enabled()) { return null; } $scheduled_at = new \DateTime(); $scheduled_at->setTimezone(Timezone::site_timezone()); $scheduled_at->setTimestamp(\wp_next_scheduled('iawp_prune')); $day = $scheduled_at->format(\get_option('date_format')); $time = $scheduled_at->format(\IAWPSCOPED\iawp()->get_option('time_format', 'g:i a')); return \sprintf(\__('Next data pruning scheduled for %s at %s.', 'independent-analytics'), '' . $day . '', '' . $time . ''); } public function get_pruning_description(string $cutoff) : string { $date = $this->convert_cutoff_to_date($cutoff, \true); $utc_date = $this->convert_cutoff_to_date($cutoff); $formatted_date = $date->format(WordPress_Site_Date_Format_Pattern::for_php()); $estimates = $this->get_pruning_estimates($utc_date); return \sprintf(\__("All data from before %1\$s will be deleted immediately. This will remove %2\$s of your %3\$s tracked sessions. \n\n This process will repeat daily at midnight.", 'independent-analytics'), $formatted_date, \number_format_i18n($estimates['sessions_to_be_deleted']), \number_format_i18n($estimates['sessions'])); } /** * @return array{sessions: int, sessions_to_be_deleted: int} */ public function get_pruning_estimates(\DateTime $cutoff_date) : array { $sessions_table = Query::get_table_name(Query::SESSIONS); $sessions = Illuminate_Builder::new()->from($sessions_table)->selectRaw('COUNT(*) as sessions')->value('sessions'); $sessions_to_be_deleted = Illuminate_Builder::new()->from($sessions_table)->selectRaw('COUNT(*) as sessions')->where('created_at', '<', $cutoff_date)->value('sessions'); return ['sessions' => $sessions, 'sessions_to_be_deleted' => $sessions_to_be_deleted]; } public function update_pruning_cutoff(string $cutoff) : bool { $is_valid_cutoff = \false; foreach (self::$cutoff_options as $option) { if ($option[0] === $cutoff) { $is_valid_cutoff = \true; } } if (!$is_valid_cutoff) { return \false; } \update_option('iawp_pruning_cutoff', $cutoff, \true); $this->schedule_pruning($cutoff); return \true; } /** * Attempt to schedule pruning based on whatever existing cutoff option is saved * * @return void */ public function schedule() : void { $cutoff = \get_option('iawp_pruning_cutoff', ''); $this->update_pruning_cutoff($cutoff); } public function unschedule() : void { $scheduled_at_timestamp = \wp_next_scheduled('iawp_prune'); if (\is_int($scheduled_at_timestamp)) { \wp_unschedule_event($scheduled_at_timestamp, 'iawp_prune'); } } private function schedule_pruning(string $cutoff) : void { $this->unschedule(); if ($cutoff === 'disabled') { return; } $tomorrow = new \DateTime('tomorrow', Timezone::site_timezone()); \wp_schedule_event($tomorrow->getTimestamp(), 'daily', 'iawp_prune'); } private function convert_cutoff_to_date(string $cutoff, bool $as_site_timezone = \false) : \DateTime { $beginning_of_today = new CarbonImmutable('today', Timezone::site_timezone()); if (!$as_site_timezone) { $beginning_of_today = $beginning_of_today->setTimezone(Timezone::utc_timezone()); } switch ($cutoff) { case 'thirty-days': return $beginning_of_today->subDays(30)->toDate(); case 'sixty-days': return $beginning_of_today->subDays(60)->toDate(); case 'ninety-days': return $beginning_of_today->subDays(90)->toDate(); case 'one-hundred-and-eighty-days': return $beginning_of_today->subDays(180)->toDate(); case 'one-year': return $beginning_of_today->subYearsNoOverflow(1)->toDate(); case 'two-years': return $beginning_of_today->subYearsNoOverflow(2)->toDate(); case 'three-years': return $beginning_of_today->subYearsNoOverflow(3)->toDate(); case 'four-years': return $beginning_of_today->subYearsNoOverflow(4)->toDate(); } return $beginning_of_today->toDate(); } } IAWP/Date_Picker/Date_Picker.php000064400000003315147600331220012341 0ustar00start = $start; $this->end = $end; $this->relative_range = $relative_range; $this->first_data = Relative_Date_Range::beginning_of_time(); } public function calendar_html() { return \IAWPSCOPED\iawp_blade()->run('date-picker.date-picker', ['months' => $this->months(), 'start_date' => $this->start, 'end_date' => $this->end, 'relative_range' => $this->relative_range, 'date_ranges' => Relative_Date_Range::ranges(), 'timezone' => Timezone::site_timezone(), 'user_format' => \get_option('date_format'), 'first_data' => $this->first_data->format('Y-m-d'), 'site_offset_in_seconds' => Timezone::site_offset_in_seconds($this->start)]); } private function months() : array { $first_day_last_year = new \DateTime('first day of January last year', Timezone::site_timezone()); $start = $this->first_data < $first_day_last_year ? clone $this->first_data : clone $first_day_last_year; $start->modify('first day of this month')->setTime(0, 0, 0); $end = (new \DateTime('last day of this month', Timezone::site_timezone()))->setTime(23, 59, 59); $interval = new \DateInterval('P1M'); // 1 month interval $period = new \DatePeriod($start, $interval, $end); $months = []; foreach ($period as $month) { $months[] = new \IAWP\Date_Picker\Month($month, $start); } return $months; } } IAWP/Date_Picker/Month.php000064400000006611147600331220011256 0ustar00date = $date; $this->first_month = $first_month; } public function name() : string { return \IAWPSCOPED\iawp()->date_i18n('F Y', $this->date); } public function date_string() : string { return $this->date->format('Y-m'); } public function days() : \DatePeriod { $start = $this->date->modify('first day of this month'); $end = (clone $this->date)->modify('last day of this month'); $end->setTime(23, 59, 59); $interval = new \DateInterval('P1D'); // 1 day interval return new \DatePeriod($start, $interval, $end); } public function extra_cells() : int { $user_dow = \IAWPSCOPED\iawp()->get_option('iawp_dow', 0); $start = $this->date->modify('first day of this month'); $month_dow = $start->format('w'); if ($month_dow >= $user_dow) { return $month_dow - $user_dow; } else { return 7 - ($user_dow - $month_dow); } } public function month_class() : string { $now = new \DateTime('now'); $month = clone $this->date; $class = 'iawp-calendar-month'; if ($month->format('Y-m') === $this->first_month->format('Y-m')) { $class .= ' iawp-first-month'; } if ($now->format('Y-m') === $month->format('Y-m')) { $class .= ' iawp-current iawp-last-month'; } // Modifying $month here if ($now->format('Y n') === $month->modify('first day of +1 month')->format('Y n')) { $class .= ' iawp-previous'; } return $class; } public function day_class(\DateTime $day, string $first_data, string $start_date, string $end_date) : string { $date = $day->format('Y-m-d'); $class = 'iawp-day iawp-cell'; if ($date === \date('Y-m-d')) { $class .= ' iawp-today'; } if ($day->format('j') == '1') { $class .= ' first-of-month'; } if ($date === $first_data) { $class .= ' iawp-first-data'; } if ($date < $first_data || $date > \date('Y-m-d')) { $class .= ' out-of-range'; } if ($date === $start_date) { $class .= ' iawp-start'; if ($date === $end_date) { $class .= ' iawp-end'; } } elseif ($date === $end_date) { $class .= ' iawp-end'; } elseif ($date > $start_date && $date < $end_date) { $class .= ' in-range'; } return $class; } public function days_of_week() : string { $days = []; $html = ''; // Get the correct HTML for ($i = 0; $i < 7; $i++) { $days[] = '' . \date_i18n("D", \strtotime("Sunday +{$i} days")) . ''; } // Shift based on the user's selection for ($i = 0; $i < \IAWPSCOPED\iawp()->get_option('iawp_dow', 0); $i++) { $first_day = \array_shift($days); \array_push($days, $first_day); } // Create the HTMl string foreach ($days as $day) { $html .= $day; } return $html; } } IAWP/Date_Range/Date_Range.php000064400000006555147600331220012010 0ustar00start; } /** * @return string */ public function iso_start() : string { return $this->start->format('Y-m-d\\TH:i:s'); } /** * @return DateTime */ public function end() : DateTime { return $this->end; } /** * @return string */ public function iso_end() : string { return $this->end->format('Y-m-d\\TH:i:s'); } /** * TODO - Doesn't work well for units of varying size such as months * * @return Date_Range */ public function previous_period() : \IAWP\Date_Range\Date_Range { $range_size = $this->range_size_in_days(); $previous_start = (clone $this->start)->modify("-{$range_size} days"); $previous_end = (clone $this->end)->modify("-{$range_size} days"); return new \IAWP\Date_Range\Exact_Date_Range($previous_start, $previous_end, \false); } /** * TODO - Doesn't work well for units of varying size such as months * * @return Date_Range */ public function next_period() : \IAWP\Date_Range\Date_Range { $range_size = $this->range_size_in_days(); $next_start = (clone $this->start)->modify("+{$range_size} days"); $next_end = (clone $this->end)->modify("+{$range_size} days"); return new \IAWP\Date_Range\Exact_Date_Range($next_start, $next_end, \false); } public function number_of_days() : int { return \intval($this->start->diff($this->end)->format('%a')) + 1; } protected function set_range(DateTime $start, DateTime $end, bool $convert_to_full_days) { $start = clone $start; $end = clone $end; if ($convert_to_full_days) { $start = $this->start_of_locale_day($start); $end = $this->end_of_locale_day($end); } $this->start = $start; $this->end = $end; } /** * Return the range size in days for previous period calculations * * TODO - Doesn't work well for units of varying size such as months * * @return int */ private function range_size_in_days() : int { return $this->start->diff($this->end)->days + 1; } /** * Return a new DateTime representing the start of the day in the users timezone * * @param DateTime $datetime * * @return DateTime */ private function start_of_locale_day(\DateTime $datetime) : \DateTime { $datetime = clone $datetime; return $datetime->setTimezone(Timezone::site_timezone())->setTime(0, 0, 0)->setTimezone(Timezone::utc_timezone()); } /** * Return a new DateTime representing the end of the day in the users timezone * * @param DateTime $datetime * * @return DateTime */ private function end_of_locale_day(\DateTime $datetime) : \DateTime { $datetime = clone $datetime; return $datetime->setTimezone(Timezone::site_timezone())->setTime(23, 59, 59)->setTimezone(Timezone::utc_timezone()); } } IAWP/Date_Range/Exact_Date_Range.php000064400000002300147600331220013114 0ustar00set_range($start, $end, $convert_to_full_days); } /** * Get a formatted label for the range * * @return string */ public function label() : string { $formatted_start = \IAWPSCOPED\iawp()->date_i18n(\get_option('date_format'), $this->start); $formatted_end = \IAWPSCOPED\iawp()->date_i18n(\get_option('date_format'), $this->end); return $formatted_start . ' - ' . $formatted_end; } /** * Get a range that covers the entirety of the plugins lifetime * * @return Exact_Date_Range */ public static function comprehensive_range() : \IAWP\Date_Range\Exact_Date_Range { return new \IAWP\Date_Range\Exact_Date_Range(new DateTime('1991-01-06'), new DateTime()); } } IAWP/Date_Range/Relative_Date_Range.php000064400000022203147600331220013627 0ustar00relative_range_id = $relative_range_id; } // Call the method whose name matches the relative range id $method_name = \strtolower($relative_range_id); list($start, $end, $label) = $this->{$method_name}(); $this->set_range($start, $end, $convert_to_full_days); $this->label = $label; } /** * Get the id of the current range such as THIS_YEAR * * @return string */ public function relative_range_id() : string { return $this->relative_range_id; } public function label() : string { return $this->label; } private function today() : array { $tz = Timezone::site_timezone(); $today = new DateTime('now', $tz); return [$today, $today, \__('Today', 'independent-analytics')]; } private function yesterday() : array { $tz = Timezone::site_timezone(); $yesterday = new DateTime('-1 day', $tz); return [$yesterday, $yesterday, \__('Yesterday', 'independent-analytics')]; } private function last_seven() : array { $tz = Timezone::site_timezone(); $today = new DateTime('now', $tz); $seven_days_ago = new DateTime('-6 days', $tz); return [$seven_days_ago, $today, \__('Last 7 Days', 'independent-analytics')]; } private function last_thirty() : array { $tz = Timezone::site_timezone(); $today = new DateTime('now', $tz); $thirty_days_ago = new DateTime('-29 days', $tz); return [$thirty_days_ago, $today, \__('Last 30 Days', 'independent-analytics')]; } private function last_sixty() : array { $tz = Timezone::site_timezone(); $today = new DateTime('now', $tz); $sixty_days_ago = new DateTime('-59 days', $tz); return [$sixty_days_ago, $today, \__('Last 60 Days', 'independent-analytics')]; } private function last_ninety() : array { $tz = Timezone::site_timezone(); $today = new DateTime('now', $tz); $ninety_days_ago = new DateTime('-89 days', $tz); return [$ninety_days_ago, $today, \__('Last 90 Days', 'independent-analytics')]; } private function this_week() : array { $tz = Timezone::site_timezone(); $today = new DateTime('now', $tz); $firstDayOfWeek = \intval(\get_option('iawp_dow')); $currentDayOfWeek = \intval($today->format('w')); $startOfWeekDaysAgo = $currentDayOfWeek - $firstDayOfWeek; if ($startOfWeekDaysAgo < 0) { $startOfWeekDaysAgo += 7; } $startOfWeek = new DateTime("-{$startOfWeekDaysAgo} days", $tz); $endOfWeek = (clone $startOfWeek)->modify('+6 days'); return [$startOfWeek, $endOfWeek, \__('This Week', 'independent-analytics')]; } private function last_week() : array { list($start, $end) = $this->this_week(); $startOfWeek = $start->modify('-7 days'); $endOfWeek = $end->modify('-7 days'); return [$startOfWeek, $endOfWeek, \__('Last Week', 'independent-analytics')]; } private function this_month() : array { $tz = Timezone::site_timezone(); $today = new DateTime('now', $tz); $day_of_month = \intval($today->format('d')) - 1; $days_in_month = \intval($today->format('t')) - 1; $start_of_month = (clone $today)->modify("-{$day_of_month} days"); $end_of_month = (clone $start_of_month)->modify("+{$days_in_month} days"); return [$start_of_month, $end_of_month, \__('This Month', 'independent-analytics')]; } private function last_month() : array { list($start, $end) = $this->this_month(); $start_of_last_month = (clone $start)->modify('-1 month'); $days_in_last_month = \intval($start_of_last_month->format('t')) - 1; $end_of_last_month = (clone $start_of_last_month)->modify("+{$days_in_last_month} days"); return [$start_of_last_month, $end_of_last_month, \__('Last Month', 'independent-analytics')]; } private function last_three_months() : array { $tz = Timezone::site_timezone(); $first_of_three_months_ago = new DateTime('first day of last month', $tz); $first_of_three_months_ago = $first_of_three_months_ago->modify('-2 months'); $last_of_last_month = new DateTime('last day of last month', $tz); return [$first_of_three_months_ago, $last_of_last_month, \__('Last 3 Months', 'independent-analytics')]; } private function last_six_months() : array { $tz = Timezone::site_timezone(); $first_of_six_months_ago = new DateTime('first day of last month', $tz); $first_of_six_months_ago = $first_of_six_months_ago->modify('-5 months'); $last_of_last_month = new DateTime('last day of last month', $tz); return [$first_of_six_months_ago, $last_of_last_month, \__('Last 6 Months', 'independent-analytics')]; } private function last_twelve_months() : array { $tz = Timezone::site_timezone(); $first_of_twelve_months_ago = new DateTime('first day of last month', $tz); $first_of_twelve_months_ago = $first_of_twelve_months_ago->modify('-11 months'); $last_of_last_month = new DateTime('last day of last month', $tz); return [$first_of_twelve_months_ago, $last_of_last_month, \__('Last 12 Months', 'independent-analytics')]; } private function this_year() : array { $tz = Timezone::site_timezone(); $today = new DateTime('now', $tz); $year = \intval($today->format('Y')); $start_of_year = (clone $today)->setDate($year, 1, 1); $end_of_year = clone $today; return [$start_of_year, $end_of_year, \__('This Year', 'independent-analytics')]; } private function last_year() : array { $tz = Timezone::site_timezone(); $today = new DateTime('now', $tz); $last_year = \intval($today->format('Y')) - 1; $start_of_last_year = (clone $today)->setDate($last_year, 1, 1); $end_of_last_year = (clone $today)->setDate($last_year, 12, 31); return [$start_of_last_year, $end_of_last_year, \__('Last Year', 'independent-analytics')]; } private function all_time() : array { $tz = Timezone::site_timezone(); $today = new DateTime('now', $tz); return [self::beginning_of_time(), $today, \__('All Time', 'independent-analytics')]; } /** * Returns an array of relative ranges representing all supported ranges * * @return Relative_Date_Range[] */ public static function ranges() : array { return \array_map(function (string $range_id) { return new self($range_id); }, self::VALID_RELATIVE_RANGE_IDS); } /** * @return string[] */ public static function range_ids() : array { return self::VALID_RELATIVE_RANGE_IDS; } /** * @param string $relative_range_id * * @return bool */ public static function is_valid_range(string $relative_range_id) : bool { if (\in_array($relative_range_id, self::VALID_RELATIVE_RANGE_IDS)) { return \true; } return \false; } public static function beginning_of_time() : DateTime { $option_value = \get_option('iawp_beginning_of_time'); if ($option_value !== \false && $option_value !== '') { try { $date = new DateTime($option_value, Timezone::utc_timezone()); $date->setTimezone(Timezone::site_timezone()); return $date; } catch (\Throwable $e) { return new DateTime('now', Timezone::site_timezone()); } } $views_table = Query::get_table_name(Query::VIEWS); $first_view_at = Illuminate_Builder::new()->select('viewed_at')->from($views_table, 'views')->orderBy('viewed_at')->value('viewed_at'); if (\is_null($first_view_at)) { return new DateTime('now', Timezone::site_timezone()); } try { $date = new DateTime($first_view_at, Timezone::utc_timezone()); \update_option('iawp_beginning_of_time', $first_view_at); return $date; } catch (\Throwable $e) { return new DateTime('now', Timezone::site_timezone()); } } } IAWP/Ecommerce/SureCart_Event_Sync_Job.php000064400000004344147600331220014376 0ustar00is_surecart_support_enabled(); } public function handle() : void { $last_seen_event_at = \get_option('iawp_last_seen_surecart_event_at', \time()); $events = new Collection(); $page = 1; while (\true) { // If an event is older than the last one we've seen, then we have all the events we need if ($events->isNotEmpty() && $events->last()->created_at < $last_seen_event_at) { break; } if (!\class_exists('\\SureCart\\Models\\Event')) { break; } $page_of_events = \SureCart\Models\Event::where(['type' => ['refund.succeeded', 'purchase.created'], 'limit' => 100, 'page' => $page])->get(); if (\is_wp_error($page_of_events) || \count($page_of_events) === 0) { break; } $events = $events->concat($page_of_events); $page = $page + 1; } if ($events->isNotEmpty()) { \update_option('iawp_last_seen_surecart_event_at', $events->first()->created_at); } $events = $events->filter(function ($event) use($last_seen_event_at) { return $event->created_at > $last_seen_event_at; }); $events->filter(function ($event) { return $event->type === 'refund.succeeded'; })->map(function ($event) { return $event->data->object->charge; })->unique()->each(function ($charge_id) { \IAWP\Ecommerce\SureCart_Order::update_order_using_charge_id($charge_id); }); $events->filter(function ($event) { return $event->type === 'purchase.created'; })->map(function ($event) { return $event->data->object->initial_order; })->unique()->each(function ($order_id) { \IAWP\Ecommerce\SureCart_Order::update_order_using_order_id($order_id); }); } } IAWP/Ecommerce/SureCart_Order.php000064400000007174147600331220012606 0ustar00find($order_id); $this->order_id = $order_id; $this->status = $order->checkout->status; $this->total = $order->checkout->total_amount; $this->total_refunded = \absint($order->checkout->refunded_amount); $this->total_refunds = 0; if ($this->total_refunded > 0) { $refunds = \SureCart\Models\Refund::where(['charge_ids' => (new Collection($order->checkout->charges->data))->pluck('id')->toArray()])->get(); $this->total_refunds = \count($refunds); } $this->is_discounted = \absint($order->checkout->discount_amount) > 0 || \absint($order->checkout->total_savings_amount) > 0; } public function insert() : void { $visitor = Visitor::fetch_current_visitor(); if (!$visitor->has_recorded_session()) { return; } $orders_table = Query::get_table_name(Query::ORDERS); Illuminate_Builder::new()->from($orders_table)->insertOrIgnore(['is_included_in_analytics' => $this->status === 'paid', 'surecart_order_id' => $this->order_id, 'surecart_order_status' => $this->status, 'view_id' => $visitor->most_recent_view_id(), 'initial_view_id' => $visitor->most_recent_initial_view_id(), 'total' => $this->total, 'total_refunded' => $this->total_refunded, 'total_refunds' => $this->total_refunds, 'is_discounted' => $this->is_discounted, 'created_at' => (new \DateTime())->format('Y-m-d H:i:s')]); } public function update() : void { $orders_table = Query::get_table_name(Query::ORDERS); Illuminate_Builder::new()->from($orders_table)->where('surecart_order_id', '=', $this->order_id)->update(['is_included_in_analytics' => $this->status === 'paid', 'surecart_order_status' => $this->status, 'total' => $this->total, 'total_refunded' => $this->total_refunded, 'total_refunds' => $this->total_refunds, 'is_discounted' => $this->is_discounted]); } public static function register_hooks() { \add_action('surecart/purchase_created', function ($purchase) { try { $surecart_order = new self($purchase->getAttribute('initial_order')); $surecart_order->insert(); } catch (\Throwable $e) { \error_log('Independent Analytics was unable to track the analytics for a SureCart order. Please report this error to Independent Analytics. The error message is below.'); \error_log($e->getMessage()); } }, 10, 1); } public static function update_order_using_charge_id(string $charge_id) : void { if (!\class_exists('\\SureCart\\Models\\Charge')) { return; } $charge = \SureCart\Models\Charge::with(['checkout'])->find($charge_id); $surecart_order = new self($charge->checkout->order); $surecart_order->update(); } public static function update_order_using_order_id(string $order_id) : void { $surecart_order = new self($order_id); $surecart_order->update(); } } IAWP/Ecommerce/SureCart_Store.php000064400000001737147600331220012626 0ustar00currency); } } catch (\Throwable $e) { \update_option('iawp_surecart_currency_code', 'usd'); } } } public static function get_currency_code() : string { $currency_code = \get_option('iawp_surecart_currency_code', 'usd'); if (!\class_exists('\\SureCart\\Support\\Currency')) { return 'usd'; } if (!\array_key_exists($currency_code, \SureCart\Support\Currency::getSupportedCurrencies())) { $currency_code = 'usd'; } return $currency_code; } } IAWP/Ecommerce/WooCommerce_Order.php000064400000016230147600331220013266 0ustar00get_total() * 100)); // Total based on order currency, not shop currency $total_refunded = \intval(\round(\floatval($order->get_total_refunded()) * 100)); // Refund amount based on order currency, not shop currency // Aelia Currency Switcher $aelia_exchange_rate = $order->get_meta('_base_currency_exchange_rate'); if (\is_numeric($aelia_exchange_rate)) { // Exchange rate is from order currency to shop currency (multiply) $total = \intval(\round($total * \floatval($aelia_exchange_rate))); $total_refunded = \intval(\round($total_refunded * \floatval($aelia_exchange_rate))); } // WPML $wpml_exchange_rate = $this->wpml_exchange_rate($order->get_currency()); if (\is_float($wpml_exchange_rate)) { // Exchange rate is from shop currency to order currency (divide) $total = \intval(\round($total / $wpml_exchange_rate)); $total_refunded = \intval(\round($total_refunded / $wpml_exchange_rate)); } // Price Based on Country for WooCommerce $wcpbc_exchange_rate = $order->get_meta('_wcpbc_base_exchange_rate'); if (\is_numeric($wcpbc_exchange_rate)) { // Exchange rate is from order currency to shop currency (multiply) $total = \intval(\round($total * \floatval($wcpbc_exchange_rate))); $total_refunded = \intval(\round($total_refunded * \floatval($wcpbc_exchange_rate))); } $this->order_id = $order_id; $this->status = $order->get_status(); $this->total = $total; $this->total_refunded = $total_refunded; $this->total_refunds = \count($order->get_refunds()); $this->is_discounted = $this->is_discounted_order($order); } public function insert() : void { $visitor = Visitor::fetch_current_visitor(); if (!$visitor->has_recorded_session()) { return; } $orders_table = Query::get_table_name(Query::ORDERS); Illuminate_Builder::new()->from($orders_table)->insertOrIgnore(['is_included_in_analytics' => (new \IAWP\Ecommerce\WooCommerce_Status_Manager())->is_tracked_status($this->status), 'woocommerce_order_id' => $this->order_id, 'woocommerce_order_status' => $this->status, 'view_id' => $visitor->most_recent_view_id(), 'initial_view_id' => $visitor->most_recent_initial_view_id(), 'total' => $this->total, 'total_refunded' => $this->total_refunded, 'total_refunds' => $this->total_refunds, 'is_discounted' => $this->is_discounted, 'created_at' => (new \DateTime())->format('Y-m-d H:i:s')]); } public function update() : void { $orders_table = Query::get_table_name(Query::ORDERS); Illuminate_Builder::new()->from($orders_table)->where('woocommerce_order_id', '=', $this->order_id)->update(['is_included_in_analytics' => (new \IAWP\Ecommerce\WooCommerce_Status_Manager())->is_tracked_status($this->status), 'woocommerce_order_status' => $this->status, 'total' => $this->total, 'total_refunded' => $this->total_refunded, 'total_refunds' => $this->total_refunds, 'is_discounted' => $this->is_discounted]); } private function is_discounted_order($order) : bool { if ($order->get_total_discount() > 0) { return \true; } foreach ($order->get_items() as $item) { if ($item->get_product()->is_on_sale()) { return \true; } } return \false; } private function wpml_exchange_rate(string $currency_code) : ?float { if (!\is_plugin_active('woocommerce-multilingual/wpml-woocommerce.php')) { return null; } $wcml_options = \get_option('_wcml_settings'); if (!\is_array($wcml_options)) { return null; } if (!\array_key_exists('currency_options', $wcml_options)) { return null; } if (!\is_array($wcml_options['currency_options']) || !\array_key_exists($currency_code, $wcml_options['currency_options'])) { return null; } if (!\is_array($wcml_options['currency_options'][$currency_code]) || !\array_key_exists('rate', $wcml_options['currency_options'][$currency_code])) { return null; } $exchange_rate = \floatval($wcml_options['currency_options'][$currency_code]['rate']); // Was there an error parsing value as float? if ($exchange_rate === 0.0) { return null; } return $exchange_rate; } public static function register_hooks() { // Required for block checkout \add_action('woocommerce_store_api_checkout_order_processed', function ($order) { try { $woocommerce_order = new self($order->get_id()); $woocommerce_order->insert(); } catch (\Throwable $e) { \error_log('Independent Analytics was unable to track the analytics for a WooCommerce order. Please report this error to Independent Analytics. The error message is below.'); \error_log($e->getMessage()); } }); // Required for shortcode checkout \add_action('woocommerce_checkout_order_created', function ($order) { try { $woocommerce_order = new self($order->get_id()); $woocommerce_order->insert(); } catch (\Throwable $e) { \error_log('Independent Analytics was unable to track the analytics for a WooCommerce order. Please report this error to Independent Analytics. The error message is below.'); \error_log($e->getMessage()); } }); \add_action('woocommerce_order_status_changed', function ($order_id) { try { $woocommerce_order = new self($order_id); $woocommerce_order->update(); } catch (\Throwable $e) { \error_log('Independent Analytics was unable to track the analytics for a WooCommerce order. Please report this error to Independent Analytics. The error message is below.'); \error_log($e->getMessage()); } }); // Captures a partial refund, something that woocommerce_order_status_changed will not do \add_action('woocommerce_order_refunded', function ($order_id) { try { $woocommerce_order = new self($order_id); $woocommerce_order->update(); } catch (\Throwable $e) { \error_log('Independent Analytics was unable to track the analytics for a WooCommerce order. Please report this error to Independent Analytics. The error message is below.'); \error_log($e->getMessage()); } }); } } IAWP/Ecommerce/WooCommerce_Referrer_Meta_Box.php000064400000014614147600331220015551 0ustar00is_woocommerce_support_enabled()) { return; } $order = $post_or_order_object instanceof \WP_Post ? wc_get_order($post_or_order_object->ID) : $post_or_order_object; if ($order === \false) { return; } $woocommerce_screen = \class_exists('\\Automattic\\WooCommerce\\Internal\\DataStores\\Orders\\CustomOrdersTableController') && wc_get_container()->get(CustomOrdersTableController::class)->custom_orders_table_usage_is_enabled() ? wc_get_page_screen_id('shop-order') : 'shop_order'; $current_screen = \get_current_screen(); if (\is_null($current_screen) || $current_screen->id !== $woocommerce_screen) { return; } $referrer_row = $this->get_referrer_for($order->get_id()); $this->referrer = \is_object($referrer_row) ? new Referrer($referrer_row) : null; $campaign_row = $this->get_campaign_for($order->get_id()); $this->campaign = \is_object($campaign_row) ? new Campaign($campaign_row) : null; if (\is_null($this->referrer) && \is_null($this->campaign)) { return; } \add_meta_box('iawp-wc-referrer-source', \esc_html__('Order Referrer', 'independent-analytics'), [$this, 'render_meta_box_content'], $woocommerce_screen, 'side'); } public function render_meta_box_content($post_or_order_object) : void { $order = $post_or_order_object instanceof \WP_Post ? wc_get_order($post_or_order_object->ID) : $post_or_order_object; if (!\is_null($this->referrer)) { if ($this->referrer->has_link()) { $content = '' . Security::string($this->referrer->referrer()) . ''; } else { $content = Security::string($this->referrer->referrer()); } echo '

' . \esc_html__('Referrer:', 'independent-analytics') . ' ' . $content . '

'; } if (!\is_null($this->campaign)) { if (\is_string($this->campaign->utm_source())) { echo '

' . \__('Campaign Source', 'independent-analytics') . ': ' . Security::string($this->campaign->utm_source()) . '

'; } if (\is_string($this->campaign->utm_medium())) { echo '

' . \__('Campaign Medium', 'independent-analytics') . ': ' . Security::string($this->campaign->utm_medium()) . '

'; } if (\is_string($this->campaign->utm_campaign())) { echo '

' . \__('Campaign Name', 'independent-analytics') . ': ' . Security::string($this->campaign->utm_campaign()) . '

'; } if (\is_string($this->campaign->utm_term())) { echo '

' . \__('Campaign Term', 'independent-analytics') . ': ' . Security::string($this->campaign->utm_term()) . '

'; } if (\is_string($this->campaign->utm_content())) { echo '

' . \__('Campaign Content', 'independent-analytics') . ': ' . Security::string($this->campaign->utm_content()) . '

'; } } } private function get_campaign_for($order_id) : ?object { $orders_table = Query::get_table_name(Query::ORDERS); $campaigns_table = Query::get_table_name(Query::CAMPAIGNS); $views_table = Query::get_table_name(Query::VIEWS); $sessions_table = Query::get_table_name(Query::SESSIONS); $campaign_query = Illuminate_Builder::new()->select("landing_page_title AS title", "utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content")->from($orders_table, 'orders')->join("{$views_table} AS views", function (JoinClause $join) { $join->on('views.id', '=', 'orders.view_id'); })->join("{$sessions_table} AS sessions", function (JoinClause $join) { $join->on('sessions.session_id', '=', 'views.session_id'); })->join("{$campaigns_table} AS campaigns", function (JoinClause $join) { $join->on('sessions.campaign_id', '=', 'campaigns.campaign_id'); })->where('orders.woocommerce_order_id', '=', $order_id); $record = $campaign_query->get()->first(); return $record; } private function get_referrer_for($order_id) : ?object { $orders_table = Query::get_table_name(Query::ORDERS); $views_table = Query::get_table_name(Query::VIEWS); $sessions_table = Query::get_table_name(Query::SESSIONS); $referrer_table = Query::get_table_name(Query::REFERRERS); $referrer_query = Illuminate_Builder::new()->select('sessions.referrer_id', 'referrer', 'type AS referrer_type', 'domain')->from($orders_table, 'orders')->join("{$views_table} AS views", function (JoinClause $join) { $join->on('views.id', '=', 'orders.view_id'); })->join("{$sessions_table} AS sessions", function (JoinClause $join) { $join->on('sessions.session_id', '=', 'views.session_id'); })->join("{$referrer_table} AS referrers", function (JoinClause $join) { $join->on('referrers.id', '=', 'sessions.referrer_id'); })->where('orders.woocommerce_order_id', '=', $order_id); $record = $referrer_query->get()->first(); return $record; } } IAWP/Ecommerce/WooCommerce_Status_Manager.php000064400000006743147600331220015140 0ustar00 $value) { if (Str::startsWith($key, 'wc-')) { $key = Str::replaceFirst('wc-', '', $key); } $statuses[] = ['id' => \strval($key), 'name' => \strval($value), 'is_tracked' => $this->is_tracked_status($key)]; } return $statuses; } public function is_valid_status(string $status_id) : bool { $statuses = $this->get_statuses(); foreach ($statuses as $status) { if ($status['id'] === $status_id) { return \true; } } return \false; } /** * Use the currently configured statuses to recalculate if a given order in `wp_orders` * should be included in the analytics or not. * * @return void */ public function update_order_records_based_on_tracked_statuses() : void { $orders_table = Query::get_table_name(Query::ORDERS); Illuminate_Builder::new()->from($orders_table)->whereNotIn('woocommerce_order_status', $this->get_tracked_status_ids())->update(['is_included_in_analytics' => \false]); Illuminate_Builder::new()->from($orders_table)->whereIn('woocommerce_order_status', $this->get_tracked_status_ids())->update(['is_included_in_analytics' => \true]); } public function set_tracked_statuses(array $tracked_status_ids) : void { $filtered_statuses = \array_filter($tracked_status_ids, function ($status_id) { return $this->is_valid_status($status_id); }); \update_option('iawp_tracked_woocommerce_status_ids', $filtered_statuses); } public function is_tracked_status(string $status_id) : bool { return \in_array($status_id, $this->get_tracked_status_ids()); } public function reset_tracked_statuses() : void { \delete_option('iawp_tracked_woocommerce_status_ids'); } /** * @return string[] */ private function get_tracked_status_ids() : array { $status_ids = \IAWPSCOPED\iawp()->get_option('iawp_tracked_woocommerce_status_ids', []); $prefixed_statuses = []; if (!\is_array($status_ids) || \count($status_ids) === 0) { $status_ids = self::$default_status_to_track; } // These need to be prefixed, because you never know what you're going to get back from WooCommerce foreach ($status_ids as $status_id) { $prefixed_statuses[] = 'wc-' . $status_id; } return \array_merge($status_ids, $prefixed_statuses); } } IAWP/Email_Reports/Email_Chart.php000064400000004067147600331220012737 0ustar00statistics = $statistics; $this->views = self::views(); $this->most_views = self::most_views(); $this->y_labels = self::y_labels(); $this->x_labels = self::x_labels(); } public function views() { return \array_map(function ($day) { return $day[1]; }, $this->statistics->get_statistic('views')->statistic_over_time()); } public function most_views() { return \round(\max($this->views) * 1.1); } public function y_labels() { return [Number::abbreviate($this->most_views), Number::abbreviate($this->most_views / 2), 0]; } public function x_labels() { $interval = \IAWPSCOPED\iawp()->get_option('iawp_email_report_interval', 'monthly'); $format = 'M j'; if ($interval == 'weekly') { $format = 'D'; } elseif ($interval == 'daily') { $format = \IAWPSCOPED\iawp()->get_option('time_format', 'g:i a'); } $all_x_labels = \array_map(function ($day) use($format) { return $day[0]->format($format); }, $this->statistics->get_statistic('views')->statistic_over_time()); $x_labels = []; if ($interval == 'monthly') { for ($x = 0; $x < \count($all_x_labels); $x++) { if (($x + 5) % 5 == 0) { $x_labels[] = $all_x_labels[$x]; } } } elseif ($interval == 'weekly') { $x_labels = $all_x_labels; } elseif ($interval == 'daily') { for ($x = 0; $x < \count($all_x_labels); $x++) { if (($x + 6) % 6 == 0) { $x_labels[] = $all_x_labels[$x]; } } } return $x_labels; } } IAWP/Email_Reports/Email_Reports.php000064400000022634147600331220013334 0ustar00unschedule(); if (empty(\IAWPSCOPED\iawp()->get_option('iawp_email_report_email_addresses', []))) { return; } \wp_schedule_event($this->interval()->next_interval_start()->getTimestamp(), $this->interval()->id(), 'iawp_send_email_report'); } public function unschedule() { $timestamp = \wp_next_scheduled('iawp_send_email_report'); if (\is_int($timestamp)) { \wp_unschedule_event($timestamp, 'iawp_send_email_report'); } } /** * For testing purposes, get the * * @return DateTime */ public function next_event_scheduled_at() : ?DateTime { if (!\wp_next_scheduled('iawp_send_email_report')) { return null; } $date = new DateTime(); $date->setTimezone(Timezone::site_timezone()); $date->setTimestamp(\wp_next_scheduled('iawp_send_email_report')); return $date; } public function next_email_at_for_humans() : string { if (!\wp_next_scheduled('iawp_send_email_report')) { return \esc_html__('There is no email scheduled.', 'independent-analytics'); } $date = $this->interval()->next_interval_start(); $day = $date->format(\get_option('date_format')); $time = $date->format(\IAWPSCOPED\iawp()->get_option('time_format', 'g:i a')); return \sprintf(\__('Next email scheduled for %s at %s.', 'independent-analytics'), '' . $day . '', '' . $time . ''); } public function maybe_reschedule() { if (!\wp_next_scheduled('iawp_send_email_report')) { return; } if (\IAWPSCOPED\iawp()->get_option('iawp_email_report_interval', 'monthly') != 'weekly') { return; } $this->schedule(); } public function send_email_report(bool $is_test_email = \false) { // This code was added to fix an issue with monthly email reports. When you set up a monthly // email report, the first email will always be correct because we pick the exact timestamp // we want to send it. The issue is with the recurring interval. It's backed by MONTH_IN_SECONDS // which is a fixed constant. Months have a varying number of seconds so this caused slight // differences in when subsequent monthly email reports were sent. The code below fixes this by // rescheduling monthly email reports as they're sent. That allows us to pinpoint the exact // correct next time to run it, while still falling back to the inaccurate monthly interval // should a given email never send for some reason. if ($this->interval()->id() === 'monthly') { $this->schedule(); } $to = \IAWPSCOPED\iawp()->get_option('iawp_email_report_email_addresses', []); if (empty($to)) { return; } $from = \IAWPSCOPED\iawp()->get_option('iawp_email_report_from_address', \get_option('admin_email')); $body = $this->get_email_body(); $headers[] = 'From: ' . \get_bloginfo('name') . ' <' . \esc_attr($from) . '>'; $headers[] = 'Content-Type: text/html; charset=UTF-8'; return \wp_mail($to, $this->subject_line($is_test_email), $body, $headers); } public function get_email_body($colors = '') { $statistics = new Page_Statistics($this->interval()->date_range()); $quick_stats = \array_values(\array_filter($statistics->get_statistics(), function (Statistic $statistics) { return $statistics->is_visible() && $statistics->is_group_plugin_enabled(); })); $chart = new \IAWP\Email_Reports\Email_Chart($statistics); $colors = $colors == '' ? \IAWPSCOPED\iawp()->get_option('iawp_email_report_colors', ['#5123a0', '#fafafa', '#3a1e6b', '#fafafa', '#5123a0', '#a985e6', '#ece9f2', '#f7f5fa', '#ece9f2', '#dedae6']) : \explode(',', $colors); return \IAWPSCOPED\iawp_blade()->run('email.email', [ 'site_title' => \get_bloginfo('name'), 'site_url' => URL::new(\get_site_url())->get_domain(), 'date' => $this->interval()->report_time_period_for_humans(), // The value that needs to change 'stats' => $quick_stats, 'top_ten' => $this->get_top_ten(), 'chart_views' => $chart->views, 'chart_title' => $this->interval()->chart_title(), 'most_views' => $chart->most_views, 'y_labels' => $chart->y_labels, 'x_labels' => $chart->x_labels, 'colors' => $colors, ]); } private function subject_line(bool $is_test_email) : string { $parts = []; if ($is_test_email) { $parts[] = \__('[Test]', 'independent-analytics'); } $parts[] = \__('Analytics Report for', 'independent-analytics'); $parts[] = \get_bloginfo('name'); $parts[] = '[' . $this->interval()->report_time_period_for_humans() . ']'; return \esc_html(\implode(' ', $parts)); } private function get_top_ten() : array { $date_range = $this->interval()->date_range(); $queries = ['pages' => 'title', 'referrers' => 'referrer', 'countries' => 'country', 'devices' => 'device_type', 'campaigns' => 'title', 'landing_pages' => 'title', 'exit_pages' => 'title']; $top_ten = []; $sort_configuration = new Sort_Configuration('views', 'desc'); $title = ''; foreach ($queries as $type => $title) { if ($type === 'pages') { $query = new Pages($date_range, 10, null, $sort_configuration); $title = \esc_html__('Pages', 'independent-analytics'); } elseif ($type === 'referrers') { $query = new Referrers($date_range, 10, null, $sort_configuration); $title = \esc_html__('Referrers', 'independent-analytics'); } elseif ($type === 'countries') { $query = new Countries($date_range, 10, null, $sort_configuration); $title = \esc_html__('Countries', 'independent-analytics'); } elseif ($type === 'devices') { $query = new Device_Types($date_range, 10, null, $sort_configuration); $title = \esc_html__('Devices', 'independent-analytics'); } elseif ($type === 'campaigns') { $query = new Campaigns($date_range, 10, null, $sort_configuration); $title = \esc_html__('Campaigns', 'independent-analytics'); } elseif ($type === 'landing_pages') { $query = new Pages($date_range, 10, null, new Sort_Configuration('entrances', 'desc')); $title = \esc_html__('Landing Pages', 'independent-analytics'); } elseif ($type === 'exit_pages') { $query = new Pages($date_range, 10, null, new Sort_Configuration('exits', 'desc')); $title = \esc_html__('Exit Pages', 'independent-analytics'); } else { continue; } $rows = \array_map(function ($row, $index) use($type) { if ($type == 'referrers') { $edited_title = $row->referrer(); } elseif ($type == 'countries') { $edited_title = $row->country(); } elseif ($type == 'devices') { $edited_title = $row->device_type(); } elseif ($type == 'campaigns') { $edited_title = $row->utm_campaign(); } else { $edited_title = $row->title(); } $edited_title = \mb_strlen($edited_title) > 30 ? \mb_substr($edited_title, 0, 30) . '...' : $edited_title; $metric = 'views'; if ($type == 'landing_pages') { $metric = 'entrances'; } elseif ($type == 'exit_pages') { $metric = 'exits'; } return ['title' => $edited_title, 'views' => $row->{$metric}()]; }, $query->rows(), \array_keys($query->rows())); if (\count($rows) == 0) { continue; } $top_ten[$type] = ['title' => $title, 'rows' => $rows]; } return $top_ten; } } IAWP/Email_Reports/Interval.php000064400000004630147600331220012347 0ustar00id = $attributes['id']; $this->relative_date_range_id = $attributes['relative_date_range_id']; $this->datetime_prefix = $attributes['datetime_prefix'] ?? ''; $this->datetime_format_pattern = $attributes['datetime_format_pattern']; $this->chart_title = $attributes['chart_title']; } public function id() : string { return $this->id; } public function report_time_period_for_humans() : string { $prefix = $this->datetime_prefix; if (\strlen($prefix) > 0 && !String_Util::str_ends_with($prefix, ' ')) { $prefix .= ' '; } $start = $this->date_range()->start()->setTimezone(Timezone::site_timezone()); $formatted_date = Carbon::parse($start)->translatedFormat($this->datetime_format_pattern); return $prefix . $formatted_date; } public function chart_title() : string { return $this->chart_title; } public function next_interval_start() : DateTime { $start = $this->current_date_range()->next_period()->start(); $delivery_hour = \intval(\IAWPSCOPED\iawp()->get_option('iawp_email_report_time', 9)); $start->setTimezone(Timezone::site_timezone()); $start->setTime($delivery_hour, 0, 0); return $start; } /** * This is the date range that the email report covers, which is the previous period, not the * current period. * * @return Date_Range */ public function date_range() : Date_Range { // This exception is necessary because in Date_Range, range_sizes_in_days doesn't take the // months length into account if ($this->id === 'monthly') { return new Relative_Date_Range('LAST_MONTH'); } return $this->current_date_range()->previous_period(); } private function current_date_range() : Relative_Date_Range { return new Relative_Date_Range($this->relative_date_range_id); } } IAWP/Email_Reports/Interval_Factory.php000064400000002735147600331220014042 0ustar00 'daily', 'relative_date_range_id' => 'TODAY', 'datetime_format_pattern' => 'l, M jS', 'chart_title' => \__('Hourly Views', 'independent-analytics')]); } public static function weekly() : \IAWP\Email_Reports\Interval { return new \IAWP\Email_Reports\Interval(['id' => 'weekly', 'relative_date_range_id' => 'THIS_WEEK', 'datetime_prefix' => \__('Week of', 'independent-analytics'), 'datetime_format_pattern' => 'l, M jS', 'chart_title' => \__('Daily Views', 'independent-analytics')]); } public static function monthly() : \IAWP\Email_Reports\Interval { return new \IAWP\Email_Reports\Interval(['id' => 'monthly', 'relative_date_range_id' => 'THIS_MONTH', 'datetime_format_pattern' => 'F Y', 'chart_title' => \__('Daily Views', 'independent-analytics')]); } } IAWP/Filter_Lists/Author_Filter_List.php000064400000001217147600331220014161 0ustar00roles as $role_name => $role_obj) { if ($role_obj['capabilities']['edit_posts'] ?? \false) { $roles_that_can_edit_posts[] = $role_name; } } $authors = \get_users(['role__in' => $roles_that_can_edit_posts]); return \array_map(function ($author) { return [$author->ID, $author->display_name]; }, $authors); } } IAWP/Filter_Lists/Category_Filter_List.php000064400000000517147600331220014476 0ustar00term_id, $category->name]; }, \get_categories()); } } IAWP/Filter_Lists/Device_Browser_Filter_List.php000064400000001140147600331220015614 0ustar00from($device_browsers_table)->select('device_browser_id', 'device_browser')->get()->all(); return \array_map(function ($record) { return [$record->device_browser_id, $record->device_browser]; }, $records); } } IAWP/Filter_Lists/Device_OS_Filter_List.php000064400000001070147600331220014514 0ustar00from($device_oss_table)->select('device_os_id', 'device_os')->get()->all(); return \array_map(function ($record) { return [$record->device_os_id, $record->device_os]; }, $records); } } IAWP/Filter_Lists/Device_Type_Filter_List.php000064400000001110147600331220015107 0ustar00from($device_types_table)->select('device_type_id', 'device_type')->get()->all(); return \array_map(function ($record) { return [$record->device_type_id, $record->device_type]; }, $records); } } IAWP/Filter_Lists/Filter_List_Trait.php000064400000001245147600331220014003 0ustar00from(Tables::link_rules())->select('link_rule_id', 'name')->get()->all(); return \array_map(function ($record) { return [$record->link_rule_id, $record->name]; }, $records); } } IAWP/Filter_Lists/Page_Type_Filter_List.php000064400000003606147600331220014600 0ustar00 \true, '_builtin' => \false]) as $custom_type) { $options[] = [$custom_type, \get_post_type_object($custom_type)->labels->singular_name]; } $options[] = ['category', \esc_html__('Category', 'independent-analytics')]; $options[] = ['post_tag', \esc_html__('Tag', 'independent-analytics')]; foreach (\get_taxonomies(['public' => \true, '_builtin' => \false]) as $taxonomy) { $label = \get_taxonomy_labels(\get_taxonomy($taxonomy))->singular_name; /** * WooCommerce category and tag taxonomies have the same singular name as WordPress * category and tag taxonomies, so use the name here instead */ if (\in_array($taxonomy, ['product_cat', 'product_tag'])) { $label = \get_taxonomy_labels(\get_taxonomy($taxonomy))->name; } $options[] = [$taxonomy, \ucwords($label)]; } $options[] = ['blog-archive', \esc_html__('Blog Home', 'independent-analytics')]; $options[] = ['author-archive', \esc_html__('Author Archive', 'independent-analytics')]; $options[] = ['date-archive', \esc_html__('Date Archive', 'independent-analytics')]; $options[] = ['search-archive', \esc_html__('Search Results', 'independent-analytics')]; $options[] = ['not-found', \esc_html__('404', 'independent-analytics')]; return $options; } } IAWP/Filter_Lists/Referrer_Type_Filter_List.php000064400000001003147600331220015465 0ustar00 1, 'name' => 'Fluent Forms', 'plugin_slugs' => ['fluentform/fluentform.php']], ['id' => 2, 'name' => 'WPForms', 'plugin_slugs' => ['wpforms-lite/wpforms.php', 'wpforms/wpforms.php']], ['id' => 3, 'name' => 'Contact Form 7', 'plugin_slugs' => ['contact-form-7/wp-contact-form-7.php']], ['id' => 4, 'name' => 'Gravity Forms', 'plugin_slugs' => ['gravityforms/gravityforms.php']], ['id' => 5, 'name' => 'Ninja Forms', 'plugin_slugs' => ['ninja-forms/ninja-forms.php']], ['id' => 6, 'name' => 'MailOptin', 'plugin_slugs' => ['mailoptin/mailoptin.php']], ['id' => 7, 'name' => 'Convert Pro', 'plugin_slugs' => ['convertpro/convertpro.php']], ['id' => 8, 'name' => 'Elementor Pro', 'plugin_slugs' => ['elementor-pro/elementor-pro.php']], ['id' => 9, 'name' => 'JetFormBuilder', 'plugin_slugs' => ['jetformbuilder/jet-form-builder.php']], ['id' => 10, 'name' => 'Formidable Forms', 'plugin_slugs' => ['formidable/formidable.php']], ['id' => 11, 'name' => 'WS Form', 'plugin_slugs' => ['ws-form/ws-form.php', 'ws-form-pro/ws-form.php']], ['id' => 12, 'name' => 'Amelia', 'plugin_slugs' => ['ameliabooking/ameliabooking.php']], ['id' => 13, 'name' => 'Bricks Builder', 'theme' => 'bricks'], ['id' => 14, 'name' => 'ARForms', 'plugin_slugs' => ['arforms-form-builder/arforms-form-builder.php']], ['id' => 15, 'name' => 'Custom form submissions'], ['id' => 16, 'name' => 'Bit Form', 'plugin_slugs' => ['bit-form/bitforms.php']], ['id' => 17, 'name' => 'Forminator', 'plugin_slugs' => ['forminator/forminator.php']], ['id' => 18, 'name' => 'Hustle', 'plugin_slugs' => ['wordpress-popup/popover.php', 'hustle/opt-in.php']], ['id' => 19, 'name' => 'Avada', 'plugin_slugs' => ['fusion-builder/fusion-builder.php', 'fusion-core/fusion-core.php']], ['id' => 20, 'name' => 'WP Store Locator', 'plugin_slugs' => ['wp-store-locator/wp-store-locator.php']]]; /** * @var array An key(plugin_id) value(bool) pair of plugin IDs */ private static $has_any_tracked_submissions_cache = []; private function __construct(int $id, string $title, int $plugin_id) { $this->id = $id; $this->title = $title; $this->plugin_id = $plugin_id; } public function id() : int { return $this->id; } public function title() : string { return $this->title; } public function icon() : string { $lowercase = \strtolower($this->plugin_name()); $hyphenated = \str_replace(' ', '_', $lowercase); return $hyphenated; } public function plugin_name() : string { return \IAWP\Form_Submissions\Form::find_plugin_by_id($this->plugin_id)['name']; } public function is_plugin_active() : bool { return self::static_is_plugin_active($this->plugin_id); } public function submissions_column() : string { return "form_submissions_for_{$this->id}"; } public function conversion_rate_column() : string { return "form_conversion_rate_for_{$this->id}"; } public static function has_active_form_plugin() : bool { return \is_array(self::get_first_active_form_plugin()); } public static function get_first_active_form_plugin_name() : ?string { $active_plugin = self::get_first_active_form_plugin(); return \is_array($active_plugin) ? $active_plugin['name'] : null; } public static function find_form_by_column_name(string $column_name) : ?\IAWP\Form_Submissions\Form { $id = \intval(\preg_match('/(\\d+)\\z/', $column_name)); $forms = self::get_forms(); foreach ($forms as $form) { if ($id === $form->id()) { return $form; } } return null; } /** * @return Form[] */ public static function get_forms() : array { if (\is_array(self::$forms)) { return self::$forms; } $forms_table = Query::get_table_name(Query::FORMS); $query = Illuminate_Builder::new()->select(['form_id', 'cached_form_title', 'plugin_id'])->from($forms_table); $forms = \array_filter(\array_map(function ($form) { if (\is_null(self::find_plugin_by_id($form->plugin_id))) { return null; } return new self($form->form_id, $form->cached_form_title, $form->plugin_id); }, $query->get()->all())); \usort($forms, function (\IAWP\Form_Submissions\Form $a, \IAWP\Form_Submissions\Form $b) { // First level sort by plugin name $plugin_name_comparison = \strcmp($a->plugin_name(), $b->plugin_name()); // If types are equal, sort by 'name' if ($plugin_name_comparison === 0) { return \strcmp($a->title(), $b->title()); } return $plugin_name_comparison; }); self::$forms = $forms; return self::$forms; } private static function has_any_tracked_submissions(int $plugin_id) : bool { if (\array_key_exists($plugin_id, self::$has_any_tracked_submissions_cache)) { return self::$has_any_tracked_submissions_cache[$plugin_id]; } $forms_table = Query::get_table_name(Query::FORMS); $form_submissions_table = Query::get_table_name(Query::FORM_SUBMISSIONS); $has_submissions = Illuminate_Builder::new()->from($forms_table, 'forms')->join("{$form_submissions_table} AS form_submissions", 'forms.form_id', '=', 'form_submissions.form_id')->where('forms.plugin_id', '=', $plugin_id)->exists(); self::$has_any_tracked_submissions_cache[$plugin_id] = $has_submissions; return $has_submissions; } private static function get_first_active_form_plugin() : ?array { foreach (\IAWP\Form_Submissions\Form::$plugins as $plugin) { if (self::static_is_plugin_active($plugin['id'])) { return $plugin; } } return null; } private static function static_is_plugin_active(int $plugin_id) : bool { $plugin = \IAWP\Form_Submissions\Form::find_plugin_by_id($plugin_id); if (!\array_key_exists('plugin_slugs', $plugin) && !\array_key_exists('theme', $plugin)) { return self::has_any_tracked_submissions($plugin_id); } if (\array_key_exists('theme', $plugin)) { if (\get_template() === $plugin['theme']) { return \true; } } if (\array_key_exists('plugin_slugs', $plugin)) { foreach ($plugin['plugin_slugs'] as $slug) { if (\is_plugin_active($slug)) { return \true; } } } return \false; } private static function find_plugin_by_id(int $id) : ?array { foreach (self::$plugins as $plugin) { if ($plugin['id'] === $id) { return $plugin; } } return null; } } IAWP/Form_Submissions/Submission.php000064400000002771147600331220013456 0ustar00plugin_id = $plugin_id; $this->plugin_form_id = $plugin_form_id; $this->form_title = $form_title; } public function record_submission() : void { $form_submissions_table = Query::get_table_name(Query::FORM_SUBMISSIONS); $visitor = Visitor::fetch_current_visitor(); if (!$visitor->has_recorded_session()) { return; } Illuminate_Builder::new()->from($form_submissions_table)->insert(['form_id' => $this->get_form_id(), 'session_id' => $visitor->most_recent_session_id(), 'view_id' => $visitor->most_recent_view_id(), 'initial_view_id' => $visitor->most_recent_initial_view_id(), 'created_at' => (new \DateTime())->format('Y-m-d\\TH:i:s')]); } private function get_form_id() : int { $forms_table = Query::get_table_name(Query::FORMS); Illuminate_Builder::new()->from($forms_table)->updateOrInsert(['plugin_id' => $this->plugin_id, 'plugin_form_id' => $this->plugin_form_id], ['cached_form_title' => $this->form_title]); return Illuminate_Builder::new()->from($forms_table)->where(['plugin_id' => $this->plugin_id, 'plugin_form_id' => $this->plugin_form_id])->value('form_id'); } } IAWP/Form_Submissions/Submission_Listener.php000064400000031404147600331220015316 0ustar00id), Security::string($form->title)); $submission->record_submission(); } catch (\Throwable $e) { } }, 20, 3); // WPForms \add_action('wpforms_process_complete', function ($fields, $entry, $form_data, $entry_id) { try { $submission = new \IAWP\Form_Submissions\Submission(2, \intval($form_data['id']), Security::string($form_data['settings']['form_title'])); $submission->record_submission(); } catch (\Throwable $e) { } }, 10, 4); // Contact Form 7 \add_action('wpcf7_mail_sent', function ($form) { try { $submission = new \IAWP\Form_Submissions\Submission(3, \intval($form->id()), Security::string($form->title())); $submission->record_submission(); } catch (\Throwable $e) { } }); // Gravity Forms \add_action('gform_after_submission', function ($entry, $form) { try { $submission = new \IAWP\Form_Submissions\Submission(4, \intval($form['id']), Security::string($form['title'])); $submission->record_submission(); } catch (\Throwable $e) { } }, 10, 2); // Ninja Forms \add_action('ninja_forms_after_submission', function ($form_data) { try { $submission = new \IAWP\Form_Submissions\Submission(5, \intval($form_data['form_id']), Security::string($form_data['settings']['title'])); $submission->record_submission(); } catch (\Throwable $e) { } }, 10, 1); // MailOptin \add_action('mailoptin_track_conversions', function ($lead_data) { try { if (!\class_exists('\\MailOptin\\Core\\Repositories\\OptinCampaignsRepository')) { return; } $form_title = \MailOptin\Core\Repositories\OptinCampaignsRepository::get_optin_campaign_name($lead_data['optin_campaign_id']); if (\is_null($form_title)) { return; } $submission = new \IAWP\Form_Submissions\Submission(6, \intval($lead_data['optin_campaign_id']), Security::string($form_title)); $submission->record_submission(); } catch (\Throwable $e) { } }, 10, 1); // Convert Pro \add_action('cpro_form_submit', function ($response, $post_data) { try { $post_id = \intval($post_data['style_id']); $post = \get_post($post_id); if (\is_null($post)) { return; } $submission = new \IAWP\Form_Submissions\Submission(7, \intval($post_id), Security::string($post->post_title)); $submission->record_submission(); } catch (\Throwable $e) { } }, 10, 2); // Elementor \add_action('elementor_pro/forms/new_record', function ($record) { // Elementor form ids are generated using dechex(rand()), so hexdec is required to // convert the id back into an integer try { $submission = new \IAWP\Form_Submissions\Submission(8, \intval(\hexdec($record->get_form_settings('id'))), Security::string($record->get_form_settings('form_name'))); $submission->record_submission(); } catch (\Throwable $e) { } }, 10, 1); // JetFormBuilder \add_action('jet-form-builder/form-handler/after-send', function ($form) { try { if (!$form->is_success) { return; } $post_id = \intval($form->form_id); $post = \get_post($post_id); if (\is_null($post)) { return; } $submission = new \IAWP\Form_Submissions\Submission(9, \intval($post_id), Security::string($post->post_title)); $submission->record_submission(); } catch (\Throwable $e) { } }, 10, 1); // Formidable Forms \add_action('frm_after_create_entry', function ($entry_id, $form_id) { try { if (!\class_exists('\\FrmForm')) { return; } $form = \FrmForm::getOne($form_id); $submission = new \IAWP\Form_Submissions\Submission(10, \intval($form_id), Security::string($form->name)); $submission->record_submission(); } catch (\Throwable $e) { } }, 10, 2); // WS Form \add_action('wsf_submit_post_complete', function ($submission) { try { $submission = new \IAWP\Form_Submissions\Submission(11, \intval($submission->form_id), Security::string($submission->form_object->label)); $submission->record_submission(); } catch (\Throwable $e) { } }, 10, 1); // Amelia \add_action('amelia_after_appointment_booking_saved', function ($booking, $reservation) { try { $submission = new \IAWP\Form_Submissions\Submission(12, 1, 'Amelia ' . \__('Appointment', 'independent-analytics')); $submission->record_submission(); } catch (\Throwable $e) { } }, 10, 2); // Amelia \add_action('amelia_after_event_booking_saved', function ($booking, $reservation) { try { $submission = new \IAWP\Form_Submissions\Submission(12, 2, 'Amelia ' . \__('Event', 'independent-analytics')); $submission->record_submission(); } catch (\Throwable $e) { } }, 10, 2); // Bricks Builder \add_action('bricks/form/custom_action', function ($form) { try { $fields = $form->get_fields(); if (!\array_key_exists('iawp-form-id', $fields) || \intval($fields['iawp-form-id']) === 0) { return; } if (!\array_key_exists('iawp-form-title', $fields) || \strlen($fields['iawp-form-title']) === 0) { return; } $submission = new \IAWP\Form_Submissions\Submission(13, \intval($fields['iawp-form-id']), Security::string($fields['iawp-form-title'])); $submission->record_submission(); } catch (\Throwable $e) { } }, 10, 1); // ARForms Pro \add_action('arfaftercreateentry', function ($entry_id, $form_id) { try { global $wpdb; $forms_table = "{$wpdb->prefix}arf_forms"; $form_name = Illuminate_Builder::new()->from($forms_table)->where('id', $form_id)->value('name'); if (\is_null($form_name)) { return; } $submission = new \IAWP\Form_Submissions\Submission(14, \intval($form_id), Security::string($form_name)); $submission->record_submission(); } catch (\Throwable $e) { } }, 10, 2); // ARForms Lite \add_action('arfliteaftercreateentry', function ($entry_id, $form_id) { try { global $wpdb; $forms_table = "{$wpdb->prefix}arf_forms"; $form_name = Illuminate_Builder::new()->from($forms_table)->where('id', $form_id)->value('name'); if (\is_null($form_name)) { return; } $submission = new \IAWP\Form_Submissions\Submission(14, \intval($form_id), Security::string($form_name)); $submission->record_submission(); } catch (\Throwable $e) { } }, 10, 2); // Custom form submissions \add_action('iawp_custom_form_submissions', function (int $form_id, string $form_title) { try { $submission = new \IAWP\Form_Submissions\Submission(15, \intval($form_id), Security::string($form_title)); $submission->record_submission(); } catch (\Throwable $e) { } }, 10, 2); // Bit Form \add_action('bitform_submit_success', function ($form_id, $entry_id, $form_data) { try { if (!\class_exists('\\BitCode\\BitForm\\Core\\Form\\FormManager')) { return; } $form = new \BitCode\BitForm\Core\Form\FormManager($form_id); $form_name = $form->getFormName(); $submission = new \IAWP\Form_Submissions\Submission(16, \intval($form_id), Security::string($form_name)); $submission->record_submission(); } catch (\Throwable $e) { } }, 10, 3); // Forminator \add_action('forminator_form_submit_response', function ($response, $form_id) { if (!\function_exists('IAWPSCOPED\\forminator_get_form_name')) { return $response; } $form_name = forminator_get_form_name($form_id); try { $submission = new \IAWP\Form_Submissions\Submission(17, \intval($form_id), Security::string($form_name)); $submission->record_submission(); } catch (\Throwable $e) { } return $response; }, 10, 2); // Forminator (ajax) \add_action('forminator_form_ajax_submit_response', function ($response, $form_id) { if (!\function_exists('IAWPSCOPED\\forminator_get_form_name')) { return $response; } $form_name = forminator_get_form_name($form_id); try { $submission = new \IAWP\Form_Submissions\Submission(17, \intval($form_id), Security::string($form_name)); $submission->record_submission(); } catch (\Throwable $e) { } return $response; }, 10, 2); // Hustle \add_action('hustle_form_after_handle_submit', function ($module_id, $response) { try { if ($response['success'] === \false) { return; } if (!\class_exists('\\Hustle_Model')) { return; } $module = \Hustle_Model::get_module($module_id); if (\is_wp_error($module)) { return; } $submission = new \IAWP\Form_Submissions\Submission(18, \intval($module_id), Security::string($module->module_name)); $submission->record_submission(); } catch (\Throwable $e) { } }, 10, 2); // Avada \add_action('fusion_form_submission_data', function ($form_data, $form_post_id) { try { $form_id = $form_data['submission']['form_id']; $form_name = \get_the_title($form_post_id); $submission = new \IAWP\Form_Submissions\Submission(19, \intval($form_id), Security::string($form_name)); $submission->record_submission(); } catch (\Throwable $e) { } }, 10, 2); // WP Store Locator \add_action('wpsl_store_search', function () { try { $is_autoloaded = isset($_GET['autoload']) && $_GET['autoload']; // This hooks fires after the locations are fetched on page load. We only want to track // manual form submissions. if ($is_autoloaded) { return; } // There's only one possible form for this plugin. This is why the form id and the forms // name are hardcoded. $submission = new \IAWP\Form_Submissions\Submission(20, \intval(1), Security::string('WP Store Locator')); $submission->record_submission(); } catch (\Throwable $e) { } }, 10, 0); // // Template // add_action('iawp_some_form_callback', function () { // try { // return; // $submission = new Submission( // 0, // intval(0), // Form id // Security::string('') // Form title // ); // $submission->record_submission(); // } catch (\Throwable $e) { // // } // }, 10, 0); } } IAWP/Interval/Interval.php000064400000002441147600331220011364 0ustar00interval_multiplier(); if ($interval === 0) { return \esc_html__('now', 'independent-analytics'); } else { return '-' . $interval . ' ' . $this->short_label(); } }, $intervals); } public function get_full_labels($intervals) : array { return \array_map(function ($interval) { $interval = $interval * $this->interval_multiplier(); if ($interval === 1) { return $interval . ' ' . $this->long_label_singular(); } else { return $interval . ' ' . $this->long_label_plural(); } }, $intervals); } } IAWP/Interval/Minute_Interval.php000064400000002650147600331220012707 0ustar00from($views_table, 'views')->selectRaw('COUNT(DISTINCT (sessions.visitor_id)) AS visitors')->selectRaw('COUNT(*) AS views')->selectRaw("ABS(CEILING(TIMESTAMPDIFF(MINUTE, '{$date_range->iso_end()}', views.viewed_at))) AS interval_ago")->leftJoin("{$sessions_table} AS sessions", function (JoinClause $join) { $join->on('views.session_id', '=', 'sessions.session_id'); })->whereBetween('viewed_at', [$date_range->iso_start(), $date_range->iso_end()])->groupBy('interval_ago')->get()->all(); } public function get_date_interval() : \DateInterval { return new \DateInterval('PT1M'); } public function short_label() : string { return \__('min'); } public function long_label_singular() : string { return \__('minute ago'); } public function long_label_plural() : string { return \__('minutes ago'); } public function interval_multiplier() : int { return 1; } } IAWP/Interval/Ten_Second_Interval.php000064400000002663147600331220013473 0ustar00from($views_table, 'views')->selectRaw('COUNT(DISTINCT (sessions.visitor_id)) AS visitors')->selectRaw('COUNT(*) AS views')->selectRaw("ABS(CEILING(TIMESTAMPDIFF(SECOND, '{$date_range->iso_end()}', views.viewed_at) / 10)) AS interval_ago")->leftJoin("{$sessions_table} AS sessions", function (JoinClause $join) { $join->on('views.session_id', '=', 'sessions.session_id'); })->whereBetween('viewed_at', [$date_range->iso_start(), $date_range->iso_end()])->groupBy('interval_ago')->get()->all(); } public function get_date_interval() : \DateInterval { return new \DateInterval('PT10S'); } public function short_label() : string { return \__('sec'); } public function long_label_singular() : string { return \__('second ago'); } public function long_label_plural() : string { return \__('seconds ago'); } public function interval_multiplier() : int { return 10; } } IAWP/Menu_Bar_Stats/Menu_Bar_Stats.php000064400000013001147600331220013522 0ustar00current_resource_identifier = Resource_Identifier::for_resource_being_edited(); } else { $this->current_resource_identifier = Resource_Identifier::for_resource_being_viewed(); } if (!\is_null($this->current_resource_identifier)) { $this->views_today = self::get_views_in_date_range($today); $this->views_yesterday = self::get_views_in_date_range($yesterday); $this->views_last_thirty = self::get_views_in_date_range($last_thirty); $this->views_total = self::get_views_in_date_range($all_time); } } /** * @return bool */ public function is_enabled() : bool { if (!self::is_option_enabled()) { return \false; } if (\is_null($this->current_resource_identifier)) { return \false; } return \true; } /** * @return array[] */ private function get_menu_bar_items() : array { $today = Number_Formatter::decimal($this->views_today); $yesterday = Number_Formatter::decimal($this->views_yesterday); $last_thirty = Number_Formatter::decimal($this->views_last_thirty); $total = Number_Formatter::decimal($this->views_total); return [['id' => 'iawp_admin_bar', 'title' => '' . \sprintf('%d %s', $today, \esc_html__('Views', 'independent-analytics')), 'meta' => ['class' => 'iawp_admin_bar_button']], ['id' => 'iawp_admin_bar_group_title', 'title' => '' . \esc_html__('Date', 'independent-analytics') . ' ' . '' . \esc_html__('Views', 'independent-analytics') . '', 'parent' => 'iawp_admin_bar'], ['id' => 'iawp_admin_bar_today', 'title' => '' . \esc_html__('Today:', 'independent-analytics') . ' ' . \esc_html__($today) . '', 'parent' => 'iawp_admin_bar'], ['id' => 'iawp_admin_bar_yesterday', 'title' => '' . \esc_html__('Yesterday:', 'independent-analytics') . ' ' . \esc_html__($yesterday) . '', 'parent' => 'iawp_admin_bar'], ['id' => 'iawp_admin_bar_last_thirty', 'title' => '' . \esc_html__('Last 30 Days:', 'independent-analytics') . ' ' . \esc_html__($last_thirty) . '', 'parent' => 'iawp_admin_bar'], ['id' => 'iawp_admin_bar_total', 'title' => '' . \esc_html__('All Time:', 'independent-analytics') . ' ' . \esc_html__($total) . '', 'parent' => 'iawp_admin_bar'], ['id' => 'iawp_admin_bar_dashboard_group', 'parent' => 'iawp_admin_bar', 'is_group' => \true], ['id' => 'iawp_admin_bar_dashboard_link', 'title' => \esc_html__('Analytics Dashboard', 'independent-analytics') . ' →', 'href' => \esc_url(\IAWPSCOPED\iawp_dashboard_url()), 'parent' => 'iawp_admin_bar_dashboard_group']]; } private function get_views_in_date_range(Date_Range $date_range) : int { $resources_table = Query::get_table_name(Query::RESOURCES); $views_table = Query::get_table_name(Query::VIEWS); $resource_statistics_query = Illuminate_Builder::new(); $resource = $this->current_resource_identifier; $resource_statistics_query->selectRaw('COUNT(*) AS views')->from("{$resources_table} as resources")->join("{$views_table} AS views", function (JoinClause $join) { $join->on('resources.id', '=', 'views.resource_id'); })->where('resource', '=', $resource->type())->when($resource->has_meta(), function (Builder $query) use($resource) { $query->where($resource->meta_key(), '=', $resource->meta_value()); })->whereBetween('views.viewed_at', [$date_range->iso_start(), $date_range->iso_end()]); $resource_statistics = $resource_statistics_query->get()->first(); return $resource_statistics->views ?? 0; } public static function is_option_enabled() : bool { return \IAWPSCOPED\iawp()->get_option('iawp_disable_admin_toolbar_analytics', \false) === \false && Capability_Manager::can_view(); } public static function register() { \add_action('admin_bar_menu', function ($admin_bar) { $menu_bar_stats = new self(); if (!$menu_bar_stats->is_enabled()) { return; } foreach ($menu_bar_stats->get_menu_bar_items() as $menu_bar_item) { $is_group = $menu_bar_item['is_group'] ?? \false; // Should the item be registered as a group or a node? if ($is_group) { $admin_bar->add_group($menu_bar_item); } else { $admin_bar->add_node($menu_bar_item); } } }, 100); } } IAWP/Migrations/Creates_Reports.php000064400000002176147600331220013241 0ustar00 $value) { $columns[] = $key; $values_placeholders[] = "%s"; $values[] = $value; } $columns = \implode(', ', $columns); $values_placeholders = \implode(', ', $values_placeholders); return $wpdb->prepare("\n INSERT INTO {$tables::reports()}\n ({$columns})\n VALUES\n ({$values_placeholders});\n ", ...$values); } } IAWP/Migrations/Migration.php000064400000001315147600331220012060 0ustar00database_version, '<')) { $this->migrate(); \update_option('iawp_db_version', $this->database_version, \true); } } /** * Classes that extend must define a handle method where migration work is done * * @return void */ protected abstract function migrate() : void; } IAWP/Migrations/Migrations.php000064400000016140147600331220012245 0ustar00'); } public static function is_actually_migrating() : bool { return \get_option('iawp_is_migrating') === '1'; } /** * @return bool */ public static function should_migrate() : bool { $db_version = \get_option('iawp_db_version', '0'); $is_migrating = \get_option('iawp_is_migrating') === '1'; $is_current = \version_compare($db_version, '39', '='); $is_outdated = !$is_current; return $is_outdated && !$is_migrating; } public static function handle_migration_18_error() : void { $directory = \trailingslashit(\wp_upload_dir()['basedir']) . 'iawp/'; $db_version = \get_option('iawp_db_version', '0'); $is_migrating = \get_option('iawp_is_migrating', '0') === '1'; if ($db_version === '17' && $is_migrating && \is_dir($directory)) { \update_option('iawp_db_version', '18', \true); \update_option('iawp_is_migrating', '0', \true); \delete_option('iawp_last_finished_migration_step'); \delete_option('iawp_migration_error'); \delete_option('iawp_migration_error_query'); try { $directory = \trailingslashit(\wp_upload_dir()['basedir']) . 'iawp/'; Dir::delete($directory); } catch (\Throwable $e) { } } } public static function handle_migration_22_error() : void { $db_version = \get_option('iawp_db_version', '0'); $is_migrating = \get_option('iawp_is_migrating', '0') === '1'; $last_finished_step = \get_option('iawp_last_finished_migration_step', '0'); $has_error = \get_option('iawp_migration_error_query', null) !== null && \get_option('iawp_migration_error', null) !== null; $referrers_table = Query::get_table_name(Query::REFERRERS); $has_index = Database::has_index($referrers_table, 'referrers_domain_index'); if ($db_version === '21' && $is_migrating && $last_finished_step === '0' && $has_error && !$has_index) { \update_option('iawp_is_migrating', '0', \true); \delete_option('iawp_last_finished_migration_step'); \delete_option('iawp_migration_error'); \delete_option('iawp_migration_error_query'); } } public static function handle_migration_29_error() : void { global $wpdb; $db_version = \get_option('iawp_db_version', '0'); $is_migrating = \get_option('iawp_is_migrating', '0') === '1'; $last_finished_step = \get_option('iawp_last_finished_migration_step', '0'); $has_error = \get_option('iawp_migration_error_query', null) !== null && \get_option('iawp_migration_error', null) !== null; if ($db_version === '28' && $is_migrating && $last_finished_step === '5' && $has_error) { $sessions_table = Query::get_table_name(Query::SESSIONS); $wpdb->query("ALTER TABLE {$sessions_table} DROP COLUMN visitor_id"); $wpdb->query("ALTER TABLE {$sessions_table} CHANGE COLUMN old_visitor_id visitor_id varchar(32)"); \delete_option('iawp_last_finished_migration_step'); \delete_option('iawp_migration_error'); \delete_option('iawp_migration_error_query'); \update_option('iawp_is_migrating', '0', \true); } } /** * @param Step_Migration[] $migrations * * @return bool */ private static function run_step_migrations(array $migrations) : bool { foreach ($migrations as $migration) { $completed = $migration->migrate(); if (!$completed) { return \false; } } return \true; } } IAWP/Migrations/Migration_10.php000064400000011245147600331220012363 0ustar00query("\n UPDATE {$referrers_table} SET domain = SUBSTRING(domain, 1, 255) WHERE LENGTH(domain) > 255;\n "); $wpdb->query("\n ALTER TABLE {$referrers_table} MODIFY COLUMN domain VARCHAR(255) NOT NULL;\n "); $wpdb->query("\n UPDATE {$referrer_groups_table} SET name = SUBSTRING(name, 1, 255) WHERE LENGTH(name) > 255;\n "); $wpdb->query("\n ALTER TABLE {$referrer_groups_table} MODIFY COLUMN name VARCHAR(255) NOT NULL;\n "); $wpdb->query("\n UPDATE {$referrer_groups_table} SET domain = SUBSTRING(domain, 1, 255) WHERE LENGTH(domain) > 255;\n "); $wpdb->query("\n ALTER TABLE {$referrer_groups_table} MODIFY COLUMN domain VARCHAR(255) NOT NULL;\n "); $wpdb->query("\n UPDATE {$referrer_groups_table} SET domain_to_match = SUBSTRING(domain_to_match, 1, 255) WHERE LENGTH(domain_to_match) > 255;\n "); $wpdb->query("\n ALTER TABLE {$referrer_groups_table} MODIFY COLUMN domain_to_match VARCHAR(255) NOT NULL;\n "); $wpdb->query("\n CREATE INDEX views_viewed_at_index\n ON {$views_table} (viewed_at);\n "); $wpdb->query("\n CREATE INDEX views_resource_id_index\n ON {$views_table} (resource_id);\n "); $wpdb->query("\n CREATE INDEX wc_orders_view_id_index\n ON {$wc_orders_table} (view_id);\n "); $wpdb->query("\n CREATE INDEX wc_orders_created_at_index\n ON {$wc_orders_table} (created_at);\n "); $wpdb->query("\n CREATE INDEX sessions_created_at_index\n ON {$sessions_table} (created_at);\n "); // Remove any duplicate referrer groups where a given domain_to_match already exists $wpdb->query("\n DELETE referrer_groups FROM {$referrer_groups_table} AS referrer_groups\n INNER JOIN (\n SELECT\n domain_to_match,\n MIN(referrer_group_id) AS min_referrer_group_id\n FROM\n {$referrer_groups_table}\n GROUP BY\n domain_to_match\n HAVING\n COUNT(*) > 1) AS duplicates ON referrer_groups.domain_to_match = duplicates.domain_to_match\n AND referrer_groups.referrer_group_id > duplicates.min_referrer_group_id;\n "); $wpdb->query("\n CREATE UNIQUE INDEX referrer_groups_domain_to_match_index\n ON {$referrer_groups_table} (domain_to_match);\n "); $wpdb->query("\n UPDATE\n {$sessions_table} AS sessions\n INNER JOIN {$referrers_table} AS referrers ON sessions.referrer_id = referrers.id\n INNER JOIN (\n SELECT\n MIN(referrers.id) AS min_referrer_id,\n referrers.domain\n FROM\n {$sessions_table} AS sessions\n INNER JOIN {$referrers_table} AS referrers ON sessions.referrer_id = referrers.id\n GROUP BY\n referrers.domain) AS matcher ON referrers.domain = matcher.domain\n AND referrers.id != matcher.min_referrer_id SET sessions.referrer_id = matcher.min_referrer_id;\n "); $wpdb->query("\n DELETE referrers FROM {$referrers_table} AS referrers\n LEFT JOIN {$sessions_table} AS sessions ON referrers.id = sessions.referrer_id\n WHERE sessions.session_id IS NULL;\n "); $wpdb->query("\n CREATE UNIQUE INDEX referrers_domain_index\n ON {$referrers_table} (domain);\n "); $wpdb->query("\n ALTER TABLE {$referrer_groups_table} MODIFY COLUMN type ENUM ('Search', 'Social', 'Referrer') NOT NULL;\n "); Known_Referrers::replace_known_referrers_table(); } } IAWP/Migrations/Migration_11.php000064400000006016147600331220012364 0ustar00query("\n ALTER TABLE {$views_table} ADD COLUMN next_view_id BIGINT(20) UNSIGNED, ADD COLUMN next_viewed_at DATETIME;\n "); $wpdb->query("\n ALTER TABLE {$sessions_table} ADD COLUMN final_view_id BIGINT(20) UNSIGNED, ADD COLUMN ended_at DATETIME;\n "); // Populate ended_at for all sessions where legacy_view=0 // Find the sessions last view and use it's viewed_at value for sessions.ended_at $wpdb->query("\n UPDATE\n {$sessions_table} AS sessions\n INNER JOIN (\n SELECT\n sessions.session_id AS session_id,\n MAX(views.id) AS final_view_id,\n MAX(views.viewed_at) AS ended_at\n FROM\n {$sessions_table} AS sessions\n INNER JOIN {$views_table} AS views ON sessions.session_id = views.session_id\n AND sessions.initial_view_id != views.id\n WHERE\n sessions.legacy_view = FALSE\n GROUP BY\n sessions.session_id) AS query ON sessions.session_id = query.session_id\n SET sessions.ended_at = query.ended_at, sessions.final_view_id = query.final_view_id\n "); // Populate next_viewed_at for all views where session.legacy_view=0 // Find the most previous view based on views.viewed_at that belongs to the same session $wpdb->query("\n UPDATE\n {$views_table} AS views\n INNER JOIN (\n SELECT\n views.id AS id,\n views.viewed_at AS viewed_at,\n MIN(query.id) AS next_view_id,\n MIN(query.viewed_at) AS next_viewed_at\n FROM\n {$views_table} AS views\n INNER JOIN (\n SELECT\n *\n FROM\n {$views_table} AS views) AS query ON views.session_id = query.session_id\n AND views.id != query.id\n WHERE\n views.id < query.id\n GROUP BY\n views.id) AS query ON views.id = query.id\n SET views.next_viewed_at = query.next_viewed_at, views.next_view_id = query.next_view_id\n "); } } IAWP/Migrations/Migration_12.php000064400000004071147600331220012364 0ustar00prefix . 'wc_order_stats'; $wpdb->query("\n ALTER TABLE {$wc_orders_table} \n ADD COLUMN total DOUBLE,\n ADD COLUMN total_refunded DOUBLE,\n ADD COLUMN total_refunds SMALLINT,\n ADD COLUMN status VARCHAR(200);\n "); if (\IAWPSCOPED\iawp()->is_woocommerce_support_enabled()) { $wpdb->query("\n UPDATE\n {$wc_orders_table} AS wc_orders\n LEFT JOIN (\n SELECT\n wc_order_stats.order_id,\n wc_order_stats.status,\n wc_order_stats.total_sales,\n IFNULL(ABS(SUM(refunds.total_sales)), 0) AS total_refunded,\n COUNT(DISTINCT refunds.order_id) AS total_refunds\n FROM\n {$wc_orders_table} AS wc_orders\n JOIN {$wc_order_stats_table} AS wc_order_stats ON wc_orders.order_id = wc_order_stats.order_id\n LEFT JOIN {$wc_order_stats_table} AS refunds ON wc_order_stats.order_id = refunds.parent_id\n AND refunds.total_sales < 0\n GROUP BY\n wc_order_stats.order_id\n ) AS wc_order_stats ON wc_orders.order_id = wc_order_stats.order_id\n SET\n wc_orders.status = wc_order_stats.status,\n wc_orders.total = wc_order_stats.total_sales,\n wc_orders.total_refunded = wc_order_stats.total_refunded,\n wc_orders.total_refunds = wc_order_stats.total_refunds;\n "); } } } IAWP/Migrations/Migration_13.php000064400000014613147600331220012370 0ustar00remove_city_neighborhood_data(); $this->add_index_for_visitors_table(); $this->create_cities_table(); $this->create_countries_table(); $this->add_foreign_keys_to_sessions(); $this->populate_countries(); $this->populate_cities(); $this->link_sessions_to_city_and_country(); $this->drop_visitors_table(); } private function add_index_for_visitors_table() { global $wpdb; $visitors_table = Query::get_table_name(Query::VISITORS); $wpdb->query("\n CREATE INDEX visitors_migration_index\n ON {$visitors_table} (country_code, subdivision, city)\n "); } private function create_cities_table() { global $wpdb; $charset_and_collation = $wpdb->get_charset_collate(); $cities_table = Query::get_table_name(Query::CITIES); $wpdb->query("DROP TABLE IF EXISTS {$cities_table}"); $wpdb->query("\n CREATE TABLE {$cities_table} (\n city_id bigint(20) UNSIGNED AUTO_INCREMENT,\n country_id bigint(20) UNSIGNED NOT NULL,\n subdivision varchar(64) NOT NULL,\n city varchar(64) NOT NULL,\n PRIMARY KEY (city_id)\n ) {$charset_and_collation}\n "); $wpdb->query("\n CREATE UNIQUE INDEX cities_unique_index\n ON {$cities_table} (country_id, subdivision, city)\n "); } private function create_countries_table() { global $wpdb; $charset_and_collation = $wpdb->get_charset_collate(); $countries_table = Query::get_table_name(Query::COUNTRIES); $wpdb->query("DROP TABLE IF EXISTS {$countries_table}"); $wpdb->query("\n CREATE TABLE {$countries_table} (\n country_id bigint(20) UNSIGNED AUTO_INCREMENT,\n country_code varchar(4) NOT NULL,\n country varchar(64) NOT NULL,\n continent varchar(16) NOT NULL,\n PRIMARY KEY (country_id)\n ) {$charset_and_collation}\n "); $wpdb->query("\n CREATE UNIQUE INDEX countries_unique_index\n ON {$countries_table} (country_code, country, continent)\n "); } private function add_foreign_keys_to_sessions() { global $wpdb; $sessions_table = Query::get_table_name(Query::SESSIONS); $wpdb->query("\n ALTER TABLE {$sessions_table}\n ADD COLUMN city_id BIGINT(20) UNSIGNED,\n ADD COLUMN country_id BIGINT(20) UNSIGNED;\n "); $wpdb->query("\n ALTER TABLE {$sessions_table}\n ADD INDEX(city_id),\n ADD INDEX(country_id);\n "); } private function remove_city_neighborhood_data() { global $wpdb; $visitors_table = Query::get_table_name(Query::VISITORS); $wpdb->query("\n UPDATE\n {$visitors_table}\n SET\n city = TRIM(SUBSTRING_INDEX(city, '(', 1)) \n "); } private function populate_countries() { global $wpdb; $countries_tables = Query::get_table_name(Query::COUNTRIES); $visitors_table = Query::get_table_name(Query::VISITORS); $wpdb->query("\n INSERT IGNORE INTO {$countries_tables} (continent, country_code, country)\n SELECT\n continent,\n country_code,\n country\n FROM\n {$visitors_table}\n WHERE\n continent IS NOT NULL\n AND country_code IS NOT NULL\n AND country IS NOT NULL\n GROUP BY\n continent,\n country_code,\n country \n "); } private function populate_cities() { global $wpdb; $cities_tables = Query::get_table_name(Query::CITIES); $countries_table = Query::get_table_name(Query::COUNTRIES); $visitors_table = Query::get_table_name(Query::VISITORS); $wpdb->query("\n INSERT IGNORE INTO {$cities_tables} (country_id, subdivision, city)\n SELECT\n countries.country_id,\n subdivision,\n city\n FROM\n {$visitors_table} AS visitors\n LEFT JOIN {$countries_table} AS countries ON visitors.country_code = countries.country_code\n WHERE\n subdivision IS NOT NULL\n AND city IS NOT NULL\n GROUP BY\n countries.country_id,\n subdivision,\n city\n "); } private function link_sessions_to_city_and_country() { global $wpdb; $cities_tables = Query::get_table_name(Query::CITIES); $countries_table = Query::get_table_name(Query::COUNTRIES); $visitors_table = Query::get_table_name(Query::VISITORS); $sessions_table = Query::get_table_name(Query::SESSIONS); $wpdb->query("\n UPDATE\n {$sessions_table} AS sessions\n LEFT JOIN {$visitors_table} AS visitors ON sessions.visitor_id = visitors.visitor_id\n LEFT JOIN (\n SELECT\n countries.country_id,\n cities.city_id,\n countries.country_code,\n cities.subdivision,\n cities.city\n FROM\n {$cities_tables} AS cities\n LEFT JOIN {$countries_table} AS countries ON cities.country_id = countries.country_id) AS locations ON visitors.country_code = locations.country_code\n AND visitors.subdivision = locations.subdivision\n AND visitors.city = locations.city\n SET sessions.country_id = locations.country_id, sessions.city_id = locations.city_id\n "); } private function drop_visitors_table() { global $wpdb; $visitors_table = Query::get_table_name(Query::VISITORS); $wpdb->query("DROP TABLE IF EXISTS {$visitors_table}"); } } IAWP/Migrations/Migration_14.php000064400000003505147600331220012367 0ustar00create_devices_table(); $this->add_foreign_keys_to_sessions(); } private function create_devices_table() { global $wpdb; $charset_and_collation = $wpdb->get_charset_collate(); $devices_table = Query::get_table_name(Query::DEVICES); $wpdb->query("DROP TABLE IF EXISTS {$devices_table}"); $wpdb->query("\n CREATE TABLE {$devices_table} (\n device_id bigint(20) UNSIGNED AUTO_INCREMENT,\n type varchar(16),\n os varchar(16),\n browser varchar(32),\n PRIMARY KEY (device_id)\n ) {$charset_and_collation}\n "); $wpdb->query("\n CREATE UNIQUE INDEX devices_unique_index\n ON {$devices_table} (type, os, browser)\n "); $wpdb->query("\n CREATE INDEX type_index\n ON {$devices_table} (type)\n "); $wpdb->query("\n CREATE INDEX os_index\n ON {$devices_table} (os)\n "); $wpdb->query("\n CREATE INDEX browser_index\n ON {$devices_table} (browser)\n "); } private function add_foreign_keys_to_sessions() { global $wpdb; $sessions_table = Query::get_table_name(Query::SESSIONS); $wpdb->query("\n ALTER TABLE {$sessions_table}\n ADD COLUMN device_id BIGINT(20) UNSIGNED;\n "); $wpdb->query("\n ALTER TABLE {$sessions_table}\n ADD INDEX(device_id);\n "); } } IAWP/Migrations/Migration_15.php000064400000001072147600331220012365 0ustar00make_subdivision_nullable(); } private function make_subdivision_nullable() : void { global $wpdb; $cities_table = Query::get_table_name(Query::CITIES); $wpdb->query("ALTER TABLE {$cities_table} MODIFY subdivision VARCHAR(64);"); } } IAWP/Migrations/Migration_16.php000064400000002522147600331220012367 0ustar00create_reports_table(); } private function create_reports_table() : void { global $wpdb; $charset_collate = $wpdb->get_charset_collate(); $reports_table = Query::get_table_name(Query::REPORTS); $wpdb->query("DROP TABLE IF EXISTS {$reports_table}"); $wpdb->query("CREATE TABLE {$reports_table} (\n report_id bigint(20) UNSIGNED AUTO_INCREMENT,\n user_created_report boolean NOT NULL DEFAULT true,\n name varchar(255) NOT NULL,\n type varchar(64) NOT NULL,\n exact_start datetime,\n exact_end datetime,\n relative_range_id varchar(64),\n sort_column varchar(64),\n sort_direction varchar(64),\n group_name varchar(64),\n chart_interval varchar(64),\n columns text,\n filters text,\n visible_datasets text,\n position int,\n PRIMARY KEY (report_id)\n ) {$charset_collate}"); } } IAWP/Migrations/Migration_17.php000064400000007067147600331220012401 0ustar00add_initial_saved_reports(); } private function add_initial_saved_reports() : void { Report_Finder::create_report(['name' => \esc_html__('Blog Posts', 'independent-analytics'), 'type' => 'views', 'user_created_report' => 0, 'filters' => [['inclusion' => 'include', 'column' => 'type', 'operator' => 'is', 'operand' => 'post']]]); Report_Finder::create_report(['name' => \esc_html__('Top Landing Pages', 'independent-analytics'), 'type' => 'views', 'user_created_report' => 0, 'sort_column' => 'entrances', 'sort_direction' => 'desc', 'columns' => ['title', 'visitors', 'views', 'average_view_duration', 'bounce_rate', 'entrances', 'url', 'type']]); Report_Finder::create_report(['name' => \esc_html__('Fastest-Growing Pages', 'independent-analytics'), 'type' => 'views', 'user_created_report' => 0, 'sort_column' => 'visitors_growth', 'sort_direction' => 'desc', 'columns' => ['title', 'visitors', 'views', 'average_view_duration', 'bounce_rate', 'visitors_growth', 'url', 'type'], 'filters' => [['inclusion' => 'exclude', 'column' => 'visitors', 'operator' => 'lesser', 'operand' => '5']]]); Report_Finder::create_report(['name' => \esc_html__('Today', 'independent-analytics'), 'type' => 'views', 'user_created_report' => 0, 'relative_range_id' => 'TODAY']); Report_Finder::create_report(['name' => \esc_html__('Search Engine Traffic', 'independent-analytics'), 'type' => 'referrers', 'user_created_report' => 0, 'filters' => [['inclusion' => 'include', 'column' => 'referrer_type', 'operator' => 'is', 'operand' => 'Search']]]); Report_Finder::create_report(['name' => \esc_html__('Social Media Traffic', 'independent-analytics'), 'type' => 'referrers', 'user_created_report' => 0, 'filters' => [['inclusion' => 'include', 'column' => 'referrer_type', 'operator' => 'is', 'operand' => 'Social']]]); Report_Finder::create_report(['name' => \esc_html__('Fastest-Growing Referrers', 'independent-analytics'), 'type' => 'referrers', 'user_created_report' => 0, 'sort_column' => 'visitors_growth', 'sort_direction' => 'desc', 'columns' => ['referrer', 'referrer_type', 'visitors', 'views', 'average_session_duration', 'bounce_rate', 'visitors_growth'], 'filters' => [['inclusion' => 'exclude', 'column' => 'visitors', 'operator' => 'lesser', 'operand' => '5']]]); Report_Finder::create_report(['name' => \esc_html__('Last 7 Days', 'independent-analytics'), 'type' => 'referrers', 'user_created_report' => 0, 'relative_range_id' => 'LAST_SEVEN']); Report_Finder::create_report(['name' => \esc_html__('Cities', 'independent-analytics'), 'type' => 'geo', 'group_name' => 'city', 'user_created_report' => 0]); Report_Finder::create_report(['name' => \esc_html__('European Countries', 'independent-analytics'), 'type' => 'geo', 'user_created_report' => 0, 'filters' => [['inclusion' => 'include', 'column' => 'continent', 'operator' => 'exact', 'operand' => 'Europe']]]); Report_Finder::create_report(['name' => \esc_html__('Browsers', 'independent-analytics'), 'type' => 'devices', 'group_name' => 'browser', 'user_created_report' => 0]); Report_Finder::create_report(['name' => \esc_html_x('OS', 'short for operating system', 'independent-analytics'), 'type' => 'devices', 'group_name' => 'os', 'user_created_report' => 0]); } } IAWP/Migrations/Migration_18.php000064400000000725147600331220012374 0ustar00get_charset_collate(); $referrers_table = Query::get_table_name(Query::REFERRERS); $wpdb->query("DROP TABLE IF EXISTS {$referrers_table}"); $wpdb->query("CREATE TABLE {$referrers_table} (\n id bigint(20) UNSIGNED AUTO_INCREMENT,\n url varchar(2048) NOT NULL,\n PRIMARY KEY (id)\n ) {$charset_collate}"); $views_table = Query::get_table_name(Query::VIEWS); $wpdb->query("DROP TABLE IF EXISTS {$views_table}"); $wpdb->query("CREATE TABLE {$views_table} (\n id bigint(20) UNSIGNED AUTO_INCREMENT,\n referrer_id bigint(20) UNSIGNED,\n resource_id bigint(20) UNSIGNED NOT NULL,\n viewed_at datetime,\n PRIMARY KEY (id)\n ) {$charset_collate}"); $resources_table = Query::get_table_name(Query::RESOURCES); $wpdb->query("DROP TABLE IF EXISTS {$resources_table}"); $wpdb->query("CREATE TABLE {$resources_table} (\n id bigint(20) UNSIGNED AUTO_INCREMENT,\n resource varchar(256) NOT NULL,\n page bigint(20) UNSIGNED NOT NULL DEFAULT 1,\n singular_id bigint(20) UNSIGNED,\n author_id bigint(20) UNSIGNED,\n date_archive varchar(256),\n search_query varchar(256),\n post_type varchar(256),\n term_id bigint(20) UNSIGNED,\n not_found_url varchar(256),\n cached_title varchar(256),\n cached_url varchar(256),\n cached_type varchar(256),\n cached_type_label varchar(256),\n cached_author_id bigint(20) UNSIGNED,\n cached_author varchar(256),\n cached_date varchar(256),\n PRIMARY KEY (id)\n ) {$charset_collate}"); } } IAWP/Migrations/Migration_1_6.php000064400000001546147600331220012533 0ustar00get_charset_collate(); $views_table = Query::get_table_name(Query::VIEWS); $wpdb->query("ALTER TABLE {$views_table} ADD visitor_id bigint(20) UNSIGNED"); $visitors_table = Query::get_table_name(Query::VISITORS); $wpdb->query("DROP TABLE IF EXISTS {$visitors_table}"); $wpdb->query("CREATE TABLE {$visitors_table} (\n id bigint(20) UNSIGNED AUTO_INCREMENT,\n visitor_token varchar(256),\n PRIMARY KEY (id)\n ) {$charset_collate}"); } } IAWP/Migrations/Migration_1_8.php000064400000011114147600331220012525 0ustar00get_charset_collate(); $views_table = Query::get_table_name(Query::VIEWS); $resources_table = Query::get_table_name(Query::RESOURCES); $referrer_groups_table = Query::get_table_name(Query::REFERRER_GROUPS); $referrers_table = Query::get_table_name(Query::REFERRERS); $known_referrers = Known_Referrers::referrers(); // Create the groups table $wpdb->query("DROP TABLE IF EXISTS {$referrer_groups_table}"); $wpdb->query("CREATE TABLE {$referrer_groups_table} (\n referrer_group_id bigint(20) UNSIGNED AUTO_INCREMENT,\n name varchar(2048) NOT NULL,\n domain varchar(2048) NOT NULL,\n domain_to_match varchar(2048) NOT NULL,\n type ENUM ('Search', 'Social') NOT NULL,\n PRIMARY KEY (referrer_group_id)\n ) {$charset_collate}"); // Insert predefined groups foreach ($known_referrers as $group) { foreach ($group['domains'] as $domain) { $wpdb->insert($referrer_groups_table, ['name' => $group['name'], 'domain' => $group['domains'][0], 'domain_to_match' => $domain, 'type' => $group['type']]); } } $wpdb->query("\n ALTER TABLE {$referrers_table} CHANGE COLUMN url domain varchar(2048) NOT NULL;\n "); $rows = $wpdb->get_results("SELECT * FROM {$referrers_table}"); foreach ($rows as $row) { $potential_url = new URL($row->domain); if ($potential_url->is_valid_url()) { $wpdb->query($wpdb->prepare("UPDATE {$referrers_table} SET domain = %s WHERE id = %d", $potential_url->get_domain(), $row->id)); } } // add a new page field to view table $wpdb->query("\n ALTER TABLE {$views_table} ADD COLUMN page bigint(20) UNSIGNED NOT NULL DEFAULT 1;\n "); // move the page number to the view and set the resource_id to first of similar resources $wpdb->query("\n UPDATE {$views_table} AS views\n INNER JOIN {$resources_table} AS resources ON views.resource_id = resources.id\n INNER JOIN\n (\n SELECT MIN({$resources_table}.id) as resource_id,\n resource,\n singular_id,\n author_id,\n date_archive,\n search_query,\n post_type,\n term_id,\n not_found_url\n FROM {$views_table}\n INNER JOIN {$resources_table}\n ON {$resources_table}.id = {$views_table}.resource_id\n GROUP BY resource, singular_id, author_id, date_archive, search_query, post_type, term_id, not_found_url\n ) AS matcher ON resources.resource = matcher.resource\n AND (resources.singular_id = matcher.singular_id OR resources.singular_id IS NULL OR matcher.singular_id IS NULL)\n AND (resources.author_id = matcher.author_id OR resources.author_id IS NULL OR matcher.author_id IS NULL)\n AND (resources.date_archive = matcher.date_archive OR resources.date_archive IS NULL OR matcher.date_archive IS NULL)\n AND (resources.search_query = matcher.search_query OR resources.search_query IS NULL OR matcher.search_query IS NULL)\n AND (resources.post_type = matcher.post_type OR resources.post_type IS NULL OR matcher.post_type IS NULL)\n AND (resources.term_id = matcher.term_id OR resources.term_id IS NULL OR matcher.term_id IS NULL)\n AND (resources.not_found_url = matcher.not_found_url OR resources.not_found_url IS NULL OR matcher.not_found_url IS NULL)\n AND resources.id != matcher.resource_id\n SET views.resource_id = matcher.resource_id, views.page = resources.page\n "); // delete the extra duplicate resources (or don't?) $wpdb->query("\n DELETE resources FROM {$resources_table} AS resources \n LEFT JOIN {$views_table} AS views ON resources.id = views.resource_id\n WHERE views.id IS NULL\n "); // remove the page column from resources $wpdb->query("\n ALTER TABLE {$resources_table} DROP COLUMN page;\n "); } } IAWP/Migrations/Migration_1_9.php000064400000001261147600331220012530 0ustar00query("\n ALTER TABLE {$visitors_table}\n ADD (\n country_code varchar(256),\n city varchar(256),\n subdivision varchar(256),\n country varchar(256),\n continent varchar(256)\n )\n "); } } IAWP/Migrations/Migration_2.php000064400000001030147600331220012273 0ustar00query("\n ALTER TABLE {$resources_table}\n ADD (\n cached_category varchar(256)\n )\n "); } } IAWP/Migrations/Migration_20.php000064400000002250147600331220012360 0ustar00query("\n ALTER TABLE {$views_table}\n ADD INDEX(session_id, viewed_at)\n "); $wpdb->query("\n ALTER TABLE {$sessions_table}\n ADD COLUMN total_views int\n "); $wpdb->query("\n UPDATE\n {$sessions_table} AS sessions\n LEFT JOIN (\n SELECT\n session_id,\n COUNT(*) AS view_count\n FROM\n {$views_table} AS views\n GROUP BY\n session_id\n ) AS view_counts ON sessions.session_id = view_counts.session_id\n SET sessions.total_views = COALESCE(view_counts.view_count, 0)\n "); } } IAWP/Migrations/Migration_21.php000064400000001171147600331220012362 0ustar00query("\n ALTER TABLE {$referrer_groups_table} MODIFY COLUMN type ENUM ('Search', 'Social', 'Referrer', 'Ad') NOT NULL;\n "); Known_Referrers::replace_known_referrers_table(); } } IAWP/Migrations/Migration_22.php000064400000013330147600331220012363 0ustar00remove_index(), $this->add_columns(), $this->clip_domains(), $this->reduce_domain_column_size(), $this->populate_group_data(), $this->update_non_grouped_referrers(), $this->match_session_with_new_referrers(), $this->remove_duplicates(), $this->restore_index(), $this->create_direct_referrer(), $this->link_direct_sessions_to_direct_referrer(), $this->drop_referrer_groups()]; } private function remove_index() : ?string { $referrers_table = Query::get_table_name(Query::REFERRERS); if (!Database::has_index($referrers_table, 'referrers_domain_index')) { return null; } return "\n ALTER TABLE {$referrers_table} DROP INDEX referrers_domain_index;\n "; } private function add_columns() : string { $referrers_table = Query::get_table_name(Query::REFERRERS); return "\n ALTER TABLE {$referrers_table}\n ADD COLUMN type ENUM('Ad', 'Direct', 'Referrer', 'Search', 'Social'),\n ADD COLUMN referrer VARCHAR(128)\n "; } private function clip_domains() : string { $referrers_table = Query::get_table_name(Query::REFERRERS); return "\n UPDATE {$referrers_table}\n SET domain = SUBSTRING(domain, 1, 128)\n WHERE LENGTH(domain) > 128;\n "; } private function reduce_domain_column_size() : string { $referrers_table = Query::get_table_name(Query::REFERRERS); return "\n ALTER TABLE {$referrers_table}\n MODIFY COLUMN domain VARCHAR(128) NOT NULL;\n "; } private function populate_group_data() : string { $referrers_table = Query::get_table_name(Query::REFERRERS); $referrer_groups_table = Query::get_table_name(Query::REFERRER_GROUPS); return "\n UPDATE {$referrers_table} AS referrers\n JOIN {$referrer_groups_table} AS referrer_groups ON referrers.domain = referrer_groups.domain_to_match\n SET\n referrers.referrer = referrer_groups.name,\n referrers.type = referrer_groups.type,\n referrers.domain = referrer_groups.domain\n "; } private function update_non_grouped_referrers() : string { $referrers_table = Query::get_table_name(Query::REFERRERS); return "\n UPDATE {$referrers_table} AS referrers\n SET type = 'Referrer', referrer = IF(referrers.domain LIKE 'www.%', SUBSTR(referrers.domain, 5), referrers.domain)\n WHERE referrers.referrer IS NULL\n "; } private function match_session_with_new_referrers() : string { $referrers_table = Query::get_table_name(Query::REFERRERS); $sessions_table = Query::get_table_name(Query::SESSIONS); return "\n UPDATE {$sessions_table} AS sessions\n JOIN {$referrers_table} AS referrers ON sessions.referrer_id = referrers.id\n JOIN (\n SELECT\n MIN(referrers.id) AS referrer_id,\n domain,\n type,\n referrer\n FROM {$sessions_table} AS sessions\n JOIN {$referrers_table} AS referrers ON sessions.referrer_id = referrers.id\n WHERE domain IS NOT NULL AND type IS NOT NULL AND referrer IS NOT NULL\n GROUP BY domain, type, referrer\n ) AS first_match\n ON referrers.domain = first_match.domain\n AND referrers.type = first_match.type\n AND referrers.referrer = first_match.referrer\n SET sessions.referrer_id = first_match.referrer_id\n "; } private function remove_duplicates() : string { $referrers_table = Query::get_table_name(Query::REFERRERS); $sessions_table = Query::get_table_name(Query::SESSIONS); return "\n DELETE referrers FROM {$referrers_table} AS referrers\n LEFT JOIN {$sessions_table} AS sessions on referrers.id = sessions.referrer_id\n WHERE sessions.session_id IS NULL\n "; } private function restore_index() : string { $referrers_table = Query::get_table_name(Query::REFERRERS); return "\n CREATE UNIQUE INDEX referrers_domain_index ON {$referrers_table} (domain);\n "; } private function create_direct_referrer() : string { global $wpdb; $referrers_table = Query::get_table_name(Query::REFERRERS); return $wpdb->prepare("\n INSERT INTO {$referrers_table}\n (domain, type, referrer)\n VALUES (%s, %s, %s); \n ", '', 'Direct', 'Direct'); } private function link_direct_sessions_to_direct_referrer() : string { $referrers_table = Query::get_table_name(Query::REFERRERS); $sessions_table = Query::get_table_name(Query::SESSIONS); return "\n UPDATE {$sessions_table} AS sessions\n SET\n sessions.referrer_id = (\n SELECT id FROM {$referrers_table} WHERE domain = ''\n )\n WHERE sessions.referrer_id IS NULL \n "; } private function drop_referrer_groups() : string { $referrer_groups_table = Query::get_table_name(Query::REFERRER_GROUPS); return "\n DROP TABLE IF EXISTS {$referrer_groups_table}\n "; } } IAWP/Migrations/Migration_23.php000064400000015676147600331220012403 0ustar00maybe_drop_device_types_table(), $this->create_device_types_table(), $this->maybe_drop_device_oss_table(), $this->create_device_oss_table(), $this->maybe_drop_device_browsers_table(), $this->create_device_browsers_table(), $this->add_columns_to_sessions(), $this->populate_device_types(), $this->populate_device_oss(), $this->populate_device_browsers(), $this->link_sessions_with_types(), $this->link_sessions_with_oss(), $this->link_sessions_with_browsers(), $this->drop_device_id_column_from_sessions(), $this->drop_original_devices_table()]; } private function maybe_drop_device_types_table() : string { $device_types_table = Query::get_table_name(Query::DEVICE_TYPES); return "\n DROP TABLE IF EXISTS {$device_types_table}\n "; } private function create_device_types_table() : string { global $wpdb; $charset_collate = $wpdb->get_charset_collate(); $device_types_table = Query::get_table_name(Query::DEVICE_TYPES); return "\n CREATE TABLE {$device_types_table} (\n device_type_id bigint(20) UNSIGNED AUTO_INCREMENT,\n device_type varchar(64) NOT NULL UNIQUE,\n PRIMARY KEY (device_type_id)\n ) {$charset_collate}\n "; } private function maybe_drop_device_oss_table() : string { $device_oss_table = Query::get_table_name(Query::DEVICE_OSS); return "\n DROP TABLE IF EXISTS {$device_oss_table}\n "; } private function create_device_oss_table() : string { global $wpdb; $charset_collate = $wpdb->get_charset_collate(); $device_oss_table = Query::get_table_name(Query::DEVICE_OSS); return "\n CREATE TABLE {$device_oss_table} (\n device_os_id bigint(20) UNSIGNED AUTO_INCREMENT,\n device_os varchar(64) NOT NULL UNIQUE,\n PRIMARY KEY (device_os_id)\n ) {$charset_collate}\n "; } private function maybe_drop_device_browsers_table() : string { $device_browsers_table = Query::get_table_name(Query::DEVICE_BROWSERS); return "\n DROP TABLE IF EXISTS {$device_browsers_table}\n "; } private function create_device_browsers_table() : string { global $wpdb; $charset_collate = $wpdb->get_charset_collate(); $device_browsers_table = Query::get_table_name(Query::DEVICE_BROWSERS); return "\n CREATE TABLE {$device_browsers_table} (\n device_browser_id bigint(20) UNSIGNED AUTO_INCREMENT,\n device_browser varchar(64) NOT NULL UNIQUE,\n PRIMARY KEY (device_browser_id)\n ) {$charset_collate}\n "; } private function add_columns_to_sessions() : string { $sessions_table = Query::get_table_name(Query::SESSIONS); return "\n ALTER TABLE {$sessions_table}\n ADD COLUMN device_type_id BIGINT(20) UNSIGNED,\n ADD COLUMN device_os_id BIGINT(20) UNSIGNED,\n ADD COLUMN device_browser_id BIGINT(20) UNSIGNED,\n ADD INDEX (device_type_id),\n ADD INDEX (device_os_id),\n ADD INDEX (device_browser_id);\n "; } private function populate_device_types() : string { $devices_table = Query::get_table_name(Query::DEVICES); $device_types_table = Query::get_table_name(Query::DEVICE_TYPES); return "\n INSERT INTO {$device_types_table} (device_type)\n SELECT DISTINCT type\n FROM {$devices_table} WHERE type IS NOT NULL\n "; } private function populate_device_oss() : string { $devices_table = Query::get_table_name(Query::DEVICES); $device_oss_table = Query::get_table_name(Query::DEVICE_OSS); return "\n INSERT INTO {$device_oss_table} (device_os)\n SELECT DISTINCT os\n FROM {$devices_table} WHERE os IS NOT NULL\n "; } private function populate_device_browsers() { $devices_table = Query::get_table_name(Query::DEVICES); $device_browsers_table = Query::get_table_name(Query::DEVICE_BROWSERS); return "\n INSERT INTO {$device_browsers_table} (device_browser)\n SELECT DISTINCT browser\n FROM {$devices_table} WHERE browser IS NOT NULL\n "; } private function link_sessions_with_types() : string { $sessions_table = Query::get_table_name(Query::SESSIONS); $devices_table = Query::get_table_name(Query::DEVICES); $device_types_table = Query::get_table_name(Query::DEVICE_TYPES); return "\n UPDATE {$sessions_table} AS sessions\n JOIN {$devices_table} AS devices ON sessions.device_id = devices.device_id\n JOIN {$device_types_table} AS device_types ON devices.type = device_types.device_type\n SET sessions.device_type_id = device_types.device_type_id;\n "; } private function link_sessions_with_oss() : string { $sessions_table = Query::get_table_name(Query::SESSIONS); $devices_table = Query::get_table_name(Query::DEVICES); $device_oss_table = Query::get_table_name(Query::DEVICE_OSS); return "\n UPDATE {$sessions_table} AS sessions\n JOIN {$devices_table} AS devices ON sessions.device_id = devices.device_id\n JOIN {$device_oss_table} AS device_oss ON devices.os = device_oss.device_os\n SET sessions.device_os_id = device_oss.device_os_id;\n "; } private function link_sessions_with_browsers() : string { $sessions_table = Query::get_table_name(Query::SESSIONS); $devices_table = Query::get_table_name(Query::DEVICES); $device_browsers_table = Query::get_table_name(Query::DEVICE_BROWSERS); return "\n UPDATE {$sessions_table} AS sessions\n JOIN {$devices_table} AS devices ON sessions.device_id = devices.device_id\n JOIN {$device_browsers_table} AS device_browsers ON devices.browser = device_browsers.device_browser\n SET sessions.device_browser_id = device_browsers.device_browser_id;\n "; } private function drop_device_id_column_from_sessions() : string { $sessions_table = Query::get_table_name(Query::SESSIONS); return "\n ALTER TABLE {$sessions_table} DROP COLUMN device_id;\n "; } private function drop_original_devices_table() : string { $devices_table = Query::get_table_name(Query::DEVICES); return "\n DROP TABLE IF EXISTS {$devices_table};\n "; } } IAWP/Migrations/Migration_24.php000064400000007272147600331220012375 0ustar00add_column(), $this->insert_campaigns(), $this->link_sessions_with_campaigns(), $this->delete_unused_campaigns()]; } private function add_column() : string { $campaigns_table = Query::get_table_name(Query::CAMPAIGNS); return "\n ALTER TABLE {$campaigns_table}\n ADD COLUMN landing_page_title VARCHAR(128) AFTER campaign_id\n "; } private function insert_campaigns() : string { $views_table = Query::get_table_name(Query::VIEWS); $sessions_table = Query::get_table_name(Query::SESSIONS); $campaigns_table = Query::get_table_name(Query::CAMPAIGNS); $resources_table = Query::get_table_name(Query::RESOURCES); return "\n INSERT INTO {$campaigns_table} (landing_page_title, utm_source, utm_medium, utm_campaign, utm_term, utm_content)\n SELECT DISTINCT\n initial_resource.cached_title,\n campaigns.utm_source,\n campaigns.utm_medium,\n campaigns.utm_campaign,\n campaigns.utm_term,\n campaigns.utm_content\n FROM {$resources_table} AS initial_resource\n JOIN {$views_table} AS initial_view ON initial_resource.id = initial_view.resource_id\n JOIN {$sessions_table} AS sessions ON initial_view.session_id = sessions.session_id AND initial_view.id = sessions.initial_view_id\n JOIN {$campaigns_table} AS campaigns ON sessions.campaign_id = campaigns.campaign_id \n "; } private function link_sessions_with_campaigns() : string { $views_table = Query::get_table_name(Query::VIEWS); $sessions_table = Query::get_table_name(Query::SESSIONS); $campaigns_table = Query::get_table_name(Query::CAMPAIGNS); $resources_table = Query::get_table_name(Query::RESOURCES); return "\n UPDATE {$sessions_table} AS sessions\n JOIN {$views_table} AS initial_view ON initial_view.session_id = sessions.session_id AND sessions.initial_view_id = initial_view.id\n JOIN {$resources_table} AS initial_resource ON initial_view.resource_id = initial_resource.id\n JOIN {$campaigns_table} AS campaigns ON sessions.campaign_id = campaigns.campaign_id\n JOIN {$campaigns_table} AS new_campaign ON initial_resource.cached_title = new_campaign.landing_page_title\n AND campaigns.utm_source = new_campaign.utm_source\n AND campaigns.utm_medium = new_campaign.utm_medium\n AND campaigns.utm_campaign = new_campaign.utm_campaign\n AND (campaigns.utm_term = new_campaign.utm_term OR (campaigns.utm_term IS NULL AND new_campaign.utm_term IS NULL))\n AND (campaigns.utm_content = new_campaign.utm_content OR (campaigns.utm_content IS NULL AND new_campaign.utm_content IS NULL))\n SET sessions.campaign_id = new_campaign.campaign_id \n "; } private function delete_unused_campaigns() : string { $sessions_table = Query::get_table_name(Query::SESSIONS); $campaigns_table = Query::get_table_name(Query::CAMPAIGNS); return "\n DELETE campaigns from {$campaigns_table} AS campaigns\n LEFT JOIN {$sessions_table} AS sessions ON campaigns.campaign_id = sessions.campaign_id\n WHERE sessions.session_id IS NULL \n "; } } IAWP/Migrations/Migration_25.php000064400000003002147600331220012361 0ustar00add_temporary_column(), $this->copy_timestamp_data_to_temporary_column(), $this->delete_original_column(), $this->rename_temporary_column()]; } private function add_temporary_column() : string { $resources_table = Query::get_table_name(Query::RESOURCES); return "\n ALTER TABLE {$resources_table} ADD COLUMN cached_date_temp DATE; \n "; } private function copy_timestamp_data_to_temporary_column() : string { $resources_table = Query::get_table_name(Query::RESOURCES); return "\n UPDATE {$resources_table} SET cached_date_temp = FROM_UNIXTIME(cached_date) WHERE cached_date REGEXP '^[0-9]+\$';\n "; } private function delete_original_column() : string { $resources_table = Query::get_table_name(Query::RESOURCES); return "\n ALTER TABLE {$resources_table} DROP COLUMN cached_date;\n "; } private function rename_temporary_column() : string { $resources_table = Query::get_table_name(Query::RESOURCES); return "\n ALTER TABLE {$resources_table} CHANGE COLUMN cached_date_temp cached_date DATE;\n "; } } IAWP/Migrations/Migration_26.php000064400000002335147600331220012372 0ustar00set_empty_values_to_null('cached_title'), $this->set_empty_values_to_null('cached_url'), $this->set_empty_values_to_null('cached_type'), $this->set_empty_values_to_null('cached_type_label'), $this->set_empty_values_to_null('cached_author'), $this->set_empty_values_to_null('cached_category'), $this->nullify_authors_with_id_of_zero()]; } private function set_empty_values_to_null(string $column) : string { $resources_table = Query::get_table_name(Query::RESOURCES); return "\n UPDATE {$resources_table} SET {$column} = NULL WHERE {$column} = '' \n "; } private function nullify_authors_with_id_of_zero() : string { $resources_table = Query::get_table_name(Query::RESOURCES); return "\n UPDATE {$resources_table} SET cached_author_id = NULL, cached_author = NULL WHERE cached_author_id = 0\n "; } } IAWP/Migrations/Migration_27.php000064400000001203147600331220012364 0ustar00add_virtual_page_id()]; } private function add_virtual_page_id() : string { $resources_table = Query::get_table_name(Query::RESOURCES); return "\n ALTER TABLE {$resources_table} ADD COLUMN virtual_page_id VARCHAR(32) AFTER author_id;\n "; } } IAWP/Migrations/Migration_28.php000064400000002744147600331220012400 0ustar00add_initial_view_id_column(), $this->populate_column(), $this->index_column()]; } private function add_initial_view_id_column() : string { $wc_orders_table = Query::get_table_name(Query::WC_ORDERS); return "\n ALTER TABLE {$wc_orders_table} ADD COLUMN initial_view_id BIGINT(20) UNSIGNED AFTER view_id;\n "; } private function populate_column() : string { $views_table = Query::get_table_name(Query::VIEWS); $sessions_table = Query::get_table_name(Query::SESSIONS); $wc_orders_table = Query::get_table_name(Query::WC_ORDERS); return "\n UPDATE {$wc_orders_table} AS orders\n JOIN {$views_table} AS views ON orders.view_id = views.id\n JOIN {$sessions_table} AS sessions on views.session_id = sessions.session_id\n SET orders.initial_view_id = sessions.initial_view_id\n "; } private function index_column() : string { $wc_orders_table = Query::get_table_name(Query::WC_ORDERS); return "\n CREATE INDEX initial_view_id ON {$wc_orders_table} (initial_view_id)\n "; } } IAWP/Migrations/Migration_29.php000064400000006224147600331220012376 0ustar00rename_visitor_id_column(), $this->create_new_visitor_id_column(), $this->drop_table_if_exists(Query::get_table_name(Query::VISITORS)), $this->create_visitors_table(), $this->populate_visitors_table(), $this->populate_token_id_column(), $this->add_index(), $this->remove_very_old_visitors_archive_table()]; } private function rename_visitor_id_column() : string { $sessions_table = Query::get_table_name(Query::SESSIONS); return "\n ALTER TABLE {$sessions_table} CHANGE COLUMN visitor_id old_visitor_id varchar(32);\n "; } private function create_new_visitor_id_column() : string { $sessions_table = Query::get_table_name(Query::SESSIONS); return "\n ALTER TABLE {$sessions_table} ADD COLUMN visitor_id BIGINT(20) UNSIGNED AFTER old_visitor_id\n "; } private function create_visitors_table() : string { $visitors_table = Query::get_table_name(Query::VISITORS); $character_set = Database::character_set(); $collation = Database::collation(); return "\n CREATE TABLE IF NOT EXISTS {$visitors_table} (\n visitor_id BIGINT(20) UNSIGNED AUTO_INCREMENT,\n hash VARCHAR(32) NOT NULL,\n PRIMARY KEY (visitor_id),\n UNIQUE INDEX (hash)\n ) DEFAULT CHARACTER SET {$character_set} COLLATE {$collation};\n "; } private function populate_visitors_table() : string { $sessions_table = Query::get_table_name(Query::SESSIONS); $visitors_table = Query::get_table_name(Query::VISITORS); return "\n INSERT INTO {$visitors_table} (hash)\n SELECT DISTINCT old_visitor_id\n FROM {$sessions_table}\n WHERE old_visitor_id IS NOT NULL\n "; } private function populate_token_id_column() : string { $sessions_table = Query::get_table_name(Query::SESSIONS); $visitors_table = Query::get_table_name(Query::VISITORS); return "\n UPDATE {$sessions_table} AS sessions\n JOIN {$visitors_table} AS visitors on sessions.old_visitor_id = visitors.hash\n SET sessions.visitor_id = visitors.visitor_id\n "; } private function add_index() : string { $sessions_table = Query::get_table_name(Query::SESSIONS); return "\n CREATE INDEX new_bigint_visitor_id ON {$sessions_table} (visitor_id)\n "; } private function remove_very_old_visitors_archive_table() : ?string { $visitors_archive_table = Query::get_table_name(Query::VISITORS_1_16_ARCHIVE); if (\strlen($visitors_archive_table) > 64) { return null; } return "\n DROP TABLE IF EXISTS {$visitors_archive_table};\n "; } } IAWP/Migrations/Migration_3.php000064400000003447147600331220012312 0ustar00get_charset_collate(); $campaigns_table = Query::get_table_name(Query::CAMPAIGNS); $wpdb->query("DROP TABLE IF EXISTS {$campaigns_table}"); $wpdb->query("CREATE TABLE {$campaigns_table} (\n campaign_id bigint(20) UNSIGNED AUTO_INCREMENT,\n utm_source varchar(2048) NOT NULL, \n utm_medium varchar(2048) NOT NULL,\n utm_campaign varchar(2048) NOT NULL,\n utm_term varchar(2048),\n utm_content varchar(2048),\n PRIMARY KEY (campaign_id)\n ) {$charset_collate}"); $campaign_urls_table = Query::get_table_name(Query::CAMPAIGN_URLS); $wpdb->query("DROP TABLE IF EXISTS {$campaign_urls_table}"); $wpdb->query("CREATE TABLE {$campaign_urls_table} (\n campaign_url_id bigint(20) UNSIGNED AUTO_INCREMENT,\n path varchar(2048), \n utm_source varchar(2048) NOT NULL, \n utm_medium varchar(2048) NOT NULL,\n utm_campaign varchar(2048) NOT NULL,\n utm_term varchar(2048),\n utm_content varchar(2048),\n created_at datetime NOT NULL,\n PRIMARY KEY (campaign_url_id)\n ) {$charset_collate}"); $views_table = Query::get_table_name(Query::VIEWS); $wpdb->query("\n ALTER TABLE {$views_table}\n ADD (\n campaign_id bigint(20) UNSIGNED\n )\n "); } } IAWP/Migrations/Migration_30.php000064400000006015147600331220012364 0ustar00add_session_index(), $this->add_session_country_index(), $this->add_session_city_index(), $this->add_session_device_type_index(), $this->add_session_device_browser_index(), $this->add_session_device_os_index(), $this->add_session_campaign_index(), $this->add_views_index()]; } private function add_session_index() : string { $sessions_table = Query::get_table_name(Query::SESSIONS); return "\n CREATE UNIQUE INDEX sessions_summary_index ON {$sessions_table} (created_at, session_id, visitor_id, referrer_id, total_views)\n "; } private function add_session_country_index() : string { $sessions_table = Query::get_table_name(Query::SESSIONS); return "\n CREATE UNIQUE INDEX sessions_country_summary_index ON {$sessions_table} (created_at, session_id, visitor_id, country_id, total_views)\n "; } private function add_session_city_index() : string { $sessions_table = Query::get_table_name(Query::SESSIONS); return "\n CREATE UNIQUE INDEX sessions_city_summary_index ON {$sessions_table} (created_at, session_id, visitor_id, city_id, total_views)\n "; } private function add_session_device_type_index() : string { $sessions_table = Query::get_table_name(Query::SESSIONS); return "\n CREATE UNIQUE INDEX sessions_device_type_summary_index ON {$sessions_table} (created_at, session_id, visitor_id, device_type_id, total_views)\n "; } private function add_session_device_browser_index() : string { $sessions_table = Query::get_table_name(Query::SESSIONS); return "\n CREATE UNIQUE INDEX sessions_device_browser_summary_index ON {$sessions_table} (created_at, session_id, visitor_id, device_browser_id, total_views)\n "; } private function add_session_device_os_index() : string { $sessions_table = Query::get_table_name(Query::SESSIONS); return "\n CREATE UNIQUE INDEX sessions_device_os_summary_index ON {$sessions_table} (created_at, session_id, visitor_id, device_os_id, total_views)\n "; } private function add_session_campaign_index() : string { $sessions_table = Query::get_table_name(Query::SESSIONS); return "\n CREATE UNIQUE INDEX sessions_campaign_summary_index ON {$sessions_table} (created_at, session_id, visitor_id, campaign_id, total_views)\n "; } private function add_views_index() : string { $views_table = Query::get_table_name(Query::VIEWS); return "\n CREATE INDEX views_summary_index ON {$views_table} (session_id, viewed_at, resource_id)\n "; } } IAWP/Migrations/Migration_31.php000064400000004115147600331220012364 0ustar00drop_table_if_exists(Query::get_table_name(Query::FORMS)), $this->drop_table_if_exists(Query::get_table_name(Query::FORM_SUBMISSIONS)), $this->create_forms_table(), $this->create_form_submissions_table()]; } private function create_forms_table() : string { $forms_table = Query::get_table_name(Query::FORMS); $character_set = Database::character_set(); $collation = Database::collation(); return "\n CREATE TABLE IF NOT EXISTS {$forms_table} (\n form_id BIGINT(20) UNSIGNED AUTO_INCREMENT,\n plugin_id BIGINT(20) UNSIGNED NOT NULL,\n plugin_form_id BIGINT(20) UNSIGNED NOT NULL,\n cached_form_title VARCHAR(64) NOT NULL,\n PRIMARY KEY (form_id),\n UNIQUE INDEX (plugin_id, plugin_form_id)\n ) DEFAULT CHARACTER SET {$character_set} COLLATE {$collation};\n "; } private function create_form_submissions_table() : string { $form_submissions_table = Query::get_table_name(Query::FORM_SUBMISSIONS); $character_set = Database::character_set(); $collation = Database::collation(); return "\n CREATE TABLE IF NOT EXISTS {$form_submissions_table} (\n form_submission_id BIGINT(20) UNSIGNED AUTO_INCREMENT,\n form_id BIGINT(20) UNSIGNED NOT NULL,\n session_id BIGINT(20) UNSIGNED NOT NULL,\n view_id BIGINT(20) UNSIGNED NOT NULL,\n initial_view_id BIGINT(20) UNSIGNED NOT NULL,\n created_at DATETIME NOT NULL,\n PRIMARY KEY (form_submission_id)\n ) DEFAULT CHARACTER SET {$character_set} COLLATE {$collation};\n "; } } IAWP/Migrations/Migration_32.php000064400000001237147600331220012367 0ustar00add_quick_stats_column_to_reports()]; } private function add_quick_stats_column_to_reports() : string { $reports_table = Query::get_table_name(Query::REPORTS); return "\n ALTER TABLE {$reports_table}\n ADD COLUMN quick_stats TEXT AFTER group_name\n "; } } IAWP/Migrations/Migration_33.php000064400000001413147600331220012364 0ustar00add_chart_metrics_to_reports()]; } private function add_chart_metrics_to_reports() : string { $reports_table = Query::get_table_name(Query::REPORTS); return "\n ALTER TABLE {$reports_table}\n ADD COLUMN primary_chart_metric_id varchar(255),\n ADD COLUMN secondary_chart_metric_id varchar(255),\n DROP COLUMN visible_datasets\n "; } } IAWP/Migrations/Migration_34.php000064400000001217147600331220012367 0ustar00add_index_for_cached_author_id()]; } private function add_index_for_cached_author_id() : string { $resources_table = Query::get_table_name(Query::RESOURCES); return "\n ALTER TABLE {$resources_table}\n ADD INDEX(cached_author_id);\n "; } } IAWP/Migrations/Migration_35.php000064400000007022147600331220012370 0ustar00maybe_drop_order_table(), $this->create_orders_table(), $this->populate_orders_table()]; } private function maybe_drop_order_table() : string { $orders_table = Query::get_table_name(Query::ORDERS); return "\n DROP TABLE IF EXISTS {$orders_table}\n "; } private function create_orders_table() : string { $orders_table = Query::get_table_name(Query::ORDERS); $character_set = Database::character_set(); $collation = Database::collation(); return "\n CREATE TABLE {$orders_table} (\n order_id BIGINT(20) UNSIGNED AUTO_INCREMENT,\n is_included_in_analytics BOOLEAN NOT NULL, \n \n woocommerce_order_id BIGINT(20) UNSIGNED,\n woocommerce_order_status VARCHAR(64),\n surecart_order_id VARCHAR(36),\n surecart_order_status VARCHAR(64),\n \n view_id BIGINT(20) UNSIGNED NOT NULL,\n initial_view_id BIGINT(20) UNSIGNED NOT NULL,\n \n total INT NOT NULL,\n total_refunded INT NOT NULL,\n total_refunds SMALLINT NOT NULL,\n\n is_discounted BOOLEAN NOT NULL, \n \n created_at DATETIME NOT NULL,\n \n PRIMARY KEY (order_id),\n INDEX(view_id),\n INDEX(initial_view_id),\n INDEX(created_at)\n ) DEFAULT CHARACTER SET {$character_set} COLLATE {$collation};\n "; } private function populate_orders_table() : string { $wc_orders_table = Query::get_table_name(Query::WC_ORDERS); $orders_table = Query::get_table_name(Query::ORDERS); return "\n INSERT INTO {$orders_table} (\n is_included_in_analytics,\n woocommerce_order_id,\n woocommerce_order_status,\n surecart_order_id,\n surecart_order_status,\n view_id,\n initial_view_id,\n total,\n total_refunded,\n total_refunds,\n is_discounted,\n created_at\n )\n SELECT\n IF(status IN('wc-completed', 'completed', 'wc-processing', 'processing', 'wc-refunded', 'refunded', 'wc-shipped', 'shipped', 'wc-partial-shipped', 'partial-shipped', 'wc-delivered', 'delivered', 'wc-sent-to-fba', 'sent-to-fba', 'wc-part-to-fba', 'part-to-fba'), TRUE, FALSE) AS is_included_in_analytics,\n wc.order_id AS woocommerce_order_id,\n wc.status AS woocommerce_order_status,\n NULL AS surecart_order_id,\n NULL AS surecart_order_status,\n wc.view_id AS view_id,\n wc.initial_view_id AS initial_view_id,\n ROUND(wc.total * 100) AS total,\n ROUND(wc.total_refunded * 100) AS total_refunded,\n wc.total_refunds AS total_refunds,\n FALSE AS is_discounted,\n wc.created_at AS created_at\n FROM {$wc_orders_table} AS wc\n "; } } IAWP/Migrations/Migration_36.php000064400000001233147600331220012367 0ustar00increase_size_of_virtual_page_id()]; } private function increase_size_of_virtual_page_id() : string { $resources_table = Query::get_table_name(Query::RESOURCES); return "\n ALTER TABLE {$resources_table} MODIFY virtual_page_id VARCHAR(64)\n "; } } IAWP/Migrations/Migration_37.php000064400000004617147600331220012401 0ustar00remove_duplicate_woocommerce_orders(), $this->remove_duplicate_surecart_orders(), $this->add_unique_index_for_woocommerce_order_id(), $this->add_unique_index_for_surecart_order_id()]; } private function remove_duplicate_woocommerce_orders() : string { $orders_table = Query::get_table_name(Query::ORDERS); return "\n DELETE orders\n FROM\n {$orders_table} orders\n JOIN (\n SELECT\n woocommerce_order_id,\n MIN(order_id) AS first_order_id\n FROM\n {$orders_table}\n GROUP BY\n woocommerce_order_id\n ) first_orders ON orders.woocommerce_order_id = first_orders.woocommerce_order_id\n AND orders.order_id > first_orders.first_order_id; \n "; } private function remove_duplicate_surecart_orders() : string { $orders_table = Query::get_table_name(Query::ORDERS); return "\n DELETE orders\n FROM\n {$orders_table} orders\n JOIN (\n SELECT\n surecart_order_id,\n MIN(order_id) AS first_order_id\n FROM\n {$orders_table}\n GROUP BY\n surecart_order_id\n ) first_orders ON orders.surecart_order_id = first_orders.surecart_order_id\n AND orders.order_id > first_orders.first_order_id;\n "; } private function add_unique_index_for_woocommerce_order_id() : string { $orders_table = Query::get_table_name(Query::ORDERS); return "\n CREATE UNIQUE INDEX orders_woocommerce_order_id_index ON {$orders_table} (woocommerce_order_id)\n "; } private function add_unique_index_for_surecart_order_id() : string { $orders_table = Query::get_table_name(Query::ORDERS); return "\n CREATE UNIQUE INDEX orders_surecart_order_id_index ON {$orders_table} (surecart_order_id)\n "; } } IAWP/Migrations/Migration_38.php000064400000012112147600331220012367 0ustar00drop_table_if_exists($this->tables::clicks()), $this->create_clicks_table(), $this->drop_table_if_exists($this->tables::click_targets()), $this->create_click_targets_table(), $this->drop_table_if_exists($this->tables::clicked_links()), $this->create_clicked_links_table(), $this->drop_table_if_exists($this->tables::link_rules()), $this->create_link_rules_table(), $this->add_initial_rules(), $this->create_pdf_report(), $this->create_zip_report(), $this->create_email_report(), $this->create_phone_number_report()]; } private function create_clicks_table() : string { return "\n CREATE TABLE {$this->tables::clicks()} (\n click_id BIGINT(20) UNSIGNED AUTO_INCREMENT,\n view_id BIGINT(20) UNSIGNED,\n click_target_id BIGINT(20) UNSIGNED,\n created_at DATETIME NOT NULL,\n PRIMARY KEY (click_id),\n INDEX (view_id),\n INDEX (click_target_id)\n ) DEFAULT CHARACTER SET {$this->character_set()} COLLATE {$this->collation()};\n \n "; } private function create_click_targets_table() : string { return "\n CREATE TABLE {$this->tables::click_targets()} (\n click_target_id BIGINT(20) UNSIGNED AUTO_INCREMENT,\n target VARCHAR(2083),\n protocol ENUM('mailto', 'tel'),\n PRIMARY KEY (click_target_id)\n ) DEFAULT CHARACTER SET {$this->character_set()} COLLATE {$this->collation()};\n "; } private function create_clicked_links_table() : string { return "\n CREATE TABLE {$this->tables::clicked_links()} (\n click_id BIGINT(20) UNSIGNED AUTO_INCREMENT,\n link_rule_id BIGINT(20) UNSIGNED,\n PRIMARY KEY (click_id, link_rule_id)\n ) DEFAULT CHARACTER SET {$this->character_set()} COLLATE {$this->collation()};\n \n "; } private function create_link_rules_table() : string { return "\n CREATE TABLE {$this->tables::link_rules()} (\n link_rule_id BIGINT(20) UNSIGNED AUTO_INCREMENT,\n name VARCHAR(255) NOT NULL,\n type VARCHAR(255) NOT NULL,\n value VARCHAR(255) NOT NULL,\n is_active BOOLEAN NOT NULL DEFAULT TRUE,\n position INT UNSIGNED DEFAULT 0,\n created_at DATETIME NOT NULL,\n PRIMARY KEY (link_rule_id)\n ) DEFAULT CHARACTER SET {$this->character_set()} COLLATE {$this->collation()};\n "; } private function add_initial_rules() : string { global $wpdb; $created_at = (new \DateTime())->format('Y-m-d H:i:s'); return $wpdb->prepare("\n INSERT INTO {$this->tables::link_rules()}\n (link_rule_id, name, type, value, position, created_at)\n VALUES\n (1, 'PDF', 'extension', 'pdf', 0, %s),\n (2, 'Zip', 'extension', 'zip', 1, %s),\n (3, 'Email', 'protocol', 'mailto', 2, %s),\n (4, 'Phone number', 'protocol', 'tel', 3, %s);\n ", $created_at, $created_at, $created_at, $created_at); } private function create_pdf_report() : string { return $this->build_report_insert_query(['name' => \esc_html__('PDFs', 'independent-analytics'), 'type' => 'clicks', 'user_created_report' => 0, 'sort_column' => 'link_clicks', 'sort_direction' => 'desc', 'filters' => [['inclusion' => 'include', 'column' => 'link_name', 'operator' => 'is', 'operand' => '1']]]); } private function create_zip_report() : string { return $this->build_report_insert_query(['name' => \esc_html__('Zips', 'independent-analytics'), 'type' => 'clicks', 'user_created_report' => 0, 'sort_column' => 'link_clicks', 'sort_direction' => 'desc', 'filters' => [['inclusion' => 'include', 'column' => 'link_name', 'operator' => 'is', 'operand' => '2']]]); } private function create_email_report() : string { return $this->build_report_insert_query(['name' => \esc_html__('Emails', 'independent-analytics'), 'type' => 'clicks', 'user_created_report' => 0, 'sort_column' => 'link_clicks', 'sort_direction' => 'desc', 'filters' => [['inclusion' => 'include', 'column' => 'link_name', 'operator' => 'is', 'operand' => '3']]]); } private function create_phone_number_report() : string { return $this->build_report_insert_query(['name' => \esc_html__('Phone numbers', 'independent-analytics'), 'type' => 'clicks', 'user_created_report' => 0, 'sort_column' => 'link_clicks', 'sort_direction' => 'desc', 'filters' => [['inclusion' => 'include', 'column' => 'link_name', 'operator' => 'is', 'operand' => '4']]]); } } IAWP/Migrations/Migration_39.php000064400000001525147600331220012376 0ustar00increase_size_of_cached_url(), $this->increase_size_of_not_found_url()]; } private function increase_size_of_cached_url() : string { return "\n ALTER TABLE {$this->tables::resources()} MODIFY COLUMN cached_url VARCHAR(2083);\n "; } private function increase_size_of_not_found_url() : string { return "\n ALTER TABLE {$this->tables::resources()} MODIFY COLUMN not_found_url VARCHAR(2083);\n "; } } IAWP/Migrations/Migration_4.php000064400000000543147600331220012305 0ustar00get_charset_collate(); $sessions_table = Query::get_table_name(Query::SESSIONS); $views_table = Query::get_table_name(Query::VIEWS); $visitors_table = Query::get_table_name(Query::VISITORS); $wpdb->query("DROP TABLE IF EXISTS {$sessions_table};"); $wpdb->query("CREATE TABLE {$sessions_table} (\n session_id bigint(20) UNSIGNED AUTO_INCREMENT,\n visitor_id varchar(32),\n initial_view_id bigint(20) UNSIGNED,\n referrer_id bigint(20) UNSIGNED,\n campaign_id bigint(20) UNSIGNED,\n created_at datetime NOT NULL,\n legacy_view boolean DEFAULT false NOT NULL,\n PRIMARY KEY (session_id)\n ) {$charset_collate};"); $wpdb->query("\n ALTER TABLE {$views_table}\n ADD (\n session_id bigint(20) UNSIGNED\n ),\n ADD INDEX (visitor_id);\n "); $wpdb->query("\n INSERT INTO {$sessions_table} (visitor_id, initial_view_id, referrer_id, campaign_id, created_at, legacy_view)\n SELECT IF(visitors.visitor_token = '', NULL, LEFT(visitors.visitor_token, 32)) AS visitor_id,\n views.id AS initial_view_id,\n views.referrer_id,\n views.campaign_id,\n views.viewed_at AS created_at,\n 1 AS legacy_view\n FROM {$views_table} AS views\n LEFT JOIN {$visitors_table} AS visitors ON views.visitor_id = visitors.id;\n "); // Add the indices after bulk insert $wpdb->query("\n ALTER TABLE {$sessions_table}\n ADD INDEX(visitor_id),\n ADD INDEX(initial_view_id),\n ADD INDEX(referrer_id),\n ADD INDEX(campaign_id);\n "); $wpdb->query("\n UPDATE\n {$views_table} AS views\n INNER JOIN {$sessions_table} AS sessions ON views.id = sessions.initial_view_id\n SET\n views.session_id = sessions.session_id;\n "); $wpdb->query("\n ALTER TABLE {$views_table} DROP COLUMN referrer_id, DROP INDEX visitor_id, DROP COLUMN visitor_id, DROP COLUMN campaign_id, ADD INDEX (session_id);\n "); $visitors_tmp_table = Query::get_table_name(Query::VISITORS_TMP); $visitors_archive_table = Query::get_table_name(Query::VISITORS_1_16_ARCHIVE); $wpdb->query("DROP TABLE IF EXISTS {$visitors_tmp_table};"); $wpdb->query("CREATE TABLE {$visitors_tmp_table} (\n visitor_id varchar(32),\n country_code varchar(256),\n city varchar(256),\n subdivision varchar(256),\n country varchar(256),\n continent varchar(256),\n PRIMARY KEY (visitor_id)\n ) {$charset_collate};"); $wpdb->query("INSERT INTO {$visitors_tmp_table} (visitor_id, country_code, city, subdivision, country, continent)\n SELECT\n LEFT(visitor_token, 32) AS visitor_token,\n country_code,\n city,\n subdivision,\n country,\n continent\n FROM\n {$visitors_table} AS visitors ON DUPLICATE KEY UPDATE country_code = visitors.country_code,\n city = visitors.city,\n subdivision = visitors.subdivision,\n country = visitors.country,\n continent = visitors.continent;\n "); $wpdb->query("DROP TABLE IF EXISTS {$visitors_archive_table};"); $wpdb->query("RENAME TABLE {$visitors_table} TO {$visitors_archive_table};"); $wpdb->query("RENAME TABLE {$visitors_tmp_table} TO {$visitors_table};"); } } IAWP/Migrations/Migration_8.php000064400000001423147600331220012307 0ustar00get_charset_collate(); $wc_orders_table = Query::get_table_name(Query::WC_ORDERS); $wpdb->query("DROP TABLE IF EXISTS {$wc_orders_table};"); $wpdb->query("CREATE TABLE {$wc_orders_table} (\n order_id bigint(20) UNSIGNED NOT NULL,\n view_id bigint(20) UNSIGNED NOT NULL,\n created_at datetime NOT NULL,\n PRIMARY KEY (order_id)\n ) {$charset_collate};"); } } IAWP/Migrations/Migration_9.php000064400000003303147600331220012307 0ustar00sessions_fix_required()) { $wpdb->query("\n ALTER TABLE {$sessions_table} MODIFY COLUMN visitor_id VARCHAR(32);\n "); } if ($this->visitors_fix_required()) { $wpdb->query("\n ALTER TABLE {$visitors_table} MODIFY COLUMN visitor_id VARCHAR(32);\n "); } } private function sessions_fix_required() : bool { $sessions_table = Query::get_table_name(Query::SESSIONS); return $this->fix_required($sessions_table); } private function visitors_fix_required() : bool { $visitors_table = Query::get_table_name(Query::VISITORS); return $this->fix_required($visitors_table); } private function fix_required(string $table) : bool { global $wpdb; $big_field = $wpdb->get_row("\n SELECT\n CHARACTER_MAXIMUM_LENGTH\n FROM\n information_schema.columns\n WHERE\n TABLE_NAME = '" . $table . "'\n AND COLUMN_NAME = 'visitor_id'\n AND CHARACTER_MAXIMUM_LENGTH > 32;\n "); if (\is_null($big_field) || $wpdb->last_error !== '') { return \false; } return \true; } } IAWP/Migrations/Migration_Job.php000064400000001515147600331220012654 0ustar00dispatch(); } } } IAWP/Migrations/Step_Migration.php000064400000005235147600331220013060 0ustar00database_version()), '>=')) { return \true; } $completed = $this->run_queries(); if ($completed) { \update_option('iawp_db_version', $this->database_version(), \true); } return $completed; } public function character_set() : string { return Database::character_set(); } public function collation() : string { return Database::collation(); } protected function drop_table_if_exists(string $table_name) : string { return "\n DROP TABLE IF EXISTS {$table_name};\n "; } private function run_queries() : bool { global $wpdb; $queries = $this->queries(); foreach ($queries as $index => $query) { // Skip the step if there is no query to run if (\is_null($query)) { \update_option('iawp_last_finished_migration_step', $index + 1, \true); continue; } $initial_response = $wpdb->query($query); if ($initial_response === \false) { \sleep(1); \update_option('iawp_migration_error_original_error_message', \trim($wpdb->last_error), \true); $is_connected = $wpdb->check_connection(\false); if (!$is_connected) { // There is no database connection at this point, so options cannot be updated return \false; } $retry_response = $wpdb->query($query); if ($retry_response === \false) { // You cannot take these variable values and inline them below. The calls to // update_option use $wpdb, so last_error and last_query will be altered $last_error = \trim($wpdb->last_error); $last_query = \trim($wpdb->last_query); \update_option('iawp_migration_error', $last_error, \true); \update_option('iawp_migration_error_query', $last_query, \true); return \false; } } \update_option('iawp_last_finished_migration_step', $index + 1, \true); } return \true; } } IAWP/Models/Campaign.php000064400000003665147600331220010767 0ustar00row = $row; $this->title = $row->title; $this->utm_source = $row->utm_source; $this->utm_medium = $row->utm_medium; $this->utm_campaign = $row->utm_campaign; $this->utm_term = $row->utm_term; $this->utm_content = $row->utm_content; } /* * Column names have shared logic between tables. So "title" for resources has the same logic * as "title" for campaigns. Adding is_deleted ensures that the method can be called even though * campaigns can never be deleted. A better code base would allow this to be removed. */ public function is_deleted() { return \false; } public function title() { return $this->title; } public function utm_source() { return $this->utm_source; } public function utm_medium() { return $this->utm_medium; } public function utm_campaign() { return $this->utm_campaign; } public function utm_term() { return $this->utm_term; } public function utm_content() { return $this->utm_content; } /** * This isn't building a URL param that's used in a URL. This is building a unique id that's * used for uniqueness in real-times most popular campaign list. * * @return string */ public function params() : string { return \http_build_query(['title' => $this->title(), 'utm_source' => $this->utm_source(), 'utm_medium' => $this->utm_medium(), 'utm_campaign' => $this->utm_campaign(), 'utm_term' => $this->utm_term(), 'utm_content' => $this->utm_content()]); } } IAWP/Models/Click.php000064400000001220147600331220010256 0ustar00row = $row; $this->link_name = $row->link_name; $this->link_target = $row->link_target; $this->link_clicks = \intval($row->link_clicks); } public function link_name() : string { return $this->link_name; } public function link_target() : ?string { return $this->link_target; } public function link_clicks() : int { return $this->link_clicks; } } IAWP/Models/ClickWhale_Link_Page.php000064400000002222147600331220013153 0ustar00virtual_page_id, 'clickwhale_link_page_'); global $wpdb; $table_name = $wpdb->prefix . 'clickwhale_linkpages'; $this->database_record = Illuminate_Builder::new()->from($table_name)->find($link_page_id); parent::__construct($row); } protected function calculate_url() { if (\is_null($this->database_record)) { return null; } return \esc_url(\home_url('/' . $this->database_record->slug . '/')); } protected function calculate_title() { if (\is_null($this->database_record)) { return 'ClickWhale Link Page'; } return $this->database_record->title; } protected function calculate_type() { return 'clickwhale_link_page'; } protected function calculate_type_label() { return 'ClickWhale Link Page'; } } IAWP/Models/Current_Traffic.php000064400000002224147600331220012316 0ustar00visitor_count = \intval($row->visitor_count); $this->page_count = \intval($row->page_count); $this->referrer_count = \intval($row->referrer_count); $this->country_count = \intval($row->country_count); $this->campaign_count = \intval($row->campaign_count); $this->view_count = \intval($row->view_count); } public function get_visitor_count() { return $this->visitor_count; } public function get_page_count() { return $this->page_count; } public function get_referrer_count() { return $this->referrer_count; } public function get_country_count() { return $this->country_count; } public function get_campaign_count() { return $this->campaign_count; } public function get_view_count() { return $this->view_count; } } IAWP/Models/Device.php000064400000001143147600331220010434 0ustar00row = $row; $this->type = $row->device_type ?? null; $this->os = $row->os ?? null; $this->browser = $row->browser ?? null; } public function device_type() { return $this->type; } public function browser() { return $this->browser; } public function os() { return $this->os; } } IAWP/Models/Geo.php000064400000001644147600331220007755 0ustar00row = $row; $this->continent = $row->continent; $this->country = $row->country; $this->country_code = $row->country_code; $this->subdivision = $row->subdivision ?? ''; $this->city = $row->city ?? ''; } public function continent() { return $this->continent; } public function country() { return $this->country; } public function country_code() { return $this->country_code; } public function subdivision() { return $this->subdivision; } public function city() { return $this->city; } } IAWP/Models/Page.php000064400000021374147600331220010121 0ustar00row = $row; $this->id = $row->id ?? null; $this->resource = $row->resource ?? null; $this->entrances = $row->entrances ?? 0; $this->exits = $row->exits ?? 0; $this->exit_percent = $row->exit_percent ?? 0; // If $row is a full row from the database, use that for the cache // Eventually, I'd like to avoid selecting resources.* and just get the cached_.* // fields for the rows that are going to be shown. if (\is_string($row->cached_title ?? null)) { $this->cache = $row; } } protected abstract function resource_key(); protected abstract function resource_value(); protected abstract function calculate_is_deleted() : bool; protected abstract function calculate_url(); protected abstract function calculate_title(); protected abstract function calculate_type(); protected abstract function calculate_type_label(); protected abstract function calculate_icon(); protected abstract function calculate_author(); protected abstract function calculate_author_id(); protected abstract function calculate_avatar(); protected abstract function calculate_date(); protected abstract function calculate_category(); public function entrances() : int { return $this->entrances; } public function exits() : int { return $this->exits; } public function exit_percent() : float { return $this->exit_percent; } /** * By default, pages don't have the ability to have comments. * This can be overridden by a subclass to return an actual comments value. * * @return int|null */ public function comments() : ?int { return null; } public function get_singular_id() : ?int { if ($this->resource_key() !== 'singular_id') { return null; } return $this->resource_value(); } public final function is_deleted() : bool { if (!\is_null($this->is_deleted)) { return $this->is_deleted; } $this->is_deleted = $this->calculate_is_deleted(); return $this->is_deleted; } public final function update_cache() : void { $resources_table = Query::get_table_name(Query::RESOURCES); $resource_key = $this->resource_key(); $resource_value = $this->resource_value(); $url = $this->calculate_url(); Illuminate_Builder::new()->from($resources_table)->where($resource_key, '=', $resource_value)->update(['cached_title' => $this->calculate_title(), 'cached_url' => \is_string($url) ? Str::limit($url, 2083) : $url, 'cached_type' => $this->calculate_type(), 'cached_type_label' => $this->calculate_type_label(), 'cached_author_id' => $this->calculate_author_id(), 'cached_author' => $this->calculate_author(), 'cached_date' => $this->calculate_date(), 'cached_category' => !empty($this->calculate_category()) ? \implode(', ', $this->calculate_category()) : null]); } public final function id() { return $this->id; } public final function url($full_url = \false) { if ($this->use_cache()) { $url = $this->cache->cached_url; } else { $url = $this->calculate_url(); } if (\is_null($url)) { return null; } if ($full_url) { return $url; } else { return Request::path_relative_to_site_url($url); } } public final function title() { if ($this->use_cache()) { return $this->cache->cached_title; } if (\is_null($this->cached_title)) { $this->cached_title = $this->calculate_title(); } return \strlen($this->cached_title) > 0 ? $this->cached_title : '(no title)'; } public final function type($raw = \false) { if ($raw) { if ($this->use_cache()) { return $this->cache->cached_type; } if (\is_null($this->cached_type)) { $this->cached_type = $this->calculate_type(); } return $this->cached_type; } else { if ($this->use_cache()) { return $this->cache->cached_type_label; } if (\is_null($this->cached_type_label)) { $this->cached_type_label = $this->calculate_type_label(); } return $this->cached_type_label; } } public final function icon() { if (\is_null($this->cached_icon)) { $this->cached_icon = $this->calculate_icon(); } return $this->cached_icon; } public final function author() { if ($this->use_cache()) { return $this->cache->cached_author; } if (\is_null($this->cached_author)) { $this->cached_author = $this->calculate_author(); } return $this->cached_author; } public final function author_id() { if ($this->use_cache()) { return $this->cache->cached_author_id; } if (\is_null($this->cached_author_id)) { $this->cached_author_id = $this->calculate_author_id(); } return $this->cached_author_id; } public final function avatar() { if (\is_null($this->cached_avatar)) { $this->cached_avatar = $this->calculate_avatar(); } return $this->cached_avatar; } public final function date() { if (\is_null($this->cached_date)) { $this->cached_date = $this->calculate_date(); } return $this->cached_date; } public final function formatted_category() : ?string { $categories = $this->category(\false); $category_names = []; if (\count($categories) === 0) { return null; } foreach ($categories as $category_id) { $category = \get_the_category_by_ID($category_id); if (!\is_wp_error($category)) { $category_names[] = $category; } } return \implode(', ', $category_names); } public final function category($formatted = \true) { if ($formatted === \true) { return $this->formatted_category(); } if (\is_null($this->cached_category)) { $this->cached_category = $this->calculate_category(); } return $this->cached_category; } public function most_popular_subtitle() : ?string { return null; } private function use_cache() : bool { if (!\is_null($this->cache)) { return \true; } $deleted = $this->is_deleted(); if ($deleted) { $this->cache = $this->get_cache(); } return $deleted; } private function get_cache() { global $wpdb; $resources_table = Query::get_table_name(Query::RESOURCES); $resource_key = $this->resource_key(); $resource_value = $this->resource_value(); $query = $wpdb->prepare("SELECT * FROM {$resources_table} WHERE {$resource_key} = %s", $resource_value); return $wpdb->get_row($query); } public static function from_row(object $row) : \IAWP\Models\Page { switch ($row->resource) { case 'singular': return new \IAWP\Models\Page_Singular($row); case 'author_archive': return new \IAWP\Models\Page_Author_Archive($row); case 'date_archive': return new \IAWP\Models\Page_Date_Archive($row); case 'post_type_archive': return new \IAWP\Models\Page_Post_Type_Archive($row); case 'term_archive': return new \IAWP\Models\Page_Term_Archive($row); case 'search': return new \IAWP\Models\Page_Search($row); case 'home': return new \IAWP\Models\Page_Home($row); case 'virtual_page': return \IAWP\Models\Page_Virtual::from($row); default: return new \IAWP\Models\Page_Not_Found($row); } } } IAWP/Models/Page_Author_Archive.php000064400000003165147600331220013102 0ustar00author_id = $row->author_id; parent::__construct($row); } protected function resource_key() : string { return 'author_id'; } protected function resource_value() : string { return $this->author_id; } protected function calculate_is_deleted() : bool { return \get_userdata($this->author_id) == \false; } protected function calculate_url() { return \get_author_posts_url($this->author_id); } protected function calculate_title() { return \get_the_author_meta('display_name', $this->author_id) . ' ' . \esc_html__('Archive', 'independent-analytics'); } protected function calculate_type() { return 'author-archive'; } protected function calculate_type_label() { return \esc_html__('Author Archive', 'independent-analytics'); } protected function calculate_icon() { return ''; } protected function calculate_author_id() { return $this->author_id; } protected function calculate_author() { return \get_the_author_meta('display_name', $this->author_id); } protected function calculate_avatar() { return \get_avatar($this->author_id, 20); } protected function calculate_date() { return null; } protected function calculate_category() { return []; } } IAWP/Models/Page_Date_Archive.php000064400000004575147600331220012523 0ustar00date_archive = $row->date_archive; parent::__construct($row); } protected function resource_key() : string { return 'date_archive'; } protected function resource_value() : string { return $this->date_archive; } protected function calculate_is_deleted() : bool { return \false; } protected function calculate_url() { list($type, $year, $month, $day) = $this->date_archive_type(); if ($type == 'year') { return \get_year_link($year); } elseif ($type == 'month') { return \get_month_link($year, $month); } else { return \get_day_link($year, $month, $day); } } protected function calculate_title() { return $this->date_archive; } protected function calculate_type() { return 'date-archive'; } protected function calculate_type_label() { list($type) = $this->date_archive_type(); if ($type == 'year') { return \esc_html__('Date Archive (Year)', 'independent-analytics'); } elseif ($type == 'month') { return \esc_html__('Date Archive (Month)', 'independent-analytics'); } else { return \esc_html__('Date Archive (Day)', 'independent-analytics'); } } protected function calculate_icon() { return ''; } protected function calculate_author_id() { return null; } protected function calculate_author() { return null; } protected function calculate_avatar() { return null; } protected function calculate_date() { return null; } protected function calculate_category() { return []; } private function date_archive_type() { list($year, $month, $day) = \array_pad(\explode('-', $this->date_archive), 3, null); if (\is_null($day) && \is_null($month)) { return ['year', $year, null, null]; } elseif (\is_null($day)) { return ['month', $year, $month, null]; } else { return ['day', $year, $month, $day]; } } } IAWP/Models/Page_Home.php000064400000003330147600331220011061 0ustar00'; } else { return ''; } } protected function calculate_author_id() { return null; } protected function calculate_author() { return null; } protected function calculate_avatar() { return null; } protected function calculate_date() { return null; } protected function calculate_category() { return []; } } IAWP/Models/Page_Not_Found.php000064400000002762147600331220012074 0ustar00not_found_url = $row->not_found_url; parent::__construct($row); } public function most_popular_subtitle() : string { return $this->url(); } protected function resource_key() : string { return 'not_found_url'; } protected function resource_value() : string { return Str::limit($this->not_found_url, 2083); } protected function calculate_is_deleted() : bool { return \false; } protected function calculate_url() { return \site_url($this->not_found_url); } protected function calculate_title() { return '404'; } protected function calculate_type() { return 'not-found'; } protected function calculate_type_label() { return '404'; } protected function calculate_icon() { return ''; } protected function calculate_author_id() { return null; } protected function calculate_author() { return null; } protected function calculate_avatar() { return null; } protected function calculate_date() { return null; } protected function calculate_category() { return []; } } IAWP/Models/Page_Post_Type_Archive.php000064400000004523147600331220013565 0ustar00post_type = $row->post_type; parent::__construct($row); } protected function resource_key() : string { return 'post_type'; } protected function resource_value() : string { return $this->post_type; } protected function calculate_is_deleted() : bool { return \is_null(\get_post_type_object($this->post_type)); } protected function calculate_url() { return \get_post_type_archive_link($this->post_type); } protected function calculate_title() { if ($this->post_type === 'product') { return \esc_html__('Shop', 'independent-analytics'); } $post_type_object = \get_post_type_object($this->post_type); if (\is_null($post_type_object)) { return null; } return \get_post_type_object($this->post_type)->labels->singular_name . ' ' . \esc_html__('Archive', 'independent-analytics'); } protected function calculate_type() { return $this->post_type . '-archive'; } protected function calculate_type_label() { return $this->title(); } protected function calculate_icon() { $icon = null; if (!$this->calculate_is_deleted()) { $icon = \get_post_type_object($this->post_type)->menu_icon; } $has_icon = !\is_null($icon); $html = ''; if ($has_icon) { if (\esc_url_raw($icon) === $icon) { $html .= ''; } else { $html .= ''; } } else { $html .= ''; } return $html; } protected function calculate_author_id() { return null; } protected function calculate_author() { return null; } protected function calculate_avatar() { return null; } protected function calculate_date() { return null; } protected function calculate_category() { return []; } } IAWP/Models/Page_Search.php000064400000002720147600331220011400 0ustar00search_query = $row->search_query; parent::__construct($row); } public function calculate_url() { return \get_search_link($this->search_query); } protected function resource_key() : string { return 'search_query'; } protected function resource_value() : string { return $this->search_query; } protected function calculate_is_deleted() : bool { return \false; } protected function calculate_title() { return \esc_html__('Search:', 'independent-analytics') . ' "' . $this->search_query . '"'; } protected function calculate_type() { return 'search-archive'; } protected function calculate_type_label() { return \esc_html__('Search', 'independent-analytics'); } protected function calculate_icon() { return ''; } protected function calculate_author_id() { return null; } protected function calculate_author() { return null; } protected function calculate_avatar() { return null; } protected function calculate_date() { return null; } protected function calculate_category() { return []; } } IAWP/Models/Page_Singular.php000064400000010215147600331220011755 0ustar00singular_id = $row->singular_id; $this->comments = $row->comments ?? 0; parent::__construct($row); } /** * Override comments method to add comments support for singular pages. * * @return int|null */ public function comments() : ?int { return $this->comments; } protected function resource_key() : string { return 'singular_id'; } protected function resource_value() : string { return $this->singular_id; } protected function calculate_is_deleted() : bool { $post = \get_post($this->singular_id); return \is_null($post) || \is_null(\get_post_type_object($post->post_type)); } protected function calculate_url() { return $this->convert_wpml_url(\get_permalink($this->singular_id)); } protected function calculate_title() { return \get_the_title($this->singular_id); } protected function calculate_type() { $post_type_object = \get_post_type_object(\get_post_type($this->singular_id)); if (\is_null($post_type_object)) { return null; } return $post_type_object->name; } protected function calculate_type_label() { $post_type_object = \get_post_type_object(\get_post_type($this->singular_id)); if (\is_null($post_type_object)) { return null; } return $post_type_object->labels->singular_name; } protected function calculate_icon() { $icon = null; if (!$this->calculate_is_deleted()) { $icon = \get_post_type_object($this->type(\true))->menu_icon; } $has_icon = !\is_null($icon); $html = '
'; if ($has_icon) { if (\esc_url_raw($icon) == $icon) { if (String_Util::str_contains($icon, 'svg')) { $html .= ''; } else { $html .= ''; } } else { $html .= ''; } } else { $html .= ''; } $html .= '
'; return $html; } protected function calculate_author_id() { $author_id = \get_post_field('post_author', $this->singular_id); if ($author_id === '') { return null; } return $author_id; } protected function calculate_author() { return \get_the_author_meta('display_name', $this->author_id()); } protected function calculate_avatar() { return \get_avatar($this->author_id(), 20); } protected function calculate_date() { $date = \get_the_date('Y-m-d', $this->singular_id); if (!\is_string($date)) { return null; } return $date; } protected function calculate_category() { $post_type_still_registered = \in_array($this->calculate_type(), \get_post_types()); $categories = []; if (!$post_type_still_registered) { return []; } foreach (\get_the_category($this->singular_id) as $category) { $categories[] = $category->term_id; } return $categories; } protected function convert_wpml_url($permalink) { if (\is_plugin_active('sitepress-multilingual-cms/sitepress.php')) { $language = \apply_filters('wpml_post_language_details', null, $this->singular_id); $permalink = \apply_filters('wpml_permalink', $permalink, $language['language_code'], \true); } return $permalink; } } IAWP/Models/Page_Term_Archive.php000064400000003677147600331220012557 0ustar00term_id = \intval($row->term_id); parent::__construct($row); } protected function resource_key() : string { return 'term_id'; } protected function resource_value() : string { return $this->term_id; } protected function calculate_is_deleted() : bool { try { $term = \get_term($this->term_id); return \is_wp_error($term) || \is_null($term); } catch (\Throwable $e) { return \true; } } protected function calculate_url() { return \get_term_link($this->term_id); } protected function calculate_title() { return $this->term()->name; } protected function calculate_type() { return $this->term()->taxonomy; } protected function calculate_type_label() { return \get_taxonomy_labels(\get_taxonomy($this->term()->taxonomy))->singular_name; } protected function calculate_icon() { $icon = 'dashicons-category'; if (!$this->calculate_is_deleted()) { if ($this->type() == 'Tag') { $icon = 'dashicons-tag'; } } $html = '
'; $html .= ''; $html .= '
'; return $html; } protected function calculate_author_id() { return null; } protected function calculate_author() { return null; } protected function calculate_avatar() { return null; } protected function calculate_date() { return null; } protected function calculate_category() { return []; } private function term() { return \get_term($this->term_id); } } IAWP/Models/Page_Virtual.php000064400000014042147600331220011621 0ustar00virtual_page_id = $row->virtual_page_id; parent::__construct($row); } protected function resource_key() : string { return 'virtual_page_id'; } protected function resource_value() : string { return $this->virtual_page_id; } protected function calculate_is_deleted() : bool { return \false; } protected function calculate_url() { $surecart_product = $this->get_surecart_product(); if ($surecart_product) { return $surecart_product->getPermalinkAttribute(); } $surecart_collection = $this->get_surecart_collection(); if ($surecart_collection) { return $surecart_collection->getPermalinkAttribute(); } $surecart_upsell = $this->get_surecart_upsell(); if ($surecart_upsell) { return $surecart_upsell->getPermalinkAttribute(); } return null; } protected function calculate_title() { if ($this->virtual_page_id === 'wc_checkout_success') { return \__('Checkout Success', 'independent-analytics'); } $surecart_product = $this->get_surecart_product(); if ($surecart_product) { return $surecart_product->name; } $surecart_collection = $this->get_surecart_collection(); if ($surecart_collection) { return $surecart_collection->name; } $surecart_upsell = $this->get_surecart_upsell(); if ($surecart_upsell) { return $surecart_upsell->metadata->title; } return \__('Page', 'independent-analytics'); } protected function calculate_type() { $surecart_product = $this->get_surecart_product(); if ($surecart_product) { return 'sc_product'; } $surecart_collection = $this->get_surecart_collection(); if ($surecart_collection) { return 'sc_collection'; } $surecart_upsell = $this->get_surecart_upsell(); if ($surecart_upsell) { return 'sc_upsell'; } return 'page'; } protected function calculate_type_label() { $surecart_product = $this->get_surecart_product(); if ($surecart_product) { return \__('Product', 'independent-analytics'); } $surecart_collection = $this->get_surecart_collection(); if ($surecart_collection) { return \__('Collection', 'independent-analytics'); } $surecart_upsell = $this->get_surecart_upsell(); if ($surecart_upsell) { return \__('Upsell', 'independent-analytics'); } return 'Page'; } protected function calculate_icon() { $surecart_product = $this->get_surecart_product(); $surecart_collection = $this->get_surecart_collection(); $surecart_upsell = $this->get_surecart_upsell(); if ($surecart_product || $surecart_collection || $surecart_upsell) { return ''; } return ''; } protected function calculate_author_id() { return null; } protected function calculate_author() { return null; } protected function calculate_avatar() { return null; } protected function calculate_date() { return null; } protected function calculate_category() { return []; } private function get_surecart_product() : ?object { if (\is_object($this->surecart_product)) { return $this->surecart_product; } if (Str::startsWith($this->virtual_page_id, 'sc_product_') && \class_exists('\\SureCart\\Models\\Product')) { try { $id = Str::after($this->virtual_page_id, 'sc_product_'); $this->surecart_product = \SureCart\Models\Product::find($id); return $this->surecart_product; } catch (\Throwable $e) { return null; } } return null; } private function get_surecart_collection() : ?object { if (\is_object($this->surecart_collection)) { return $this->surecart_collection; } if (Str::startsWith($this->virtual_page_id, 'sc_collection_') && \class_exists('IAWPSCOPED\\SureCart\\Models\\ProductCollection')) { try { $id = Str::after($this->virtual_page_id, 'sc_collection_'); $this->surecart_collection = \IAWPSCOPED\SureCart\Models\ProductCollection::find($id); return $this->surecart_collection; } catch (\Throwable $e) { return null; } } return null; } private function get_surecart_upsell() : ?object { if (\is_object($this->surecart_upsell)) { return $this->surecart_upsell; } if (Str::startsWith($this->virtual_page_id, 'sc_upsell_') && \class_exists('\\SureCart\\Models\\Upsell')) { try { $id = Str::after($this->virtual_page_id, 'sc_upsell_'); $this->surecart_upsell = \SureCart\Models\Upsell::find($id); return $this->surecart_upsell; } catch (\Throwable $e) { return null; } } return null; } public static function from(object $row) : \IAWP\Models\Page_Virtual { $virtual_page_id = $row->virtual_page_id; if (Str::startsWith($virtual_page_id, 'clickwhale_link_page')) { return new \IAWP\Models\ClickWhale_Link_Page($row); } return new self($row); } } IAWP/Models/Referrer.php000064400000002473147600331220011020 0ustar00row = $row; $this->is_direct = $row->domain === ''; $this->referrer = $row->referrer; $this->domain = $row->domain; $this->referrer_type = $row->referrer_type; } /** * Return group name, referrer url, or direct. * * @return string Referrer */ // Todo - This is the one the table is doing... public function referrer() : string { return $this->referrer; } public function referrer_url() : string { return $this->domain; } /** * Return group referrer type, referrer, or direct. * * @return string Referrer type */ public function referrer_type() : string { return $this->referrer_type; } public function is_direct() : bool { return $this->is_direct; } /** * Should the referrer record link back to the referrering domain? * * @return bool */ public function has_link() : bool { return !$this->is_direct() && $this->referrer_type !== 'Ad'; } } IAWP/Models/Universal_Model_Columns.php000064400000011336147600331220014032 0ustar00as_int($name); } elseif (Str::startsWith($name, 'form_conversion_rate_for_')) { return $this->as_float($name); } } public function form_submissions() : int { return $this->as_int('form_submissions'); } public function form_conversion_rate() : float { return $this->as_float('form_conversion_rate'); } public function wc_orders() : float { return $this->as_float('wc_orders'); } public function wc_gross_sales() : float { return $this->as_float('wc_gross_sales'); } public function wc_refunds() : float { return $this->as_float('wc_refunds'); } public function wc_refunded_amount() : float { return $this->as_float('wc_refunded_amount'); } public function wc_net_sales() : float { return $this->as_float('wc_net_sales'); } public function wc_conversion_rate() : float { return $this->as_float('wc_conversion_rate'); } public function wc_earnings_per_visitor() : float { return $this->as_float('wc_earnings_per_visitor'); } public function wc_average_order_volume() : float { return $this->as_float('wc_average_order_volume'); } public function views() : int { return $this->as_int('views'); } public function previous_period_views() : int { return $this->as_int('previous_period_views'); } public function views_growth() : float { return $this->as_float('views_growth'); } public function views_per_session() : float { return $this->as_float('views_per_session'); } public function visitors() : int { return $this->as_int('visitors'); } public function previous_period_visitors() : int { return $this->as_int('previous_period_views'); } public function visitors_growth() : float { return $this->as_float('visitors_growth'); } public function clicks() : float { return $this->as_int('clicks'); } public function average_session_duration() : ?int { return $this->as_int('average_session_duration', null); } public function average_session_duration_growth() : float { $current = $this->average_session_duration(); $previous = $this->previous_period_average_session_duration(); if ($current == 0 || $previous == 0) { return 0; } else { return ($current - $previous) / $previous * 100; } } public function average_view_duration() : ?int { return $this->as_int('average_view_duration', null); } public function average_view_duration_growth() : float { $current = $this->average_view_duration(); $previous = $this->previous_period_average_view_duration(); if ($current == 0 || $previous == 0) { return 0; } else { return ($current - $previous) / $previous * 100; } } public function sessions() : int { return $this->as_int('sessions'); } public function previous_period_sessions() : int { return $this->as_int('previous_period_sessions'); } public function sessions_growth() : float { $current = $this->sessions(); $previous = $this->previous_period_sessions(); if ($current == 0 || $previous == 0) { return 0; } else { return ($current - $previous) / $previous * 100; } } public function previous_period_average_session_duration() : int { return $this->as_int('previous_period_average_session_duration'); } public function previous_period_average_view_duration() : int { return $this->as_int('previous_period_average_view_duration'); } public function bounces() : int { return $this->as_int('bounces'); } public function bounce_rate() : float { return $this->as_float('bounce_rate'); } private function as_float($property, $default = 0) : ?float { return \property_exists($this->row, $property) && $this->row->{$property} !== null ? \floatval($this->row->{$property}) : $default; } private function as_int($property, $default = 0) : ?int { return \property_exists($this->row, $property) && $this->row->{$property} !== null ? \intval($this->row->{$property}) : $default; } } IAWP/Models/Visitor.php000064400000007160147600331220010701 0ustar00id(); * @internal */ class Visitor { private $id; private $geoposition; private $current_session; /** * New instances should be created with a string ip address * * @param string $ip * @param string $user_agent */ public function __construct(string $ip, string $user_agent) { $this->id = $this->fetch_visitor_id_by_hash($this->calculate_hash($ip, $user_agent)); $this->geoposition = new Geoposition($ip); $this->current_session = $this->fetch_current_session(); } public function geoposition() : Geoposition { return $this->geoposition; } public function has_recorded_session() : bool { return \is_object($this->current_session); } public function most_recent_session_id() : ?int { $session_id = \IAWPSCOPED\iawp_intify($this->current_session->session_id); if ($this->has_recorded_session() && \is_int($session_id)) { return $session_id; } else { return null; } } public function most_recent_initial_view_id() : ?int { $initial_view_id = \IAWPSCOPED\iawp_intify($this->current_session->initial_view_id); if ($this->has_recorded_session() && \is_int($initial_view_id)) { return $initial_view_id; } else { return null; } } public function most_recent_final_view_id() : ?int { $final_view_id = \IAWPSCOPED\iawp_intify($this->current_session->final_view_id); if ($this->has_recorded_session() && \is_int($final_view_id)) { return $final_view_id; } else { return null; } } public function most_recent_view_id() : ?int { return $this->most_recent_final_view_id() ?? $this->most_recent_initial_view_id(); } /** * Return the database id for a visitor * * @return string */ public function id() : string { return $this->id; } /** * @param string $ip * @param string $user_agent * @return string */ private function calculate_hash(string $ip, string $user_agent) : string { $salt = Salt::visitor_token_salt(); $result = $salt . $ip . $user_agent; return \md5($result); } private function fetch_current_session() { $sessions_table = Query::get_table_name(Query::SESSIONS); $session = Illuminate_Builder::new()->from($sessions_table, 'sessions')->selectRaw('IFNULL(ended_at, created_at) AS latest_view_at')->selectRaw('sessions.*')->where('visitor_id', '=', $this->id)->havingRaw('latest_view_at > DATE_SUB(UTC_TIMESTAMP(), INTERVAL 30 MINUTE)')->orderBy('latest_view_at', 'DESC')->first(); return $session; } public static function fetch_visitor_id_by_hash(string $hash) : int { $visitors_table = Query::get_table_name(Query::VISITORS); Illuminate_Builder::new()->from($visitors_table)->insertOrIgnore([['hash' => $hash]]); return Illuminate_Builder::new()->from($visitors_table)->where('hash', '=', $hash)->value('visitor_id'); } public static function fetch_current_visitor() : self { return new \IAWP\Models\Visitor(Request::ip(), Request::user_agent()); } } IAWP/Public_API/Analytics.php000064400000003024147600331220011650 0ustar00views = $row->views ?? 0; $this->visitors = $row->visitors ?? 0; $this->sessions = $row->sessions ?? 0; } /** * @param Date_Range $date_range * * @return self */ public static function for(Date_Range $date_range) : self { $resources_table = Query::get_table_name(Query::RESOURCES); $views_table = Query::get_table_name(Query::VIEWS); $sessions_table = Query::get_table_name(Query::SESSIONS); $resource_statistics_query = Illuminate_Builder::new(); $resource_statistics_query->selectRaw('COUNT(DISTINCT views.id) AS views')->selectRaw('COUNT(DISTINCT sessions.visitor_id) AS visitors')->selectRaw('COUNT(DISTINCT sessions.session_id) AS sessions')->from("{$views_table} as views")->join("{$resources_table} AS resources", function (JoinClause $join) { $join->on('resources.id', '=', 'views.resource_id'); })->join("{$sessions_table} AS sessions", function (JoinClause $join) { $join->on('sessions.session_id', '=', 'views.session_id'); })->whereBetween('views.viewed_at', [$date_range->iso_start(), $date_range->iso_end()]); return new self($resource_statistics_query->get()->first()); } } IAWP/Public_API/Singular_Analytics.php000064400000003605147600331220013521 0ustar00singular_id = $singular_id; $this->views = $row->views ?? 0; $this->visitors = $row->visitors ?? 0; $this->sessions = $row->sessions ?? 0; } /** * @param string|int $singular_id * @param Date_Range $date_range * * @return self */ public static function for($singular_id, Date_Range $date_range) : ?self { if (\get_post($singular_id) === null) { return null; } $resources_table = Query::get_table_name(Query::RESOURCES); $views_table = Query::get_table_name(Query::VIEWS); $sessions_table = Query::get_table_name(Query::SESSIONS); $resource_statistics_query = Illuminate_Builder::new(); $resource_statistics_query->selectRaw('COUNT(DISTINCT views.id) AS views')->selectRaw('COUNT(DISTINCT sessions.visitor_id) AS visitors')->selectRaw('COUNT(DISTINCT sessions.session_id) AS sessions')->from("{$views_table} as views")->join("{$resources_table} AS resources", function (JoinClause $join) { $join->on('resources.id', '=', 'views.resource_id'); })->join("{$sessions_table} AS sessions", function (JoinClause $join) { $join->on('sessions.session_id', '=', 'views.session_id'); })->where('resources.resource', '=', 'singular')->where('resources.singular_id', '=', $singular_id)->whereBetween('views.viewed_at', [$date_range->iso_start(), $date_range->iso_end()])->groupBy('resources.id'); return new self((int) $singular_id, $resource_statistics_query->get()->first()); } } IAWP/Rows/Campaigns.php000064400000017277147600331220010665 0ustar00joinSub($this->query(\true), 'campaign_rows', function (JoinClause $join) { $join->on('campaign_rows.campaign_id', '=', 'sessions.campaign_id'); }); } protected function fetch_rows() : array { $rows = $this->query()->get()->all(); return \array_map(function ($row) { return new Campaign($row); }, $rows); } private function query(?bool $skip_pagination = \false) : Builder { if ($skip_pagination) { $this->number_of_rows = null; } $views_table = Query::get_table_name(Query::VIEWS); $sessions_table = Query::get_table_name(Query::SESSIONS); $orders_table = Query::get_table_name(Query::ORDERS); $campaigns_table = Query::get_table_name(Query::CAMPAIGNS); $orders_query = Illuminate_Builder::new(); $orders_query->select(['orders.view_id AS view_id'])->selectRaw('IFNULL(COUNT(DISTINCT orders.order_id), 0) AS wc_orders')->selectRaw('IFNULL(ROUND(CAST(SUM(orders.total) AS SIGNED)), 0) AS wc_gross_sales')->selectRaw('IFNULL(ROUND(CAST(SUM(orders.total_refunded) AS SIGNED)), 0) AS wc_refunded_amount')->selectRaw('IFNULL(SUM(orders.total_refunds), 0) AS wc_refunds')->from($orders_table, 'orders')->where('orders.is_included_in_analytics', '=', \true)->whereBetween('orders.created_at', $this->get_current_period_iso_range())->groupBy('orders.view_id'); $campaigns_query = Illuminate_Builder::new(); $campaigns_query->select('campaigns.campaign_id', 'landing_page_title AS title', 'utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content')->selectRaw('COUNT(DISTINCT views.id) AS views')->selectRaw('COUNT(DISTINCT sessions.visitor_id) AS visitors')->selectRaw('COUNT(DISTINCT sessions.session_id) AS sessions')->selectRaw('ROUND(AVG( TIMESTAMPDIFF(SECOND, sessions.created_at, sessions.ended_at))) AS average_session_duration')->selectRaw('COUNT(DISTINCT IF(sessions.final_view_id IS NULL, sessions.session_id, NULL)) AS bounces')->selectRaw('COUNT(DISTINCT clicks.click_id) AS clicks')->selectRaw('IFNULL(SUM(the_orders.wc_orders), 0) AS wc_orders')->selectRaw('IFNULL(SUM(the_orders.wc_gross_sales), 0) AS wc_gross_sales')->selectRaw('IFNULL(SUM(the_orders.wc_refunded_amount), 0) AS wc_refunded_amount')->selectRaw('IFNULL(SUM(the_orders.wc_refunds), 0) AS wc_refunds')->selectRaw('IFNULL(SUM(form_submissions.form_submissions), 0) AS form_submissions')->tap(function (Builder $query) { foreach (Form::get_forms() as $form) { $query->selectRaw("SUM(IF(form_submissions.form_id = ?, form_submissions.form_submissions, 0)) AS {$form->submissions_column()}", [$form->id()]); } })->from($views_table, 'views')->leftJoin($campaigns_query->raw($sessions_table . ' AS sessions'), function (JoinClause $join) { $join->on('views.session_id', '=', 'sessions.session_id'); })->join($campaigns_query->raw($campaigns_table . ' AS campaigns'), function (JoinClause $join) { $join->on('sessions.campaign_id', '=', 'campaigns.campaign_id'); })->leftJoin($campaigns_query->raw(Tables::clicks() . ' AS clicks'), function (JoinClause $join) { $join->on('clicks.view_id', '=', 'views.id'); })->leftJoinSub($orders_query, 'the_orders', function (JoinClause $join) { $join->on('the_orders.view_id', '=', 'views.id'); })->leftJoinSub($this->get_form_submissions_query(), 'form_submissions', function (JoinClause $join) { $join->on('form_submissions.view_id', '=', 'views.id'); })->whereBetween('views.viewed_at', $this->get_current_period_iso_range())->when(!$this->appears_to_be_for_real_time_analytics(), function (Builder $query) { $query->whereBetween('sessions.created_at', $this->get_current_period_iso_range()); })->tap(Query_Taps::tap_authored_content_check())->when(\count($this->filters) > 0, function (Builder $query) { foreach ($this->filters as $filter) { if (!$this->is_a_calculated_column($filter->column())) { $filter->apply_to_query($query); } } })->groupBy('campaigns.campaign_id')->having('views', '>', 0)->when(!$this->is_using_a_calculated_column(), function (Builder $query) { $query->when($this->sort_configuration->is_column_nullable(), function (Builder $query) { $query->orderByRaw("CASE WHEN {$this->sort_configuration->column()} IS NULL THEN 1 ELSE 0 END"); })->orderBy($this->sort_configuration->column(), $this->sort_configuration->direction())->orderBy('title')->when(\is_int($this->number_of_rows), function (Builder $query) { $query->limit($this->number_of_rows); }); }); $previous_period_query = Illuminate_Builder::new(); $previous_period_query->select(['sessions.campaign_id'])->selectRaw('SUM(sessions.total_views) AS previous_period_views')->selectRaw('COUNT(DISTINCT sessions.visitor_id) AS previous_period_visitors')->from($sessions_table, 'sessions')->whereBetween('sessions.created_at', $this->get_previous_period_iso_range())->groupBy('sessions.campaign_id'); $outer_query = Illuminate_Builder::new(); $outer_query->selectRaw('campaigns.*')->selectRaw('IF(sessions = 0, 0, views / sessions) AS views_per_session')->selectRaw('IFNULL((views - previous_period_views) / previous_period_views * 100, 0) AS views_growth')->selectRaw('IFNULL((visitors - previous_period_visitors) / previous_period_visitors * 100, 0) AS visitors_growth')->selectRaw('IFNULL(bounces / sessions * 100, 0) AS bounce_rate')->selectRaw('ROUND(CAST(wc_gross_sales - wc_refunded_amount AS SIGNED)) AS wc_net_sales')->selectRaw('IF(visitors = 0, 0, (wc_orders / visitors) * 100) AS wc_conversion_rate')->selectRaw('IF(visitors = 0, 0, (wc_gross_sales - wc_refunded_amount) / visitors) AS wc_earnings_per_visitor')->selectRaw('IF(wc_orders = 0, 0, ROUND(CAST(wc_gross_sales / wc_orders AS SIGNED))) AS wc_average_order_volume')->selectRaw('IF(visitors = 0, 0, (form_submissions / visitors) * 100) AS form_conversion_rate')->tap(function (Builder $query) { foreach (Form::get_forms() as $form) { $query->selectRaw("IF(visitors = 0, 0, ({$form->submissions_column()} / visitors) * 100) AS {$form->conversion_rate_column()}"); } })->when(\count($this->filters) > 0, function (Builder $query) { foreach ($this->filters as $filter) { if ($this->is_a_calculated_column($filter->column())) { $filter->apply_to_query($query); } } })->fromSub($campaigns_query, 'campaigns')->leftJoinSub($previous_period_query, 'previous_period_stats', 'campaigns.campaign_id', '=', 'previous_period_stats.campaign_id')->when($this->is_using_a_calculated_column(), function (Builder $query) { $query->when($this->sort_configuration->is_column_nullable(), function (Builder $query) { $query->orderByRaw("CASE WHEN {$this->sort_configuration->column()} IS NULL THEN 1 ELSE 0 END"); })->orderBy($this->sort_configuration->column(), $this->sort_configuration->direction())->orderBy('title')->when(\is_int($this->number_of_rows), function (Builder $query) { $query->limit($this->number_of_rows); }); }); return $outer_query; } } IAWP/Rows/Cities.php000064400000017541147600331220010175 0ustar00joinSub($this->query(\true), 'city_rows', function (JoinClause $join) { $join->on('city_rows.city_id', '=', 'sessions.city_id'); }); } protected function fetch_rows() : array { $rows = $this->query()->get()->all(); return \array_map(function ($row) { return new Geo($row); }, $rows); } private function query(?bool $skip_pagination = \false) : Builder { if ($skip_pagination) { $this->number_of_rows = null; } $views_table = Query::get_table_name(Query::VIEWS); $sessions_table = Query::get_table_name(Query::SESSIONS); $orders_table = Query::get_table_name(Query::ORDERS); $countries_table = Query::get_table_name(Query::COUNTRIES); $cities_table = Query::get_table_name(Query::CITIES); $orders_query = Illuminate_Builder::new(); $orders_query->select(['orders.view_id AS view_id'])->selectRaw('IFNULL(COUNT(DISTINCT orders.order_id), 0) AS wc_orders')->selectRaw('IFNULL(ROUND(CAST(SUM(orders.total) AS SIGNED)), 0) AS wc_gross_sales')->selectRaw('IFNULL(ROUND(CAST(SUM(orders.total_refunded) AS SIGNED)), 0) AS wc_refunded_amount')->selectRaw('IFNULL(SUM(orders.total_refunds), 0) AS wc_refunds')->from($orders_table, 'orders')->where('orders.is_included_in_analytics', '=', \true)->whereBetween('orders.created_at', $this->get_current_period_iso_range())->groupBy('orders.view_id'); $cities_query = Illuminate_Builder::new(); $cities_query->select('countries.country_id', 'countries.country_code', 'countries.country', 'countries.continent', 'cities.subdivision', 'cities.city', 'cities.city_id')->selectRaw('COUNT(DISTINCT views.id) AS views')->selectRaw('COUNT(DISTINCT sessions.visitor_id) AS visitors')->selectRaw('COUNT(DISTINCT sessions.session_id) AS sessions')->selectRaw('ROUND(AVG( TIMESTAMPDIFF(SECOND, sessions.created_at, sessions.ended_at))) AS average_session_duration')->selectRaw('COUNT(DISTINCT IF(sessions.final_view_id IS NULL, sessions.session_id, NULL)) AS bounces')->selectRaw('COUNT(DISTINCT clicks.click_id) AS clicks')->selectRaw('IFNULL(SUM(the_orders.wc_orders), 0) AS wc_orders')->selectRaw('IFNULL(SUM(the_orders.wc_gross_sales), 0) AS wc_gross_sales')->selectRaw('IFNULL(SUM(the_orders.wc_refunded_amount), 0) AS wc_refunded_amount')->selectRaw('IFNULL(SUM(the_orders.wc_refunds), 0) AS wc_refunds')->selectRaw('IFNULL(SUM(form_submissions.form_submissions), 0) AS form_submissions')->tap(function (Builder $query) { foreach (Form::get_forms() as $form) { $query->selectRaw("SUM(IF(form_submissions.form_id = ?, form_submissions.form_submissions, 0)) AS {$form->submissions_column()}", [$form->id()]); } })->from($views_table, 'views')->leftJoin($cities_query->raw($sessions_table . ' AS sessions'), function (JoinClause $join) { $join->on('views.session_id', '=', 'sessions.session_id'); })->join($cities_query->raw($cities_table . ' AS cities'), function (JoinClause $join) { $join->on('sessions.city_id', '=', 'cities.city_id'); })->join($cities_query->raw($countries_table . ' AS countries'), function (JoinClause $join) { $join->on('cities.country_id', '=', 'countries.country_id'); })->leftJoin($cities_query->raw(Tables::clicks() . ' AS clicks'), function (JoinClause $join) { $join->on('clicks.view_id', '=', 'views.id'); })->leftJoinSub($orders_query, 'the_orders', function (JoinClause $join) { $join->on('the_orders.view_id', '=', 'views.id'); })->leftJoinSub($this->get_form_submissions_query(), 'form_submissions', function (JoinClause $join) { $join->on('form_submissions.view_id', '=', 'views.id'); })->whereBetween('views.viewed_at', $this->get_current_period_iso_range())->when(!$this->appears_to_be_for_real_time_analytics(), function (Builder $query) { $query->whereBetween('sessions.created_at', $this->get_current_period_iso_range()); })->tap(Query_Taps::tap_authored_content_check())->when(\count($this->filters) > 0, function (Builder $query) { foreach ($this->filters as $filter) { if (!$this->is_a_calculated_column($filter->column())) { $filter->apply_to_query($query); } } })->groupBy('cities.city_id')->having('views', '>', 0)->when(!$this->is_using_a_calculated_column(), function (Builder $query) { $query->when($this->sort_configuration->is_column_nullable(), function (Builder $query) { $query->orderByRaw("CASE WHEN {$this->sort_configuration->column()} IS NULL THEN 1 ELSE 0 END"); })->orderBy($this->sort_configuration->column(), $this->sort_configuration->direction())->orderBy('city')->when(\is_int($this->number_of_rows), function (Builder $query) { $query->limit($this->number_of_rows); }); }); $previous_period_query = Illuminate_Builder::new(); $previous_period_query->select(['sessions.city_id'])->selectRaw('SUM(sessions.total_views) AS previous_period_views')->selectRaw('COUNT(DISTINCT sessions.visitor_id) AS previous_period_visitors')->from($sessions_table, 'sessions')->whereBetween('sessions.created_at', $this->get_previous_period_iso_range())->groupBy('sessions.city_id'); $outer_query = Illuminate_Builder::new(); $outer_query->selectRaw('cities.*')->selectRaw('IF(sessions = 0, 0, views / sessions) AS views_per_session')->selectRaw('IFNULL((views - previous_period_views) / previous_period_views * 100, 0) AS views_growth')->selectRaw('IFNULL((visitors - previous_period_visitors) / previous_period_visitors * 100, 0) AS visitors_growth')->selectRaw('IFNULL(bounces / sessions * 100, 0) AS bounce_rate')->selectRaw('ROUND(CAST(wc_gross_sales - wc_refunded_amount AS SIGNED)) AS wc_net_sales')->selectRaw('IF(visitors = 0, 0, (wc_orders / visitors) * 100) AS wc_conversion_rate')->selectRaw('IF(visitors = 0, 0, (wc_gross_sales - wc_refunded_amount) / visitors) AS wc_earnings_per_visitor')->selectRaw('IF(wc_orders = 0, 0, ROUND(CAST(wc_gross_sales / wc_orders AS SIGNED))) AS wc_average_order_volume')->selectRaw('IF(visitors = 0, 0, (form_submissions / visitors) * 100) AS form_conversion_rate')->tap(function (Builder $query) { foreach (Form::get_forms() as $form) { $query->selectRaw("IF(visitors = 0, 0, ({$form->submissions_column()} / visitors) * 100) AS {$form->conversion_rate_column()}"); } })->when(\count($this->filters) > 0, function (Builder $query) { foreach ($this->filters as $filter) { if ($this->is_a_calculated_column($filter->column())) { $filter->apply_to_query($query); } } })->fromSub($cities_query, 'cities')->leftJoinSub($previous_period_query, 'previous_period_stats', 'cities.city_id', '=', 'previous_period_stats.city_id')->when($this->is_using_a_calculated_column(), function (Builder $query) { $query->when($this->sort_configuration->is_column_nullable(), function (Builder $query) { $query->orderByRaw("CASE WHEN {$this->sort_configuration->column()} IS NULL THEN 1 ELSE 0 END"); })->orderBy($this->sort_configuration->column(), $this->sort_configuration->direction())->orderBy('city')->when(\is_int($this->number_of_rows), function (Builder $query) { $query->limit($this->number_of_rows); }); }); return $outer_query; } } IAWP/Rows/Clicks.php000064400000004521147600331220010157 0ustar00joinSub($this->query(\true), 'click_rows', function (JoinClause $join) { $join->on('click_rows.link_rule_id', '=', 'link_rules.link_rule_id'); $join->on('click_rows.click_target_id', '=', 'click_targets.click_target_id'); }); } protected function fetch_rows() : array { $rows = $this->query()->get()->all(); return \array_map(function ($row) { return new Click($row); }, $rows); } private function query(?bool $skip_pagination = \false) : Builder { if ($skip_pagination) { $this->number_of_rows = null; } $query = Illuminate_Builder::new()->select(['link_rules.link_rule_id AS link_rule_id', 'click_targets.click_target_id AS click_target_id', 'link_rules.name AS link_name', 'click_targets.target AS link_target'])->selectRaw('COUNT(DISTINCT clicks.click_id) AS link_clicks')->from($this->tables::link_rules(), 'link_rules')->leftJoin($this->tables::clicked_links() . ' AS clicked_links', 'clicked_links.link_rule_id', '=', 'link_rules.link_rule_id')->leftJoin($this->tables::clicks() . ' AS clicks', 'clicks.click_id', '=', 'clicked_links.click_id')->leftJoin($this->tables::click_targets() . ' AS click_targets', 'click_targets.click_target_id', '=', 'clicks.click_target_id')->whereBetween('clicks.created_at', $this->get_current_period_iso_range())->when(\count($this->filters) > 0, function (Builder $query) { foreach ($this->filters as $filter) { if (!$this->is_a_calculated_column($filter->column())) { $filter->apply_to_query($query); } } })->when(\is_int($this->number_of_rows), function (Builder $query) { $query->limit($this->number_of_rows); })->tap(Query_Taps::tap_authored_content_for_clicks())->orderBy($this->sort_configuration->column(), $this->sort_configuration->direction())->orderBy('link_name')->groupBy('link_rules.link_rule_id', 'clicks.click_target_id'); return $query; } } IAWP/Rows/Countries.php000064400000017215147600331220010726 0ustar00joinSub($this->query(\true), 'country_rows', function (JoinClause $join) { $join->on('country_rows.country_id', '=', 'sessions.country_id'); }); } protected function fetch_rows() : array { $rows = $this->query()->get()->all(); return \array_map(function ($row) { return new Geo($row); }, $rows); } private function query(?bool $skip_pagination = \false) : Builder { if ($skip_pagination) { $this->number_of_rows = null; } $views_table = Query::get_table_name(Query::VIEWS); $sessions_table = Query::get_table_name(Query::SESSIONS); $orders_table = Query::get_table_name(Query::ORDERS); $countries_table = Query::get_table_name(Query::COUNTRIES); $orders_query = Illuminate_Builder::new(); $orders_query->select(['orders.view_id AS view_id'])->selectRaw('IFNULL(COUNT(DISTINCT orders.order_id), 0) AS wc_orders')->selectRaw('IFNULL(ROUND(CAST(SUM(orders.total) AS SIGNED)), 0) AS wc_gross_sales')->selectRaw('IFNULL(ROUND(CAST(SUM(orders.total_refunded) AS SIGNED)), 0) AS wc_refunded_amount')->selectRaw('IFNULL(SUM(orders.total_refunds), 0) AS wc_refunds')->from($orders_table, 'orders')->where('orders.is_included_in_analytics', '=', \true)->whereBetween('orders.created_at', $this->get_current_period_iso_range())->groupBy('orders.view_id'); $countries_query = Illuminate_Builder::new(); $countries_query->select('countries.country_id', 'countries.country_code', 'countries.country', 'countries.continent')->selectRaw('COUNT(DISTINCT views.id) AS views')->selectRaw('COUNT(DISTINCT sessions.visitor_id) AS visitors')->selectRaw('COUNT(DISTINCT sessions.session_id) AS sessions')->selectRaw('ROUND(AVG( TIMESTAMPDIFF(SECOND, sessions.created_at, sessions.ended_at))) AS average_session_duration')->selectRaw('COUNT(DISTINCT IF(sessions.final_view_id IS NULL, sessions.session_id, NULL)) AS bounces')->selectRaw('COUNT(DISTINCT clicks.click_id) AS clicks')->selectRaw('IFNULL(SUM(the_orders.wc_orders), 0) AS wc_orders')->selectRaw('IFNULL(SUM(the_orders.wc_gross_sales), 0) AS wc_gross_sales')->selectRaw('IFNULL(SUM(the_orders.wc_refunded_amount), 0) AS wc_refunded_amount')->selectRaw('IFNULL(SUM(the_orders.wc_refunds), 0) AS wc_refunds')->selectRaw('IFNULL(SUM(form_submissions.form_submissions), 0) AS form_submissions')->tap(function (Builder $query) { foreach (Form::get_forms() as $form) { $query->selectRaw("SUM(IF(form_submissions.form_id = ?, form_submissions.form_submissions, 0)) AS {$form->submissions_column()}", [$form->id()]); } })->from($views_table, 'views')->leftJoin($countries_query->raw($sessions_table . ' AS sessions'), function (JoinClause $join) { $join->on('views.session_id', '=', 'sessions.session_id'); })->join($countries_query->raw($countries_table . ' AS countries'), function (JoinClause $join) { $join->on('sessions.country_id', '=', 'countries.country_id'); })->leftJoin($countries_query->raw(Tables::clicks() . ' AS clicks'), function (JoinClause $join) { $join->on('clicks.view_id', '=', 'views.id'); })->leftJoinSub($orders_query, 'the_orders', function (JoinClause $join) { $join->on('the_orders.view_id', '=', 'views.id'); })->leftJoinSub($this->get_form_submissions_query(), 'form_submissions', function (JoinClause $join) { $join->on('form_submissions.view_id', '=', 'views.id'); })->whereBetween('views.viewed_at', $this->get_current_period_iso_range())->when(!$this->appears_to_be_for_real_time_analytics(), function (Builder $query) { $query->whereBetween('sessions.created_at', $this->get_current_period_iso_range()); })->tap(Query_Taps::tap_authored_content_check())->when(\count($this->filters) > 0, function (Builder $query) { foreach ($this->filters as $filter) { if (!$this->is_a_calculated_column($filter->column())) { $filter->apply_to_query($query); } } })->groupBy('countries.country_id')->having('views', '>', 0)->when(!$this->is_using_a_calculated_column(), function (Builder $query) { $query->when($this->sort_configuration->is_column_nullable(), function (Builder $query) { $query->orderByRaw("CASE WHEN {$this->sort_configuration->column()} IS NULL THEN 1 ELSE 0 END"); })->orderBy($this->sort_configuration->column(), $this->sort_configuration->direction())->orderBy('country')->when(\is_int($this->number_of_rows), function (Builder $query) { $query->limit($this->number_of_rows); }); }); $previous_period_query = Illuminate_Builder::new(); $previous_period_query->select(['sessions.country_id'])->selectRaw('SUM(sessions.total_views) AS previous_period_views')->selectRaw('COUNT(DISTINCT sessions.visitor_id) AS previous_period_visitors')->from($sessions_table, 'sessions')->whereBetween('sessions.created_at', $this->get_previous_period_iso_range())->groupBy('sessions.country_id'); $outer_query = Illuminate_Builder::new(); $outer_query->selectRaw('countries.*')->selectRaw('IF(sessions = 0, 0, views / sessions) AS views_per_session')->selectRaw('IFNULL((views - previous_period_views) / previous_period_views * 100, 0) AS views_growth')->selectRaw('IFNULL((visitors - previous_period_visitors) / previous_period_visitors * 100, 0) AS visitors_growth')->selectRaw('IFNULL(bounces / sessions * 100, 0) AS bounce_rate')->selectRaw('ROUND(CAST(wc_gross_sales - wc_refunded_amount AS SIGNED)) AS wc_net_sales')->selectRaw('IF(visitors = 0, 0, (wc_orders / visitors) * 100) AS wc_conversion_rate')->selectRaw('IF(visitors = 0, 0, (wc_gross_sales - wc_refunded_amount) / visitors) AS wc_earnings_per_visitor')->selectRaw('IF(wc_orders = 0, 0, ROUND(CAST(wc_gross_sales / wc_orders AS SIGNED))) AS wc_average_order_volume')->selectRaw('IF(visitors = 0, 0, (form_submissions / visitors) * 100) AS form_conversion_rate')->tap(function (Builder $query) { foreach (Form::get_forms() as $form) { $query->selectRaw("IF(visitors = 0, 0, ({$form->submissions_column()} / visitors) * 100) AS {$form->conversion_rate_column()}"); } })->when(\count($this->filters) > 0, function (Builder $query) { foreach ($this->filters as $filter) { if ($this->is_a_calculated_column($filter->column())) { $filter->apply_to_query($query); } } })->fromSub($countries_query, 'countries')->leftJoinSub($previous_period_query, 'previous_period_stats', 'countries.country_id', '=', 'previous_period_stats.country_id')->when($this->is_using_a_calculated_column(), function (Builder $query) { $query->when($this->sort_configuration->is_column_nullable(), function (Builder $query) { $query->orderByRaw("CASE WHEN {$this->sort_configuration->column()} IS NULL THEN 1 ELSE 0 END"); })->orderBy($this->sort_configuration->column(), $this->sort_configuration->direction())->orderBy('country')->when(\is_int($this->number_of_rows), function (Builder $query) { $query->limit($this->number_of_rows); }); }); return $outer_query; } } IAWP/Rows/Device_Browsers.php000064400000017464147600331220012046 0ustar00joinSub($this->query(\true), 'device_browser_rows', function (JoinClause $join) { $join->on('device_browser_rows.device_browser_id', '=', 'sessions.device_browser_id'); }); } protected function fetch_rows() : array { $rows = $this->query()->get()->all(); return \array_map(function ($row) { return new Device($row); }, $rows); } private function query(?bool $skip_pagination = \false) : Builder { if ($skip_pagination) { $this->number_of_rows = null; } $views_table = Query::get_table_name(Query::VIEWS); $sessions_table = Query::get_table_name(Query::SESSIONS); $orders_table = Query::get_table_name(Query::ORDERS); $device_browsers_table = Query::get_table_name(Query::DEVICE_BROWSERS); $orders_query = Illuminate_Builder::new(); $orders_query->select(['orders.view_id AS view_id'])->selectRaw('IFNULL(COUNT(DISTINCT orders.order_id), 0) AS wc_orders')->selectRaw('IFNULL(ROUND(CAST(SUM(orders.total) AS SIGNED)), 0) AS wc_gross_sales')->selectRaw('IFNULL(ROUND(CAST(SUM(orders.total_refunded) AS SIGNED)), 0) AS wc_refunded_amount')->selectRaw('IFNULL(SUM(orders.total_refunds), 0) AS wc_refunds')->from($orders_table, 'orders')->where('orders.is_included_in_analytics', '=', \true)->whereBetween('orders.created_at', $this->get_current_period_iso_range())->groupBy('orders.view_id'); $device_browsers_query = Illuminate_Builder::new(); $device_browsers_query->select('device_browsers.device_browser_id', 'device_browsers.device_browser AS browser')->selectRaw('COUNT(DISTINCT views.id) AS views')->selectRaw('COUNT(DISTINCT sessions.visitor_id) AS visitors')->selectRaw('COUNT(DISTINCT sessions.session_id) AS sessions')->selectRaw('ROUND(AVG( TIMESTAMPDIFF(SECOND, sessions.created_at, sessions.ended_at))) AS average_session_duration')->selectRaw('COUNT(DISTINCT IF(sessions.final_view_id IS NULL, sessions.session_id, NULL)) AS bounces')->selectRaw('COUNT(DISTINCT clicks.click_id) AS clicks')->selectRaw('IFNULL(SUM(the_orders.wc_orders), 0) AS wc_orders')->selectRaw('IFNULL(SUM(the_orders.wc_gross_sales), 0) AS wc_gross_sales')->selectRaw('IFNULL(SUM(the_orders.wc_refunded_amount), 0) AS wc_refunded_amount')->selectRaw('IFNULL(SUM(the_orders.wc_refunds), 0) AS wc_refunds')->selectRaw('IFNULL(SUM(form_submissions.form_submissions), 0) AS form_submissions')->tap(function (Builder $query) { foreach (Form::get_forms() as $form) { $query->selectRaw("SUM(IF(form_submissions.form_id = ?, form_submissions.form_submissions, 0)) AS {$form->submissions_column()}", [$form->id()]); } })->from($views_table, 'views')->leftJoin($device_browsers_query->raw($sessions_table . ' AS sessions'), function (JoinClause $join) { $join->on('views.session_id', '=', 'sessions.session_id'); })->join($device_browsers_query->raw($device_browsers_table . ' AS device_browsers'), function (JoinClause $join) { $join->on('sessions.device_browser_id', '=', 'device_browsers.device_browser_id'); })->leftJoin($device_browsers_query->raw(Tables::clicks() . ' AS clicks'), function (JoinClause $join) { $join->on('clicks.view_id', '=', 'views.id'); })->leftJoinSub($orders_query, 'the_orders', function (JoinClause $join) { $join->on('the_orders.view_id', '=', 'views.id'); })->leftJoinSub($this->get_form_submissions_query(), 'form_submissions', function (JoinClause $join) { $join->on('form_submissions.view_id', '=', 'views.id'); })->whereBetween('views.viewed_at', $this->get_current_period_iso_range())->when(!$this->appears_to_be_for_real_time_analytics(), function (Builder $query) { $query->whereBetween('sessions.created_at', $this->get_current_period_iso_range()); })->tap(Query_Taps::tap_authored_content_check())->when(\count($this->filters) > 0, function (Builder $query) { foreach ($this->filters as $filter) { if (!$this->is_a_calculated_column($filter->column())) { $filter->apply_to_query($query); } } })->groupBy('device_browsers.device_browser_id')->having('views', '>', 0)->when(!$this->is_using_a_calculated_column(), function (Builder $query) { $query->when($this->sort_configuration->is_column_nullable(), function (Builder $query) { $query->orderByRaw("CASE WHEN {$this->sort_configuration->column()} IS NULL THEN 1 ELSE 0 END"); })->orderBy($this->sort_configuration->column(), $this->sort_configuration->direction())->orderBy('browser')->when(\is_int($this->number_of_rows), function (Builder $query) { $query->limit($this->number_of_rows); }); }); $previous_period_query = Illuminate_Builder::new(); $previous_period_query->select(['sessions.device_browser_id'])->selectRaw('SUM(sessions.total_views) AS previous_period_views')->selectRaw('COUNT(DISTINCT sessions.visitor_id) AS previous_period_visitors')->from($sessions_table, 'sessions')->whereBetween('sessions.created_at', $this->get_previous_period_iso_range())->groupBy('sessions.device_browser_id'); $outer_query = Illuminate_Builder::new(); $outer_query->selectRaw('device_browsers.*')->selectRaw('IF(sessions = 0, 0, views / sessions) AS views_per_session')->selectRaw('IFNULL((views - previous_period_views) / previous_period_views * 100, 0) AS views_growth')->selectRaw('IFNULL((visitors - previous_period_visitors) / previous_period_visitors * 100, 0) AS visitors_growth')->selectRaw('IFNULL(bounces / sessions * 100, 0) AS bounce_rate')->selectRaw('ROUND(CAST(wc_gross_sales - wc_refunded_amount AS SIGNED)) AS wc_net_sales')->selectRaw('IF(visitors = 0, 0, (wc_orders / visitors) * 100) AS wc_conversion_rate')->selectRaw('IF(visitors = 0, 0, (wc_gross_sales - wc_refunded_amount) / visitors) AS wc_earnings_per_visitor')->selectRaw('IF(wc_orders = 0, 0, ROUND(CAST(wc_gross_sales / wc_orders AS SIGNED))) AS wc_average_order_volume')->selectRaw('IF(visitors = 0, 0, (form_submissions / visitors) * 100) AS form_conversion_rate')->tap(function (Builder $query) { foreach (Form::get_forms() as $form) { $query->selectRaw("IF(visitors = 0, 0, ({$form->submissions_column()} / visitors) * 100) AS {$form->conversion_rate_column()}"); } })->when(\count($this->filters) > 0, function (Builder $query) { foreach ($this->filters as $filter) { if ($this->is_a_calculated_column($filter->column())) { $filter->apply_to_query($query); } } })->fromSub($device_browsers_query, 'device_browsers')->leftJoinSub($previous_period_query, 'previous_period_stats', 'device_browsers.device_browser_id', '=', 'previous_period_stats.device_browser_id')->when($this->is_using_a_calculated_column(), function (Builder $query) { $query->when($this->sort_configuration->is_column_nullable(), function (Builder $query) { $query->orderByRaw("CASE WHEN {$this->sort_configuration->column()} IS NULL THEN 1 ELSE 0 END"); })->orderBy($this->sort_configuration->column(), $this->sort_configuration->direction())->orderBy('browser')->when(\is_int($this->number_of_rows), function (Builder $query) { $query->limit($this->number_of_rows); }); }); return $outer_query; } } IAWP/Rows/Device_OSS.php000064400000017271147600331220010700 0ustar00joinSub($this->query(\true), 'device_os_rows', function (JoinClause $join) { $join->on('device_os_rows.device_os_id', '=', 'sessions.device_os_id'); }); } protected function fetch_rows() : array { $rows = $this->query()->get()->all(); return \array_map(function ($row) { return new Device($row); }, $rows); } private function query(?bool $skip_pagination = \false) : Builder { if ($skip_pagination) { $this->number_of_rows = null; } $views_table = Query::get_table_name(Query::VIEWS); $sessions_table = Query::get_table_name(Query::SESSIONS); $orders_table = Query::get_table_name(Query::ORDERS); $device_oss_table = Query::get_table_name(Query::DEVICE_OSS); $orders_query = Illuminate_Builder::new(); $orders_query->select(['orders.view_id AS view_id'])->selectRaw('IFNULL(COUNT(DISTINCT orders.order_id), 0) AS wc_orders')->selectRaw('IFNULL(ROUND(CAST(SUM(orders.total) AS SIGNED)), 0) AS wc_gross_sales')->selectRaw('IFNULL(ROUND(CAST(SUM(orders.total_refunded) AS SIGNED)), 0) AS wc_refunded_amount')->selectRaw('IFNULL(SUM(orders.total_refunds), 0) AS wc_refunds')->from($orders_table, 'orders')->where('orders.is_included_in_analytics', '=', \true)->whereBetween('orders.created_at', $this->get_current_period_iso_range())->groupBy('orders.view_id'); $device_oss_query = Illuminate_Builder::new(); $device_oss_query->select('device_oss.device_os_id', 'device_oss.device_os AS os')->selectRaw('COUNT(DISTINCT views.id) AS views')->selectRaw('COUNT(DISTINCT sessions.visitor_id) AS visitors')->selectRaw('COUNT(DISTINCT sessions.session_id) AS sessions')->selectRaw('ROUND(AVG( TIMESTAMPDIFF(SECOND, sessions.created_at, sessions.ended_at))) AS average_session_duration')->selectRaw('COUNT(DISTINCT IF(sessions.final_view_id IS NULL, sessions.session_id, NULL)) AS bounces')->selectRaw('COUNT(DISTINCT clicks.click_id) AS clicks')->selectRaw('IFNULL(SUM(the_orders.wc_orders), 0) AS wc_orders')->selectRaw('IFNULL(SUM(the_orders.wc_gross_sales), 0) AS wc_gross_sales')->selectRaw('IFNULL(SUM(the_orders.wc_refunded_amount), 0) AS wc_refunded_amount')->selectRaw('IFNULL(SUM(the_orders.wc_refunds), 0) AS wc_refunds')->selectRaw('IFNULL(SUM(form_submissions.form_submissions), 0) AS form_submissions')->tap(function (Builder $query) { foreach (Form::get_forms() as $form) { $query->selectRaw("SUM(IF(form_submissions.form_id = ?, form_submissions.form_submissions, 0)) AS {$form->submissions_column()}", [$form->id()]); } })->from($views_table, 'views')->leftJoin($device_oss_query->raw($sessions_table . ' AS sessions'), function (JoinClause $join) { $join->on('views.session_id', '=', 'sessions.session_id'); })->join($device_oss_query->raw($device_oss_table . ' AS device_oss'), function (JoinClause $join) { $join->on('sessions.device_os_id', '=', 'device_oss.device_os_id'); })->leftJoin($device_oss_query->raw(Tables::clicks() . ' AS clicks'), function (JoinClause $join) { $join->on('clicks.view_id', '=', 'views.id'); })->leftJoinSub($orders_query, 'the_orders', function (JoinClause $join) { $join->on('the_orders.view_id', '=', 'views.id'); })->leftJoinSub($this->get_form_submissions_query(), 'form_submissions', function (JoinClause $join) { $join->on('form_submissions.view_id', '=', 'views.id'); })->whereBetween('views.viewed_at', $this->get_current_period_iso_range())->when(!$this->appears_to_be_for_real_time_analytics(), function (Builder $query) { $query->whereBetween('sessions.created_at', $this->get_current_period_iso_range()); })->tap(Query_Taps::tap_authored_content_check())->when(\count($this->filters) > 0, function (Builder $query) { foreach ($this->filters as $filter) { if (!$this->is_a_calculated_column($filter->column())) { $filter->apply_to_query($query); } } })->groupBy('device_oss.device_os_id')->having('views', '>', 0)->when(!$this->is_using_a_calculated_column(), function (Builder $query) { $query->when($this->sort_configuration->is_column_nullable(), function (Builder $query) { $query->orderByRaw("CASE WHEN {$this->sort_configuration->column()} IS NULL THEN 1 ELSE 0 END"); })->orderBy($this->sort_configuration->column(), $this->sort_configuration->direction())->orderBy('os')->when(\is_int($this->number_of_rows), function (Builder $query) { $query->limit($this->number_of_rows); }); }); $previous_period_query = Illuminate_Builder::new(); $previous_period_query->select(['sessions.device_os_id'])->selectRaw('SUM(sessions.total_views) AS previous_period_views')->selectRaw('COUNT(DISTINCT sessions.visitor_id) AS previous_period_visitors')->from($sessions_table, 'sessions')->whereBetween('sessions.created_at', $this->get_previous_period_iso_range())->groupBy('sessions.device_os_id'); $outer_query = Illuminate_Builder::new(); $outer_query->selectRaw('device_oss.*')->selectRaw('IF(sessions = 0, 0, views / sessions) AS views_per_session')->selectRaw('IFNULL((views - previous_period_views) / previous_period_views * 100, 0) AS views_growth')->selectRaw('IFNULL((visitors - previous_period_visitors) / previous_period_visitors * 100, 0) AS visitors_growth')->selectRaw('IFNULL(bounces / sessions * 100, 0) AS bounce_rate')->selectRaw('ROUND(CAST(wc_gross_sales - wc_refunded_amount AS SIGNED)) AS wc_net_sales')->selectRaw('IF(visitors = 0, 0, (wc_orders / visitors) * 100) AS wc_conversion_rate')->selectRaw('IF(visitors = 0, 0, (wc_gross_sales - wc_refunded_amount) / visitors) AS wc_earnings_per_visitor')->selectRaw('IF(wc_orders = 0, 0, ROUND(CAST(wc_gross_sales / wc_orders AS SIGNED))) AS wc_average_order_volume')->selectRaw('IF(visitors = 0, 0, (form_submissions / visitors) * 100) AS form_conversion_rate')->tap(function (Builder $query) { foreach (Form::get_forms() as $form) { $query->selectRaw("IF(visitors = 0, 0, ({$form->submissions_column()} / visitors) * 100) AS {$form->conversion_rate_column()}"); } })->when(\count($this->filters) > 0, function (Builder $query) { foreach ($this->filters as $filter) { if ($this->is_a_calculated_column($filter->column())) { $filter->apply_to_query($query); } } })->fromSub($device_oss_query, 'device_oss')->leftJoinSub($previous_period_query, 'previous_period_stats', 'device_oss.device_os_id', '=', 'previous_period_stats.device_os_id')->when($this->is_using_a_calculated_column(), function (Builder $query) { $query->when($this->sort_configuration->is_column_nullable(), function (Builder $query) { $query->orderByRaw("CASE WHEN {$this->sort_configuration->column()} IS NULL THEN 1 ELSE 0 END"); })->orderBy($this->sort_configuration->column(), $this->sort_configuration->direction())->orderBy('os')->when(\is_int($this->number_of_rows), function (Builder $query) { $query->limit($this->number_of_rows); }); }); Illuminate_Builder::ray($outer_query); return $outer_query; } } IAWP/Rows/Device_Types.php000064400000017324147600331220011337 0ustar00joinSub($this->query(\true), 'device_type_rows', function (JoinClause $join) { $join->on('device_type_rows.device_type_id', '=', 'sessions.device_type_id'); }); } protected function fetch_rows() : array { $rows = $this->query()->get()->all(); return \array_map(function ($row) { return new Device($row); }, $rows); } private function query(?bool $skip_pagination = \false) : Builder { if ($skip_pagination) { $this->number_of_rows = null; } $views_table = Query::get_table_name(Query::VIEWS); $sessions_table = Query::get_table_name(Query::SESSIONS); $orders_table = Query::get_table_name(Query::ORDERS); $device_types_table = Query::get_table_name(Query::DEVICE_TYPES); $orders_query = Illuminate_Builder::new(); $orders_query->select(['orders.view_id AS view_id'])->selectRaw('IFNULL(COUNT(DISTINCT orders.order_id), 0) AS wc_orders')->selectRaw('IFNULL(ROUND(CAST(SUM(orders.total) AS SIGNED)), 0) AS wc_gross_sales')->selectRaw('IFNULL(ROUND(CAST(SUM(orders.total_refunded) AS SIGNED)), 0) AS wc_refunded_amount')->selectRaw('IFNULL(SUM(orders.total_refunds), 0) AS wc_refunds')->from($orders_table, 'orders')->where('orders.is_included_in_analytics', '=', \true)->whereBetween('orders.created_at', $this->get_current_period_iso_range())->groupBy('orders.view_id'); $device_types_query = Illuminate_Builder::new(); $device_types_query->select('device_types.device_type_id', 'device_types.device_type')->selectRaw('COUNT(DISTINCT views.id) AS views')->selectRaw('COUNT(DISTINCT sessions.visitor_id) AS visitors')->selectRaw('COUNT(DISTINCT sessions.session_id) AS sessions')->selectRaw('ROUND(AVG( TIMESTAMPDIFF(SECOND, sessions.created_at, sessions.ended_at))) AS average_session_duration')->selectRaw('COUNT(DISTINCT IF(sessions.final_view_id IS NULL, sessions.session_id, NULL)) AS bounces')->selectRaw('COUNT(DISTINCT clicks.click_id) AS clicks')->selectRaw('IFNULL(SUM(the_orders.wc_orders), 0) AS wc_orders')->selectRaw('IFNULL(SUM(the_orders.wc_gross_sales), 0) AS wc_gross_sales')->selectRaw('IFNULL(SUM(the_orders.wc_refunded_amount), 0) AS wc_refunded_amount')->selectRaw('IFNULL(SUM(the_orders.wc_refunds), 0) AS wc_refunds')->selectRaw('IFNULL(SUM(form_submissions.form_submissions), 0) AS form_submissions')->tap(function (Builder $query) { foreach (Form::get_forms() as $form) { $query->selectRaw("SUM(IF(form_submissions.form_id = ?, form_submissions.form_submissions, 0)) AS {$form->submissions_column()}", [$form->id()]); } })->from($views_table, 'views')->leftJoin($device_types_query->raw($sessions_table . ' AS sessions'), function (JoinClause $join) { $join->on('views.session_id', '=', 'sessions.session_id'); })->join($device_types_query->raw($device_types_table . ' AS device_types'), function (JoinClause $join) { $join->on('sessions.device_type_id', '=', 'device_types.device_type_id'); })->leftJoin($device_types_query->raw(Tables::clicks() . ' AS clicks'), function (JoinClause $join) { $join->on('clicks.view_id', '=', 'views.id'); })->leftJoinSub($orders_query, 'the_orders', function (JoinClause $join) { $join->on('the_orders.view_id', '=', 'views.id'); })->leftJoinSub($this->get_form_submissions_query(), 'form_submissions', function (JoinClause $join) { $join->on('form_submissions.view_id', '=', 'views.id'); })->whereBetween('views.viewed_at', $this->get_current_period_iso_range())->when(!$this->appears_to_be_for_real_time_analytics(), function (Builder $query) { $query->whereBetween('sessions.created_at', $this->get_current_period_iso_range()); })->tap(Query_Taps::tap_authored_content_check())->when(\count($this->filters) > 0, function (Builder $query) { foreach ($this->filters as $filter) { if (!$this->is_a_calculated_column($filter->column())) { $filter->apply_to_query($query); } } })->groupBy('device_types.device_type_id')->having('views', '>', 0)->when(!$this->is_using_a_calculated_column(), function (Builder $query) { $query->when($this->sort_configuration->is_column_nullable(), function (Builder $query) { $query->orderByRaw("CASE WHEN {$this->sort_configuration->column()} IS NULL THEN 1 ELSE 0 END"); })->orderBy($this->sort_configuration->column(), $this->sort_configuration->direction())->orderBy('device_type')->when(\is_int($this->number_of_rows), function (Builder $query) { $query->limit($this->number_of_rows); }); }); $previous_period_query = Illuminate_Builder::new(); $previous_period_query->select(['sessions.device_type_id'])->selectRaw('SUM(sessions.total_views) AS previous_period_views')->selectRaw('COUNT(DISTINCT sessions.visitor_id) AS previous_period_visitors')->from($sessions_table, 'sessions')->whereBetween('sessions.created_at', $this->get_previous_period_iso_range())->groupBy('sessions.device_type_id'); $outer_query = Illuminate_Builder::new(); $outer_query->selectRaw('device_types.*')->selectRaw('IF(sessions = 0, 0, views / sessions) AS views_per_session')->selectRaw('IFNULL((views - previous_period_views) / previous_period_views * 100, 0) AS views_growth')->selectRaw('IFNULL((visitors - previous_period_visitors) / previous_period_visitors * 100, 0) AS visitors_growth')->selectRaw('IFNULL(bounces / sessions * 100, 0) AS bounce_rate')->selectRaw('ROUND(CAST(wc_gross_sales - wc_refunded_amount AS SIGNED)) AS wc_net_sales')->selectRaw('IF(visitors = 0, 0, (wc_orders / visitors) * 100) AS wc_conversion_rate')->selectRaw('IF(visitors = 0, 0, (wc_gross_sales - wc_refunded_amount) / visitors) AS wc_earnings_per_visitor')->selectRaw('IF(wc_orders = 0, 0, ROUND(CAST(wc_gross_sales / wc_orders AS SIGNED))) AS wc_average_order_volume')->selectRaw('IF(visitors = 0, 0, (form_submissions / visitors) * 100) AS form_conversion_rate')->tap(function (Builder $query) { foreach (Form::get_forms() as $form) { $query->selectRaw("IF(visitors = 0, 0, ({$form->submissions_column()} / visitors) * 100) AS {$form->conversion_rate_column()}"); } })->when(\count($this->filters) > 0, function (Builder $query) { foreach ($this->filters as $filter) { if ($this->is_a_calculated_column($filter->column())) { $filter->apply_to_query($query); } } })->fromSub($device_types_query, 'device_types')->leftJoinSub($previous_period_query, 'previous_period_stats', 'device_types.device_type_id', '=', 'previous_period_stats.device_type_id')->when($this->is_using_a_calculated_column(), function (Builder $query) { $query->when($this->sort_configuration->is_column_nullable(), function (Builder $query) { $query->orderByRaw("CASE WHEN {$this->sort_configuration->column()} IS NULL THEN 1 ELSE 0 END"); })->orderBy($this->sort_configuration->column(), $this->sort_configuration->direction())->orderBy('device_type')->when(\is_int($this->number_of_rows), function (Builder $query) { $query->limit($this->number_of_rows); }); }); return $outer_query; } } IAWP/Rows/Filter.php000064400000022455147600331220010202 0ustar00filter = $filter; } public function filter() : array { return $this->filter; } public function apply_to_query(Builder $query) : void { if ($this->filter['column'] === 'category') { $this->apply_category_filter($query); } else { $method = $this->method(); $query->{$method}($this->column(), $this->operator(), $this->value()); } // If a filter is based on comments, remove all non-singular pages if ($this->filter['column'] === 'comments') { $query->whereNotNull('pages.singular_id'); } } public function html_description() : string { return $this->condition_string($this->filter()); } public function method() : string { if ($this->filter['column'] === $this->filter['database_column']) { return 'having'; } else { return 'where'; } } public function column() : string { return $this->filter['database_column']; } // Fix deprecation warning in PHP 8 while still working in PHP 7 #[\ReturnTypeWillChange] public function jsonSerialize() { return $this->filter; } /** * Category filters are different from the other filters * * @param Builder $query * @return void */ private function apply_category_filter(Builder $query) : void { $wp_query = new \WP_Query(['posts_per_page' => -1, 'cat' => $this->filter['operand'], 'fields' => 'ids']); $post_ids = $wp_query->posts; $include = $this->filter['inclusion'] === 'include'; $is = $this->filter['operator'] === 'is'; if ($include === $is) { $query->whereIn('singular_id', $post_ids); } else { $query->where(function (Builder $query) use($post_ids) { $query->whereNotIn('singular_id', $post_ids)->orWhereNull('singular_id'); }); } } private function condition_string(array $condition) : string { $full_string = ''; foreach ($condition as $key => $value) { if (!\in_array($key, ['inclusion', 'column', 'operator', 'operand'])) { continue; } $condition_string = ''; if ($key == 'inclusion' && $value == 'include') { $condition_string = \esc_html__('Include', 'independent-analytics'); } elseif ($key == 'inclusion' && $value == 'exclude') { $condition_string = \esc_html__('Exclude', 'independent-analytics'); } elseif ($key == 'operator' && $value == 'lesser') { $condition_string = '<'; } elseif ($key == 'operator' && $value == 'greater') { $condition_string = '>'; } elseif ($key == 'operator' && $value == 'equal') { $condition_string = '='; } elseif ($key == 'operator' && $value == 'on') { $condition_string = \esc_html__('On', 'independent-analytics'); } elseif ($key == 'operator' && $value == 'before') { $condition_string = \esc_html__('Before', 'independent-analytics'); } elseif ($key == 'operator' && $value == 'after') { $condition_string = \esc_html__('After', 'independent-analytics'); } elseif ($key == 'operator' && $value == 'contains') { $condition_string = \esc_html__('Contains', 'independent-analytics'); } elseif ($key == 'operator' && $value == 'exact') { $condition_string = \esc_html__('Exactly matches', 'independent-analytics'); } elseif ($key == 'operator' && $value == 'is') { $condition_string = \esc_html__('Is', 'independent-analytics'); } elseif ($key == 'operator' && $value == 'isnt') { $condition_string = \esc_html__("Isn't", 'independent-analytics'); } elseif ($key == 'operand' && $condition['column'] == 'browser') { $condition_string = Device_Browser_Filter_List::option($value); } elseif ($key == 'operand' && $condition['column'] == 'os') { $condition_string = Device_OS_Filter_List::option($value); } elseif ($key == 'operand' && $condition['column'] == 'device_type') { $condition_string = Device_Type_Filter_List::option($value); } elseif ($key == 'operand' && $condition['column'] == 'date') { try { $date = \DateTime::createFromFormat('U', $value); $condition_string = $date->format(WordPress_Site_Date_Format_Pattern::for_php()); } catch (\Throwable $e) { $condition_string = $value; } } elseif ($key == 'operand' && $condition['column'] == 'author') { $condition_string = Author_Filter_List::option($value); } elseif ($key == 'operand' && $condition['column'] == 'category') { $condition_string = Category_Filter_List::option($value); } elseif ($key == 'operand' && $condition['column'] == 'referrer_type') { $condition_string = Referrer_Type_Filter_List::option($value); } elseif ($key == 'operand' && $condition['column'] == 'link_name') { $condition_string = Link_Name_Filter_List::option($value); } elseif ($key == 'operand' && $condition['column'] == 'type') { $condition_string = Page_Type_Filter_List::option($value); } elseif ($key == 'column' && \str_contains($value, 'wc')) { $condition_string = \str_replace(['_', '-'], ' ', $value); $condition_string = \str_replace('wc', 'WC', $condition_string); } elseif ($key == 'column' && String_Util::str_starts_with($condition['column'], 'form_submissions_for_')) { $condition_string = \__('Submissions for', 'independent-analytics') . ' ' . Form::find_form_by_column_name($condition['column'])->title(); } elseif ($key == 'column' && String_Util::str_starts_with($condition['column'], 'form_conversion_rate_for_')) { $condition_string = \__('Conversion rate for', 'independent-analytics') . ' ' . Form::find_form_by_column_name($condition['column'])->title(); } elseif ($key == 'column' && $condition['column'] == 'link_name') { $condition_string = \__('Link Pattern', 'independent-analytics') . ' '; } else { $condition_string .= \ucwords(\str_replace(['_', '-'], ' ', $value)) . ' '; } if ($key == 'column' || $key == 'operand') { $condition_string = '' . $condition_string . ' '; } $full_string .= $condition_string . ' '; } return \trim($full_string); } private function operator() : string { $operator = $this->filter['operator']; $result = ''; if ($operator === 'equal' || $operator === 'is' || $operator === 'exact' || $operator === 'on') { $result = '='; } if ($operator === 'contains') { $result = 'like'; } if ($operator === 'isnt') { $result = '!='; } if ($operator === 'greater' || $operator === 'after') { $result = '>'; } if ($operator === 'lesser' || $operator === 'before') { $result = '<'; } if ($this->filter['inclusion'] === 'exclude') { if ($result === '=') { return '!='; } elseif ($result === '!=') { return '='; } elseif ($result === '>') { return '<='; } elseif ($result === '<') { return '>='; } elseif ($result === 'like') { return 'not like'; } } return $result; } private function value() : string { if ($this->filter['operator'] === 'contains') { return '%' . $this->filter['operand'] . '%'; } if ($this->filter['database_column'] === 'cached_date') { try { $date = \DateTime::createFromFormat('U', $this->filter['operand']); } catch (\Throwable $e) { $date = new \DateTime(); } return $date->format('Y-m-d'); } if (\in_array($this->filter['database_column'], ['wc_gross_sales', 'wc_refunded_amount', 'wc_net_sales', 'wc_earnings_per_visitor', 'wc_average_order_volume'])) { return \strval(\floatval($this->filter['operand']) * 100); } return $this->filter['operand']; } } IAWP/Rows/Pages.php000064400000025147147600331220010015 0ustar00joinSub($this->query(\true), 'page_rows', function (JoinClause $join) { $join->on('page_rows.id', '=', 'views.resource_id'); }); } protected function fetch_rows() : array { $rows = $this->query()->get()->all(); return \array_map(function (object $row) { return Page::from_row($row); }, $rows); } private function has_wp_comments_table() : bool { if (\is_bool(self::$has_wp_comments_table)) { return self::$has_wp_comments_table; } global $wpdb; self::$has_wp_comments_table = Database::has_table($wpdb->prefix . 'comments'); return self::$has_wp_comments_table; } private function query(?bool $skip_pagination = \false) : Builder { if ($skip_pagination) { $this->number_of_rows = null; } $views_table = Query::get_table_name(Query::VIEWS); $sessions_table = Query::get_table_name(Query::SESSIONS); $resources_table = Query::get_table_name(Query::RESOURCES); $orders_table = Query::get_table_name(Query::ORDERS); $database_sort_columns = ['title' => 'cached_title', 'url' => 'cached_url', 'author' => 'cached_author', 'type' => 'cached_type_label', 'date' => 'cached_date', 'category' => 'cached_category']; $sort_column = $this->sort_configuration->column(); foreach ($database_sort_columns as $key => $value) { if ($sort_column === $key) { $sort_column = $value; } } $orders_query = Illuminate_Builder::new(); $orders_query->select(['sessions.initial_view_id AS view_id'])->selectRaw('IFNULL(COUNT(DISTINCT orders.order_id), 0) AS wc_orders')->selectRaw('IFNULL(ROUND(CAST(SUM(orders.total) AS SIGNED)), 0) AS wc_gross_sales')->selectRaw('IFNULL(ROUND(CAST(SUM(orders.total_refunded) AS SIGNED)), 0) AS wc_refunded_amount')->selectRaw('IFNULL(SUM(orders.total_refunds), 0) AS wc_refunds')->from($orders_table, 'orders')->leftJoin($orders_query->raw($views_table . ' AS views'), function (JoinClause $join) { $join->on('orders.view_id', '=', 'views.id'); })->leftJoin($orders_query->raw($sessions_table . ' AS sessions'), function (JoinClause $join) { $join->on('views.session_id', '=', 'sessions.session_id'); })->where('orders.is_included_in_analytics', '=', \true)->whereBetween('orders.created_at', $this->get_current_period_iso_range())->groupBy('orders.view_id'); $pages_query = Illuminate_Builder::new(); $pages_query->select('resources.*')->selectRaw('COUNT(DISTINCT views.id) AS views')->selectRaw('COUNT(DISTINCT sessions.visitor_id) AS visitors')->selectRaw('COUNT(DISTINCT IF(initial_view.resource_id = resources.id, sessions.visitor_id, NULL)) AS landing_page_visitors')->selectRaw('COUNT(DISTINCT sessions.session_id) AS sessions')->selectRaw('COUNT(DISTINCT IF(sessions.final_view_id IS NULL, sessions.session_id, NULL)) AS bounces')->selectRaw('AVG(TIMESTAMPDIFF(SECOND, views.viewed_at, views.next_viewed_at)) AS average_view_duration')->selectRaw('COUNT(DISTINCT IF(resources.id = initial_view.resource_id, sessions.session_id, NULL)) AS entrances')->selectRaw('COUNT(DISTINCT IF((resources.id = final_view.resource_id OR (resources.id = initial_view.resource_id AND sessions.final_view_id IS NULL)), sessions.session_id, NULL)) AS exits')->selectRaw('COUNT(DISTINCT clicks.click_id) AS clicks')->selectRaw('IFNULL(SUM(the_orders.wc_orders), 0) AS wc_orders')->selectRaw('IFNULL(SUM(the_orders.wc_gross_sales), 0) AS wc_gross_sales')->selectRaw('IFNULL(SUM(the_orders.wc_refunded_amount), 0) AS wc_refunded_amount')->selectRaw('IFNULL(SUM(wc_refunds), 0) AS wc_refunds')->selectRaw('IFNULL(SUM(form_submissions.form_submissions), 0) AS form_submissions')->tap(function (Builder $query) { foreach (Form::get_forms() as $form) { $query->selectRaw("SUM(IF(form_submissions.form_id = ?, form_submissions.form_submissions, 0)) AS {$form->submissions_column()}", [$form->id()]); } })->from($views_table, 'views')->leftJoin($pages_query->raw($sessions_table . ' AS sessions'), function (JoinClause $join) { $join->on('views.session_id', '=', 'sessions.session_id'); })->leftJoin($pages_query->raw($resources_table . ' AS resources'), function (JoinClause $join) { $join->on('views.resource_id', '=', 'resources.id'); })->leftJoin($pages_query->raw($views_table . ' AS initial_view'), function (JoinClause $join) { $join->on('sessions.initial_view_id', '=', 'initial_view.id'); })->leftJoin($pages_query->raw($views_table . ' AS final_view'), function (JoinClause $join) { $join->on('sessions.final_view_id', '=', 'final_view.id'); })->leftJoin($pages_query->raw(Tables::clicks() . ' AS clicks'), function (JoinClause $join) { $join->on('clicks.view_id', '=', 'views.id'); })->leftJoinSub($orders_query, 'the_orders', function (JoinClause $join) { $join->on('the_orders.view_id', '=', 'views.id'); })->tap(Query_Taps::tap_authored_content_check(\false))->when($this->has_wp_comments_table(), function (Builder $query) { $query->selectRaw('IFNULL(comments.comments, 0) AS comments'); $query->leftJoinSub($this->get_comments_query(), 'comments', 'comments.resource_id', '=', 'resources.id'); }, function (Builder $query) { $query->selectRaw('0 AS comments'); })->leftJoinSub($this->get_form_submissions_query(), 'form_submissions', function (JoinClause $join) { $join->on('form_submissions.view_id', '=', 'views.id'); })->whereBetween('views.viewed_at', $this->get_current_period_iso_range())->when(!$this->appears_to_be_for_real_time_analytics(), function (Builder $query) { $query->whereBetween('sessions.created_at', $this->get_current_period_iso_range()); })->when(\count($this->filters) > 0, function (Builder $query) { foreach ($this->filters as $filter) { if (!$this->is_a_calculated_column($filter->column())) { $filter->apply_to_query($query); } } })->groupBy('resources.id')->having('views', '>', 0)->when(!$this->is_using_a_calculated_column(), function (Builder $query) use($sort_column) { $query->when($this->sort_configuration->is_column_nullable(), function (Builder $query) use($sort_column) { $query->orderByRaw("CASE WHEN {$sort_column} IS NULL THEN 1 ELSE 0 END"); })->orderBy($sort_column, $this->sort_configuration->direction())->orderBy('cached_title')->when(\is_int($this->number_of_rows), function (Builder $query) { $query->limit($this->number_of_rows); }); }); $previous_period_query = Illuminate_Builder::new(); $previous_period_query->select(['views.resource_id'])->selectRaw('COUNT(*) AS previous_period_views')->selectRaw('COUNT(DISTINCT sessions.visitor_id) AS previous_period_visitors')->from($views_table, 'views')->join($previous_period_query->raw($sessions_table . ' AS sessions'), 'views.session_id', '=', 'sessions.session_id')->whereBetween('views.viewed_at', $this->get_previous_period_iso_range())->whereBetween('sessions.created_at', $this->get_previous_period_iso_range())->groupBy('views.resource_id'); $outer_query = Illuminate_Builder::new(); $outer_query->selectRaw('pages.*')->selectRaw('IFNULL((views - previous_period_views) / previous_period_views * 100, 0) AS views_growth')->selectRaw('IFNULL((visitors - previous_period_visitors) / previous_period_visitors * 100, 0) AS visitors_growth')->selectRaw('IFNULL(bounces / sessions * 100, 0) AS bounce_rate')->selectRaw('IFNULL((exits / views) * 100, 0) AS exit_percent')->selectRaw('ROUND(CAST(wc_gross_sales - wc_refunded_amount AS SIGNED)) AS wc_net_sales')->selectRaw('IF(visitors = 0, 0, (wc_orders / landing_page_visitors) * 100) AS wc_conversion_rate')->selectRaw('IF(visitors = 0, 0, (wc_gross_sales - wc_refunded_amount) / landing_page_visitors) AS wc_earnings_per_visitor')->selectRaw('IF(wc_orders = 0, 0, ROUND(CAST(wc_gross_sales / wc_orders AS SIGNED))) AS wc_average_order_volume')->selectRaw('IF(visitors = 0, 0, (form_submissions / visitors) * 100) AS form_conversion_rate')->tap(function (Builder $query) { foreach (Form::get_forms() as $form) { $query->selectRaw("IF(visitors = 0, 0, ({$form->submissions_column()} / visitors) * 100) AS {$form->conversion_rate_column()}"); } })->when(\count($this->filters) > 0, function (Builder $query) { foreach ($this->filters as $filter) { if ($this->is_a_calculated_column($filter->column())) { $filter->apply_to_query($query); } } })->fromSub($pages_query, 'pages')->leftJoinSub($previous_period_query, 'previous_period_stats', 'pages.id', '=', 'previous_period_stats.resource_id')->when($this->is_using_a_calculated_column(), function (Builder $query) use($sort_column) { $query->when($this->sort_configuration->is_column_nullable(), function (Builder $query) use($sort_column) { $query->orderByRaw("CASE WHEN {$sort_column} IS NULL THEN 1 ELSE 0 END"); })->orderBy($sort_column, $this->sort_configuration->direction())->orderBy('cached_title')->when(\is_int($this->number_of_rows), function (Builder $query) { $query->limit($this->number_of_rows); }); }); return $outer_query; } private function get_comments_query() : Builder { global $wpdb; $comments_table = $wpdb->prefix . 'comments'; $resources_table = Query::get_table_name(Query::RESOURCES); $comments_query = Illuminate_Builder::new()->select(['resources.id AS resource_id'])->selectRaw('COUNT(*) AS comments')->from($comments_table, 'comments')->join($resources_table . " AS resources", 'comments.comment_post_ID', '=', 'resources.singular_id')->where('comments.comment_type', '=', 'comment')->where('comments.comment_approved', '=', '1')->whereBetween('comments.comment_date_gmt', $this->get_current_period_iso_range())->groupBy('resources.id'); return $comments_query; } } IAWP/Rows/Referrers.php000064400000017207147600331220010713 0ustar00joinSub($this->query(\true), 'referrer_rows', function (JoinClause $join) { $join->on('referrer_rows.referrer_id', '=', 'sessions.referrer_id'); }); } protected function fetch_rows() : array { $rows = $this->query()->get()->all(); return \array_map(function ($row) { return new Referrer($row); }, $rows); } private function query(?bool $skip_pagination = \false) : Builder { if ($skip_pagination) { $this->number_of_rows = null; } $views_table = Query::get_table_name(Query::VIEWS); $sessions_table = Query::get_table_name(Query::SESSIONS); $orders_table = Query::get_table_name(Query::ORDERS); $referrers_table = Query::get_table_name(Query::REFERRERS); $orders_query = Illuminate_Builder::new(); $orders_query->select(['orders.view_id AS view_id'])->selectRaw('IFNULL(COUNT(DISTINCT orders.order_id), 0) AS wc_orders')->selectRaw('IFNULL(ROUND(CAST(SUM(orders.total) AS SIGNED)), 0) AS wc_gross_sales')->selectRaw('IFNULL(ROUND(CAST(SUM(orders.total_refunded) AS SIGNED)), 0) AS wc_refunded_amount')->selectRaw('IFNULL(SUM(orders.total_refunds), 0) AS wc_refunds')->from($orders_table, 'orders')->where('orders.is_included_in_analytics', '=', \true)->whereBetween('orders.created_at', $this->get_current_period_iso_range())->groupBy('orders.view_id'); $referrers_query = Illuminate_Builder::new(); $referrers_query->select('sessions.referrer_id', 'referrer', 'type AS referrer_type', 'domain')->selectRaw('COUNT(DISTINCT views.id) AS views')->selectRaw('COUNT(DISTINCT sessions.visitor_id) AS visitors')->selectRaw('COUNT(DISTINCT sessions.session_id) AS sessions')->selectRaw('ROUND(AVG( TIMESTAMPDIFF(SECOND, sessions.created_at, sessions.ended_at))) AS average_session_duration')->selectRaw('COUNT(DISTINCT IF(sessions.final_view_id IS NULL, sessions.session_id, NULL)) AS bounces')->selectRaw('COUNT(DISTINCT clicks.click_id) AS clicks')->selectRaw('IFNULL(SUM(the_orders.wc_orders), 0) AS wc_orders')->selectRaw('IFNULL(SUM(the_orders.wc_gross_sales), 0) AS wc_gross_sales')->selectRaw('IFNULL(SUM(the_orders.wc_refunded_amount), 0) AS wc_refunded_amount')->selectRaw('IFNULL(SUM(the_orders.wc_refunds), 0) AS wc_refunds')->selectRaw('IFNULL(SUM(form_submissions.form_submissions), 0) AS form_submissions')->tap(function (Builder $query) { foreach (Form::get_forms() as $form) { $query->selectRaw("SUM(IF(form_submissions.form_id = ?, form_submissions.form_submissions, 0)) AS {$form->submissions_column()}", [$form->id()]); } })->from($views_table, 'views')->leftJoin($referrers_query->raw($sessions_table . ' AS sessions'), function (JoinClause $join) { $join->on('views.session_id', '=', 'sessions.session_id'); })->leftJoin($referrers_query->raw($referrers_table . ' AS referrers'), function (JoinClause $join) { $join->on('sessions.referrer_id', '=', 'referrers.id'); })->leftJoin($referrers_query->raw(Tables::clicks() . ' AS clicks'), function (JoinClause $join) { $join->on('clicks.view_id', '=', 'views.id'); })->leftJoinSub($orders_query, 'the_orders', function (JoinClause $join) { $join->on('the_orders.view_id', '=', 'views.id'); })->leftJoinSub($this->get_form_submissions_query(), 'form_submissions', function (JoinClause $join) { $join->on('form_submissions.view_id', '=', 'views.id'); })->whereBetween('views.viewed_at', $this->get_current_period_iso_range())->when(!$this->appears_to_be_for_real_time_analytics(), function (Builder $query) { $query->whereBetween('sessions.created_at', $this->get_current_period_iso_range()); })->tap(Query_Taps::tap_authored_content_check())->when(\count($this->filters) > 0, function (Builder $query) { foreach ($this->filters as $filter) { if (!$this->is_a_calculated_column($filter->column())) { $filter->apply_to_query($query); } } })->groupBy('sessions.referrer_id')->having('views', '>', 0)->when(!$this->is_using_a_calculated_column(), function (Builder $query) { $query->when($this->sort_configuration->is_column_nullable(), function (Builder $query) { $query->orderByRaw("CASE WHEN {$this->sort_configuration->column()} IS NULL THEN 1 ELSE 0 END"); })->orderBy($this->sort_configuration->column(), $this->sort_configuration->direction())->orderBy('referrer')->when(\is_int($this->number_of_rows), function (Builder $query) { $query->limit($this->number_of_rows); }); }); $previous_period_query = Illuminate_Builder::new(); $previous_period_query->select(['sessions.referrer_id'])->selectRaw('SUM(sessions.total_views) AS previous_period_views')->selectRaw('COUNT(DISTINCT sessions.visitor_id) AS previous_period_visitors')->from($sessions_table, 'sessions')->whereBetween('sessions.created_at', $this->get_previous_period_iso_range())->groupBy('sessions.referrer_id'); $outer_query = Illuminate_Builder::new(); $outer_query->selectRaw('referrers.*')->selectRaw('IF(sessions = 0, 0, views / sessions) AS views_per_session')->selectRaw('IFNULL((views - previous_period_views) / previous_period_views * 100, 0) AS views_growth')->selectRaw('IFNULL((visitors - previous_period_visitors) / previous_period_visitors * 100, 0) AS visitors_growth')->selectRaw('IFNULL(bounces / sessions * 100, 0) AS bounce_rate')->selectRaw('ROUND(CAST(wc_gross_sales - wc_refunded_amount AS SIGNED)) AS wc_net_sales')->selectRaw('IF(visitors = 0, 0, (wc_orders / visitors) * 100) AS wc_conversion_rate')->selectRaw('IF(visitors = 0, 0, (wc_gross_sales - wc_refunded_amount) / visitors) AS wc_earnings_per_visitor')->selectRaw('IF(wc_orders = 0, 0, ROUND(CAST(wc_gross_sales / wc_orders AS SIGNED))) AS wc_average_order_volume')->selectRaw('IF(visitors = 0, 0, (form_submissions / visitors) * 100) AS form_conversion_rate')->tap(function (Builder $query) { foreach (Form::get_forms() as $form) { $query->selectRaw("IF(visitors = 0, 0, ({$form->submissions_column()} / visitors) * 100) AS {$form->conversion_rate_column()}"); } })->when(\count($this->filters) > 0, function (Builder $query) { foreach ($this->filters as $filter) { if ($this->is_a_calculated_column($filter->column())) { $filter->apply_to_query($query); } } })->fromSub($referrers_query, 'referrers')->leftJoinSub($previous_period_query, 'previous_period_stats', 'referrers.referrer_id', '=', 'previous_period_stats.referrer_id')->when($this->is_using_a_calculated_column(), function (Builder $query) { $query->when($this->sort_configuration->is_column_nullable(), function (Builder $query) { $query->orderByRaw("CASE WHEN {$this->sort_configuration->column()} IS NULL THEN 1 ELSE 0 END"); })->orderBy($this->sort_configuration->column(), $this->sort_configuration->direction())->orderBy('referrer')->when(\is_int($this->number_of_rows), function (Builder $query) { $query->limit($this->number_of_rows); }); }); return $outer_query; } } IAWP/Rows/Rows.php000064400000006606147600331220007707 0ustar00date_range = $date_range; $this->number_of_rows = $number_of_rows; $this->filters = $filters ?? []; $this->sort_configuration = $sort_configuration ?? new Sort_Configuration('visitors'); } protected abstract function fetch_rows() : array; public abstract function attach_filters(Builder $query) : void; public function rows() { if (\is_array($this->rows)) { return $this->rows; } $this->rows = $this->fetch_rows(); return $this->rows; } /** * @return string[] */ protected function calculated_columns() : array { $calculated_columns = ['comments', 'exit_percent', 'views_per_session', 'views_growth', 'visitors_growth', 'bounce_rate', 'wc_net_sales', 'wc_conversion_rate', 'wc_earnings_per_visitor', 'wc_average_order_volume', 'form_conversion_rate']; foreach (Form::get_forms() as $form) { $calculated_columns[] = $form->conversion_rate_column(); } return $calculated_columns; } protected function is_a_calculated_column(string $column_name) : bool { return \in_array($column_name, $this->calculated_columns()); } protected function is_using_a_calculated_column() : bool { $is_using_a_calculated_column = \false; foreach ($this->filters as $filter) { if (\in_array($filter->column(), $this->calculated_columns())) { $is_using_a_calculated_column = \true; } } if (\in_array($this->sort_configuration->column(), $this->calculated_columns())) { $is_using_a_calculated_column = \true; } return $is_using_a_calculated_column; } protected function get_current_period_iso_range() : array { return [$this->date_range->iso_start(), $this->date_range->iso_end()]; } protected function appears_to_be_for_real_time_analytics() : bool { $difference_in_seconds = $this->date_range->end()->getTimestamp() - $this->date_range->start()->getTimestamp(); $one_hour_in_seconds = 3600; return $difference_in_seconds < $one_hour_in_seconds; } protected function get_previous_period_iso_range() : array { return [$this->date_range->previous_period()->iso_start(), $this->date_range->previous_period()->iso_end()]; } protected function get_form_submissions_query() : Builder { $form_submissions_table = Query::get_table_name(Query::FORM_SUBMISSIONS); return Illuminate_Builder::new()->select(['form_id', 'view_id'])->selectRaw('COUNT(*) AS form_submissions')->from($form_submissions_table, 'form_submissions')->whereBetween('created_at', $this->get_current_period_iso_range())->groupBy(['form_id', 'view_id']); } } IAWP/Statistics/Intervals/Daily.php000064400000001456147600331220013164 0ustar00setTime(0, 0, 0); return $date_time; } public function get_label_for(\DateTime $date_time) : array { return ['tick' => $this->format($date_time, 'M j'), 'tooltipLabel' => $this->format($date_time, 'F jS (l)')]; } } IAWP/Statistics/Intervals/Hourly.php000064400000002176147600331220013404 0ustar00setTime(\intval($date_time->format('G')), 0, 0); return $date_time; } public function get_label_for(\DateTime $date_time) : array { $date_format = 'F jS'; $time_format = \IAWPSCOPED\iawp()->get_option('time_format', 'g:i a'); $in_one_hour = (clone $date_time)->add(new \DateInterval('PT1H')); return ['tick' => $this->format($date_time, $time_format), 'tooltipLabel' => $this->format($date_time, $time_format) . " - " . $this->format($in_one_hour, $time_format) . $this->format($date_time, ' (' . $date_format . ')')]; } } IAWP/Statistics/Intervals/Interval.php000064400000001573147600331220013706 0ustar00id() === $interval->id(); } protected function format(\DateTime $date_time, string $format) { return \wp_date($format, $date_time->getTimestamp(), $date_time->getTimezone()); } } IAWP/Statistics/Intervals/Intervals.php000064400000002653147600331220014071 0ustar00id() === $interval_id) { return $interval; } } return new \IAWP\Statistics\Intervals\Daily(); } public static function default_for(int $days) : \IAWP\Statistics\Intervals\Interval { if ($days <= 3) { return new \IAWP\Statistics\Intervals\Hourly(); } elseif ($days <= 84) { return new \IAWP\Statistics\Intervals\Daily(); } elseif ($days <= 182) { return new \IAWP\Statistics\Intervals\Weekly(); } else { return new \IAWP\Statistics\Intervals\Monthly(); } } // public static function create_interval(?string $interval_id): Interval // { // // Switch case... // } } IAWP/Statistics/Intervals/Monthly.php000064400000001622147600331220013547 0ustar00setDate(\intval($date_time->format('Y')), \intval($date_time->format('m')), 1); $date_time->setTime(0, 0, 0); return $date_time; } public function get_label_for(\DateTime $date_time) : array { return ['tick' => $this->format($date_time, 'F'), 'tooltipLabel' => $this->format($date_time, 'F Y')]; } } IAWP/Statistics/Intervals/Weekly.php000064400000002505147600331220013356 0ustar00setTime(0, 0, 0); $start_of_week = \intval(\get_option('iawp_dow', 0)); $day_of_week = \intval($date_time->format('w')); $days_to_subtract = $day_of_week - $start_of_week; if ($days_to_subtract < 0) { $days_to_subtract = 7 - \abs($days_to_subtract); } $interval_to_subtract = new \DateInterval('P' . $days_to_subtract . "D"); $date_time->sub($interval_to_subtract); return $date_time; } public function get_label_for(\DateTime $date_time) : array { $in_six_days = (clone $date_time)->add(new \DateInterval('P6D')); return ['tick' => $this->format($date_time, 'M j'), 'tooltipLabel' => $this->format($date_time, 'F jS') . ' - ' . $this->format($in_six_days, 'F jS')]; } } IAWP/Statistics/Campaign_Statistics.php000064400000000334147600331220014076 0ustar00selectRaw('COUNT(DISTINCT link_rules.link_rule_id, clicks.click_target_id) AS total_table_rows')->from($this->tables::link_rules(), 'link_rules')->leftJoin($this->tables::clicked_links() . ' AS clicked_links', 'clicked_links.link_rule_id', '=', 'link_rules.link_rule_id')->leftJoin($this->tables::clicks() . ' AS clicks', 'clicks.click_id', '=', 'clicked_links.click_id')->leftJoin($this->tables::click_targets() . ' AS click_targets', 'click_targets.click_target_id', '=', 'clicks.click_target_id')->when(!\is_null($this->rows), function (Builder $query) { $this->rows->attach_filters($query); })->tap(Query_Taps::tap_authored_content_for_clicks())->whereBetween('clicks.created_at', [$this->date_range->iso_start(), $this->date_range->iso_end()]); return $query->value('total_table_rows'); } protected function make_statistic_instances() : array { return [$this->make_statistic(['id' => 'clicks', 'name' => \__('Clicks', 'independent-analytics'), 'plugin_group' => 'general'])]; } protected function query(Date_Range $range, ?Rows $rows = null, bool $is_grouped_by_date_interval = \false) { $utc_offset = Timezone::utc_offset(); $site_offset = Timezone::site_offset(); $query = Illuminate_Builder::new()->selectRaw('COUNT(DISTINCT clicks.click_id) AS clicks')->from($this->tables::link_rules(), 'link_rules')->leftJoin($this->tables::clicked_links() . ' AS clicked_links', 'clicked_links.link_rule_id', '=', 'link_rules.link_rule_id')->leftJoin($this->tables::clicks() . ' AS clicks', 'clicks.click_id', '=', 'clicked_links.click_id')->leftJoin($this->tables::click_targets() . ' AS click_targets', 'click_targets.click_target_id', '=', 'clicks.click_target_id')->when(!\is_null($rows), function (Builder $query) use($rows) { $rows->attach_filters($query); })->tap(Query_Taps::tap_authored_content_for_clicks())->whereBetween('clicks.created_at', [$range->iso_start(), $range->iso_end()])->when($is_grouped_by_date_interval, function (Builder $query) use($utc_offset, $site_offset) { if ($this->chart_interval->id() === 'daily') { $query->selectRaw("DATE(CONVERT_TZ(clicks.created_at, '{$utc_offset}', '{$site_offset}')) AS date"); } elseif ($this->chart_interval->id() === 'monthly') { $query->selectRaw("DATE_FORMAT(CONVERT_TZ(clicks.created_at, '{$utc_offset}', '{$site_offset}'), '%Y-%m-01 00:00:00') AS date"); } elseif ($this->chart_interval->id() === 'weekly') { $day_of_week = \IAWPSCOPED\iawp()->get_option('iawp_dow', 0) + 1; $query->selectRaw("\n IF (\n DAYOFWEEK(CONVERT_TZ(clicks.created_at, '{$utc_offset}', '{$site_offset}')) - {$day_of_week} < 0,\n DATE_FORMAT(SUBDATE(CONVERT_TZ(clicks.created_at, '{$utc_offset}', '{$site_offset}'), DAYOFWEEK(CONVERT_TZ(clicks.created_at, '{$utc_offset}', '{$site_offset}')) - {$day_of_week} + 7), '%Y-%m-%d 00:00:00'),\n DATE_FORMAT(SUBDATE(CONVERT_TZ(clicks.created_at, '{$utc_offset}', '{$site_offset}'), DAYOFWEEK(CONVERT_TZ(clicks.created_at, '{$utc_offset}', '{$site_offset}')) - {$day_of_week}), '%Y-%m-%d 00:00:00')\n ) AS date\n "); } else { $query->selectRaw("DATE_FORMAT(CONVERT_TZ(clicks.created_at, '{$utc_offset}', '{$site_offset}'), '%Y-%m-%d %H:00:00') AS date"); } $query->groupByRaw("date"); }); $results = \array_map(function (object $statistic) : object { return $this->clean_up_raw_statistic_row($statistic); }, $query->get()->all()); if (!$is_grouped_by_date_interval) { return $results[0]; } return $results; } } IAWP/Statistics/Country_Statistics.php000064400000000332147600331220014020 0ustar00id = $attributes['id']; $this->name = $attributes['name']; $this->plugin_group = $attributes['plugin_group']; $this->plugin_group_header = $attributes['plugin_group_header'] ?? null; $this->icon = $attributes['icon'] ?? null; $this->statistic = $attributes['statistic'] ?? 0; $this->previous_period_statistic = $attributes['previous_period_statistic'] ?? 0; $this->unfiltered_statistic = $attributes['unfiltered_statistic'] ?? null; $this->statistic_over_time = $attributes['statistic_over_time']; $this->is_visible_in_dashboard_widget = $attributes['is_visible_in_dashboard_widget'] ?? \false; $this->format = $attributes['format'] ?? null; $this->is_growth_good = $attributes['is_growth_good'] ?? \true; $this->is_subgroup_plugin_enabled = $attributes['is_subgroup_plugin_active'] ?? \true; $this->requires_pro = $attributes['requires_pro'] ?? \false; } public function is_enabled() : bool { if ($this->requires_pro === \true && \IAWPSCOPED\iawp_is_free()) { return \false; } return \true; } public function id() : string { return $this->id; } public function name() : string { return $this->name; } public function icon() : ?string { return $this->icon; } public function plugin_group() : string { return $this->plugin_group; } public function plugin_group_header() : ?string { return $this->plugin_group_header; } public function is_visible_in_dashboard_widget() : bool { return $this->is_visible_in_dashboard_widget; } public function statistic_over_time() : array { return $this->statistic_over_time; } public function is_group_plugin_enabled() : bool { switch ($this->plugin_group) { case "ecommerce": return \IAWPSCOPED\iawp()->is_ecommerce_support_enabled(); case "forms": return \IAWPSCOPED\iawp()->is_form_submission_support_enabled(); default: return \true; } } public function is_subgroup_plugin_enabled() : bool { return $this->is_subgroup_plugin_enabled; } public function is_visible() : bool { $options = Dashboard_Options::getInstance(); return \in_array($this->id(), $options->visible_quick_stats()); } public function is_member_of_plugin_group(string $plugin_group) : bool { return $this->plugin_group === $plugin_group; } public function formatted_value() : string { return $this->format_value($this->statistic); } public function value() { return $this->statistic; } public function formatted_unfiltered_value() : ?string { if (\is_null($this->unfiltered_statistic)) { return null; } return $this->format_value($this->unfiltered_statistic); } /** * Growth can be good or bad depending on the quick stat. This allows it to be calculated on a * at the individual quick stat level. * * The default behavior is "up" and "good" so you can tweak either of those as needed * * @return string */ public function growth_html_class() : string { $html_classes = []; $has_growth = $this->growth() >= 0; if (!$has_growth) { $html_classes[] = 'down'; } if ($has_growth && !$this->is_growth_good || !$has_growth && $this->is_growth_good) { $html_classes[] = 'bad'; } return \implode(' ', $html_classes); } public function formatted_growth() : string { $growth = $this->growth(); return Number_Formatter::percent(\absint($growth)); } public function growth() { if ($this->statistic == 0 && $this->previous_period_statistic != 0) { return -100; } elseif ($this->statistic == 0 || $this->previous_period_statistic == 0) { return 0; } $percent_growth = ($this->statistic / $this->previous_period_statistic - 1) * 100; return \round($percent_growth, 0); } private function format_value($value) : string { switch ($this->format) { case 'time': return Number_Formatter::second_to_minute_timestamp($value); case 'percent': return Number_Formatter::percent($value, 2); case 'decimal': return Number_Formatter::decimal($value, 2); case 'currency': return Currency::format($value, \false); case 'rounded-currency': return Currency::format($value, \true); default: return Number_Formatter::integer($value); } } } IAWP/Statistics/Statistics.php000064400000056106147600331220012307 0ustar00date_range = $date_range; $this->rows = $rows; $this->chart_interval = $chart_interval ?? Intervals::default_for($date_range->number_of_days()); if (\is_null($rows)) { $this->statistics = $this->query($this->date_range); $this->previous_period_statistics = $this->query($this->date_range->previous_period()); $this->statistics_grouped_by_date_interval = $this->query($this->date_range, null, \true); } else { $this->statistics = $this->query($this->date_range, $rows); $this->previous_period_statistics = $this->query($this->date_range->previous_period(), $rows); $this->statistics_grouped_by_date_interval = $this->query($this->date_range, $rows, \true); $this->unfiltered_statistics = $this->query($this->date_range); $this->previous_period_unfiltered_statistic = $this->query($this->date_range->previous_period()); $this->unfiltered_statistics_grouped_by_date_interval = $this->query($this->date_range, null, \true); } $this->statistic_instances = $this->make_statistic_instances(); $this->statistic_instances = \array_filter($this->statistic_instances, function (\IAWP\Statistics\Statistic $statistic) { return $statistic->is_enabled(); }); } /** * @return Statistic[] */ public function get_statistics() : array { return $this->statistic_instances; } public function get_grouped_statistics() { // This whole thing is a bit of a mess... return Collection::make($this->statistic_instances)->groupBy(function (\IAWP\Statistics\Statistic $item, int $key) { return Plugin_Group::get_plugin_group($item->plugin_group())->name(); })->map(function (Collection $group, $plugin_group) { $items = $group->map(function (\IAWP\Statistics\Statistic $item) { if (!$item->is_group_plugin_enabled()) { return null; } return ['id' => $item->id(), 'name' => $item->name()]; })->filter(); if ($items->isEmpty()) { return null; } return ['name' => $plugin_group, 'items' => $items->toArray()]; })->filter()->values()->toArray(); } public function get_statistic(string $statistic_id) : ?\IAWP\Statistics\Statistic { foreach ($this->statistic_instances as $statistic_instance) { if ($statistic_instance->id() == $statistic_id) { return $statistic_instance; } } return null; } public function has_filters() : bool { return !\is_null($this->rows); } public function chart_interval() : Interval { return $this->chart_interval; } /** * I'm sure there's more we could do here. If you get a result back where there isn't a full * page of results or where you're not paginating, then you can just count up the rows... * * @return int|null */ public function total_number_of_rows() : ?int { $sessions_table = Query::get_table_name(Query::SESSIONS); $views_table = Query::get_table_name(Query::VIEWS); $column = $this->total_table_rows_column() ?? $this->required_column(); $query = Illuminate_Builder::new()->selectRaw("COUNT(DISTINCT {$column}) AS total_table_rows")->from("{$sessions_table} AS sessions")->join("{$views_table} AS views", function (JoinClause $join) { $join->on('sessions.session_id', '=', 'views.session_id'); })->tap(Query_Taps::tap_authored_content_check(\true))->when(!\is_null($this->rows), function (Builder $query) { $this->rows->attach_filters($query); })->whereBetween('sessions.created_at', [$this->date_range->iso_start(), $this->date_range->iso_end()])->whereBetween('views.viewed_at', [$this->date_range->iso_start(), $this->date_range->iso_end()]); return $query->value('total_table_rows'); } /** * Define which id column to use to count up the total table rows. This is only required * for classes that don't have a required column and don't override required_column * * @return string|null */ protected function total_table_rows_column() : ?string { return null; } /** * Statistics can require that a column exists in order to be included. As an example, geos * requires visitors.country_code and campaigns requires sessions.campaign_id * * @return string|null */ protected function required_column() : ?string { return null; } /** * @return Statistic[] */ protected function make_statistic_instances() : array { $statistics = [$this->make_statistic(['id' => 'visitors', 'name' => \__('Visitors', 'independent-analytics'), 'plugin_group' => 'general', 'is_visible_in_dashboard_widget' => \true]), $this->make_statistic(['id' => 'views', 'name' => \__('Views', 'independent-analytics'), 'plugin_group' => 'general', 'is_visible_in_dashboard_widget' => \true]), $this->make_statistic(['id' => 'sessions', 'name' => \__('Sessions', 'independent-analytics'), 'plugin_group' => 'general']), $this->make_statistic(['id' => 'average_session_duration', 'name' => \__('Average Session Duration', 'independent-analytics'), 'plugin_group' => 'general', 'format' => 'time']), $this->make_statistic(['id' => 'bounce_rate', 'name' => \__('Bounce Rate', 'independent-analytics'), 'plugin_group' => 'general', 'format' => 'percent', 'is_growth_good' => \false, 'compute' => function (object $statistics) { return Calculations::percentage($statistics->bounces, $statistics->sessions); }]), $this->make_statistic(['id' => 'views_per_session', 'name' => \__('Views Per Session', 'independent-analytics'), 'plugin_group' => 'general', 'format' => 'decimal', 'compute' => function (object $statistics) { return Calculations::divide($statistics->total_views, $statistics->sessions, 2); }]), $this->make_statistic(['id' => 'clicks', 'name' => \__('Clicks', 'independent-analytics'), 'plugin_group' => 'general', 'requires_pro' => \true]), $this->make_statistic(['id' => 'wc_orders', 'name' => \__('Orders', 'independent-analytics'), 'plugin_group' => 'ecommerce', 'icon' => $this->get_ecommerce_icon()]), $this->make_statistic(['id' => 'wc_gross_sales', 'name' => \__('Gross Sales', 'independent-analytics'), 'plugin_group' => 'ecommerce', 'icon' => $this->get_ecommerce_icon(), 'format' => 'rounded-currency']), $this->make_statistic(['id' => 'wc_refunds', 'name' => \__('Refunds', 'independent-analytics'), 'plugin_group' => 'ecommerce', 'icon' => $this->get_ecommerce_icon()]), $this->make_statistic(['id' => 'wc_refunded_amount', 'name' => \__('Refunded Amount', 'independent-analytics'), 'plugin_group' => 'ecommerce', 'icon' => $this->get_ecommerce_icon(), 'format' => 'rounded-currency']), $this->make_statistic(['id' => 'wc_net_sales', 'name' => \__('Total Sales', 'independent-analytics'), 'plugin_group' => 'ecommerce', 'icon' => $this->get_ecommerce_icon(), 'format' => 'rounded-currency']), $this->make_statistic(['id' => 'wc_conversion_rate', 'name' => \__('Conversion Rate', 'independent-analytics'), 'plugin_group' => 'ecommerce', 'icon' => $this->get_ecommerce_icon(), 'format' => 'percent']), $this->make_statistic(['id' => 'wc_earnings_per_visitor', 'name' => \__('Earnings Per Visitor', 'independent-analytics'), 'plugin_group' => 'ecommerce', 'icon' => $this->get_ecommerce_icon(), 'format' => 'currency']), $this->make_statistic(['id' => 'wc_average_order_volume', 'name' => \__('Average Order Volume', 'independent-analytics'), 'plugin_group' => 'ecommerce', 'icon' => $this->get_ecommerce_icon(), 'format' => 'rounded-currency']), $this->make_statistic(['id' => 'form_submissions', 'name' => \__('Form Submissions', 'independent-analytics'), 'plugin_group' => 'forms']), $this->make_statistic(['id' => 'form_conversion_rate', 'name' => \__('Form Conversion Rate', 'independent-analytics'), 'plugin_group' => 'forms', 'format' => 'percent', 'compute' => function (object $statistics) { return Calculations::percentage($statistics->form_submissions, $statistics->visitors, 2); }])]; foreach (Form::get_forms() as $form) { if (!$form->is_plugin_active()) { continue; } $statistics[] = $this->make_statistic(['id' => 'form_submissions_for_' . $form->id(), 'name' => \sprintf(\_x('%s Submissions', 'Title of the contact form', 'independent-analytics'), $form->title()), 'plugin_group' => 'forms', 'is_subgroup_plugin_active' => $form->is_plugin_active(), 'plugin_group_header' => $form->plugin_name(), 'icon' => $form->icon()]); $statistics[] = $this->make_statistic(['id' => 'form_conversion_rate_for_' . $form->id(), 'name' => \sprintf(\_x('%s Conversion Rate', 'Title of the contact form', 'independent-analytics'), $form->title()), 'plugin_group' => 'forms', 'is_subgroup_plugin_active' => $form->is_plugin_active(), 'plugin_group_header' => $form->plugin_name(), 'icon' => $form->icon(), 'format' => 'percent', 'compute' => function (object $statistics) use($form) { $form_submission_id = 'form_submissions_for_' . $form->id(); return Calculations::percentage($statistics->{$form_submission_id}, $statistics->visitors, 2); }]); } return $statistics; } protected function make_statistic(array $attributes) : \IAWP\Statistics\Statistic { $statistic_id = $attributes['id']; if (!\array_key_exists('compute', $attributes)) { $attributes['compute'] = function ($statistics, $statistic_id) { return $statistics->{$statistic_id}; }; } $attributes['statistic'] = $attributes['compute']($this->statistics, $statistic_id); $attributes['previous_period_statistic'] = $attributes['compute']($this->previous_period_statistics, $statistic_id); $attributes['statistic_over_time'] = $this->fill_in_partial_day_range($this->statistics_grouped_by_date_interval, $attributes); $attributes['unfiltered_statistic'] = $this->has_filters() ? $attributes['compute']($this->unfiltered_statistics, $statistic_id) : null; return new \IAWP\Statistics\Statistic($attributes); } protected function query(Date_Range $range, ?Rows $rows = null, bool $is_grouped_by_date_interval = \false) { $utc_offset = Timezone::utc_offset(); $site_offset = Timezone::site_offset(); $sessions_table = Query::get_table_name(Query::SESSIONS); $views_table = Query::get_table_name(Query::VIEWS); $orders_table = Query::get_table_name(Query::ORDERS); $form_submissions_table = Query::get_table_name(Query::FORM_SUBMISSIONS); $form_submissions_query = Illuminate_Builder::new()->select(['form_id', 'session_id'])->selectRaw('COUNT(*) AS form_submissions')->from($form_submissions_table, 'form_submissions')->whereBetween('created_at', [$range->iso_start(), $range->iso_end()])->groupBy(['form_id', 'session_id']); $session_statistics = Illuminate_Builder::new(); $session_statistics->select('sessions.session_id')->selectRaw('COUNT(DISTINCT views.id) AS views')->selectRaw('COUNT(DISTINCT clicks.click_id) AS clicks')->selectRaw('COUNT(DISTINCT orders.order_id) AS orders')->selectRaw('IFNULL(CAST(SUM(orders.total) AS SIGNED), 0) AS gross_sales')->selectRaw('IFNULL(CAST(SUM(orders.total_refunded) AS SIGNED), 0) AS total_refunded')->selectRaw('IFNULL(CAST(SUM(orders.total_refunds) AS SIGNED), 0) AS total_refunds')->selectRaw('IFNULL(CAST(SUM(orders.total - orders.total_refunded) AS SIGNED), 0) AS net_sales')->from("{$sessions_table} AS sessions")->join("{$views_table} AS views", function (JoinClause $join) { $join->on('sessions.session_id', '=', 'views.session_id'); })->leftJoin("{$orders_table} AS orders", function (JoinClause $join) { $join->on('views.id', '=', 'orders.initial_view_id')->where('orders.is_included_in_analytics', '=', \true); })->leftJoin("{$this->tables::clicks()} AS clicks", function (JoinClause $join) { $join->on('views.id', '=', 'clicks.view_id'); })->tap(Query_Taps::tap_authored_content_check(\true))->when(!\is_null($rows), function (Builder $query) use($rows) { $rows->attach_filters($query); })->whereBetween('sessions.created_at', [$range->iso_start(), $range->iso_end()])->whereBetween('views.viewed_at', [$range->iso_start(), $range->iso_end()])->groupBy('sessions.session_id')->when(!\is_null($this->required_column()), function (Builder $query) { $query->whereNotNull($this->required_column()); }); $statistics = Illuminate_Builder::new(); $statistics->selectRaw('IFNULL(CAST(SUM(sessions.total_views) AS SIGNED), 0) AS total_views')->selectRaw('IFNULL(CAST(SUM(session_statistics.views) AS SIGNED), 0) AS views')->selectRaw('COUNT(DISTINCT sessions.visitor_id) AS visitors')->selectRaw('COUNT(DISTINCT sessions.session_id) AS sessions')->selectRaw('IFNULL(CAST(SUM(session_statistics.clicks) AS SIGNED), 0) AS clicks')->selectRaw('IFNULL(CAST(AVG(TIMESTAMPDIFF(SECOND, sessions.created_at, sessions.ended_at)) AS SIGNED), 0) AS average_session_duration')->selectRaw('COUNT(DISTINCT IF(sessions.final_view_id IS NULL, sessions.session_id, NULL)) AS bounces')->selectRaw('IFNULL(CAST(SUM(session_statistics.orders) AS SIGNED), 0) AS wc_orders')->selectRaw('IFNULL(CAST(SUM(session_statistics.gross_sales) AS SIGNED), 0) AS wc_gross_sales')->selectRaw('IFNULL(CAST(SUM(session_statistics.total_refunds) AS SIGNED), 0) AS wc_refunds')->selectRaw('IFNULL(CAST(SUM(session_statistics.total_refunded) AS SIGNED), 0) AS wc_refunded_amount')->selectRaw('IFNULL(CAST(SUM(session_statistics.net_sales) AS SIGNED), 0) AS wc_net_sales')->selectRaw('IFNULL(SUM(form_submissions.form_submissions), 0) AS form_submissions')->tap(function (Builder $query) { foreach (Form::get_forms() as $form) { $query->selectRaw('IFNULL(SUM(IF(form_submissions.form_id = ?, form_submissions.form_submissions, 0)), 0) AS ' . $form->submissions_column(), [$form->id()]); } })->from("{$sessions_table} AS sessions")->joinSub($session_statistics, 'session_statistics', function (JoinClause $join) { $join->on('sessions.session_id', '=', 'session_statistics.session_id'); })->leftJoinSub($form_submissions_query, 'form_submissions', 'sessions.session_id', '=', 'form_submissions.session_id')->whereBetween('sessions.created_at', [$range->iso_start(), $range->iso_end()])->when($is_grouped_by_date_interval, function (Builder $query) use($utc_offset, $site_offset) { if ($this->chart_interval->id() === 'daily') { $query->selectRaw("DATE(CONVERT_TZ(sessions.created_at, '{$utc_offset}', '{$site_offset}')) AS date"); } elseif ($this->chart_interval->id() === 'monthly') { $query->selectRaw("DATE_FORMAT(CONVERT_TZ(sessions.created_at, '{$utc_offset}', '{$site_offset}'), '%Y-%m-01 00:00:00') AS date"); } elseif ($this->chart_interval->id() === 'weekly') { $day_of_week = \IAWPSCOPED\iawp()->get_option('iawp_dow', 0) + 1; $query->selectRaw("\n IF (\n DAYOFWEEK(CONVERT_TZ(sessions.created_at, '{$utc_offset}', '{$site_offset}')) - {$day_of_week} < 0,\n DATE_FORMAT(SUBDATE(CONVERT_TZ(sessions.created_at, '{$utc_offset}', '{$site_offset}'), DAYOFWEEK(CONVERT_TZ(sessions.created_at, '{$utc_offset}', '{$site_offset}')) - {$day_of_week} + 7), '%Y-%m-%d 00:00:00'),\n DATE_FORMAT(SUBDATE(CONVERT_TZ(sessions.created_at, '{$utc_offset}', '{$site_offset}'), DAYOFWEEK(CONVERT_TZ(sessions.created_at, '{$utc_offset}', '{$site_offset}')) - {$day_of_week}), '%Y-%m-%d 00:00:00')\n ) AS date\n "); } else { $query->selectRaw("DATE_FORMAT(CONVERT_TZ(sessions.created_at, '{$utc_offset}', '{$site_offset}'), '%Y-%m-%d %H:00:00') AS date"); } $query->groupByRaw("date"); }); $outer_query = Illuminate_Builder::new()->selectRaw('statistics.*')->selectRaw('IF(statistics.visitors = 0, 0, (statistics.wc_orders / statistics.visitors) * 100) AS wc_conversion_rate')->selectRaw('IF(statistics.visitors = 0, 0, (statistics.wc_gross_sales - statistics.wc_refunded_amount) / visitors) AS wc_earnings_per_visitor')->selectRaw('IF(statistics.wc_orders = 0, 0, ROUND(CAST(statistics.wc_gross_sales / statistics.wc_orders AS DECIMAL(10, 2)))) AS wc_average_order_volume')->fromSub($statistics, 'statistics'); $results = \array_map(function (object $statistic) : object { return $this->clean_up_raw_statistic_row($statistic); }, $outer_query->get()->all()); if (!$is_grouped_by_date_interval) { return $results[0]; } return $results; } protected function clean_up_raw_statistic_row(object $statistic) : object { if (\property_exists($statistic, 'wc_gross_sales')) { $statistic->wc_gross_sales = \intval($statistic->wc_gross_sales); } if (\property_exists($statistic, 'wc_refunded_amount')) { $statistic->wc_refunded_amount = \intval($statistic->wc_refunded_amount); } if (\property_exists($statistic, 'wc_net_sales')) { $statistic->wc_net_sales = \intval($statistic->wc_net_sales); } if (\property_exists($statistic, 'wc_earnings_per_visitor')) { $statistic->wc_earnings_per_visitor = \intval($statistic->wc_earnings_per_visitor); } foreach ($statistic as $key => $value) { if (Str::startsWith($key, 'form_submissions')) { $statistic->{$key} = \intval($value); } } return $statistic; } /** * @param array $partial_day_range * @param array $attributes * * @return array */ private function fill_in_partial_day_range(array $partial_day_range, array $attributes) : array { $original_start = (clone $this->date_range->start())->setTimezone(Timezone::site_timezone()); $start = $this->chart_interval->calculate_start_of_interval_for($original_start); $original_end = (clone $this->date_range->end())->setTimezone(Timezone::site_timezone()); $end = $this->chart_interval->calculate_start_of_interval_for($original_end); $end->add(new DateInterval('PT1S')); $is_problematic_timezone = \in_array(Timezone::site_timezone()->getName(), ['Asia/Beirut', 'America/Santiago', 'America/Havana', 'America/Asuncion']); // Imagine a scenario where the offset for the start date is -4 and the offset for the // end date is -3. In that case, the DatePeriod is actually going to have its end date // short an hour, causing a date we care about to be chopped off the end. This code makes // sure that the end date is still the day after the last date we care about, so it // can get chopped off without consequence. if ($is_problematic_timezone) { $offset_difference = $end->getOffset() - $start->getOffset(); $interval = DateInterval::createFromDateString($offset_difference . ' seconds'); $end->add($interval); } $date_range = new DatePeriod($start, $this->chart_interval->date_interval(), $end); $filled_in_data = []; foreach ($date_range as $date) { // If the timezone switches at midnight, there will be a date where there is no midnight. It'll be something // like 1am instead. All dates after the day that switches will also be at 1am even though they have a // midnight. This alters those back to midnight, so they can be matched against correctly. if ($is_problematic_timezone && $date->format('H:i:s') === "01:00:00") { $date->setTime(0, 0, 0); } $stat = $this->get_statistic_for_date($partial_day_range, $date, $attributes); $filled_in_data[] = [$date, $stat]; } return $filled_in_data; } /** * @param array $partial_day_range * @param DateTime $datetime_to_match * @param array $attributes * * @return float|int */ private function get_statistic_for_date(array $partial_day_range, DateTime $datetime_to_match, array $attributes) { foreach ($partial_day_range as $day) { $date = $day->date; $value = $attributes['compute']($day, $attributes['id']); try { $datetime = new DateTime($date, Timezone::site_timezone()); } catch (Throwable $e) { return 0; } // Intentionally using non-strict equality to see if two distinct DateTime objects represent the same time if ($datetime == $datetime_to_match) { if (\is_string($value)) { if (\strpos($value, '.') !== \false) { return \floatval($value); } else { return \intval($value); } } return $value; } } return 0; } private function get_ecommerce_icon() : ?string { if (\IAWPSCOPED\iawp()->is_woocommerce_support_enabled() && !\IAWPSCOPED\iawp()->is_surecart_support_enabled()) { return 'woocommerce'; } if (\IAWPSCOPED\iawp()->is_surecart_support_enabled() && !\IAWPSCOPED\iawp()->is_woocommerce_support_enabled()) { return 'surecart'; } return null; } } IAWP/Tables/Columns/Column.php000064400000010726147600331220012110 0ustar00id = $attributes['id']; $this->name = $attributes['name']; $this->plugin_group = $attributes['plugin_group'] ?? 'general'; $this->plugin_group_header = $attributes['plugin_group_header'] ?? null; $this->visible = $attributes['visible'] ?? \false; $this->type = $attributes['type']; $this->exportable = $attributes['exportable'] ?? \true; $this->options = $attributes['options'] ?? []; $this->filter_placeholder = $attributes['filter_placeholder'] ?? ''; $this->unavailable_for = $attributes['unavailable_for'] ?? []; $this->database_column = $attributes['database_column'] ?? null; $this->is_nullable = $attributes['is_nullable'] ?? \false; $this->is_plugin_active = $attributes['is_subgroup_plugin_active'] ?? \true; $this->requires_pro = $attributes['requires_pro'] ?? \false; } public function is_enabled() : bool { if ($this->requires_pro === \true && \IAWPSCOPED\iawp_is_free()) { return \false; } return \true; } public function is_enabled_for_group(Group $group) : bool { return !\in_array($group->id(), $this->unavailable_for); } public function is_group_dependent() : bool { return \count($this->unavailable_for) > 0; } public function id() : string { return $this->id; } public function name() : string { return $this->name; } public function plugin_group() : string { return $this->plugin_group; } public function database_column() : string { return !\is_null($this->database_column) ? $this->database_column : $this->id; } public function is_group_plugin_enabled() : bool { switch ($this->plugin_group) { case "ecommerce": return \IAWPSCOPED\iawp()->is_ecommerce_support_enabled(); case "forms": return \IAWPSCOPED\iawp()->is_form_submission_support_enabled(); default: return \true; } } public function is_subgroup_plugin_enabled() : bool { return $this->is_plugin_active; } public function is_visible() : bool { return $this->visible; } public function is_member_of_plugin_group(string $plugin_group) : bool { return $this->plugin_group === $plugin_group; } public function plugin_group_header() : ?string { return $this->plugin_group_header; } public function type() : string { return $this->type; } /** * @return string[] */ public function filter_operators() : array { switch ($this->type) { case 'string': return ['contains', 'exact']; case 'date': return ['before', 'after', 'on']; case 'select': return ['is', 'isnt']; default: // int return ['greater', 'lesser', 'equal']; } } public function is_valid_filter_operator(string $operator) : bool { return \in_array($operator, $this->filter_operators()); } public function sort_direction() : string { $descending_types = ['int', 'date']; return \in_array($this->type, $descending_types) ? 'desc' : 'asc'; } public function set_visibility(bool $visible) : void { $this->visible = $visible; } public function exportable() : bool { return $this->exportable; } /** * @return array List of possible options for this filter such as a list of authors or list of post categories */ public function options() : array { return $this->options; } public function filter_placeholder() : string { return $this->filter_placeholder; } public function is_nullable() : bool { return $this->is_nullable; } } IAWP/Tables/Groups/Group.php000064400000001661147600331220011604 0ustar00id = $id; $this->singular = $singular; $this->rows_class = $rows_class; $this->statistics_class = $statistics_class; } public function id() : string { return $this->id; } public function singular() : string { return $this->singular; } /** * @return class-string */ public function rows_class() : string { return $this->rows_class; } /** * @return class-string */ public function statistics_class() : string { return $this->statistics_class; } } IAWP/Tables/Groups/Groups.php000064400000002547147600331220011773 0ustar00groups = $groups; } public function add(\IAWP\Tables\Groups\Group $group) : void { $this->groups[] = $group; } public function find_by_id(?string $id = null) : \IAWP\Tables\Groups\Group { if (\is_null($id)) { return $this->default_group(); } $array = \array_filter($this->groups(), function ($group) use($id) { return $group->id() === $id; }); $match = \reset($array); return $match === \false ? $this->default_group() : $match; } /** * Return an array of groups representing buttons one can select * * @return Group[] */ public function buttons() : array { if ($this->has_grouping_options()) { return []; } else { return $this->groups(); } } public function has_grouping_options() : bool { return \count($this->groups()) > 1; } /** * @return Group[] */ public function groups() : array { return $this->groups; } private function default_group() : \IAWP\Tables\Groups\Group { return $this->groups()[0]; } } IAWP/Tables/Table.php000064400000056475147600331220010275 0ustar00visible_columns = Dashboard_Options::getInstance()->visible_columns(); $this->group = $this->groups()->find_by_id($group_id); $this->is_new_group = $is_new_group; $this->filters = new Filters(); } protected abstract function groups() : Groups; /** * @return array */ protected abstract function local_columns() : array; protected abstract function table_name() : string; public function visible_column_ids() { $visible_columns = []; foreach ($this->get_columns() as $column) { if ($column->is_visible()) { $visible_columns[] = $column->id(); } } return $visible_columns; } public function group() : Group { return $this->group; } public function column_picker_html() : string { return \IAWPSCOPED\iawp_blade()->run('plugin-group-options', ['option_type' => 'columns', 'option_name' => \__('Toggle Columns', 'independent-analytics'), 'option_icon' => 'columns', 'plugin_groups' => Plugin_Group::get_plugin_groups(), 'options' => $this->get_columns(\true)]); } public function get_table_toolbar_markup() { return \IAWPSCOPED\iawp_blade()->run('tables.table-toolbar', ['plugin_groups' => Plugin_Group::get_plugin_groups(), 'columns' => $this->get_columns(\true), 'groups' => $this->groups(), 'current_group' => $this->group()]); } public function get_table_markup(string $sort_column, string $sort_direction) { return \IAWPSCOPED\iawp_blade()->run('tables.table', ['table' => $this, 'table_name' => $this->table_name(), 'all_columns' => $this->get_columns(), 'visible_column_count' => $this->visible_column_count(), 'number_of_shown_rows' => 0, 'rows' => [], 'render_skeleton' => \true, 'page_size' => \IAWPSCOPED\iawp()->pagination_page_size(), 'sort_column' => $sort_column, 'sort_direction' => $sort_direction, 'has_campaigns' => Campaign_Builder::has_campaigns()]); } public function set_statistics(Statistics $statistics) { $this->statistics = $statistics; } public function get_row_data_attributes($row) { $html = ''; foreach ($this->get_columns() as $column) { $id = $column->id(); $data_val = $row->{$id}(); $html .= ' data-' . \esc_attr($column->id()) . '="' . \esc_attr($data_val) . '"'; } return $html; } public function get_cell_content($row, Column $column) { $column_id = $column->id(); if (\is_null($row->{$column_id}())) { return '-'; } if ($column_id == 'title' && $row->is_deleted()) { return Security::string($row->{$column_id}()) . ' ' . \esc_html__('(deleted)', 'independent-analytics') . ''; } elseif ($column_id == 'views') { $views = Number_Formatter::decimal($row->views()); // Getting a divide by zero error from the line below? // It's likely an issue with $this->views which is an instance of Views. Make sure the queries there are working. $views_percentage = Number_Formatter::percent($row->views() / $this->statistics->get_statistic('views')->value() * 100, 2); return '' . Security::string($views) . ' (' . Security::string($views_percentage) . ')'; } elseif ($column_id == 'visitors') { $visitors = Number_Formatter::decimal($row->visitors()); $visitors_percentage = Number_Formatter::percent($row->visitors() / $this->statistics->get_statistic('visitors')->value() * 100, 2); return '' . Security::string($visitors) . ' (' . Security::string($visitors_percentage) . ')'; } elseif ($column_id == 'sessions') { $sessions = Number_Formatter::decimal($row->sessions()); $sessions_percentage = Number_Formatter::percent($row->sessions() / $this->statistics->get_statistic('sessions')->value() * 100, 2); return '' . Security::string($sessions) . ' (' . Security::string($sessions_percentage) . ')'; } elseif ($column_id === 'entrances') { $entrances = Number_Formatter::decimal($row->entrances()); $entrances_percentage = Number_Formatter::percent($row->entrances() / $this->statistics->get_statistic('sessions')->value() * 100, 2); return '' . Security::string($entrances) . ' (' . Security::string($entrances_percentage) . ')'; } elseif ($column_id === 'exits') { $exits = Number_Formatter::decimal($row->exits()); $exits_percentage = Number_Formatter::percent($row->exits() / $this->statistics->get_statistic('sessions')->value() * 100, 2); return '' . Security::string($exits) . ' (' . Security::string($exits_percentage) . ')'; } elseif ($column_id === 'bounce_rate') { return Security::string(Number_Formatter::percent($row->bounce_rate())); } elseif ($column_id === 'average_session_duration' || $column_id === 'average_view_duration') { return Number_Formatter::second_to_minute_timestamp($row->{$column_id}()); } elseif ($column_id === 'views_growth' || $column_id === 'visitors_growth' || $column_id === 'wc_conversion_rate' || $column_id === 'exit_percent' || Str::startsWith($column_id, 'form_conversion_rate')) { return Number_Formatter::percent($row->{$column_id}(), 2); } elseif ($column_id == 'url') { if ($row->is_deleted()) { return \urldecode(\esc_url($row->url())); } else { return '' . \urldecode(\esc_url($row->url())) . ''; } } elseif ($column_id == 'author') { return Security::html($row->avatar()) . ' ' . Security::string($row->author()); } elseif ($column_id == 'date') { return Security::string(\date(WordPress_Site_Date_Format_Pattern::for_php(), \strtotime($row->date()))); } elseif ($column_id == 'type' && \method_exists($row, 'icon') && \method_exists($row, 'type')) { return $row->icon(0) . ' ' . Security::string($row->type()); } elseif ($column_id == 'referrer' && $row->has_link()) { return '' . Security::string($row->referrer()) . ''; } elseif ($column_id === 'device_type') { return Icon_Directory_Factory::device_types()->find($row->device_type()) . Security::string($row->device_type()); } elseif ($column_id === 'browser') { return Icon_Directory_Factory::browsers()->find($row->browser()) . Security::string($row->browser()); } elseif ($column_id === 'os') { return Icon_Directory_Factory::operating_systems()->find($row->os()) . Security::string($row->os()); } elseif ($column_id === 'country') { return Icon_Directory_Factory::flags()->find($row->country_code()) . Security::string($row->country()); } elseif ($column_id === 'wc_gross_sales' || $column_id === 'wc_refunded_amount' || $column_id === 'wc_net_sales' || $column_id === 'wc_average_order_volume') { return Security::string(Currency::format($row->{$column_id}())); } elseif ($column_id === 'wc_earnings_per_visitor') { return Security::string(Currency::format($row->{$column_id}(), \false)); } elseif ($column_id === 'views_per_session') { return Number_Formatter::decimal($row->{$column_id}(), 2); } elseif ($column_id === 'link_target') { $value = $row->{$column_id}(); if (!\is_string($value)) { return $value; } $url = new URL($value); if ($url->is_valid_url()) { return '' . Security::string($value) . ''; } return $value; } else { return Security::string($row->{$column_id}()); } } public function output_report_toolbar() { $options = Dashboard_Options::getInstance(); $start = $options->get_date_range()->start()->setTimezone(Timezone::site_timezone()); $end = $options->get_date_range()->end()->setTimezone(Timezone::site_timezone()); ?>
filters()->get_filters_html($this->get_columns()); ?>
filters()->get_condition_html($this->get_columns()); } public function filters_condition_buttons_html(array $filters) : string { return $this->filters()->condition_buttons_html($filters); } public final function csv(array $rows, bool $is_dashboard_export = \false) : CSV { $columns = $this->get_columns(); $csv_header = []; $csv_rows = []; foreach ($columns as $column) { if (!$this->include_column_in_csv($column, $is_dashboard_export)) { continue; } $csv_header[] = $column->name(); } foreach ($rows as $row) { $csv_row = []; foreach ($columns as $column) { if (!$this->include_column_in_csv($column, $is_dashboard_export)) { continue; } $column_id = $column->id(); $value = $row->{$column_id}(); // Todo - This logic is similar to the rendering logic for table cells. This should // all be handled via the column class itself. if (\is_null($value)) { $csv_row[] = '-'; } elseif ($column_id === 'date') { $csv_row[] = \date(WordPress_Site_Date_Format_Pattern::for_php(), \strtotime($value)); } elseif ($column_id === 'average_session_duration' || $column_id === 'average_view_duration') { $csv_row[] = Number_Formatter::second_to_minute_timestamp($value); } elseif ($column_id === 'views_per_session') { $csv_row[] = Number_Formatter::decimal($value, 2); } else { $csv_row[] = $row->{$column_id}(); } } $csv_rows[] = $csv_row; } $csv = new CSV($csv_header, $csv_rows); return $csv; } /** * @param array[] $filters Raw filter associative arrays * * @return Filter[] */ public function sanitize_filters(array $filters) : array { return \array_values(\array_filter(\array_map(function ($filter) { return $this->sanitize_filter($filter); }, $filters))); } public function sanitize_filter(array $filter) : ?Filter { $column = $this->get_column($filter['column']); if (\is_null($column)) { return null; } $valid_inclusions = ['include', 'exclude']; if (!\in_array($filter['inclusion'], $valid_inclusions)) { return null; } if (!$column->is_valid_filter_operator($filter['operator'])) { return null; } if (!$column->is_enabled_for_group($this->group())) { return null; } $operand = \trim(Security::string($filter['operand'])); if (\strlen($operand) === 0) { return null; } if ($column->database_column() === 'cached_url' && $filter['operator'] === 'exact') { $url = new URL($filter['operand']); if (!$url->is_valid_url()) { $filter['operand'] = \site_url($filter['operand']); } } // Link rules can be archived and then deleted by the user. That means that there's a very // reasonable chance that a report is filtering by an id for a rule that's since been // removed. We need to check and make sure that filters link rules still exist. if ($column->id() === 'link_name') { $match = \false; foreach ($column->options() as $option) { if ((int) $option[0] === (int) $filter['operand']) { $match = \true; } } if (!$match) { return null; } } return new Filter(['inclusion' => Security::string($filter['inclusion']), 'column' => $column->id(), 'operator' => Security::string($filter['operator']), 'operand' => Security::string($filter['operand']), 'database_column' => $column->database_column()]); } public function get_column(string $id) : ?Column { $matches = \array_filter($this->local_columns(), function (Column $column) use($id) { return $column->id() === $id; }); $column = \count($matches) === 1 ? \reset($matches) : null; if (\is_null($column) || !$column->is_enabled()) { return null; } return $column; } public function sanitize_sort_parameters(?string $sort_column = null, ?string $sort_direction = 'desc') : Sort_Configuration { if (\is_null($sort_column)) { return new Sort_Configuration($this->default_sorting_column); } $column = $this->get_column($sort_column); if (\is_null($column) || !$column->is_enabled_for_group($this->group)) { return new Sort_Configuration($this->default_sorting_column); } return new Sort_Configuration($sort_column, $sort_direction, $column->is_nullable()); } public function get_rendered_template(array $rows, bool $just_rows, string $sort_column, string $sort_direction) { if ($just_rows) { return \IAWPSCOPED\iawp_blade()->run('tables.rows', ['table' => $this, 'table_name' => $this->table_name(), 'all_columns' => $this->get_columns(), 'visible_column_count' => $this->visible_column_count(), 'number_of_shown_rows' => \count($rows), 'rows' => $rows, 'render_skeleton' => \false, 'page_size' => \IAWPSCOPED\iawp()->pagination_page_size(), 'sort_column' => $sort_column, 'sort_direction' => $sort_direction, 'has_campaigns' => Campaign_Builder::has_campaigns()]); } return \IAWPSCOPED\iawp_blade()->run('tables.table', ['table' => $this, 'table_name' => $this->table_name(), 'all_columns' => $this->get_columns(), 'visible_column_count' => $this->visible_column_count(), 'number_of_shown_rows' => \count($rows), 'rows' => $rows, 'render_skeleton' => \false, 'page_size' => \IAWPSCOPED\iawp()->pagination_page_size(), 'sort_column' => $sort_column, 'sort_direction' => $sort_direction, 'has_campaigns' => Campaign_Builder::has_campaigns()]); } protected function get_woocommerce_columns() : array { return [new Column(['id' => 'wc_orders', 'name' => \__('Orders', 'independent-analytics'), 'plugin_group' => 'ecommerce', 'type' => 'int']), new Column(['id' => 'wc_gross_sales', 'name' => \__('Gross Sales', 'independent-analytics'), 'plugin_group' => 'ecommerce', 'type' => 'int']), new Column(['id' => 'wc_refunds', 'name' => \__('Refunds', 'independent-analytics'), 'plugin_group' => 'ecommerce', 'type' => 'int']), new Column(['id' => 'wc_refunded_amount', 'name' => \__('Refunded Amount', 'independent-analytics'), 'plugin_group' => 'ecommerce', 'type' => 'int']), new Column(['id' => 'wc_net_sales', 'name' => \__('Total Sales', 'independent-analytics'), 'plugin_group' => 'ecommerce', 'type' => 'int']), new Column(['id' => 'wc_conversion_rate', 'name' => \__('Conversion Rate', 'independent-analytics'), 'plugin_group' => 'ecommerce', 'type' => 'int']), new Column(['id' => 'wc_earnings_per_visitor', 'name' => \__('Earnings Per Visitor', 'independent-analytics'), 'plugin_group' => 'ecommerce', 'type' => 'int']), new Column(['id' => 'wc_average_order_volume', 'name' => \__('Average Order Volume', 'independent-analytics'), 'plugin_group' => 'ecommerce', 'type' => 'int'])]; } protected function get_form_columns() : array { $columns = [new Column(['id' => 'form_submissions', 'name' => \__('Submissions', 'independent-analytics'), 'plugin_group' => 'forms', 'type' => 'int']), new Column(['id' => 'form_conversion_rate', 'name' => \__('Conversion Rate', 'independent-analytics'), 'plugin_group' => 'forms', 'type' => 'int'])]; foreach (Form::get_forms() as $form) { $columns[] = new Column(['id' => $form->submissions_column(), 'name' => $form->title() . ' ' . \__('Submissions', 'independent-analytics'), 'plugin_group' => 'forms', 'is_subgroup_plugin_active' => $form->is_plugin_active(), 'plugin_group_header' => $form->plugin_name(), 'type' => 'int']); $columns[] = new Column(['id' => $form->conversion_rate_column(), 'name' => $form->title() . ' ' . \__('Conversion Rate', 'independent-analytics'), 'plugin_group' => 'forms', 'is_subgroup_plugin_active' => $form->is_plugin_active(), 'plugin_group_header' => $form->plugin_name(), 'type' => 'int']); } return $columns; } private function include_column_in_csv(Column $column, bool $is_dashboard_export) : bool { if (!$column->is_visible() && $is_dashboard_export) { return \false; } if (!$column->exportable() && !$is_dashboard_export) { return \false; } if (!$column->is_group_plugin_enabled()) { return \false; } return \true; } /** * @return Column[] */ private function get_columns($show_disabled_columns = \false) : array { $columns_for_group = \array_filter($this->local_columns(), function (Column $column) { return $column->is_enabled() && $column->is_enabled_for_group($this->group) && $column->is_subgroup_plugin_enabled(); }); if ($show_disabled_columns === \true) { } else { $columns_for_group = \array_filter($columns_for_group, function (Column $column) { return $column->is_group_plugin_enabled(); }); } if (\is_null($this->visible_columns) || \count($this->visible_columns) === 0) { return $columns_for_group; } if (!$this->is_new_group) { return \array_map(function ($column) { $column->set_visibility(\in_array($column->id(), $this->visible_columns)); return $column; }, $columns_for_group); } return \array_map(function ($column) { if ($column->is_group_dependent()) { $column->set_visibility(\true); } elseif (!\in_array($column->id(), $this->visible_columns)) { $column->set_visibility(\false); } return $column; }, $columns_for_group); } /** * Get the number of visible columns * * @return int */ private function visible_column_count() : int { $visible_columns = 0; foreach ($this->get_columns() as $column) { if ($column->is_visible()) { $visible_columns++; } } return $visible_columns; } private function filters() { return $this->filters; } } IAWP/Tables/Table_Campaigns.php000064400000005225147600331220012242 0ustar00 'title', 'name' => \__('Landing Page', 'independent-analytics'), 'visible' => \true, 'type' => 'string']), new Column(['id' => 'utm_source', 'name' => \__('Source', 'independent-analytics'), 'visible' => \true, 'type' => 'string']), new Column(['id' => 'utm_medium', 'name' => \__('Medium', 'independent-analytics'), 'visible' => \true, 'type' => 'string']), new Column(['id' => 'utm_campaign', 'name' => \__('Campaign', 'independent-analytics'), 'visible' => \true, 'type' => 'string']), new Column(['id' => 'utm_term', 'name' => \__('Term', 'independent-analytics'), 'type' => 'string', 'is_nullable' => \true]), new Column(['id' => 'utm_content', 'name' => \__('Content', 'independent-analytics'), 'type' => 'string', 'is_nullable' => \true]), new Column(['id' => 'visitors', 'name' => \__('Visitors', 'independent-analytics'), 'visible' => \true, 'type' => 'int']), new Column(['id' => 'views', 'name' => \__('Views', 'independent-analytics'), 'visible' => \true, 'type' => 'int']), new Column(['id' => 'sessions', 'name' => \__('Sessions', 'independent-analytics'), 'type' => 'int']), new Column(['id' => 'average_session_duration', 'name' => \__('Session Duration', 'independent-analytics'), 'visible' => \true, 'type' => 'int', 'filter_placeholder' => 'Seconds']), new Column(['id' => 'views_per_session', 'name' => \__('Views Per Session', 'independent-analytics'), 'type' => 'int']), new Column(['id' => 'bounce_rate', 'name' => \__('Bounce Rate', 'independent-analytics'), 'visible' => \true, 'type' => 'int']), new Column(['id' => 'visitors_growth', 'name' => \__('Visitors Growth', 'independent-analytics'), 'type' => 'int', 'exportable' => \false]), new Column(['id' => 'views_growth', 'name' => \__('Views Growth', 'independent-analytics'), 'type' => 'int', 'exportable' => \false]), new Column(['id' => 'clicks', 'name' => \__('Clicks', 'independent-analytics'), 'type' => 'int', 'requires_pro' => \true])]; return \array_merge($columns, $this->get_woocommerce_columns(), $this->get_form_columns()); } } IAWP/Tables/Table_Clicks.php000064400000002335147600331220011547 0ustar00 'link_name', 'name' => \__('Link Pattern', 'independent-analytics'), 'visible' => \true, 'type' => 'select', 'options' => Link_Name_Filter_List::options(), 'database_column' => 'link_rules.link_rule_id']), new Column(['id' => 'link_target', 'name' => \__('Target', 'independent-analytics'), 'visible' => \true, 'type' => 'string']), new Column(['id' => 'link_clicks', 'name' => \__('Clicks', 'independent-analytics'), 'visible' => \true, 'type' => 'int'])]; return $columns; } } IAWP/Tables/Table_Devices.php000064400000006372147600331220011726 0ustar00 'device_type', 'name' => \__('Type', 'independent-analytics'), 'visible' => \true, 'type' => 'select', 'options' => Device_Type_Filter_List::options(), 'database_column' => 'device_types.device_type_id', 'unavailable_for' => ['browser', 'os']]), new Column(['id' => 'os', 'name' => \__('Operating System', 'independent-analytics'), 'visible' => \true, 'type' => 'select', 'options' => Device_OS_Filter_List::options(), 'database_column' => 'device_oss.device_os_id', 'unavailable_for' => ['device_type', 'browser']]), new Column(['id' => 'browser', 'name' => \__('Browser', 'independent-analytics'), 'visible' => \true, 'type' => 'select', 'options' => Device_Browser_Filter_List::options(), 'database_column' => 'device_browsers.device_browser_id', 'unavailable_for' => ['device_type', 'os']]), new Column(['id' => 'visitors', 'name' => \__('Visitors', 'independent-analytics'), 'visible' => \true, 'type' => 'int']), new Column(['id' => 'views', 'name' => \__('Views', 'independent-analytics'), 'visible' => \true, 'type' => 'int']), new Column(['id' => 'sessions', 'name' => \__('Sessions', 'independent-analytics'), 'type' => 'int']), new Column(['id' => 'average_session_duration', 'name' => \__('Session Duration', 'independent-analytics'), 'visible' => \true, 'type' => 'int', 'filter_placeholder' => 'Seconds']), new Column(['id' => 'views_per_session', 'name' => \__('Views Per Session', 'independent-analytics'), 'type' => 'int']), new Column(['id' => 'bounce_rate', 'name' => \__('Bounce Rate', 'independent-analytics'), 'visible' => \true, 'type' => 'int']), new Column(['id' => 'visitors_growth', 'name' => \__('Visitors Growth', 'independent-analytics'), 'type' => 'int', 'exportable' => \false]), new Column(['id' => 'views_growth', 'name' => \__('Views Growth', 'independent-analytics'), 'type' => 'int', 'exportable' => \false]), new Column(['id' => 'clicks', 'name' => \__('Clicks', 'independent-analytics'), 'type' => 'int', 'requires_pro' => \true])]; return \array_merge($columns, $this->get_woocommerce_columns(), $this->get_form_columns()); } } IAWP/Tables/Table_Geo.php000064400000005133147600331220011050 0ustar00 'continent', 'name' => \__('Continent', 'independent-analytics'), 'type' => 'string']), new Column(['id' => 'country', 'name' => \__('Country', 'independent-analytics'), 'visible' => \true, 'type' => 'string']), new Column(['id' => 'subdivision', 'name' => \__('Subdivision', 'independent-analytics'), 'visible' => \true, 'type' => 'string', 'unavailable_for' => ['country']]), new Column(['id' => 'city', 'name' => \__('City', 'independent-analytics'), 'visible' => \true, 'type' => 'string', 'unavailable_for' => ['country']]), new Column(['id' => 'visitors', 'name' => \__('Visitors', 'independent-analytics'), 'visible' => \true, 'type' => 'int']), new Column(['id' => 'views', 'name' => \__('Views', 'independent-analytics'), 'visible' => \true, 'type' => 'int']), new Column(['id' => 'sessions', 'name' => \__('Sessions', 'independent-analytics'), 'type' => 'int']), new Column(['id' => 'average_session_duration', 'name' => \__('Session Duration', 'independent-analytics'), 'visible' => \true, 'type' => 'int', 'filter_placeholder' => 'Seconds']), new Column(['id' => 'views_per_session', 'name' => \__('Views Per Session', 'independent-analytics'), 'type' => 'int']), new Column(['id' => 'bounce_rate', 'name' => \__('Bounce Rate', 'independent-analytics'), 'visible' => \true, 'type' => 'int']), new Column(['id' => 'visitors_growth', 'name' => \__('Visitors Growth', 'independent-analytics'), 'type' => 'int', 'exportable' => \false]), new Column(['id' => 'views_growth', 'name' => \__('Views Growth', 'independent-analytics'), 'type' => 'int', 'exportable' => \false]), new Column(['id' => 'clicks', 'name' => \__('Clicks', 'independent-analytics'), 'type' => 'int', 'requires_pro' => \true])]; return \array_merge($columns, $this->get_woocommerce_columns(), $this->get_form_columns()); } } IAWP/Tables/Table_Pages.php000064400000006635147600331220011405 0ustar00 'title', 'name' => \__('Title', 'independent-analytics'), 'visible' => \true, 'type' => 'string', 'database_column' => 'cached_title']), new Column(['id' => 'visitors', 'name' => \__('Visitors', 'independent-analytics'), 'visible' => \true, 'type' => 'int']), new Column(['id' => 'views', 'name' => \__('Views', 'independent-analytics'), 'visible' => \true, 'type' => 'int']), new Column(['id' => 'sessions', 'name' => \__('Sessions', 'independent-analytics'), 'type' => 'int']), new Column(['id' => 'average_view_duration', 'name' => \__('View Duration', 'independent-analytics'), 'visible' => \true, 'type' => 'int', 'filter_placeholder' => 'Seconds']), new Column(['id' => 'bounce_rate', 'name' => \__('Bounce Rate', 'independent-analytics'), 'visible' => \true, 'type' => 'int']), new Column(['id' => 'visitors_growth', 'name' => \__('Visitors Growth', 'independent-analytics'), 'type' => 'int', 'exportable' => \false]), new Column(['id' => 'views_growth', 'name' => \__('Views Growth', 'independent-analytics'), 'type' => 'int', 'exportable' => \false]), new Column(['id' => 'entrances', 'name' => \__('Entrances', 'independent-analytics'), 'type' => 'int']), new Column(['id' => 'exits', 'name' => \__('Exits', 'independent-analytics'), 'type' => 'int']), new Column(['id' => 'exit_percent', 'name' => \__('Exit Rate', 'independent-analytics'), 'type' => 'int']), new Column(['id' => 'clicks', 'name' => \__('Clicks', 'independent-analytics'), 'type' => 'int', 'requires_pro' => \true]), new Column(['id' => 'url', 'name' => \__('URL', 'independent-analytics'), 'visible' => \true, 'type' => 'string', 'database_column' => 'cached_url']), new Column(['id' => 'author', 'name' => \__('Author', 'independent-analytics'), 'type' => 'select', 'options' => Author_Filter_List::options(), 'database_column' => 'cached_author_id', 'is_nullable' => \true]), new Column(['id' => 'type', 'name' => \__('Page Type', 'independent-analytics'), 'visible' => \true, 'type' => 'select', 'options' => Page_Type_Filter_List::options(), 'database_column' => 'cached_type', 'is_nullable' => \true]), new Column(['id' => 'date', 'name' => \__('Publish Date', 'independent-analytics'), 'type' => 'date', 'database_column' => 'cached_date', 'is_nullable' => \true]), new Column(['id' => 'category', 'name' => \__('Post Category', 'independent-analytics'), 'type' => 'select', 'options' => Category_Filter_List::options(), 'database_column' => 'cached_category', 'is_nullable' => \true]), new Column(['id' => 'comments', 'name' => \__('Comments', 'independent-analytics'), 'type' => 'int', 'is_nullable' => \true])]; return \array_merge($columns, $this->get_woocommerce_columns(), $this->get_form_columns()); } } IAWP/Tables/Table_Referrers.php000064400000004400147600331220012271 0ustar00 'referrer', 'name' => \__('Referrer', 'independent-analytics'), 'visible' => \true, 'type' => 'string']), new Column(['id' => 'referrer_type', 'name' => \__('Referrer Type', 'independent-analytics'), 'visible' => \true, 'type' => 'select', 'options' => Referrer_Type_Filter_List::options()]), new Column(['id' => 'visitors', 'name' => \__('Visitors', 'independent-analytics'), 'visible' => \true, 'type' => 'int']), new Column(['id' => 'views', 'name' => \__('Views', 'independent-analytics'), 'visible' => \true, 'type' => 'int']), new Column(['id' => 'sessions', 'name' => \__('Sessions', 'independent-analytics'), 'type' => 'int']), new Column(['id' => 'average_session_duration', 'name' => \__('Session Duration', 'independent-analytics'), 'visible' => \true, 'type' => 'int', 'filter_placeholder' => 'Seconds']), new Column(['id' => 'views_per_session', 'name' => \__('Views Per Session', 'independent-analytics'), 'type' => 'int']), new Column(['id' => 'bounce_rate', 'name' => \__('Bounce Rate', 'independent-analytics'), 'visible' => \true, 'type' => 'int']), new Column(['id' => 'visitors_growth', 'name' => \__('Visitors Growth', 'independent-analytics'), 'type' => 'int', 'exportable' => \false]), new Column(['id' => 'views_growth', 'name' => \__('Views Growth', 'independent-analytics'), 'type' => 'int', 'exportable' => \false]), new Column(['id' => 'clicks', 'name' => \__('Clicks', 'independent-analytics'), 'type' => 'int', 'requires_pro' => \true])]; return \array_merge($columns, $this->get_woocommerce_columns(), $this->get_form_columns()); } } IAWP/Utils/BladeOne.php000064400000000376147600331220010572 0ustar00 0) { return 100; } elseif ($denominator === 0.0) { return 0; } return \round($numerator / $denominator, $precision); } public static function percentage(float $numerator, float $denominator, int $precision = 0) { if ($denominator === 0.0 && $numerator > 0) { return 100; } elseif ($denominator === 0.0) { return 0; } return \round($numerator / $denominator * 100, $precision); } } IAWP/Utils/CSV.php000064400000001407147600331220007550 0ustar00header = $header; $this->rows = $rows; } public function to_string() : string { $delimiter = ','; $enclosure = '"'; $escape_character = '\\'; $f = \fopen('php://memory', 'r+'); \fputcsv($f, $this->header, $delimiter, $enclosure, $escape_character); foreach ($this->rows as $row) { \fputcsv($f, $row, $delimiter, $enclosure, $escape_character); } \rewind($f); return \wp_kses(\stream_get_contents($f), 'strip'); } } IAWP/Utils/Currency.php000064400000002136147600331220010707 0ustar00 0]; } else { $options = null; } $formatted_value = \strip_tags(\wc_price($amount_in_cents / 100, $options)); return $formatted_value; } if (\class_exists('\\SureCart\\Support\\Currency')) { $currency_code = SureCart_Store::get_currency_code(); $formatted_value = \SureCart\Support\Currency::format($amount_in_cents, $currency_code); return $round_to_whole_dollars ? Str::before($formatted_value, ".") : $formatted_value; } // Fallback return \strval(\intval($amount_in_cents / 100)); } } IAWP/Utils/Device.php000064400000010223147600331220010310 0ustar00detector = new DeviceDetector($_SERVER['HTTP_USER_AGENT']); $cache = new \IAWP\Utils\Device_Cache(); $cache->load_from_file(); $this->detector->setCache($cache); try { @$this->detector->parse(); $this->type = $this->detect_type($this->detector); $this->os = $this->detect_os($this->detector); $this->browser = $this->detect_browser($this->detector); } catch (Throwable $e) { $this->type = null; $this->os = null; $this->browser = null; } $cache->save_to_file(); } public function type_id() : ?int { if (!\is_string($this->type) || $this->type === '') { return null; } $device_types_table = Query::get_table_name(Query::DEVICE_TYPES); $id = Illuminate_Builder::new()->select('device_type_id')->from($device_types_table)->where('device_type', '=', $this->type)->value('device_type_id'); if (\is_null($id)) { $id = Illuminate_Builder::new()->from($device_types_table)->insertGetId(['device_type' => $this->type], 'device_type_id'); } return $id; } public function os_id() : ?int { if (!\is_string($this->os) || $this->os === '') { return null; } $device_oss_table = Query::get_table_name(Query::DEVICE_OSS); $id = Illuminate_Builder::new()->select('device_os_id')->from($device_oss_table)->where('device_os', '=', $this->os)->value('device_os_id'); if (\is_null($id)) { $id = Illuminate_Builder::new()->from($device_oss_table)->insertGetId(['device_os' => $this->os], 'device_os_id'); } return $id; } public function browser_id() : ?int { if (!\is_string($this->browser) || $this->browser === '') { return null; } $device_browsers_table = Query::get_table_name(Query::DEVICE_BROWSERS); $id = Illuminate_Builder::new()->select('device_browser_id')->from($device_browsers_table)->where('device_browser', '=', $this->browser)->value('device_browser_id'); if (\is_null($id)) { $id = Illuminate_Builder::new()->from($device_browsers_table)->insertGetId(['device_browser' => $this->browser], 'device_browser_id'); } return $id; } public function is_bot() : bool { return $this->detector->isBot(); } private function detect_os(DeviceDetector $detector) : ?string { $os = $detector->getOs('name'); if ($os === "UNK") { return null; } return $os; } private function detect_type(DeviceDetector $detector) : ?string { $detected_type = $detector->getDeviceName(); $type_mapping = ['Mobile' => ['smartphone', 'phablet'], 'Tablet' => ['tablet'], 'Desktop' => ['desktop'], 'Car' => ['car browser'], 'Console' => ['console'], 'TV' => ['tv'], 'Wearable' => ['wearable']]; foreach ($type_mapping as $type => $types) { if (\in_array($detected_type, $types)) { return $type; } } return null; } private function detect_browser(DeviceDetector $detector) : ?string { $name = $detector->getClient('name'); if ($name === 'UNK' || \is_array($name)) { return null; } if ($this->should_use_browser_name($name)) { return $name; } return \ucwords(Browser::getBrowserFamily($name) ?? $name); } /** * Should the browsers name be used instead of the browsers family name? * * @param string $name * * @return bool */ private function should_use_browser_name(string $name) : bool { $exceptions = ['Microsoft Edge']; return \in_array($name, $exceptions); } } IAWP/Utils/Device_Cache.php000064400000004357147600331220011406 0ustar00cache[$id] ?? null; } /** * @param string $id * @return bool */ public function contains(string $id) : bool { return \array_key_exists($id, $this->cache); } /** * @param string $id * @param $data * @param int $lifeTime * @return bool */ public function save(string $id, $data, int $lifeTime = 0) : bool { $this->dirty = \true; $this->cache[$id] = $data; return \true; } /** * @param string $id * @return bool */ public function delete(string $id) : bool { $this->dirty = \true; unset($this->cache[$id]); return \true; } /** * @return bool */ public function flushAll() : bool { $this->dirty = \true; $this->cache = []; return \true; } public function load_from_file() { if (!\file_exists($this->file())) { $this->cache = []; return; } $json = \file_get_contents($this->file()); if ($json === \false) { $this->cache = []; return; } $data = \json_decode($json, \true); if ($data === null) { $this->cache = []; return; } $this->cache = $data; } public function save_to_file() { if ($this->dirty === \false) { return; } $this->dirty = \false; $contents = \json_encode($this->cache); if ($contents === \false) { \unlink($this->file()); return; } $response = \file_put_contents($this->file(), $contents); if ($response === \false) { \wp_mkdir_p(\IAWPSCOPED\iawp_temp_path_to('')); \file_put_contents($this->file(), $contents); } } private function file() : string { return \IAWPSCOPED\iawp_temp_path_to('device-detector.json'); } } IAWP/Utils/Dir.php000064400000001165147600331220007634 0ustar00 \__('Name cannot be empty.', 'independent-analytics'), 'empty-value' => \__('Value cannot be empty.', 'independent-analytics'), 'invalid-type' => \__('Invalid type.', 'independent-analytics'), 'class-number' => \__('Class cannot start with a number or special character.', 'independent-analytics'), 'class-space' => \__('Class cannot contain spaces.', 'independent-analytics'), 'class-characters' => \__('Class cannot contain special characters besides "-" and "_".', 'independent-analytics'), 'invalid-extension' => \__('Invalid Extension.', 'independent-analytics'), 'invalid-protocol' => \__('Invalid Protocol.', 'independent-analytics'), 'invalid-domain' => \__('Invalid domain.', 'independent-analytics'), 'invalid-subdirectory' => \__('Invalid characters in subdirectory.', 'independent-analytics')]; } public static function validate(string $property, string $value, string $type) { if ($property == 'name') { if (\trim($value) == '') { return 'empty-name'; } } elseif ($property == 'type') { if (!\array_key_exists($value, Click_Tracking::types())) { return 'invalid-type'; } } elseif ($property == 'value') { if (\trim($value) == '') { return 'empty-value'; } if ($type == 'class') { if (!\preg_match('/[a-zA-Z]/', \substr($value, 0, 1))) { return 'class-number'; } elseif (\preg_match('/\\s/', $value)) { return 'class-space'; } elseif (\preg_match('/[^a-zA-Z0-9_-]/', $value)) { return 'class-characters'; } } elseif ($type == 'extension') { if (!\in_array($value, Click_Tracking::extensions())) { return 'invalid-extension'; } } elseif ($type == 'protocol') { if (!\in_array($value, Click_Tracking::protocols())) { return 'invalid-protocol'; } } elseif ($type == 'domain') { if (!self::is_valid_domain($value)) { return 'invalid-domain'; } } elseif ($type == 'subdirectory') { if (\preg_match("/[^A-Za-z0-9-._~!\$&'()*+,;=:@\\/]/", $value)) { return 'invalid-subdirectory'; } } } return \false; } public static function is_valid_domain(string $domain) { return \preg_match('/^(http[s]?\\:\\/\\/)?((\\w+)\\.)?(([\\w-]+)+)(\\.[\\w-]+){1,2}$/', $domain); } public static function sanitize_domain($domain) { $domain = \strpos($domain, 'http') !== 0 ? "http://{$domain}" : $domain; $components = Uri::createFromString($domain); return $components->getHost(); } public static function sanitize_subdirectory($subdirectory) { return \sanitize_text_field(\trim($subdirectory, '/')); } } IAWP/Utils/Number_Formatter.php000064400000003013147600331220012363 0ustar00diff($now); return $interval->format('%i:%S'); } /** * @param int|float $number * @param int $decimals * * @return string */ public static function percent($number, int $decimals = 0) : string { if (\class_exists('\\NumberFormatter')) { $formatter = new \NumberFormatter(\get_locale(), \NumberFormatter::PERCENT); $formatter->setAttribute(\NumberFormatter::MAX_FRACTION_DIGITS, $decimals); return $formatter->format($number / 100); } else { return \number_format_i18n($number, $decimals) . '%'; } } /** * @param int|float $number * @param int $decimals * * @return string */ public static function decimal($number, int $decimals = 0) : string { return \number_format_i18n($number, $decimals); } public static function integer($number) : string { if ($number < 100000) { return \number_format_i18n($number, 0); } return Number::abbreviate($number, \false); } } IAWP/Utils/Request.php000064400000007574147600331220010560 0ustar00test('/^[a-zA-Z_]+$/')) { return $user_defined_header; } return null; } public static function user_agent() { return $_SERVER['HTTP_USER_AGENT']; } public static function is_ip_address_blocked() : bool { $blocked_ips = \IAWPSCOPED\iawp()->get_option('iawp_blocked_ips', []); // No address could be blocked if (\count($blocked_ips) == 0) { return \false; } $visitor_address = Factory::parseAddressString(self::ip()); // We cannot block invalid ip addresses if ($visitor_address === null) { return \false; } foreach ($blocked_ips as $blocked_ip) { $blocked_range = Factory::parseRangeString($blocked_ip); // We cannot check an ip address against an invalid range if ($blocked_range === null) { continue; } // If the address matches this particular blocked range, then the ip address is indeed blocked if ($blocked_range->contains($visitor_address)) { return \true; } } return \false; } private static function scheme() { if (!empty($_SERVER['REQUEST_SCHEME']) && $_SERVER['REQUEST_SCHEME'] == 'https' || !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' || !empty($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == '443') { return 'https'; } else { return 'http'; } } private static function url() { if (!empty($_SERVER['HTTP_HOST']) && !empty($_SERVER['REQUEST_URI'])) { return \esc_url_raw(self::scheme() . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']); } else { return null; } } } IAWP/Utils/Salt.php000064400000002046147600331220010020 0ustar00 ['class' => [], 'style' => []], 'select' => ['class' => []], 'option' => ['class' => [], 'value' => [], 'data-datatype' => []], 'input' => ['class' => [], 'type' => [], 'data-css' => [], 'data-dow' => [], 'data-format' => [], 'readonly'], 'button' => ['class' => []], 'span' => ['class' => [], 'style' => []]]); } public static function svg($html) { return \wp_kses($html, ['svg' => ['height' => [], 'width' => [], 'fill' => [], 'viewbox' => [], 'style' => []], 'path' => ['d' => []]]); } } IAWP/Utils/Server.php000064400000001561147600331220010364 0ustar00getOffset($date); return $offset_in_seconds; } } IAWP/Utils/URL.php000064400000003201147600331220007551 0ustar00url = $url; } public function is_valid_url() : bool { $valid_url = \filter_var($this->url, \FILTER_VALIDATE_URL); if (!$valid_url) { return \false; } try { // Recommend approach for uri validation: https://uri.thephpleague.com/uri/6.0/rfc3986/#uri-validation $components = Uri::createFromString($this->url); if (\is_null($components->getHost())) { return \false; } return \true; } catch (UriException $e) { return \false; } } public function get_domain() : ?string { if (!$this->is_valid_url()) { return null; } return Uri::createFromString($this->url)->getHost(); } public function get_extension() : ?string { if (!$this->is_valid_url()) { return null; } $path = Uri::createFromString($this->url)->getPath(); $file = Str::afterLast($path, '/'); $extension = Str::afterLast($file, '.'); return $extension !== "" ? $extension : null; } public function get_path() : ?string { if (!$this->is_valid_url()) { return null; } return Uri::createFromString($this->url)->getPath(); } public static function new(string $url) : self { return new self($url); } } IAWP/Utils/WordPress_Site_Date_Format_Pattern.php000064400000003150147600331220015770 0ustar00 'DD', 'D' => 'ddd', 'j' => 'D', 'l' => 'dddd', 'N' => 'E', 'S' => 'o', 'w' => 'e', 'z' => 'DDD', 'W' => 'W', 'F' => 'MMMM', 'm' => 'MM', 'M' => 'MMM', 'n' => 'M', 't' => '', // no equivalent 'L' => '', // no equivalent 'o' => 'YYYY', 'Y' => 'YYYY', 'y' => 'YY', 'a' => 'a', 'A' => 'A', 'B' => '', // no equivalent 'g' => 'h', 'G' => 'H', 'h' => 'hh', 'H' => 'HH', 'i' => 'mm', 's' => 'ss', 'u' => 'SSS', 'e' => 'zz', // deprecated since version 1.6.0 of moment.js 'I' => '', // no equivalent 'O' => '', // no equivalent 'P' => '', // no equivalent 'T' => '', // no equivalent 'Z' => '', // no equivalent 'c' => '', // no equivalent 'r' => '', // no equivalent 'U' => 'X', ]; return \strtr($php_format, $replacements); } } IAWP/Utils/WP_Async_Request.php000064400000006756147600331220012324 0ustar00identifier = $this->prefix . '_' . $this->action; \add_action('wp_ajax_' . $this->identifier, [$this, 'maybe_handle']); \add_action('wp_ajax_nopriv_' . $this->identifier, [$this, 'maybe_handle']); } /** * Handle * * Override this method to perform any actions required * during the async request. */ protected abstract function handle(); /** * Set data used during the request * * @param array $data Data. * * @return $this */ public function data($data) { $this->data = $data; return $this; } /** * Dispatch the async request * * @return array|\WP_Error */ public function dispatch() { $url = \add_query_arg($this->get_query_args(), $this->get_query_url()); $args = $this->get_post_args(); return \wp_remote_post(\esc_url_raw($url), $args); } /** * Maybe handle * * Check for correct nonce and pass to handler. */ public function maybe_handle() { // Don't lock up other requests while processing \session_write_close(); \check_ajax_referer($this->identifier, 'nonce'); $this->handle(); \wp_die(); } /** * Get query args * * @return array */ protected function get_query_args() { if (\property_exists($this, 'query_args')) { return $this->query_args; } $args = ['action' => $this->identifier, 'nonce' => \wp_create_nonce($this->identifier)]; /* * Filters the post arguments used during an async request. * * @param array $url */ return \apply_filters($this->identifier . '_query_args', $args); } /** * Get query URL * * @return string */ protected function get_query_url() { if (\property_exists($this, 'query_url')) { return $this->query_url; } $url = \admin_url('admin-ajax.php'); /* * Filters the post arguments used during an async request. * * @param string $url */ return \apply_filters($this->identifier . '_query_url', $url); } /** * Get post args * * @return array */ protected function get_post_args() { if (\property_exists($this, 'post_args')) { return $this->post_args; } $args = ['timeout' => 0.01, 'blocking' => \false, 'body' => $this->data, 'cookies' => $_COOKIE, 'sslverify' => \apply_filters('https_local_ssl_verify', \false)]; /* * Filters the post arguments used during an async request. * * @param array $args */ return \apply_filters($this->identifier . '_post_args', $args); } } IAWP/Campaign_Builder.php000064400000011323147600331220011200 0ustar00run('campaign-builder', ['campaigns' => $this->get_previously_created_campaigns()]); } public function create_campaign($path, $source, $medium, $campaign, $term, $content) { global $wpdb; $has_errors = \false; $path = \strlen($path) > 0 ? $path : ''; $path_error = null; $source_error = null; $medium_error = null; $campaign_error = null; $term = \strlen($term) > 0 ? $term : null; $content = \strlen($content) > 0 ? $content : null; $url = new URL(\site_url() . $path); if (!$url->is_valid_url()) { $has_errors = \true; $path_error = 'path invalid'; } if (\strlen($source) === 0) { $has_errors = \true; $source_error = 'Source is required'; } if (\strlen($medium) === 0) { $has_errors = \true; $medium_error = 'Medium is required'; } if (\strlen($campaign) === 0) { $has_errors = \true; $campaign_error = 'Campaign is required'; } if ($has_errors) { return \IAWPSCOPED\iawp_blade()->run('campaign-builder', ['path' => $path, 'path_error' => $path_error, 'utm_source' => $source, 'utm_source_error' => $source_error, 'utm_medium' => $medium, 'utm_medium_error' => $medium_error, 'utm_campaign' => $campaign, 'utm_campaign_error' => $campaign_error, 'utm_term' => $term, 'utm_content' => $content, 'campaigns' => $this->get_previously_created_campaigns()]); } $campaign_urls_table = \IAWP\Query::get_table_name(\IAWP\Query::CAMPAIGN_URLS); $wpdb->insert($campaign_urls_table, ['path' => $path, 'utm_source' => $source, 'utm_medium' => $medium, 'utm_campaign' => $campaign, 'utm_term' => $term, 'utm_content' => $content, 'created_at' => (new \DateTime())->format('Y-m-d H:i:s')]); $url = $this->build_url($path, $source, $medium, $campaign, $term, $content); return \IAWPSCOPED\iawp_blade()->run('campaign-builder', ['path' => $path, 'utm_source' => $source, 'utm_medium' => $medium, 'utm_campaign' => $campaign, 'utm_term' => $term, 'utm_content' => $content, 'new_campaign_url' => $url, 'campaigns' => $this->get_previously_created_campaigns()]); } public function build_url($path, $source, $medium, $campaign, $term = null, $content = null) : string { $path = String_Util::str_starts_with($path, '/') ? \substr($path, 1) : $path; $uri = Uri::createFromString(\trailingslashit(\site_url()) . $path); $existing_query = $uri->getQuery(); if (\is_null($existing_query)) { $existing_query = []; } else { \parse_str($existing_query, $existing_query); } $existing_query['utm_source'] = $source; $existing_query['utm_medium'] = $medium; $existing_query['utm_campaign'] = $campaign; if (isset($term)) { $existing_query['utm_term'] = $term; } if (isset($content)) { $existing_query['utm_content'] = $content; } return $uri->withQuery(\http_build_query($existing_query)); } private function get_previously_created_campaigns() { global $wpdb; $campaign_urls_table = \IAWP\Query::get_table_name(\IAWP\Query::CAMPAIGN_URLS); $results = $wpdb->get_results("\n SELECT * FROM {$campaign_urls_table} ORDER BY created_at DESC LIMIT 100\n "); return \array_map(function ($result) { $created_at = Carbon::parse($result->created_at)->diffForHumans(); return ['campaign_url_id' => $result->campaign_url_id, 'result' => \json_encode((array) $result), 'created_at' => $created_at, 'url' => $this->build_url($result->path, $result->utm_source, $result->utm_medium, $result->utm_campaign, $result->utm_term, $result->utm_content)]; }, $results); } public static function has_campaigns() : bool { $campaign_builder = new \IAWP\Campaign_Builder(); return \count($campaign_builder->get_previously_created_campaigns()) > 0; } public static function delete_campaign(string $campaign_url_id) { $campaign_urls_table = \IAWP\Query::get_table_name(\IAWP\Query::CAMPAIGN_URLS); $delete_campaign = \IAWP\Illuminate_Builder::new(); $delete_campaign->from($campaign_urls_table)->where('campaign_url_id', '=', $campaign_url_id)->delete(); } } IAWP/Capability_Manager.php000064400000007076147600331220011540 0ustar00 \esc_html__('View analytics for authored content', 'independent-analytics'), 'iawp_read_only_access' => \esc_html__('View all analytics', 'independent-analytics'), 'iawp_full_access' => \esc_html__('View all analytics and edit settings', 'independent-analytics')]; } public static function reset_capabilities() : void { $roles = \wp_roles()->roles; $edits = []; foreach ($roles as $role => $role_details) { $edits[$role] = null; } self::edit_all_capabilities($edits); } /** * Accepts an array of key value pairs where the key is the role and the value is the capability to use * * @param $capabilities * @return void */ public static function edit_all_capabilities($capabilities) : void { foreach ($capabilities as $role => $capability) { if ($role === 'administrator') { continue; } $user_role = \get_role($role); // For the role, remove all previous capabilities foreach (self::all_capabilities() as $possible_capability => $label) { $user_role->remove_cap($possible_capability); } if (\array_key_exists($capability, self::all_capabilities())) { $user_role->add_cap($capability); } } } public static function can_view() : bool { return self::is_admin_user() || \current_user_can('iawp_read_only_authored_access') || \current_user_can('iawp_read_only_access') || \current_user_can('iawp_full_access'); } public static function can_only_view_authored_analytics() : bool { return !self::is_admin_user() && \current_user_can('iawp_read_only_authored_access'); } public static function can_view_all_analytics() : bool { return self::is_admin_user() || \current_user_can('iawp_read_only_access') || \current_user_can('iawp_full_access'); } public static function can_edit() : bool { return self::is_admin_user() || \current_user_can('iawp_full_access'); } /** * Returns a capability string for admin menu pages. Admins can always see pages. Other roles * can only see pages if they have the special capability applied. * * @return string */ public static function menu_page_capability_string() : string { if (self::is_admin_user()) { return 'manage_options'; } if (self::can_edit()) { return 'iawp_full_access'; } if (self::can_only_view_authored_analytics()) { return 'iawp_read_only_authored_access'; } if (self::can_view()) { return 'iawp_read_only_access'; } return 'manage_options'; } public static function show_branded_ui() : bool { if (self::is_admin_user()) { return \true; } if (\get_option('iawp_white_label') === '1') { return \false; } return \true; } public static function show_white_labeled_ui() : bool { return !self::show_branded_ui(); } /** * @return bool */ private static function is_admin_user() : bool { if (\current_user_can('setup_network') || \in_array('administrator', \wp_get_current_user()->roles)) { return \true; } return \false; } } IAWP/Chart.php000064400000005755147600331220007070 0ustar00statistics = $statistics; $this->is_preview = $is_preview; } public function get_html() : string { $options = \IAWP\Dashboard_Options::getInstance(); $primary_statistic = $this->statistics->get_statistic($options->primary_chart_metric_id()) ?? $this->statistics->get_statistic('clicks') ?? $this->statistics->get_statistic('visitors'); $secondary_statistic = \is_string($options->secondary_chart_metric_id()) ? $this->statistics->get_statistic($options->secondary_chart_metric_id()) : null; $labels = \array_map(function ($data_point) { return Security::json_encode($this->statistics->chart_interval()->get_label_for($data_point[0])); }, $primary_statistic->statistic_over_time()); $data = []; foreach ($this->statistics->get_statistics() as $statistic) { $data[$statistic->id()] = \array_map(function ($data_point) { return $data_point[1]; }, $statistic->statistic_over_time()); } $total_chart_statistics = 0; foreach ($this->statistics->get_grouped_statistics() as $group) { $total_chart_statistics += \count($group['items']); } return \IAWPSCOPED\iawp_blade()->run('chart', ['chart' => $this, 'intervals' => Intervals::all(), 'current_interval' => $this->statistics->chart_interval(), 'available_datasets' => $this->statistics->get_grouped_statistics(), 'primary_chart_metric_id' => $primary_statistic->id(), 'secondary_chart_metric_id' => \is_null($secondary_statistic) ? null : $secondary_statistic->id(), 'stimulus_values' => ['locale' => \get_bloginfo('language'), 'currency' => $this->get_currency_code(), 'is-preview' => $this->is_preview() ? '1' : '0', 'primary-chart-metric-id' => $primary_statistic->id(), 'primary-chart-metric-name' => $primary_statistic->name(), 'secondary-chart-metric-id' => \is_null($secondary_statistic) ? null : $secondary_statistic->id(), 'secondary-chart-metric-name' => \is_null($secondary_statistic) ? null : $secondary_statistic->name(), 'labels' => $labels, 'data' => $data, 'has-multiple-datasets' => $total_chart_statistics > 1 ? 1 : 0]]); } public function is_preview() : bool { return $this->is_preview; } public function encode_json(array $array) : string { return Security::json_encode($array); } private function get_currency_code() : ?string { if (\IAWPSCOPED\iawp()->is_woocommerce_support_enabled()) { return get_woocommerce_currency(); } if (\IAWPSCOPED\iawp()->is_surecart_support_enabled()) { return SureCart_Store::get_currency_code(); } return null; } } IAWP/Chart_Geo.php000064400000006462147600331220007656 0ustar00countries = $this->parse($geos); $this->title = $title; } public function get_html() { $chart_data = \array_map(function ($country) { return [$country['country_code'], $country['views'], $this->get_tooltip($country)]; }, $this->countries); $dark_mode = \IAWPSCOPED\iawp()->get_option('iawp_dark_mode', '0'); \ob_start(); ?>

title; ?>

$country) { if ($geo->country_code() === $country['country_code']) { $existing_country_index = $index; } } if (\is_numeric($existing_country_index)) { $countries[$existing_country_index]['views'] += $geo->views(); $countries[$existing_country_index]['visitors'] += $geo->visitors(); $countries[$existing_country_index]['sessions'] += $geo->sessions(); } else { $countries[] = ['country_code' => $geo->country_code(), 'country' => $geo->country(), 'views' => $geo->views(), 'visitors' => $geo->visitors(), 'sessions' => $geo->sessions()]; } } return $countries; } private function get_tooltip($country) : string { \ob_start(); ?>
find($country['country_code']); ?>

:

:

:

run('click-tracking.menu', ['active_links' => Link_Rule_Finder::active_link_rules()->map(function ($link_rule) { return $link_rule->to_array(); })->all(), 'inactive_links' => Link_Rule_Finder::inactive_link_rules()->map(function ($link_rule) { return $link_rule->to_array(); })->all(), 'types' => self::types(), 'extensions' => self::extensions(), 'protocols' => self::protocols(), 'error_messages' => Link_Validator::error_messages(), 'show_click_tracking_cache_message' => $show_click_tracking_cache_message]); } public static function types() { return ['class' => \esc_html__('Class', 'independent-analytics'), 'extension' => \esc_html__('Extension', 'independent-analytics'), 'domain' => \esc_html__('Domain', 'independent-analytics'), 'subdirectory' => \esc_html__('Subdirectory', 'independent-analytics'), 'protocol' => \esc_html__('Protocol', 'independent-analytics')]; } public static function extensions() { return ['aif', 'aifc', 'aiff', 'avi', 'csv', 'doc', 'docx', 'epub', 'exe', 'gif', 'jpeg', 'jpg', 'mov', 'mp3', 'mp4', 'm4a', 'pdf', 'png', 'ppt', 'pptx', 'psd', 'rtf', 'txt', 'wav', 'wmv', 'xls', 'xlsx', 'zip']; } public static function protocols() { return ['mailto', 'tel']; } } IAWP/Cron_Job.php000064400000003004147600331220007503 0ustar00name, function () { if ($this->should_execute_handler()) { $this->handle(); } }); } public function unschedule() { $scheduled_at_timestamp = \wp_next_scheduled($this->name); if (\is_int($scheduled_at_timestamp)) { \wp_unschedule_event($scheduled_at_timestamp, $this->name); } } public function schedule() { $scheduled_at_timestamp = \wp_next_scheduled($this->name); if (!\is_int($scheduled_at_timestamp)) { \wp_schedule_event(\time() + 2, $this->interval, $this->name); } } public function should_execute_handler() : bool { return \true; } public static function register_custom_intervals() : void { \add_filter('cron_schedules', function ($schedules) { $schedules['monthly'] = ['interval' => \MONTH_IN_SECONDS, 'display' => \esc_html__('Once a Month', 'independent-analytics')]; $schedules['five_minutes'] = ['interval' => 300, 'display' => \esc_html__('Every 5 minutes', 'independent-analytics')]; $schedules['every_minute'] = ['interval' => 60, 'display' => \esc_html__('Every minute', 'independent-analytics')]; return $schedules; }); } } IAWP/Cron_Manager.php000064400000002254147600331220010351 0ustar00unschedule_daily_salt_refresh(); return; } $refresh_time = new \DateTime('tomorrow midnight', Timezone::site_timezone()); \wp_schedule_event($refresh_time->getTimestamp(), 'daily', 'iawp_refresh_salt'); } public function unschedule_daily_salt_refresh() { $timestamp = \wp_next_scheduled('iawp_refresh_salt'); \wp_unschedule_event($timestamp, 'iawp_refresh_salt'); } public function refresh_salt() { Salt::refresh_visitor_token_salt(); Config_File_Manager::recreate(); } } IAWP/Current_Traffic_Finder.php000064400000002602147600331220012362 0ustar00date_range = $date_range; } public function fetch() : Current_Traffic { $views_table = \IAWP\Query::get_table_name(\IAWP\Query::VIEWS); $sessions_table = \IAWP\Query::get_table_name(\IAWP\Query::SESSIONS); $row = \IAWP\Illuminate_Builder::new()->from($views_table, 'views')->selectRaw('COUNT(DISTINCT (sessions.visitor_id)) AS visitor_count')->selectRaw('COUNT(DISTINCT (views.resource_id)) AS page_count')->selectRaw('COUNT(DISTINCT (sessions.referrer_id)) AS referrer_count')->selectRaw('COUNT(DISTINCT (sessions.country_id)) AS country_count')->selectRaw('COUNT(DISTINCT (sessions.campaign_id)) AS campaign_count')->selectRaw('COUNT(*) AS view_count')->leftJoin("{$sessions_table} AS sessions", function (JoinClause $join) { $join->on('views.session_id', '=', 'sessions.session_id'); })->whereBetween('viewed_at', [$this->date_range->iso_start(), $this->date_range->iso_end()])->first(); return new Current_Traffic($row); } } IAWP/Dashboard_Options.php000064400000015374147600331220011427 0ustar00report = $this->fetch_current_report(); } public function report_name() : ?string { if (\is_null($this->report->name ?? null)) { return 'Report'; } return $this->report->name; } public function visible_columns() : ?array { if (Request::get_post_array('columns')) { return Request::get_post_array('columns'); } if (\is_null($this->report) || \is_null($this->report->columns)) { return null; } return \json_decode($this->report->columns, \true); } public function visible_quick_stats() : array { if (Request::get_post_array('quick_stats')) { return Request::get_post_array('quick_stats'); } $decoded_value = \json_decode($this->report->quick_stats ?? 'null', \true); if (\is_array($decoded_value)) { return $decoded_value; } if (\IAWP\Env::get_tab() === 'clicks') { return ['clicks']; } return self::$default_visible_quick_stats; } public function primary_chart_metric_id() : string { if (Request::get_post_string('primary_chart_metric_id')) { return Request::get_post_string('primary_chart_metric_id'); } if (\is_null($this->report->primary_chart_metric_id ?? null)) { return 'visitors'; } return $this->report->primary_chart_metric_id; } public function secondary_chart_metric_id() : ?string { if (Request::get_post_string('secondary_chart_metric_id')) { return Request::get_post_string('secondary_chart_metric_id'); } if (\is_null($this->report->secondary_chart_metric_id ?? null)) { return 'views'; } return $this->report->secondary_chart_metric_id; } public function filters() : array { if (\is_null($this->report) || \is_null($this->report->filters)) { return []; } $table_class = \IAWP\Env::get_table($this->report->type); $table = new $table_class($this->report->group_name ?? null); $filters = \json_decode($this->report->filters, \true); return \is_null($filters) ? [] : $table->sanitize_filters($filters); } public function sort_column() : ?string { return $this->report->sort_column ?? null; } public function sort_direction() : ?string { return $this->report->sort_direction ?? null; } public function group() : ?string { return $this->report->group_name ?? null; } public function chart_interval() : ?Interval { if (\is_null($this->report->chart_interval ?? null)) { return Intervals::default_for($this->get_date_range()->number_of_days()); } return Intervals::find_by_id($this->report->chart_interval); } /** * @return Date_Range */ public function get_date_range() : Date_Range { if ($this->has_exact_range()) { try { $start = new DateTime($this->start(), Timezone::site_timezone()); $end = new DateTime($this->end(), Timezone::site_timezone()); return new Exact_Date_Range($start, $end); } catch (Throwable $e) { // Do nothing and fall back to default relative date range } } return new Relative_Date_Range($this->relative_range_id()); } public function start() : ?string { if (!$this->has_exact_range()) { return null; } return $this->report->exact_start; } public function end() : ?string { if (!$this->has_exact_range()) { return null; } return $this->report->exact_end; } /** * Prefer exact range to relative range if both are provided */ public function relative_range_id() : ?string { $relative_range_id = $this->report->relative_range_id ?? null; if (!$this->has_exact_range() && $relative_range_id === null) { return 'LAST_THIRTY'; } elseif ($this->has_exact_range()) { return null; } elseif (Relative_Date_Range::is_valid_range($relative_range_id) === \false) { return 'LAST_THIRTY'; } return $relative_range_id; } public function maybe_redirect() : void { if (\IAWP\Env::get_page() !== 'independent-analytics') { return; } if (empty($_GET['report']) && empty($_GET['tab'])) { $favorite_report = \IAWP\Report_Finder::get_favorite(); if (\is_null($favorite_report)) { return; } \wp_safe_redirect($favorite_report->url()); exit; } if (!empty($_GET['report']) && \is_null($this->report)) { \wp_safe_redirect(\IAWPSCOPED\iawp_dashboard_url(['tab' => \IAWP\Env::get_tab()])); exit; } if (!\is_null($this->report) && \IAWP\Env::get_tab() !== $this->report->type) { \wp_safe_redirect(\IAWPSCOPED\iawp_dashboard_url(['tab' => $this->report->type, 'report' => $this->report->report_id])); exit; } } public function is_sidebar_collapsed() : bool { $is_sidebar_collapsed = \get_user_meta(\get_current_user_id(), 'iawp_is_sidebar_collapsed', \true) === '1'; return $is_sidebar_collapsed; } private function fetch_current_report() : ?object { $reports_table = \IAWP\Query::get_table_name(\IAWP\Query::REPORTS); $report_id = \filter_input(\INPUT_GET, 'report', \FILTER_VALIDATE_INT); if (!\is_int($report_id)) { return null; } return \IAWP\Illuminate_Builder::new()->from($reports_table)->where('report_id', '=', $report_id)->first(); } private function has_exact_range() : bool { return !\is_null($this->report->exact_start ?? null) && !\is_null($this->report->exact_end ?? null); } } IAWP/Dashboard_Widget.php000064400000002760147600331220011212 0ustar00is_enabled()) { \add_action('wp_dashboard_setup', [$this, 'add_dashboard_widget']); } } public function add_dashboard_widget() { if (\IAWP\Migrations\Migrations::is_migrating() || !\IAWP\Capability_Manager::can_view()) { return; } \ob_start(); ?> get_html(); echo $stats->get_html(); } private function is_enabled() : bool { return \get_option('iawp_disable_widget') !== '1'; } } IAWP/Database.php000064400000012127147600331220007522 0ustar00get_charset_collate. As users move their site * around, old tables might have one collation while newly created tables might have a different * one. * * @internal */ class Database { private static $character_set = null; private static $collation = null; private static $user_privileges = null; private static $required_privileges = ['SELECT', 'INSERT', 'UPDATE', 'DELETE', 'CREATE', 'ALTER', 'INDEX', 'DROP']; public static function has_correct_database_privileges() : bool { return \count(self::missing_database_privileges()) === 0; } public static function missing_database_privileges() : array { return \array_diff(self::$required_privileges, self::user_privileges()); } public static function is_missing_all_tables() : bool { global $wpdb; $tables = \IAWP\Illuminate_Builder::new()->select('*')->from('INFORMATION_SCHEMA.TABLES')->where('TABLE_SCHEMA', '=', $wpdb->dbname)->where('TABLE_NAME', 'LIKE', $wpdb->prefix . 'independent_analytics_%'); $views_table = \IAWP\Query::get_table_name(\IAWP\Query::VIEWS); $views_query = \IAWP\Illuminate_Builder::new()->selectRaw('0 AS number')->from($views_table); try { $views_query->doesntExist(); $missing_views_table = \false; } catch (QueryException $exception) { $missing_views_table = \true; } return $tables->doesntExist() && $missing_views_table; } public static function character_set() : string { if (\is_null(self::$character_set)) { self::populate_character_set_and_collation(); } return self::$character_set; } public static function collation() : string { if (\is_null(self::$collation)) { self::populate_character_set_and_collation(); } return self::$collation; } public static function has_table(string $table) : bool { global $wpdb; $tables = $wpdb->get_row($wpdb->prepare("SHOW TABLES LIKE %s", $table)); return !\is_null($tables); } public static function has_index(string $table, string $index) : bool { global $wpdb; if (!self::has_table($table)) { return \false; } $row = $wpdb->get_row($wpdb->prepare("\n SHOW INDEX FROM {$table} WHERE Key_name = %s\n ", $index)); return !\is_null($row); } /** * From MySQL: It is not possible to deny a privilege granted at a higher level by absence of that privilege at a lower level. * * @return string[] */ private static function user_privileges() : array { global $wpdb; if (!\is_null(self::$user_privileges)) { return self::$user_privileges; } $user = \IAWP\Illuminate_Builder::new()->selectRaw('CURRENT_USER() as user')->value('user'); $parts = \explode('@', $user); $grantee = "'" . $parts[0] . "'@'" . $parts[1] . "'"; $global_privileges_query = \IAWP\Illuminate_Builder::new()->select('*')->from('information_schema.user_privileges')->where('grantee', '=', $grantee); $global_privileges = \array_map(function ($record) { return $record->PRIVILEGE_TYPE; }, $global_privileges_query->get()->all()); $database_privileges_query = \IAWP\Illuminate_Builder::new()->select('*')->from('information_schema.schema_privileges')->where('grantee', '=', $grantee)->where('table_schema', '=', $wpdb->dbname); $database_privileges = \array_map(function ($record) { return $record->PRIVILEGE_TYPE; }, $database_privileges_query->get()->all()); $privileges = \array_unique(\array_merge($global_privileges, $database_privileges), \SORT_REGULAR); // If SELECT is missing, that means our query is broken and should be ignored if (!\in_array('SELECT', $privileges)) { self::$user_privileges = self::$required_privileges; } else { self::$user_privileges = $privileges; } return self::$user_privileges; } private static function populate_character_set_and_collation() : void { global $wpdb; $query = \IAWP\Illuminate_Builder::new()->selectRaw('CCSA.CHARACTER_SET_NAME AS character_set_name')->selectRaw('CCSA.COLLATION_NAME AS collation_name')->from('information_schema.TABLES', 'THE_TABLES')->leftJoin('information_schema.COLLATION_CHARACTER_SET_APPLICABILITY AS CCSA', 'CCSA.COLLATION_NAME', '=', 'THE_TABLES.TABLE_COLLATION')->where('THE_TABLES.TABLE_SCHEMA', '=', $wpdb->dbname)->where('THE_TABLES.TABLE_NAME', '=', \IAWP\Query::get_table_name(\IAWP\Query::SESSIONS)); $result = $query->first(); self::$character_set = $result->character_set_name ?? null; self::$collation = $result->collation_name ?? null; if (\is_null(self::$character_set) || \is_null(self::$collation)) { self::$character_set = $wpdb->charset; self::$collation = $wpdb->collate; } } } IAWP/Database_Manager.php000064400000003340147600331220011151 0ustar00delete_all_post_meta(); } public function delete_all_data() : void { $this->delete_all_iawp_options(); $this->delete_all_iawp_user_metadata(); $this->delete_all_iawp_tables(); $this->delete_all_post_meta(); } private function delete_all_iawp_options() : void { global $wpdb; $options = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->options} WHERE option_name LIKE %s", 'iawp_%')); foreach ($options as $option) { \delete_option($option->option_name); } } private function delete_all_iawp_user_metadata() : void { global $wpdb; $metadata = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->usermeta} WHERE meta_key LIKE %s", 'iawp_%')); foreach ($metadata as $metadata) { \delete_user_meta($metadata->user_id, $metadata->meta_key); } } private function delete_all_iawp_tables() : void { global $wpdb; $prefix = $wpdb->prefix; $rows = $wpdb->get_results($wpdb->prepare("SELECT table_name FROM information_schema.tables WHERE TABLE_SCHEMA = %s AND table_name LIKE %s", $wpdb->dbname, $prefix . 'independent_analytics_%')); foreach ($rows as $row) { $wpdb->query('DROP TABLE ' . $row->table_name); } } private function delete_all_post_meta() : void { \delete_post_meta_by_key(Views_Column::$meta_key); } } IAWP/Empty_Report_Option.php000064400000000234147600331220011773 0ustar00
'; $html .= ''; $html .= ''; $html .= ''; return $html; } /** * @param Column[] $columns * * @return void */ private function get_column_select(array $columns) { $plugin_groups = \IAWP\Plugin_Group::get_plugin_groups(); $column_sections = []; foreach ($columns as $column) { $plugin_group_id = $column->plugin_group(); $section_name = ''; $plugin_group = null; foreach ($plugin_groups as $a_plugin_group) { if ($a_plugin_group->id() === $plugin_group_id) { $section_name = $a_plugin_group->name(); $plugin_group = $a_plugin_group; } } if (!$plugin_group->has_active_group_plugins()) { continue; } if (!\is_null($column->plugin_group_header())) { $section_name = $plugin_group->name() . ' - ' . $column->plugin_group_header(); } if (!\array_key_exists($section_name, $column_sections)) { $column_sections[$section_name] = ['plugin_group' => $plugin_group, 'columns' => []]; } \array_push($column_sections[$section_name]['columns'], $column); } echo \IAWPSCOPED\iawp_blade()->run('partials.filter-column-select', ['column_sections' => $column_sections]); } private function get_all_operator_selects() { $html = ''; foreach (self::get_data_types() as $data_type) { $html .= ''; } return $html; } private function get_all_operand_fields(array $columns) { $html = ''; foreach ($columns as $column) { switch ($column->type()) { case 'string': $html .= ''; break; case 'int': $html .= ''; break; case 'date': $html .= ''; break; case 'select': $html .= ''; break; } } return $html; } private function get_data_types() { return ['string', 'int', 'date', 'select']; } private function get_operators(string $data_type) { if ($data_type == 'string') { return ['contains' => \esc_html__('Contains', 'independent-analytics'), 'exact' => \esc_html__('Exactly matches', 'independent-analytics')]; } elseif ($data_type == 'int') { return ['greater' => \esc_html__('Greater than', 'independent-analytics'), 'lesser' => \esc_html__('Less than', 'independent-analytics'), 'equal' => \esc_html__('Equal to', 'independent-analytics')]; } elseif ($data_type == 'select') { return ['is' => \esc_html__('Is', 'independent-analytics'), 'isnt' => \esc_html__('Isn\'t', 'independent-analytics')]; } elseif ($data_type == 'date') { return ['before' => \esc_html__('Before', 'independent-analytics'), 'after' => \esc_html__('After', 'independent-analytics'), 'on' => \esc_html__('On', 'independent-analytics')]; } else { return null; } } } IAWP/Geoposition.php000064400000005045147600331220010316 0ustar00geoposition = $this->fetch_geoposition($ip); } public function valid_location() : bool { $required_values = [$this->continent(), $this->country_code(), $this->country(), $this->city()]; $null_values = \array_filter($required_values, function ($item) { return \is_null($item); }); return \count($null_values) === 0; } public function country_code() : ?string { return $this->geoposition['country']['iso_code'] ?? null; } /** * Return an English city name * * @return string|null */ public function city() : ?string { $city = $this->geoposition['city']['names']['en'] ?? null; if (\is_null($city)) { return null; } return $this->strip_city_neighborhood_data($city); } /** * Return an English subdivision name * * @return string|null */ public function subdivision() : ?string { return $this->geoposition['subdivisions'][0]['names']['en'] ?? null; } /** * @return string|null */ public function country() : ?string { return $this->geoposition['country']['names']['en'] ?? null; } /** * @return string|null */ public function continent() : ?string { return $this->geoposition['continent']['names']['en'] ?? null; } /** * City names can occasionally contain neighborhood data in parentheses after the city name such * as "Philadelphia (North Philadelphia)" in of "Philadelphia". This strips that extra * neighborhood data, returning just the city name. * * @param $city_name * * @return string */ private function strip_city_neighborhood_data($city_name) : string { $position = \strpos($city_name, '('); if ($position !== \false) { $city_name = \substr($city_name, 0, $position); } return \trim($city_name); } private function fetch_geoposition(string $ip) : array { try { $reader = new Reader(\IAWP\Geo_Database_Manager::path_to_database()); $geo = $reader->get($ip); $reader->close(); return $geo; } catch (\Throwable $e) { return []; } } } IAWP/Geo_Database_Background_Job.php000064400000001427147600331220013246 0ustar00download(); } public static function maybe_dispatch() : void { $geo_database = new \IAWP\Geo_Database_Manager(); if ($geo_database->should_download()) { $background_job = new self(); $background_job->dispatch(); } } } IAWP/Geo_Database_Manager.php000064400000007701147600331220011750 0ustar00should_download()) { return; } \update_option('iawp_is_database_downloading', '1', \true); $this->download_zip_database_and_extract(); if (!$this->is_existing_database_valid()) { $this->download_raw_database(); } else { } \update_option('iawp_is_database_downloading', '0', \true); $this->record_attempt(); } public function should_download() : bool { if (!$this->has_attempt_interval_elapsed()) { return \false; } if (\get_option('iawp_is_database_downloading', '0') === '1') { return \false; } if ($this->is_existing_database_valid()) { $this->record_attempt(); return \false; } return \true; } public function delete() : void { \wp_delete_file(self::path_to_database()); } private function download_zip_database_and_extract() : void { \wp_remote_get($this->zip_download_url, ['stream' => \true, 'filename' => $this->path_to_database_zip(), 'timeout' => 60]); try { $zip = new ZipArchive(); if ($zip->open($this->path_to_database_zip()) === \true) { $zip->extractTo(\IAWPSCOPED\iawp_upload_path_to('', \true)); $zip->close(); } } catch (Throwable $e) { // It's ok to fail } \wp_delete_file($this->path_to_database_zip()); } private function download_raw_database() : void { \wp_remote_get($this->raw_download_url, ['stream' => \true, 'filename' => self::path_to_database(), 'timeout' => 60]); } private function is_existing_database_valid() : bool { if (!\file_exists(self::path_to_database())) { return \false; } try { return \verify_file_md5(self::path_to_database(), $this->database_checksum); } catch (Throwable $e) { return \false; } } private function has_attempt_interval_elapsed() : bool { $last_attempted_at = $this->last_attempted_at(); $interval = new DateInterval('PT30M'); if (\is_null($last_attempted_at)) { return \true; } $is_past_interval_time = $last_attempted_at->add($interval) < new DateTime('now', Timezone::utc_timezone()); if ($is_past_interval_time) { return \true; } return \false; } private function last_attempted_at() : ?DateTime { $option_value = \get_option('iawp_geo_database_download_last_attempted_at', \false); if (!$option_value) { return null; } try { return new DateTime($option_value, Timezone::utc_timezone()); } catch (Throwable $e) { return null; } } private function record_attempt() : void { $now = new DateTime('now', Timezone::utc_timezone()); $value = $now->format('Y-m-d\\TH:i:s'); \update_option('iawp_geo_database_download_last_attempted_at', $value, \true); } private function path_to_database_zip() : string { return \IAWPSCOPED\iawp_upload_path_to('iawp-geo-db.zip', \true); } public static function path_to_database() : string { return \IAWPSCOPED\iawp_upload_path_to('iawp-geo-db.mmdb', \true); } } IAWP/Icon_Directory.php000064400000003413147600331220010730 0ustar00directory = $directory; $this->alt_text = $alt_text; $this->files = $this->get_files_in_directory($directory); } public function find(string $icon) : string { $icon_url = $this->find_icon_url($icon); if (\is_null($icon_url)) { return ''; } return '' . \esc_attr($this->alt_text) . ''; } private function find_icon_url(string $icon) : ?string { $file_name = $this->convert_icon_name_to_file_name($icon); if (\in_array($file_name, $this->files)) { return $this->get_url_for_file($file_name); } if (\in_array('default.svg', $this->files)) { return $this->get_url_for_file('default.svg'); } return null; } private function convert_icon_name_to_file_name(string $string) : string { return \str_replace([' ', '/'], '-', \strtolower($string)) . '.svg'; } private function get_url_for_file(string $file_name) : string { return \IAWPSCOPED\iawp_url_to($this->directory . $file_name) . '?version=' . \IAWP_VERSION; } private function get_files_in_directory(string $directory) : array { $files = \scandir(\IAWPSCOPED\iawp_path_to($directory)); if ($files === \false) { return []; } $files = \array_diff($files, ['..', '.']); $files = \array_values($files); return $files; } } IAWP/Icon_Directory_Factory.php000064400000002646147600331220012426 0ustar00toSql()); $escape_mysql_format_percentages = \str_replace('%', '%%', $add_slashes); $replace_question_marks = \str_replace('?', '%s', $escape_mysql_format_percentages); if (\function_exists('IAWPSCOPED\\ray')) { return ray(\vsprintf($replace_question_marks, $builder->getBindings())); } } private static function make_connection() : Connection { global $wpdb; $raw_host = $wpdb->dbhost; $database_name = $wpdb->dbname; $charset = $wpdb->dbcharset ?? 'utf8'; $username = $wpdb->dbuser; $password = $wpdb->dbpassword; $host_data = $wpdb->parse_db_host($raw_host); list($host, $port, $socket, $is_ipv6) = $host_data; if ($is_ipv6 && \extension_loaded('mysqlnd')) { $host = "[{$host}]"; } $charset_collate = $wpdb->determine_charset($charset, ''); $charset = $charset_collate['charset']; // $collation = $charset_collate['collate']; // Collation is no longer added due to issue with WP Rocket with testing 1.23.0. In the future, // $connection_options should have the collation property added only if it's defined. It should // not get set for empty strings. $connection_options = ['driver' => 'mysql', 'database' => $database_name, 'username' => $username, 'password' => $password, 'charset' => $charset, 'prefix' => '', 'options' => self::ssl_options()]; // Ensures that we use an SSL database connection when WordPress is using one. // WordPress does SSL, but not with certificate verification. We do the same. if (self::should_use_ssl()) { $connection_options['options'][PDO::MYSQL_ATTR_SSL_CA] = \true; $connection_options['options'][PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT] = \false; } if (isset($socket)) { $connection_options['unix_socket'] = $socket; } else { $connection_options['host'] = $host; if (isset($port)) { $connection_options['port'] = $port; } } $capsule = new Capsule(); $capsule->addConnection($connection_options); $capsule->setAsGlobal(); $capsule->bootEloquent(); $connection = $capsule->getConnection(); self::disable_mariadb_optimization($connection); return $connection; } /** * This disabled the lateral derived optimization for MariaDB users. This was cause slowdowns * when filtering even with few views. * * https://mariadb.com/kb/en/lateral-derived-optimization/ * * @param Connection $connection * * @return void */ private static function disable_mariadb_optimization(Connection $connection) { $pdo = $connection->getPdo(); $version = $pdo->query("SELECT VERSION() AS version")->fetchColumn(); if (\strpos(\strtolower($version), 'mariadb') === \false) { return; } try { $pdo->exec("SET optimizer_switch='split_materialized=off'"); } catch (\Throwable $exception) { } } private static function ssl_options() : array { if (self::should_use_ssl()) { if (!\defined('MYSQL_SSL_CA')) { return [PDO::MYSQL_ATTR_SSL_CA => \true, PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => \false]; } return [PDO::MYSQL_ATTR_SSL_CA => \MYSQL_SSL_CA, PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => \true]; } if (self::should_use_ssl_without_certificate_verification()) { return [PDO::MYSQL_ATTR_SSL_CA => \true, PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => \false]; } return []; } private static function should_use_ssl() : bool { if (!\defined('MYSQL_CLIENT_FLAGS')) { return \false; } if (\MYSQL_CLIENT_FLAGS & \MYSQLI_CLIENT_SSL) { return \true; } return \false; } private static function should_use_ssl_without_certificate_verification() : bool { if (!\defined('MYSQL_CLIENT_FLAGS')) { return \false; } if (\MYSQL_CLIENT_FLAGS & \MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT) { return \true; } return \false; } } IAWP/Independent_Analytics.php000064400000060143147600331220012263 0ustar00configure_carbon(); $this->settings = new \IAWP\Settings(); new \IAWP\REST_API(); new \IAWP\Dashboard_Widget(); new \IAWP\View_Counter(); new Submission_Listener(); Pruner::register_hook(); AJAX_Manager::getInstance(); if (!Migrations::is_migrating()) { new \IAWP\Track_Resource_Changes(); Menu_Bar_Stats::register(); WooCommerce_Order::register_hooks(); SureCart_Order::register_hooks(); } \IAWP\Cron_Job::register_custom_intervals(); $this->cron_manager = new \IAWP\Cron_Manager(); (new SureCart_Event_Sync_Job())->register_handler(); (new Click_Processing_Job())->register_handler(); if (\IAWPSCOPED\iawp_is_pro()) { $this->email_reports = new Email_Reports(); new \IAWP\Campaign_Builder(); new WooCommerce_Referrer_Meta_Box(); } \add_action('admin_enqueue_scripts', [$this, 'enqueue_scripts_and_styles'], 110); // Called at 110 to dequeue other scripts \add_action('wp_enqueue_scripts', [$this, 'enqueue_scripts_and_styles_front_end']); \add_action('admin_menu', [$this, 'add_admin_menu_pages']); \add_action('admin_init', [$this, 'remove_freemius_pricing_menu']); \add_filter('plugin_action_links_independent-analytics/iawp.php', [$this, 'plugin_action_links']); \add_action('init', [$this, 'polylang_translations']); \add_action('init', [$this, 'load_textdomain']); \IAWP_FS()->add_filter('pricing_url', [$this, 'change_freemius_pricing_url'], 10); \IAWP_FS()->add_filter('show_deactivation_feedback_form', function () { return \false; }); \add_action('admin_init', [$this, 'maybe_delete_mu_plugin']); \add_action('admin_body_class', [$this, 'add_body_class']); \add_filter('sgs_whitelist_wp_content', [$this, 'whitelist_click_endpoint']); \add_filter('cmplz_whitelisted_script_tags', [$this, 'whitelist_script_tag_for_complianz']); } public function add_body_class($classes) { if (\get_option('iawp_dark_mode')) { $classes .= ' iawp-dark-mode '; } $page = \IAWP\Env::get_page(); if (\is_string($page)) { $classes .= " {$page} "; } return $classes; } /** * At one point in time, there was a must-use plugin that was created. The plugin file and the * option need to get cleaned up. * @return void */ public function maybe_delete_mu_plugin() { $already_attempted = \get_option('iawp_attempted_to_delete_mu_plugin', '0'); if ($already_attempted === '1') { return; } if (\get_option('iawp_must_use_directory_not_writable', '0') === '1') { \delete_option('iawp_must_use_directory_not_writable'); } $mu_plugin_file = \trailingslashit(\WPMU_PLUGIN_DIR) . 'iawp-performance-boost.php'; if (\file_exists($mu_plugin_file)) { \unlink($mu_plugin_file); } \update_option('iawp_attempted_to_delete_mu_plugin', '1', \true); } public function load_textdomain() { \load_plugin_textdomain('independent-analytics', \false, \IAWP_LANGUAGES_DIRECTORY); } public function polylang_translations() { if (\function_exists('IAWPSCOPED\\pll_register_string')) { pll_register_string('view_counter', 'Views:', 'Independent Analytics'); } } // Changes the URL for the "Upgrade" tab in the Account menu public function change_freemius_pricing_url() { return 'https://independentwp.com/pricing/?utm_source=User+Dashboard&utm_medium=WP+Admin&utm_campaign=Upgrade+to+Pro&utm_content=Account'; } public function add_admin_menu_pages() { $title = \IAWP\Capability_Manager::show_white_labeled_ui() ? \esc_html__('Analytics', 'independent-analytics') : 'Independent Analytics'; \add_menu_page($title, \esc_html__('Analytics', 'independent-analytics'), \IAWP\Capability_Manager::menu_page_capability_string(), 'independent-analytics', function () { $analytics_page = new Analytics_Page(); $analytics_page->render(); }, $this->get_menu_icon(), 3); if (\IAWP\Capability_Manager::can_edit()) { \add_submenu_page('independent-analytics', \esc_html__('Settings', 'independent-analytics'), \esc_html__('Settings', 'independent-analytics'), \IAWP\Capability_Manager::menu_page_capability_string(), 'independent-analytics-settings', function () { $settings_page = new Settings_Page(); $settings_page->render(\false); }); } if (\IAWPSCOPED\iawp_is_pro()) { \add_submenu_page('independent-analytics', \esc_html__('Campaign Builder', 'independent-analytics'), \esc_html__('Campaign Builder', 'independent-analytics'), \IAWP\Capability_Manager::menu_page_capability_string(), 'independent-analytics-campaign-builder', function () { $campaign_builder_page = new Campaign_Builder_Page(); $campaign_builder_page->render(\false); }); if (\IAWP\Capability_Manager::can_edit()) { \add_submenu_page('independent-analytics', \esc_html__('Click Tracking', 'independent-analytics'), \esc_html__('Click Tracking', 'independent-analytics'), \IAWP\Capability_Manager::menu_page_capability_string(), 'independent-analytics-click-tracking', function () { $click_tracking_page = new Click_Tracking_Page(); $click_tracking_page->render(\false); }); } } if (\IAWP\Capability_Manager::show_branded_ui()) { \add_submenu_page('independent-analytics', \esc_html__('Help & Support', 'independent-analytics'), \esc_html__('Help & Support', 'independent-analytics'), \IAWP\Capability_Manager::menu_page_capability_string(), 'independent-analytics-support-center', function () { $support_page = new Support_Page(); $support_page->render(\false); }); } if (\IAWP\Capability_Manager::show_branded_ui()) { $menu_html = '' . \esc_html__('Changelog', 'independent-analytics') . ''; $menu_html = $this->changelog_viewed_since_update() ? $menu_html . ' ' . \esc_html__('New', 'independent-analytics') . '' : $menu_html; \add_submenu_page('independent-analytics', \esc_html__('Changelog', 'independent-analytics'), $menu_html, \IAWP\Capability_Manager::menu_page_capability_string(), 'independent-analytics-updates', function () { $updates_page = new Updates_Page(); $updates_page->render(\false); }); } if (\IAWPSCOPED\iawp_is_free() && \IAWP\Capability_Manager::show_branded_ui()) { \add_submenu_page('independent-analytics', \esc_html__('Upgrade to Pro →', 'independent-analytics'), '' . \esc_html__('Upgrade to Pro →', 'independent-analytics') . '', \IAWP\Capability_Manager::menu_page_capability_string(), \esc_url('https://independentwp.com/pricing/?utm_source=User+Dashboard&utm_medium=WP+Admin&utm_campaign=Upgrade+to+Pro&utm_content=Sidebar')); } } // The menu link is removed in the SDK setup, but this makes it completely inaccessible public function remove_freemius_pricing_menu() { \remove_submenu_page('independent-analytics', 'independent-analytics-pricing'); } public function register_scripts_and_styles() : void { \wp_register_style('iawp-styles', \IAWPSCOPED\iawp_url_to('dist/styles/style.css'), [], \IAWP_VERSION); \wp_register_style('iawp-dashboard-widget-styles', \IAWPSCOPED\iawp_url_to('dist/styles/dashboard_widget.css'), [], \IAWP_VERSION); \wp_register_style('iawp-freemius-notice-styles', \IAWPSCOPED\iawp_url_to('dist/styles/freemius_notice_styles.css'), [], \IAWP_VERSION); \wp_register_style('iawp-posts-menu-styles', \IAWPSCOPED\iawp_url_to('dist/styles/posts_menu.css'), [], \IAWP_VERSION); \wp_register_script('iawp-javascript', \IAWPSCOPED\iawp_url_to('dist/js/index.js'), ['wp-i18n'], \IAWP_VERSION); \wp_set_script_translations('iawp-javascript', 'independent-analytics'); \wp_register_script('iawp-dashboard-widget-javascript', \IAWPSCOPED\iawp_url_to('dist/js/dashboard_widget.js'), ['wp-i18n'], \IAWP_VERSION); \wp_set_script_translations('iawp-dashboard-widget-javascript', 'independent-analytics'); \wp_register_script('iawp-layout-javascript', \IAWPSCOPED\iawp_url_to('dist/js/layout.js'), ['wp-i18n'], \IAWP_VERSION); \wp_set_script_translations('iawp-layout-javascript', 'independent-analytics'); \wp_register_script('iawp-settings-javascript', \IAWPSCOPED\iawp_url_to('dist/js/settings.js'), ['wp-color-picker', 'wp-i18n'], \IAWP_VERSION); \wp_set_script_translations('iawp-settings-javascript', 'independent-analytics'); \wp_register_script('iawp-click-tracking-menu-javascript', \IAWPSCOPED\iawp_url_to('dist/js/click-tracking-menu.js'), ['wp-i18n'], \IAWP_VERSION); \wp_set_script_translations('iawp-click-tracking-menu-javascript', 'independent-analytics'); if (Menu_Bar_Stats::is_option_enabled()) { \wp_register_style('iawp-front-end-styles', \IAWPSCOPED\iawp_url_to('dist/styles/menu_bar_stats.css'), [], \IAWP_VERSION); } if (\is_rtl()) { \wp_register_style('iawp-styles-rtl', \IAWPSCOPED\iawp_url_to('dist/styles/rtl.css'), [], \IAWP_VERSION); } } public function register_scripts_and_styles_front_end() : void { if (Menu_Bar_Stats::is_option_enabled()) { \wp_register_style('iawp-front-end-styles', \IAWPSCOPED\iawp_url_to('dist/styles/menu_bar_stats.css'), [], \IAWP_VERSION); } } public function enqueue_scripts_and_styles($hook) { $this->register_scripts_and_styles(); $page = \IAWP\Env::get_page(); $this->enqueue_translations(); $this->enqueue_nonces(); \wp_enqueue_style('iawp-freemius-notice-styles'); if (\is_string($page)) { \wp_enqueue_style('iawp-styles'); \wp_enqueue_script('iawp-javascript'); \wp_enqueue_script('iawp-layout-javascript'); $this->dequeue_bad_actors(); $this->maybe_override_adminify_styles(); if (\is_rtl()) { \wp_enqueue_style('iawp-styles-rtl'); } } if ($page === 'independent-analytics-settings') { \wp_enqueue_style('wp-color-picker'); \wp_enqueue_script('iawp-settings-javascript'); } elseif ($page === 'independent-analytics-click-tracking') { \wp_enqueue_script('iawp-click-tracking-menu-javascript'); } elseif ($hook === 'index.php') { \wp_enqueue_script('iawp-dashboard-widget-javascript'); \wp_enqueue_style('iawp-dashboard-widget-styles'); } elseif ($hook === 'edit.php') { \wp_enqueue_style('iawp-posts-menu-styles'); } if (Menu_Bar_Stats::is_option_enabled()) { \wp_enqueue_style('iawp-front-end-styles'); } } public function enqueue_scripts_and_styles_front_end() { if (Menu_Bar_Stats::is_option_enabled()) { $this->register_scripts_and_styles_front_end(); \wp_enqueue_style('iawp-front-end-styles'); } } public function enqueue_translations() { \wp_register_script('iawp-translations', ''); \wp_enqueue_script('iawp-translations'); \wp_add_inline_script('iawp-translations', 'const iawpText = ' . \json_encode(['views' => \__('Views', 'independent-analytics'), 'exactDates' => \__('Apply Exact Dates', 'independent-analytics'), 'relativeDates' => \__('Apply Relative Dates', 'independent-analytics'), 'copied' => \__('Copied', 'independent-analytics'), 'exportingPages' => \__('Exporting Pages...', 'independent-analytics'), 'exportPages' => \__('Export Pages', 'independent-analytics'), 'exportingReferrers' => \__('Exporting Referrers...', 'independent-analytics'), 'exportReferrers' => \__('Export Referrers', 'independent-analytics'), 'exportingGeolocations' => \__('Exporting Geolocations...', 'independent-analytics'), 'exportGeolocations' => \__('Export Geolocations', 'independent-analytics'), 'exportingDevices' => \__('Exporting Devices...', 'independent-analytics'), 'exportDevices' => \__('Export Devices', 'independent-analytics'), 'exportingCampaigns' => \__('Exporting Campaigns...', 'independent-analytics'), 'exportCampaigns' => \__('Export Campaigns', 'independent-analytics'), 'exportingClicks' => \__('Exporting Clicks', 'independent-analytics'), 'exportClicks' => \__('Export Clicks', 'independent-analytics'), 'invalidReportArchive' => \__('This report archive is invalid. Please export your reports and try again.', 'independent-analytics'), 'openMobileMenu' => \__('Open menu', 'independent-analytics'), 'closeMobileMenu' => \__('Close menu', 'independent-analytics')]), 'before'); } public function enqueue_nonces() { \wp_register_script('iawp-nonces', ''); \wp_enqueue_script('iawp-nonces'); \wp_add_inline_script('iawp-nonces', 'const iawpActions = ' . \json_encode(AJAX_Manager::getInstance()->get_action_signatures()), 'before'); } public function get_option($name, $default) { $option = \get_option($name, $default); return $option === '' ? $default : $option; } public function date_i18n(string $format, \DateTime $date) : string { return \date_i18n($format, $date->setTimezone(Timezone::site_timezone())->getTimestamp() + Timezone::site_offset_in_seconds($date)); } public function plugin_action_links($links) { // Create the link $settings_link = '' . \esc_html__('Analytics Dashboard', 'independent-analytics') . ''; // Add the link to the start of the array \array_unshift($links, $settings_link); return $links; } public function pagination_page_size() { return 50; } public function dequeue_bad_actors() { // https://wordpress.org/plugins/comment-link-remove/ \wp_dequeue_style('qc_clr_admin_style_css'); // https://wordpress.org/plugins/webappick-pdf-invoice-for-woocommerce/ \wp_dequeue_style('woo-invoice'); // https://wordpress.org/plugins/wp-media-files-name-rename/ \wp_dequeue_style('wpcmp_bootstrap_css'); // https://wordpress.org/plugins/morepuzzles/ \wp_dequeue_style('bscss'); \wp_dequeue_style('mypluginstyle'); } public function maybe_override_adminify_styles() { if (\is_plugin_active('adminify/adminify.php')) { $settings = \get_option('_wpadminify'); if ($settings) { if (\array_key_exists('admin_ui', $settings)) { if ($settings['admin_ui']) { \wp_register_style('iawp-adminify-styles', \IAWPSCOPED\iawp_url_to('dist/styles/adminify.css'), [], \IAWP_VERSION); \wp_enqueue_style('iawp-adminify-styles'); } } } } } public function changelog_viewed_since_update() : bool { if (\number_format(\floatval(\IAWP_VERSION), 1) > \floatval($this->get_option('iawp_last_update_viewed', '0'))) { return \true; } return \false; } public function is_form_submission_support_enabled() : bool { if (!\is_bool($this->is_form_submission_support_enabled)) { $this->is_form_submission_support_enabled = \IAWPSCOPED\iawp_is_pro() && Form::has_active_form_plugin() && \IAWP\Capability_Manager::can_view_all_analytics(); } return $this->is_form_submission_support_enabled; } public function is_woocommerce_support_enabled() : bool { if (!\is_bool($this->is_woocommerce_support_enabled)) { $this->is_woocommerce_support_enabled = $this->actually_check_if_woocommerce_support_is_enabled(); } return $this->is_woocommerce_support_enabled; } public function is_surecart_support_enabled() : bool { if (!\is_bool($this->is_surecart_support_enabled)) { $this->is_surecart_support_enabled = $this->actually_check_if_surecart_support_is_enabled(); } return $this->is_surecart_support_enabled; } public function is_ecommerce_support_enabled() : bool { return $this->is_woocommerce_support_enabled() || $this->is_surecart_support_enabled(); } // This whitelists our plugin with the "Complianz" plugin public function whitelist_script_tag_for_complianz($scripts) { $scripts[] = '/wp-json/iawp/search'; return $scripts; } // This is for compatibility with the "Lock and Protect System Folders" setting in the Security Optimizer plugin public function whitelist_click_endpoint($whitelist) { if (\IAWPSCOPED\iawp_is_free()) { return $whitelist; } $whitelist[] = 'iawp-click-endpoint.php'; return $whitelist; } private function actually_check_if_woocommerce_support_is_enabled() : bool { global $wpdb; if (\IAWPSCOPED\iawp_is_free()) { return \false; } if (\IAWP\Capability_Manager::can_only_view_authored_analytics()) { return \false; } if (!\is_plugin_active('woocommerce/woocommerce.php')) { return \false; } $table_name = $wpdb->prefix . 'wc_order_stats'; $order_stats_table = $wpdb->get_row($wpdb->prepare(' SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = %s AND TABLE_NAME = %s ', $wpdb->dbname, $table_name)); if (\is_null($order_stats_table)) { return \false; } return \true; } private function actually_check_if_surecart_support_is_enabled() : bool { if (\IAWPSCOPED\iawp_is_free()) { return \false; } return \is_plugin_active('surecart/surecart.php'); } private function get_menu_icon() { if (\is_null(\IAWP\Env::get_page())) { return 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNTEzcHgiIGhlaWdodD0iMjU0cHgiIHZpZXdCb3g9IjAgMCA1MTMgMjU0IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgogICAgPHRpdGxlPkljb248L3RpdGxlPgogICAgPGcgaWQ9IlBhZ2UtMSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9Ik1lbnUtSWNvbiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEyNiwgLTIyOCkiIGZpbGw9IiNBN0FBQUQiPgogICAgICAgICAgICA8ZyBpZD0iV2hpdGUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDgyLCA1NSkiPgogICAgICAgICAgICAgICAgPGcgaWQ9Ikljb24iIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQ0LjUsIDE3MykiPgogICAgICAgICAgICAgICAgICAgIDxwb2x5Z29uIGlkPSJOZWNrLTMiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQwMi44MDU3LCAxMDguNjEyNSkgcm90YXRlKDQ1KSB0cmFuc2xhdGUoLTQwMi44MDU3LCAtMTA4LjYxMjUpIiBwb2ludHM9IjM5MS4xNjkzNTYgNTYuMjQ4ODI1OSA0MTQuNDQyMDgzIDU2LjI0ODgyNTkgNDE0LjQ0MjA4MyAxNjAuOTc2MDk5IDM5MS4xNjkzNTYgMTYwLjk3NjA5OSI+PC9wb2x5Z29uPgogICAgICAgICAgICAgICAgICAgIDxwb2x5Z29uIGlkPSJOZWNrLTIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI1NiwgMTI1LjY3MjcpIHJvdGF0ZSgtNjApIHRyYW5zbGF0ZSgtMjU2LCAtMTI1LjY3MjcpIiBwb2ludHM9IjI0NC4zNjM2MzYgNzMuMzA5MDkwOSAyNjcuNjM2MzY0IDczLjMwOTA5MDkgMjY3LjYzNjM2NCAxNzguMDM2MzY0IDI0NC4zNjM2MzYgMTc4LjAzNjM2NCI+PC9wb2x5Z29uPgogICAgICAgICAgICAgICAgICAgIDxwb2x5Z29uIGlkPSJOZWNrLTEiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEwOS41Njk0LCAxNDQuNjg1Mikgcm90YXRlKDQ1KSB0cmFuc2xhdGUoLTEwOS41Njk0LCAtMTQ0LjY4NTIpIiBwb2ludHM9Ijk3LjkzMjk5MjMgOTIuMzIxNTUzMiAxMjEuMjA1NzIgOTIuMzIxNTUzMiAxMjEuMjA1NzIgMTk3LjA0ODgyNiA5Ny45MzI5OTIzIDE5Ny4wNDg4MjYiPjwvcG9seWdvbj4KICAgICAgICAgICAgICAgICAgICA8Y2lyY2xlIGlkPSJQb2ludC00IiBjeD0iNDY4Ljk0NTQ1NSIgY3k9IjQzLjA1NDU0NTUiIHI9IjQzLjA1NDU0NTUiPjwvY2lyY2xlPgogICAgICAgICAgICAgICAgICAgIDxjaXJjbGUgaWQ9IlBvaW50LTMiIGN4PSIzMzYuMjkwOTA5IiBjeT0iMTczLjM4MTgxOCIgcj0iNDMuMDU0NTQ1NSI+PC9jaXJjbGU+CiAgICAgICAgICAgICAgICAgICAgPGNpcmNsZSBpZD0iUG9pbnQtMiIgY3g9IjE3NS43MDkwOTEiIGN5PSI3OS4xMjcyNzI3IiByPSI0My4wNTQ1NDU1Ij48L2NpcmNsZT4KICAgICAgICAgICAgICAgICAgICA8Y2lyY2xlIGlkPSJQb2ludC0xIiBjeD0iNDMuMDU0NTQ1NSIgY3k9IjIxMC42MTgxODIiIHI9IjQzLjA1NDU0NTUiPjwvY2lyY2xlPgogICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICA8L2c+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4='; } else { return 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNTEzcHgiIGhlaWdodD0iMjU0cHgiIHZpZXdCb3g9IjAgMCA1MTMgMjU0IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgogICAgPHRpdGxlPkljb248L3RpdGxlPgogICAgPGcgaWQ9IlBhZ2UtMSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9Ik1lbnUtSWNvbiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTc3NSwgLTIyOSkiIGZpbGw9IiNGRkZGRkYiPgogICAgICAgICAgICA8ZyBpZD0iV2hpdGUtQ29weSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNzMxLCA1NikiPgogICAgICAgICAgICAgICAgPGcgaWQ9Ikljb24iIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQ0LjUsIDE3MykiPgogICAgICAgICAgICAgICAgICAgIDxwb2x5Z29uIGlkPSJOZWNrLTMiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQwMi44MDU3LCAxMDguNjEyNSkgcm90YXRlKDQ1KSB0cmFuc2xhdGUoLTQwMi44MDU3LCAtMTA4LjYxMjUpIiBwb2ludHM9IjM5MS4xNjkzNTYgNTYuMjQ4ODI1OSA0MTQuNDQyMDgzIDU2LjI0ODgyNTkgNDE0LjQ0MjA4MyAxNjAuOTc2MDk5IDM5MS4xNjkzNTYgMTYwLjk3NjA5OSI+PC9wb2x5Z29uPgogICAgICAgICAgICAgICAgICAgIDxwb2x5Z29uIGlkPSJOZWNrLTIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI1NiwgMTI1LjY3MjcpIHJvdGF0ZSgtNjApIHRyYW5zbGF0ZSgtMjU2LCAtMTI1LjY3MjcpIiBwb2ludHM9IjI0NC4zNjM2MzYgNzMuMzA5MDkwOSAyNjcuNjM2MzY0IDczLjMwOTA5MDkgMjY3LjYzNjM2NCAxNzguMDM2MzY0IDI0NC4zNjM2MzYgMTc4LjAzNjM2NCI+PC9wb2x5Z29uPgogICAgICAgICAgICAgICAgICAgIDxwb2x5Z29uIGlkPSJOZWNrLTEiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEwOS41Njk0LCAxNDQuNjg1Mikgcm90YXRlKDQ1KSB0cmFuc2xhdGUoLTEwOS41Njk0LCAtMTQ0LjY4NTIpIiBwb2ludHM9Ijk3LjkzMjk5MjMgOTIuMzIxNTUzMiAxMjEuMjA1NzIgOTIuMzIxNTUzMiAxMjEuMjA1NzIgMTk3LjA0ODgyNiA5Ny45MzI5OTIzIDE5Ny4wNDg4MjYiPjwvcG9seWdvbj4KICAgICAgICAgICAgICAgICAgICA8Y2lyY2xlIGlkPSJQb2ludC00IiBjeD0iNDY4Ljk0NTQ1NSIgY3k9IjQzLjA1NDU0NTUiIHI9IjQzLjA1NDU0NTUiPjwvY2lyY2xlPgogICAgICAgICAgICAgICAgICAgIDxjaXJjbGUgaWQ9IlBvaW50LTMiIGN4PSIzMzYuMjkwOTA5IiBjeT0iMTczLjM4MTgxOCIgcj0iNDMuMDU0NTQ1NSI+PC9jaXJjbGU+CiAgICAgICAgICAgICAgICAgICAgPGNpcmNsZSBpZD0iUG9pbnQtMiIgY3g9IjE3NS43MDkwOTEiIGN5PSI3OS4xMjcyNzI3IiByPSI0My4wNTQ1NDU1Ij48L2NpcmNsZT4KICAgICAgICAgICAgICAgICAgICA8Y2lyY2xlIGlkPSJQb2ludC0xIiBjeD0iNDMuMDU0NTQ1NSIgY3k9IjIxMC42MTgxODIiIHI9IjQzLjA1NDU0NTUiPjwvY2lyY2xlPgogICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICA8L2c+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4='; } } private function configure_carbon() { $locale = \get_locale(); // Carbon will throw an error if de_DE_Formal is used if ('de_de_formal' === \strtolower($locale)) { $locale = 'de_DE'; } Carbon::setLocale($locale); } } IAWP/Interrupt.php000064400000003225147600331220010011 0ustar00template = $template; } public function render(?array $options = null) : void { if ($this->is_admin_page()) { \add_action('admin_enqueue_scripts', [$this, 'enqueue_styles']); } \add_action('admin_menu', function () use($options) { $title = \IAWP\Capability_Manager::show_white_labeled_ui() ? \esc_html__('Analytics', 'independent-analytics') : 'Independent Analytics'; \add_menu_page($title, \esc_html__('Analytics', 'independent-analytics'), \IAWP\Capability_Manager::menu_page_capability_string(), 'independent-analytics', function () use($options) { $this->render_page($options); }, 'dashicons-analytics', 3); }); } public function enqueue_styles() { \wp_register_style('iawp-styles', \IAWPSCOPED\iawp_url_to('dist/styles/style.css'), [], \IAWP_VERSION); \wp_enqueue_style('iawp-styles'); } private function is_admin_page() : bool { $page = $_GET['page'] ?? null; return \is_admin() && $page === 'independent-analytics'; } private function render_page(?array $options) : void { if (\is_null($options)) { $options = []; } ?>
run('partials.interrupt-header'); ?> run($this->template, $options); ?>
'Google', 'type' => 'Search', 'domains' => ['www.google.com', 'www.google.ad', 'www.google.ae', 'www.google.com.af', 'www.google.com.ag', 'www.google.com.ai', 'www.google.al', 'www.google.am', 'www.google.co.ao', 'www.google.com.ar', 'www.google.as', 'www.google.at', 'www.google.com.au', 'www.google.az', 'www.google.ba', 'www.google.com.bd', 'www.google.be', 'www.google.bf', 'www.google.bg', 'www.google.com.bh', 'www.google.bi', 'www.google.bj', 'www.google.com.bn', 'www.google.com.bo', 'www.google.com.br', 'www.google.bs', 'www.google.bt', 'www.google.co.bw', 'www.google.by', 'www.google.com.bz', 'www.google.ca', 'www.google.cd', 'www.google.cf', 'www.google.cg', 'www.google.ch', 'www.google.ci', 'www.google.co.ck', 'www.google.cl', 'www.google.cm', 'www.google.cn', 'www.google.com.co', 'www.google.co.cr', 'www.google.com.cu', 'www.google.cv', 'www.google.com.cy', 'www.google.cz', 'www.google.de', 'www.google.dj', 'www.google.dk', 'www.google.dm', 'www.google.com.do', 'www.google.dz', 'www.google.com.ec', 'www.google.ee', 'www.google.com.eg', 'www.google.es', 'www.google.com.et', 'www.google.fi', 'www.google.com.fj', 'www.google.fm', 'www.google.fr', 'www.google.ga', 'www.google.ge', 'www.google.gg', 'www.google.com.gh', 'www.google.com.gi', 'www.google.gl', 'www.google.gm', 'www.google.gr', 'www.google.com.gt', 'www.google.gy', 'www.google.com.hk', 'www.google.hn', 'www.google.hr', 'www.google.ht', 'www.google.hu', 'www.google.co.id', 'www.google.ie', 'www.google.co.il', 'www.google.im', 'www.google.co.in', 'www.google.iq', 'www.google.is', 'www.google.it', 'www.google.je', 'www.google.com.jm', 'www.google.jo', 'www.google.co.jp', 'www.google.co.ke', 'www.google.com.kh', 'www.google.ki', 'www.google.kg', 'www.google.co.kr', 'www.google.com.kw', 'www.google.kz', 'www.google.la', 'www.google.com.lb', 'www.google.li', 'www.google.lk', 'www.google.co.ls', 'www.google.lt', 'www.google.lu', 'www.google.lv', 'www.google.com.ly', 'www.google.co.ma', 'www.google.md', 'www.google.me', 'www.google.mg', 'www.google.mk', 'www.google.ml', 'www.google.com.mm', 'www.google.mn', 'www.google.ms', 'www.google.com.mt', 'www.google.mu', 'www.google.mv', 'www.google.mw', 'www.google.com.mx', 'www.google.com.my', 'www.google.co.mz', 'www.google.com.na', 'www.google.com.ng', 'www.google.com.ni', 'www.google.ne', 'www.google.nl', 'www.google.no', 'www.google.com.np', 'www.google.nr', 'www.google.nu', 'www.google.co.nz', 'www.google.com.om', 'www.google.com.pa', 'www.google.com.pe', 'www.google.com.pg', 'www.google.com.ph', 'www.google.com.pk', 'www.google.pl', 'www.google.pn', 'www.google.com.pr', 'www.google.ps', 'www.google.pt', 'www.google.com.py', 'www.google.com.qa', 'www.google.ro', 'www.google.ru', 'www.google.rw', 'www.google.com.sa', 'www.google.com.sb', 'www.google.sc', 'www.google.se', 'www.google.com.sg', 'www.google.sh', 'www.google.si', 'www.google.sk', 'www.google.com.sl', 'www.google.sn', 'www.google.so', 'www.google.sm', 'www.google.sr', 'www.google.st', 'www.google.com.sv', 'www.google.td', 'www.google.tg', 'www.google.co.th', 'www.google.com.tj', 'www.google.tl', 'www.google.tm', 'www.google.tn', 'www.google.to', 'www.google.com.tr', 'www.google.tt', 'www.google.com.tw', 'www.google.co.tz', 'www.google.com.ua', 'www.google.co.ug', 'www.google.co.uk', 'www.google.com.uy', 'www.google.co.uz', 'www.google.com.vc', 'www.google.co.ve', 'www.google.vg', 'www.google.co.vi', 'www.google.com.vn', 'www.google.vu', 'www.google.ws', 'www.google.rs', 'www.google.co.za', 'www.google.co.zm', 'www.google.co.zw', 'www.google.cat', 'com.google.android.gm']], ['name' => 'Google Ads', 'type' => 'Ad', 'domains' => ['googleads.iawp']], ['name' => 'Google Display Network', 'type' => 'Ad', 'domains' => ['googleads.g.doubleclick.net']], ['name' => 'Google Docs', 'type' => 'Referrer', 'domains' => ['docs.google.com']], ['name' => 'Google Lens', 'type' => 'Search', 'domains' => ['lens.google.com']], ['name' => 'Gmail', 'type' => 'Referrer', 'domains' => ['mail.google.com']], ['name' => 'Yahoo', 'type' => 'Search', 'domains' => ['search.yahoo.com', 'at.search.yahoo.com', 'au.search.yahoo.com', 'be.search.yahoo.com', 'br.search.yahoo.com', 'ca.search.yahoo.com', 'ch.search.yahoo.com', 'de.search.yahoo.com', 'es.search.yahoo.com', 'espanol.search.yahoo.com', 'fi.search.yahoo.com', 'fr.search.yahoo.com', 'gr.search.yahoo.com', 'hk.search.yahoo.com', 'id.search.yahoo.com', 'ie.search.yahoo.com', 'il.search.yahoo.com', 'in.search.yahoo.com', 'it.search.yahoo.com', 'malaysia.search.yahoo.com', 'nl.search.yahoo.com', 'no.search.yahoo.com', 'pe.search.yahoo.com', 'ph.search.yahoo.com', 'pl.search.yahoo.com', 'qc.search.yahoo.com', 'r.search.yahoo.com', 'ro.search.yahoo.com', 'ru.search.yahoo.com', 'se.search.yahoo.com', 'sg.search.yahoo.com', 'th.search.yahoo.com', 'tr.search.yahoo.com', 'tw.search.yahoo.com', 'ua.search.yahoo.com', 'vn.search.yahoo.com', 'za.search.yahoo.com', 'uk.search.yahoo.com', 'us.search.yahoo.com', 'search.yahoo.co.jp', 'co.search.yahoo.com']], ['name' => 'Bing', 'type' => 'Search', 'domains' => ['bing.com', 'www.bing.com', 'cn.bing.com']], ['name' => 'Yandex', 'type' => 'Search', 'domains' => ['yandex.com', 'yandex.ru', 'yandex.ua', 'yandex.by', 'yandex.kz', 'yandex.uz', 'yandex.com.tr', 'yandex.fr', 'yandex.az', 'yandex.com.ge', 'yandex.com.am', 'yandex.co.il', 'yandex.lv', 'yandex.lt', 'yandex.ee', 'yandex.md', 'yandex.tm', 'yandex.tj']], ['name' => 'DuckDuckGo', 'type' => 'Search', 'domains' => ['duckduckgo.com']], ['name' => 'Ecosia', 'type' => 'Search', 'domains' => ['www.ecosia.org']], ['name' => 'Qwant', 'type' => 'Search', 'domains' => ['www.qwant.com']], ['name' => 'AlohaFind', 'type' => 'Search', 'domains' => ['alohafind.com']], ['name' => 'Brave', 'type' => 'Search', 'domains' => ['search.brave.com']], ['name' => 'Presearch', 'type' => 'Search', 'domains' => ['presearch.com']], ['name' => 'Twitter', 'type' => 'Social', 'domains' => ['twitter.com', 't.co']], ['name' => 'Facebook', 'type' => 'Social', 'domains' => ['www.facebook.com', 'm.facebook.com', 'lm.facebook.com', 'l.facebook.com']], ['name' => 'Instagram', 'type' => 'Social', 'domains' => ['instagram.com', 'www.instagram.com', 'l.instagram.com', 'lm.instagram.com']], ['name' => 'TikTok', 'type' => 'Social', 'domains' => ['www.tiktok.com']], ['name' => 'LinkedIn', 'type' => 'Social', 'domains' => ['www.linkedin.com', 'com.linkedin.android']], ['name' => 'Pinterest', 'type' => 'Social', 'domains' => ['www.pinterest.com']], ['name' => 'YouTube', 'type' => 'Social', 'domains' => ['youtube.com', 'www.youtube.com', 'm.youtube.com']], ['name' => 'AOL Search', 'type' => 'Search', 'domains' => ['search.aol.com']], ['name' => 'ArtStation', 'type' => 'Social', 'domains' => ['www.artstation.com']], ['name' => 'Baidu', 'type' => 'Search', 'domains' => ['baidu.com', 'www.baidu.com', 'm.baidu.com']], ['name' => 'Bandcamp', 'type' => 'Social', 'domains' => ['bandcamp.com']], ['name' => 'Behance', 'type' => 'Social', 'domains' => ['www.behance.net']], ['name' => 'Bitbucket', 'type' => 'Social', 'domains' => ['bitbucket.org']], ['name' => 'CodePen', 'type' => 'Social', 'domains' => ['codepen.io']], ['name' => 'DeviantArt', 'type' => 'Social', 'domains' => ['www.deviantart.com']], ['name' => 'Discord', 'type' => 'Social', 'domains' => ['discord.com']], ['name' => 'Dribble', 'type' => 'Social', 'domains' => ['dribbble.com']], ['name' => 'Flickr', 'type' => 'Social', 'domains' => ['flickr.com']], ['name' => 'GitHub', 'type' => 'Social', 'domains' => ['gist.github.com', 'github.com']], ['name' => 'Goodreads', 'type' => 'Social', 'domains' => ['www.goodreads.com']], ['name' => 'Hacker News', 'type' => 'Social', 'domains' => ['news.ycombinator.com']], ['name' => 'Meetup', 'type' => 'Social', 'domains' => ['www.meetup.com']], ['name' => 'Mixcloud', 'type' => 'Social', 'domains' => ['www.mixcloud.com']], ['name' => 'Patreon', 'type' => 'Social', 'domains' => ['www.patreon.com']], ['name' => 'PayPal', 'type' => 'Referrer', 'domains' => ['www.paypal.com']], ['name' => 'Quora', 'type' => 'Social', 'domains' => ['bn.quora.com', 'www.quora.com']], ['name' => 'Tencent QQ', 'type' => 'Social', 'domains' => ['www.qq.com']], ['name' => 'Ravelry', 'type' => 'Social', 'domains' => ['www.ravelry.com']], ['name' => 'Reddit', 'type' => 'Social', 'domains' => ['out.reddit.com', 'www.reddit.com']], ['name' => 'Slack', 'type' => 'Social', 'domains' => ['slack.com']], ['name' => 'SlideShare', 'type' => 'Social', 'domains' => ['www.slideshare.net']], ['name' => 'Snapchat', 'type' => 'Social', 'domains' => ['www.snapchat.com']], ['name' => 'SoundCloud', 'type' => 'Social', 'domains' => ['soundcloud.com']], ['name' => 'Stack Overflow', 'type' => 'Social', 'domains' => ['stackoverflow.com']], ['name' => 'Startpage', 'type' => 'Search', 'domains' => ['www.startpage.com']], ['name' => 'StumbleUpon', 'type' => 'Social', 'domains' => ['www.stumbleupon.com']], ['name' => 'Telegram', 'type' => 'Social', 'domains' => ['telegram.org']], ['name' => 'Weibo', 'type' => 'Social', 'domains' => ['weibo.com']], ['name' => 'Tumblr', 'type' => 'Social', 'domains' => ['www.tumblr.com']], ['name' => 'Twitch', 'type' => 'Social', 'domains' => ['www.twitch.tv']], ['name' => 'Vimeo', 'type' => 'Social', 'domains' => ['vimeo.com']], ['name' => 'WeChat', 'type' => 'Social', 'domains' => ['www.wechat.com']], ['name' => 'WhatsApp', 'type' => 'Social', 'domains' => ['www.whatsapp.com']], ['name' => 'Udemy', 'type' => 'Social', 'domains' => ['www.udemy.com']], ['name' => '500px', 'type' => 'Social', 'domains' => ['500px.com']], ['name' => 'WordPress.org', 'type' => 'Social', 'domains' => ['wordpress.org', 'ru.wordpress.org', 'ca.wordpress.org', 'fr.wordpress.org', 'pl.wordpress.org', 'id.wordpress.org', 'ur.wordpress.org', 'bn.wordpress.org', 'ja.wordpress.org', 'pt.wordpress.org', 'it.wordpress.org', 'hy.wordpress.org', 'hi.wordpress.org', 'de.wordpress.org', 'ar.wordpress.org', 'es.wordpress.org', 'cn.wordpress.org', 'en-ca.wordpress.org', 'en-gb.wordpress.org']]]; public static function get_group_for(string $domain) : ?array { foreach (self::$referrers as $referrer) { if (\in_array($domain, $referrer['domains'])) { return ['domain' => \reset($referrer['domains']), 'type' => $referrer['type'], 'name' => $referrer['name']]; } } return null; } public static function referrers() : array { return self::$referrers; } public static function replace_known_referrers_table() { global $wpdb; $referrer_groups_table = \IAWP\Query::get_table_name(\IAWP\Query::REFERRER_GROUPS); $known_referrers = self::referrers(); $wpdb->query("DELETE FROM {$referrer_groups_table}"); foreach ($known_referrers as $group) { foreach ($group['domains'] as $domain) { $wpdb->insert($referrer_groups_table, ['name' => $group['name'], 'domain' => $group['domains'][0], 'domain_to_match' => $domain, 'type' => $group['type']]); } } } } IAWP/Patch.php000064400000003103147600331220007047 0ustar00email_reports->next_event_scheduled_at())) { \IAWPSCOPED\iawp()->email_reports->schedule(); } \update_option('iawp_patch_2_6_2_applied', '1', \true); } } public static function patch_2_8_7_potential_duplicates() { global $wpdb; $db_version = \get_option('iawp_db_version', '0'); $is_migrating = \get_option('iawp_is_migrating', '0') === '1'; $last_finished_step = \get_option('iawp_last_finished_migration_step', '0'); $has_error = \get_option('iawp_migration_error_query', null) !== null && \get_option('iawp_migration_error', null) !== null; if ($db_version === '36' && $is_migrating && \in_array($last_finished_step, ['2', '3']) && $has_error) { if ($last_finished_step === '3') { $orders_table = \IAWP\Query::get_table_name(\IAWP\Query::ORDERS); $wpdb->query("DROP INDEX orders_woocommerce_order_id_index ON {$orders_table}"); } \delete_option('iawp_migration_error_original_error_message'); \delete_option('iawp_last_finished_migration_step'); \delete_option('iawp_migration_error'); \delete_option('iawp_migration_error_query'); \update_option('iawp_is_migrating', '0', \true); } } } IAWP/Payload_Validator.php000064400000004776147600331220011427 0ustar00payload = $payload; $this->signature = $signature; } public function is_valid() : bool { $signature = \md5(Salt::request_payload_salt() . $this->payload); if ($signature !== $this->signature) { return \false; } $decoded_payload = \json_decode($this->payload, \true); if ($decoded_payload === null) { return \false; } return \true; } public function payload() : ?array { if (!$this->is_valid()) { return null; } return \json_decode($this->payload, \true); } public function resource() : ?array { if (!$this->is_valid()) { return null; } $payload = $this->payload(); $query = \IAWP\Illuminate_Builder::new()->from(\IAWP\Tables::resources())->where('resource', '=', $payload['resource']); switch ($payload['resource']) { case 'singular': $query->where('singular_id', '=', $payload['singular_id']); break; case 'author_archive': $query->where('author_id', '=', $payload['author_id']); break; case 'date_archive': $query->where('date_archive', '=', $payload['date_archive']); break; case 'post_type_archive': $query->where('post_type', '=', $payload['post_type']); break; case 'term_archive': $query->where('term_id', '=', $payload['term_id']); break; case 'search': $query->where('search_query', '=', $payload['search_query']); break; case 'home': break; case '404': $query->where('not_found_url', '=', $payload['not_found_url']); break; case 'virtual_page': $query->where('virtual_page_id', '=', $payload['virtual_page_id']); break; } $row = $query->first(); if (!\is_object($row)) { return null; } return (array) $row; } public static function new(string $payload, string $signature) { return new self($payload, $signature); } } IAWP/Plugin_Conflict_Detector.php000064400000024262147600331220012731 0ustar00error = $this->run_conflict_check(); } /** * Did the health check pass? * * @return bool */ public function has_conflict() : bool { return !empty($this->error); } /** * Returns the health check error, if any * * @return string|null */ public function get_error() : ?string { return $this->error; } /** * @return string|null Returns a string error message if the health check fails */ private function run_conflict_check() : ?string { if (\is_plugin_active('disable-wp-rest-api/disable-wp-rest-api.php')) { return \__('The "Disable WP REST API" plugin needs to be deactivated because Independent Analytics uses the REST API to record visits.', 'independent-analytics'); } if (\is_plugin_active('all-in-one-wp-security-and-firewall/wp-security.php')) { $settings = \get_option('aio_wp_security_configs', []); if (\array_key_exists('aiowps_disallow_unauthorized_rest_requests', $settings)) { if ($settings['aiowps_disallow_unauthorized_rest_requests'] == 1) { return \__('The "All In One WP Security" plugin is blocking REST API requests, which Independent Analytics needs to record views. Please disable this setting via the WP Security > Miscellaneous menu.', 'independent-analytics'); } } } if (\is_plugin_active('disable-json-api/disable-json-api.php')) { $settings = \get_option('disable_rest_api_options', []); if (\array_key_exists('roles', $settings)) { if ($settings['roles']['none']['default_allow'] == \false) { if ($settings['roles']['none']['allow_list']['/iawp/search'] == \false) { return \__('The "Disable REST API" plugin is blocking REST API requests for unauthenticated users, which Independent Analytics needs to record views. Please enable the /iawp/search route, so Independent Analytics can track your visitors.', 'independent-analytics'); } } } } if (\is_plugin_active('disable-xml-rpc-api/disable-xml-rpc-api.php')) { $settings = \get_option('dsxmlrpc-settings'); if (\array_key_exists('json-rest-api', $settings)) { if ($settings['json-rest-api'] == 1) { return \__('The "Disable XML-RPC-API" plugin is blocking REST API requests, which Independent Analytics needs to record views. Please visit the Security Settings menu and turn off the "Disable JSON REST API" option, so Independent Analytics can track your visitors.', 'independent-analytics'); } } } if (\is_plugin_active('wpo-tweaks/wordpress-wpo-tweaks.php')) { return \__('The "WPO Tweaks & Optimizations" plugin needs to be deactivated because it is disabling the REST API, which Independent Analytics uses to record visits.', 'independent-analytics'); } if (\is_plugin_active('all-in-one-intranet/basic_all_in_one_intranet.php')) { return \__('The "All-In-One Intranet" plugin needs to be deactivated because it is disabling the REST API, which Independent Analytics uses to record visits. You may want to try the "My Private Site" plugin instead.', 'independent-analytics'); } if (\is_plugin_active('wp-security-hardening/wp-hardening.php')) { $settings = \get_option('whp_fixer_option'); if (\array_key_exists('disable_json_api', $settings)) { if ($settings['disable_json_api'] != 'off') { return \__('The "WP Hardening" plugin is blocking the REST API, which Independent Analytics needs to record views. Please visit the WP Hardening > Security Fixers menu and turn off the "Disable WP API JSON" option, so Independent Analytics can track your visitors.', 'independent-analytics'); } } } if (\is_plugin_active('wp-rest-api-authentication/miniorange-api-authentication.php')) { $settings = \get_option('mo_api_authentication_protectedrestapi_route_whitelist'); if (\in_array('/iawp/search', $settings)) { return \__('The "WordPress REST API Authentication" plugin is blocking the REST API, which Independent Analytics needs to record views. Please visit the miniOrange API Authentication > Protected REST APIs menu and uncheck the "/iawp/search" box to allow Independent Analytics to track your visitors.', 'independent-analytics'); } } if (\is_plugin_active('ninjafirewall/ninjafirewall.php')) { $settings = \get_option('nfw_options'); if (\array_key_exists('no_restapi', $settings)) { if ($settings['no_restapi'] == 1) { return \__('The "NinjaFirewall" plugin is blocking the REST API, which Independent Analytics needs to record views. Please visit the NinjaFirewall > Firewall Policies menu and uncheck the "Block any access to the API" checkbox to allow Independent Analytics to track your visitors.', 'independent-analytics'); } } } if (\is_plugin_active('wp-cerber/wp-cerber.php')) { // This option has been renamed before. If there's an issue in here, check that it wasn't renamed again. $settings = \get_option('cerber_configuration'); if ($settings === \false) { $settings = \get_option('cerber-hardening'); } if (\array_key_exists('norest', $settings)) { if ($settings['norest'] === '1') { if (!\in_array('iawp', $settings['restwhite'])) { return \__('The "WP Cerber" plugin is blocking the REST API, which Independent Analytics needs to record views. Please visit the WP Cerber > Dashboard > Hardening menu and add "iawp" to your allowed namespaces. This will keep the REST API locked down while allowing requests for Independent Analytics.', 'independent-analytics'); } } } } if (\is_plugin_active('wp-simple-firewall/icwp-wpsf.php')) { // This option has been renamed before. If there's an issue in here, check that it wasn't renamed again. $settings = \get_option('icwp_wpsf_opts_all'); if ($settings === \false) { $settings = \get_option('icwp_wpsf_opts_free'); } if (\array_key_exists('lockdown', $settings)) { if (\array_key_exists('disable_anonymous_restapi', $settings['lockdown'])) { if ($settings['lockdown']['disable_anonymous_restapi'] == 'Y') { if (\array_key_exists('api_namespace_exclusions', $settings['lockdown'])) { if (!\in_array('iawp', $settings['lockdown']['api_namespace_exclusions'])) { return \__('The "Shield Security" plugin is blocking the REST API, which Independent Analytics needs to record views. Please visit the Shield Security > Config > Lockdown menu and add "iawp" to your allowed namespaces. This will keep the REST API locked down while allowing requests for Independent Analytics.', 'independent-analytics'); } } } } } } if (\is_plugin_active('wp-hide-security-enhancer/wp-hide.php')) { $settings = \get_option('wph_settings'); if (\array_key_exists('module_settings', $settings)) { if (\array_key_exists('disable_json_rest_v2', $settings['module_settings'])) { if ($settings['module_settings']['disable_json_rest_v2'] == 'yes') { return \__('The "WP Hide" plugin is blocking the REST API, which Independent Analytics needs to record views. Please visit the WP Hide > Rewrite URLs menu and switch the "Disable JSON REST V2 service" option to "No."', 'independent-analytics'); } } if (\array_key_exists('block_json_rest', $settings['module_settings'])) { if ($settings['module_settings']['block_json_rest'] == 'yes' || $settings['module_settings']['block_json_rest'] == 'non-logged-in') { return \__('The "WP Hide" plugin is blocking the REST API, which Independent Analytics needs to record views. Please visit the WP Hide > Rewrite URLs menu and switch the "Block any JSON REST calls" option to "No."', 'independent-analytics'); } } } } if (\is_plugin_active('admin-site-enhancements/admin-site-enhancements.php')) { $settings = \get_option('admin_site_enhancements'); if (\array_key_exists('disable_rest_api', $settings)) { if ($settings['disable_rest_api']) { return \__('The "Admin and Site Enhancements" plugin is blocking the REST API, which Independent Analytics needs to record views. Please visit the Tools > Enhancements menu, click on the "Disable Components" section, and deselect the "Disable REST API" setting to allow Independent Analytics to track your visitors.', 'independent-analytics'); } } } return null; } public function plugin_requiring_logged_in_tracking() { if (\is_plugin_active('woocommerce/woocommerce.php')) { return 'WooCommerce'; } elseif (\is_plugin_active('surecart/surecart.php')) { return 'SureCart'; } elseif (\is_plugin_active('paid-memberships-pro/paid-memberships-pro.php')) { return 'Paid Memberships Pro'; } elseif (\is_plugin_active('ultimate-member/ultimate-member.php')) { return 'Ultimate Member'; } elseif (\is_plugin_active('simple-membership/simple-wp-membership.php')) { return 'Simple WordPress Membership'; } elseif (\is_plugin_active('members/members.php')) { return 'Members plugin'; } return \false; } } IAWP/Plugin_Group.php000064400000012575147600331220010437 0ustar00id = $attributes['id']; $this->name = $attributes['name']; $this->requires_pro = $attributes['requires_pro'] ?? \false; $this->has_active_group_plugins = $attributes['has_active_group_plugins'] ?? \true; $this->upgrade_message = $attributes['upgrade_message'] ?? null; $this->upgrade_link = $attributes['upgrade_link'] ?? null; $this->activate_message = $attributes['activate_message'] ?? null; $this->activate_link = $attributes['activate_link'] ?? null; $this->no_tracked_data_message = $attributes['no_tracked_data_message'] ?? null; } public function id() : string { return $this->id; } public function name() : string { return $this->name; } public function requires_pro() : bool { return $this->requires_pro; } public function has_active_group_plugins() : bool { return $this->has_active_group_plugins; } public function upgrade_message() : ?string { return $this->upgrade_message; } public function upgrade_link() : ?string { return $this->upgrade_link; } public function activate_message() : ?string { return $this->activate_message; } public function activate_link() : ?string { return $this->activate_link; } public function no_tracked_data_message() : ?string { return $this->no_tracked_data_message; } public function has_tracked_data() : bool { global $wpdb; $form_submissions_table = \IAWP\Query::get_table_name(\IAWP\Query::FORM_SUBMISSIONS); switch ($this->id) { case 'forms': $value = $wpdb->get_var("SELECT EXISTS (SELECT 1 FROM {$form_submissions_table})"); return $value === "1"; default: return \true; } } public static function get_plugin_group(string $plugin_group_id) : \IAWP\Plugin_Group { $plugin_groups = self::get_plugin_groups(); foreach ($plugin_groups as $plugin_group) { if ($plugin_group->id() == $plugin_group_id) { return $plugin_group; } } // Added to satisfy PHPStan return $plugin_groups[0]; } /** * @return Plugin_Group[] */ public static function get_plugin_groups() : array { return [new self(['id' => 'general', 'name' => \__('General', 'independent-analytics')]), new self(['id' => 'ecommerce', 'name' => self::get_ecommerce_label(), 'requires_pro' => \true, 'has_active_group_plugins' => \IAWPSCOPED\iawp()->is_ecommerce_support_enabled(), 'upgrade_message' => \__('Upgrade to Independent Analytics Pro to get eCommerce stats.', 'independent-analytics'), 'upgrade_link' => 'https://independentwp.com/features/woocommerce-analytics/?utm_source=User+Dashboard&utm_medium=WP+Admin&utm_campaign=Stat+Toggle+Link', 'activate_message' => \__('Activate a supported eCommerce plugin to display these stats.', 'independent-analytics'), 'activate_link' => 'https://independentwp.com/knowledgebase/woocommerce/supported-ecommerce-plugins/']), new self(['id' => 'forms', 'name' => \__('Forms', 'independent-analytics'), 'requires_pro' => \true, 'has_active_group_plugins' => \IAWPSCOPED\iawp()->is_form_submission_support_enabled(), 'upgrade_message' => self::form_group_upgrade_message(), 'upgrade_link' => 'https://independentwp.com/features/form-tracking/?utm_source=User+Dashboard&utm_medium=WP+Admin&utm_campaign=Stat+Toggle+Link', 'activate_message' => \__('Activate a supported form plugin to display these stats.', 'independent-analytics'), 'activate_link' => 'https://independentwp.com/knowledgebase/form-tracking/track-form-submissions/', 'no_tracked_data_message' => \__('Your forms will show up here once a submission has been recorded.', 'independent-analytics')])]; } private static function get_ecommerce_label() : string { if (\IAWPSCOPED\iawp()->is_woocommerce_support_enabled() && !\IAWPSCOPED\iawp()->is_surecart_support_enabled()) { return 'WooCommerce'; } if (\IAWPSCOPED\iawp()->is_surecart_support_enabled() && !\IAWPSCOPED\iawp()->is_woocommerce_support_enabled()) { return 'SureCart'; } return \__('eCommerce', 'independent-analytics'); } private static function form_group_upgrade_message() : string { if (Form::has_active_form_plugin()) { return \sprintf(\_x('Upgrade to Independent Analytics Pro to track %s submissions.', 'Plugin name e.g. WPForms submissions', 'independent-analytics'), Form::get_first_active_form_plugin_name()); } return \__('Upgrade to Independent Analytics Pro to track form submissions.', 'independent-analytics'); } } IAWP/Plugin_Group_Option.php000064400000000654147600331220011762 0ustar00prefix; $reflection = new \ReflectionClass(static::class); $constants = $reflection->getConstants(); if (\in_array($name, $constants)) { return $prefix . 'independent_analytics_' . $name; } else { return null; } } } IAWP/Query_Taps.php000064400000003376147600331220010120 0ustar00leftJoin($query->raw($resources_table . ' AS resources'), function (JoinClause $join) { $join->on('views.resource_id', '=', 'resources.id'); }); } $query->where('resources.cached_author_id', '=', \get_current_user_id()); }; } public static function tap_authored_content_for_clicks() { return function (Builder $query) { if (!\is_user_logged_in() || \IAWP\Capability_Manager::can_view_all_analytics()) { return; } $views_table = \IAWP\Query::get_table_name(\IAWP\Query::VIEWS); $query->leftJoin($query->raw($views_table . ' AS views'), function (JoinClause $join) { $join->on('clicks.view_id', '=', 'views.id'); }); $resources_table = \IAWP\Query::get_table_name(\IAWP\Query::RESOURCES); $query->leftJoin($query->raw($resources_table . ' AS resources'), function (JoinClause $join) { $join->on('views.resource_id', '=', 'resources.id'); }); $query->where('resources.cached_author_id', '=', \get_current_user_id()); }; } } IAWP/Quick_Stats.php000064400000002353147600331220010250 0ustar00statistics = $statistics; $this->is_dashboard_widget = $is_dashboard_widget; } public function get_html() : string { $statistics = $this->statistics->get_statistics(); $visible_quick_stats_count = \count(\array_filter($statistics, function (Statistic $statistic) : bool { return $statistic->is_visible() && $statistic->is_group_plugin_enabled(); })); $quick_stats_html_class = "quick-stats total-of-{$visible_quick_stats_count}"; if ($this->statistics->has_filters()) { $quick_stats_html_class .= ' filtered'; } return \IAWPSCOPED\iawp_blade()->run('quick-stats', ['is_dashboard_widget' => $this->is_dashboard_widget, 'quick_stats_html_class' => $quick_stats_html_class, 'statistics' => $statistics, 'plugin_groups' => \IAWP\Plugin_Group::get_plugin_groups()]); } } IAWP/Real_Time.php000064400000014050147600331220007654 0ustar00round_up_by_seconds($thirty_minutes_ago, 60); $five_minutes_ago = new DateTime('-5 minutes'); $five_minutes_ago = $this->round_up_by_seconds($five_minutes_ago, 10); $now = new DateTime(); $end_minutes = $this->round_up_by_seconds($now, 60); $end_seconds = $this->round_up_by_seconds($now, 10); $visitors_by_minute_date_range = new Exact_Date_Range($thirty_minutes_ago, $end_minutes, \false); $visitors_by_minute_finder = new \IAWP\Visitors_Over_Time_Finder($visitors_by_minute_date_range, new Minute_Interval()); $visitors_by_minute = $visitors_by_minute_finder->fetch(); $visitors_by_second_date_range = new Exact_Date_Range($five_minutes_ago, $end_seconds, \false); $visitors_by_second_finder = new \IAWP\Visitors_Over_Time_Finder($visitors_by_second_date_range, new Ten_Second_Interval()); $visitors_by_second = $visitors_by_second_finder->fetch(); $five_minute_date_range = new Exact_Date_Range($five_minutes_ago, new DateTime(), \false); $current_traffic_finder = new \IAWP\Current_Traffic_Finder($five_minute_date_range); $current_traffic = $current_traffic_finder->fetch(); $pages = new Pages($five_minute_date_range, 10); $page_rows = \array_map(function ($row, $index) { return ['id' => $row->id(), 'position' => $index + 1, 'title' => $row->title(), 'views' => $row->views(), 'subtitle' => $row->most_popular_subtitle()]; }, $pages->rows(), \array_keys($pages->rows())); $referrers = new Referrers($five_minute_date_range, 10); $referrer_rows = \array_map(function ($row, $index) { return ['id' => $row->referrer(), 'position' => $index + 1, 'title' => $row->referrer(), 'views' => $row->views()]; }, $referrers->rows(), \array_keys($referrers->rows())); $countries = new Countries($five_minute_date_range, 10); $country_rows = \array_map(function ($row, $index) { return ['id' => $row->country(), 'position' => $index + 1, 'title' => $row->country(), 'views' => $row->views(), 'flag' => \IAWP\Icon_Directory_Factory::flags()->find($row->country_code())]; }, $countries->rows(), \array_keys($countries->rows())); $campaigns = new Campaigns($five_minute_date_range, 10); $campaign_rows = \array_map(function ($row, $index) { return ['id' => $row->params(), 'position' => $index + 1, 'title' => $row->utm_campaign(), 'views' => $row->views()]; }, $campaigns->rows(), \array_keys($campaigns->rows())); $device_types = new Device_Types($five_minute_date_range, 10); $device_rows = \array_map(function ($row, $index) { return ['id' => $row->device_type(), 'position' => $index + 1, 'title' => $row->device_type(), 'views' => $row->views()]; }, $device_types->rows(), \array_keys($device_types->rows())); $visitor_message = $this->get_visitor_count_message($current_traffic->get_visitor_count()); $page_message = $this->get_count_message($current_traffic->get_page_count(), \__('Page', 'independent-analytics'), \__('Pages', 'independent-analytics')); $referrer_message = $this->get_count_message($current_traffic->get_referrer_count(), \__('Referrer', 'independent-analytics'), \__('Referrers', 'independent-analytics')); $country_message = $this->get_count_message($current_traffic->get_country_count(), \__('Country', 'independent-analytics'), \__('Countries', 'independent-analytics')); return ['visitor_message' => $visitor_message, 'page_message' => $page_message, 'referrer_message' => $referrer_message, 'country_message' => $country_message, 'chart_data' => ['minute_interval_visitors' => $visitors_by_minute->visitors, 'minute_interval_views' => $visitors_by_minute->views, 'minute_interval_labels_short' => $visitors_by_minute->interval_labels_short, 'minute_interval_labels_full' => $visitors_by_minute->interval_labels_full, 'second_interval_visitors' => $visitors_by_second->visitors, 'second_interval_views' => $visitors_by_second->views, 'second_interval_labels_short' => $visitors_by_second->interval_labels_short, 'second_interval_labels_full' => $visitors_by_second->interval_labels_full], 'lists' => ['pages' => ['title' => \__('Active Pages', 'independent-analytics'), 'entries' => $page_rows], 'referrers' => ['title' => \__('Active Referrers', 'independent-analytics'), 'entries' => $referrer_rows], 'countries' => ['title' => \__('Active Countries', 'independent-analytics'), 'entries' => $country_rows], 'campaigns' => ['title' => \__('Active Campaigns', 'independent-analytics'), 'entries' => $campaign_rows], 'device_types' => ['title' => \__('Device Types', 'independent-analytics'), 'entries' => $device_rows]]]; } public function render_real_time_analytics() { echo \IAWPSCOPED\iawp_blade()->run('real_time', $this->get_real_time_analytics()); } private function get_count_message(int $count, string $singular, string $plural) : string { return \number_format_i18n($count) . ' ' . \_n($singular, $plural, $count); } private function get_visitor_count_message(int $count) : string { return $this->get_count_message($count, \__('Active Visitor', 'independent-analytics'), \__('Active Visitors', 'independent-analytics')); } private function round_up_by_seconds(DateTime $datetime, $precision_seconds) : DateTime { $datetime = clone $datetime; $datetime->setTimestamp($precision_seconds * (int) \ceil($datetime->getTimestamp() / $precision_seconds)); return $datetime; } } IAWP/Report.php000064400000003740147600331220007272 0ustar00row = $row; } public function id() : int { return $this->row->report_id; } public function type() : string { return $this->row->type; } public function name() : string { return $this->row->name; } public function url() : string { if (!$this->is_saved_report()) { return \IAWPSCOPED\iawp_dashboard_url(['tab' => $this->row->type]); } return \IAWPSCOPED\iawp_dashboard_url(['tab' => $this->row->type, 'report' => $this->row->report_id]); } public function is_saved_report() : bool { return \property_exists($this->row, 'report_id'); } public function is_current() : bool { $report_id = \array_key_exists('report', $_GET) ? \sanitize_text_field($_GET['report']) : null; return $this->id() === \intval($report_id); } public function is_favorite() : bool { if ($this->is_saved_report()) { return \intval(\get_user_meta(\get_current_user_id(), 'iawp_favorite_report_id', \true)) === $this->id(); } return \get_user_meta(\get_current_user_id(), 'iawp_favorite_report_type', \true) === $this->type(); } public function to_array() : array { $array = (array) $this->row; if (\array_key_exists('columns', $array) && !\is_null($array['columns'])) { $array['columns'] = \json_decode($array['columns'], \true); } if (\array_key_exists('filters', $array) && !\is_null($array['filters'])) { $array['filters'] = \json_decode($array['filters'], \true); } return $array; } public static function is_valid_report_type(string $type) : bool { return \in_array($type, self::$report_types); } } IAWP/Report_Finder.php000064400000016367147600331220010572 0ustar00 \esc_html__('Pages', 'independent-analytics'), 'reports' => $this->fetch_page_reports()], ['name' => \esc_html__('Referrers', 'independent-analytics'), 'reports' => $this->fetch_referrer_reports()], ['name' => \esc_html__('Geographic', 'independent-analytics'), 'reports' => $this->fetch_geographic_reports()], ['name' => \esc_html__('Devices', 'independent-analytics'), 'reports' => $this->fetch_device_reports()], ['name' => \esc_html__('Campaigns', 'independent-analytics'), 'reports' => $this->fetch_campaign_reports()], ['name' => \esc_html__('Clicks', 'independent-analytics'), 'reports' => $this->fetch_click_reports()]]; } /** * @return Report[] */ public function fetch_page_reports() : array { return $this->by_type('views'); } /** * @return Report[] */ public function fetch_referrer_reports() : array { return $this->by_type('referrers'); } /** * @return Report[] */ public function fetch_geographic_reports() : array { return $this->by_type('geo'); } /** * @return Report[] */ public function fetch_device_reports() : array { return $this->by_type('devices'); } /** * @return Report[] */ public function fetch_campaign_reports() : array { return $this->by_type('campaigns'); } /** * @return Report[] */ public function fetch_click_reports() : array { return $this->by_type('clicks'); } public function is_real_time() : bool { return \IAWP\Env::get_tab() === 'real-time'; } public function is_settings_page() : bool { return \IAWP\Env::get_page() === 'independent-analytics-settings'; } public function is_campaign_builder_page() : bool { return \IAWP\Env::get_page() === 'independent-analytics-campaign-builder'; } public function is_page_report() : bool { return \IAWP\Env::get_tab() === 'views'; } public function is_referrer_report() : bool { return \IAWP\Env::get_tab() === 'referrers'; } public function is_geographic_report() : bool { return \IAWP\Env::get_tab() === 'geo'; } public function is_device_report() : bool { return \IAWP\Env::get_tab() === 'devices'; } public function is_campaign_report() : bool { return \IAWP\Env::get_tab() === 'campaigns'; } public function is_click_report() : bool { return \IAWP\Env::get_tab() === 'clicks'; } public function is_saved_report() : bool { $report = $this->current(); if (\is_null($report)) { return \false; } return $report->is_saved_report(); } public function current() : ?\IAWP\Report { $report_id = \array_key_exists('report', $_GET) ? \sanitize_text_field($_GET['report']) : null; if (\is_null($report_id)) { return self::get_base_report_for_current_tab(); } $report = self::by_id($report_id); if (\is_null($report)) { return self::get_base_report_for_current_tab(); } return $report; } /** * @param array $ids * * @return array|Report[]|null */ public function by_ids(array $ids) : ?array { $reports_table = \IAWP\Query::get_table_name(\IAWP\Query::REPORTS); $rows = \IAWP\Illuminate_Builder::new()->from($reports_table)->whereIn('report_id', $ids)->get()->toArray(); return \array_map(function ($row) { return new \IAWP\Report($row); }, $rows); } /** * @param string $type * * @return Report[] */ public function by_type(string $type) : array { $reports_table = \IAWP\Query::get_table_name(\IAWP\Query::REPORTS); $builder = \IAWP\Illuminate_Builder::new()->from($reports_table)->where('type', '=', $type)->orderByRaw('position IS NULL')->orderBy('position')->orderBy('report_id')->get()->escapeWhenCastingToString(); $rows = $builder->toArray(); return \array_map(function ($row) { return new \IAWP\Report($row); }, $rows); } public static function get_base_report_for_current_tab() : ?\IAWP\Report { return self::get_base_report_for_type(\IAWP\Env::get_tab()); } public static function get_favorite() : ?\IAWP\Report { $raw_id = \get_user_meta(\get_current_user_id(), 'iawp_favorite_report_id', \true); $id = \filter_var($raw_id, \FILTER_VALIDATE_INT); if ($id !== \false) { return self::by_id($id); } $raw_type = \get_user_meta(\get_current_user_id(), 'iawp_favorite_report_type', \true); $type = \filter_var($raw_type, \FILTER_SANITIZE_FULL_SPECIAL_CHARS); return self::get_base_report_for_type($type); } /** * @param string|int $id * * @return Report|null */ public static function by_id($id) : ?\IAWP\Report { $id = (string) $id; $reports_table = \IAWP\Query::get_table_name(\IAWP\Query::REPORTS); if (!\ctype_digit($id)) { return null; } $row = \IAWP\Illuminate_Builder::new()->from($reports_table)->where('report_id', '=', $id)->first(); if (\is_null($row)) { return null; } return new \IAWP\Report($row); } public static function create_report(array $attributes) : \IAWP\Report { $reports_table = \IAWP\Query::get_table_name(\IAWP\Query::REPORTS); if (\array_key_exists('columns', $attributes) && \is_array($attributes['columns'])) { $attributes['columns'] = \json_encode($attributes['columns']); } if (\array_key_exists('filters', $attributes) && \is_array($attributes['filters'])) { $attributes['filters'] = \json_encode($attributes['filters']); } $report_id = \IAWP\Illuminate_Builder::new()->from($reports_table)->insertGetId($attributes); return self::by_id($report_id); } private static function get_base_report_for_type(string $type) : ?\IAWP\Report { switch ($type) { case 'views': return new \IAWP\Report((object) ['name' => \esc_html__('Pages', 'independent-analytics'), 'type' => 'views']); case 'referrers': return new \IAWP\Report((object) ['name' => \esc_html__('Referrers', 'independent-analytics'), 'type' => 'referrers']); case 'geo': return new \IAWP\Report((object) ['name' => \esc_html__('Geographic', 'independent-analytics'), 'type' => 'geo']); case 'devices': return new \IAWP\Report((object) ['name' => \esc_html__('Devices', 'independent-analytics'), 'type' => 'devices']); case 'campaigns': return new \IAWP\Report((object) ['name' => \esc_html__('Campaigns', 'independent-analytics'), 'type' => 'campaigns']); case 'clicks': return new \IAWP\Report((object) ['name' => \esc_html__('Clicks', 'independent-analytics'), 'type' => 'clicks']); default: return null; } } } IAWP/Report_Options_Parser.php000064400000011210147600331220012310 0ustar00attributes = $attributes; } public function get_options_for_creating() : array { return \array_merge(['name' => $this->get_string_option('name'), 'type' => $this->get_string_option('type')], $this->get_options()); } public function get_options_for_updating() : array { return $this->add_update_side_effects($this->get_options()); } private function get_options() : array { return $this->strip_empty_options(['primary_chart_metric_id' => $this->get_string_option('primary_chart_metric_id'), 'secondary_chart_metric_id' => $this->get_string_option('secondary_chart_metric_id'), 'exact_start' => $this->get_string_option('exact_start'), 'exact_end' => $this->get_string_option('exact_end'), 'relative_range_id' => $this->get_string_option('relative_range_id'), 'columns' => $this->get_array_option('columns'), 'quick_stats' => $this->get_array_option('quick_stats'), 'filters' => $this->get_filters(), 'sort_column' => $this->get_string_option('sort_column'), 'sort_direction' => $this->get_string_option('sort_direction'), 'group_name' => $this->get_string_option('group_name'), 'chart_interval' => $this->get_string_option('chart_interval')]); } private function add_update_side_effects(array $options) : array { if (\array_key_exists('exact_start', $options) && !\is_null($options['exact_start']) && \array_key_exists('exact_end', $options) && !\is_null($options['exact_end'])) { $options['relative_range_id'] = null; $options['chart_interval'] = null; } if (\array_key_exists('relative_range_id', $options) && !\is_null($options['relative_range_id'])) { $options['exact_start'] = null; $options['exact_end'] = null; $options['chart_interval'] = null; } return $options; } private function strip_empty_options(array $options) : array { return \array_filter($options, function ($option) { return !$option instanceof \IAWP\Empty_Report_Option; }); } /** * @param string $key * * @return null|string|Empty_Report_Option */ private function get_string_option(string $key, bool $is_nullable = \false) { if ($is_nullable && \array_key_exists($key, $this->attributes) && \is_null($this->attributes[$key])) { return null; } if (!\array_key_exists($key, $this->attributes) || !\is_string($this->attributes[$key])) { return new \IAWP\Empty_Report_Option(); } return \sanitize_text_field($this->attributes[$key]); } /** * @param string $key * * @return array|Empty_Report_Option */ private function get_array_option(string $key) { if (!\array_key_exists($key, $this->attributes) || !\is_array($this->attributes[$key])) { return new \IAWP\Empty_Report_Option(); } foreach ($this->attributes[$key] as $visible_dataset) { if (!\is_string($visible_dataset)) { return new \IAWP\Empty_Report_Option(); } } return \array_map(function ($item) { return \sanitize_text_field($item); }, $this->attributes[$key]); } /** * @return array|array[]|Empty_Report_Option */ private function get_filters() { if (!\array_key_exists('filters', $this->attributes) || !\is_array($this->attributes['filters'])) { return new \IAWP\Empty_Report_Option(); } foreach ($this->attributes['filters'] as $filter) { if (!\is_array($filter)) { return new \IAWP\Empty_Report_Option(); } if (\array_keys($filter) !== ['inclusion', 'column', 'operator', 'operand']) { return new \IAWP\Empty_Report_Option(); } foreach ($filter as $value) { if (!\is_string($value)) { return new \IAWP\Empty_Report_Option(); } } } return \array_map(function ($filter) { return ['inclusion' => \sanitize_text_field($filter['inclusion']), 'column' => \sanitize_text_field($filter['column']), 'operator' => \sanitize_text_field($filter['operator']), 'operand' => \sanitize_text_field($filter['operand'])]; }, $this->attributes['filters']); } public static function from_json(string $json) : \IAWP\Report_Options_Parser { return new \IAWP\Report_Options_Parser(\json_decode(\stripslashes($json), \true)); } } IAWP/Resource_Identifier.php000064400000013740147600331220011751 0ustar00type = $type; $this->meta_key = $meta_key; $this->meta_value = $meta_value; } /** * @return string */ public function type() : string { return $this->type; } /** * @return string|null */ public function meta_key() : ?string { return $this->meta_key; } /** * @return int|string|null */ public function meta_value() { return $this->meta_value; } /** * @return bool */ public function has_meta() : bool { return !\is_null($this->meta_key) && !\is_null($this->meta_value); } /** * @return self|null */ public static function for_resource_being_viewed() : ?self { if (self::is_searchiq_results()) { $type = 'search'; $meta_key = 'search_query'; $meta_value = \get_query_var(\get_option('_siq_search_query_param_name', 'q')); } elseif (\is_string(self::get_virtual_page_id())) { $type = 'virtual_page'; $meta_key = 'virtual_page_id'; $meta_value = self::get_virtual_page_id(); } elseif (\is_singular()) { $type = 'singular'; $meta_key = 'singular_id'; $meta_value = \get_queried_object_id(); } elseif (\is_author()) { $type = 'author_archive'; $meta_key = 'author_id'; $meta_value = \get_queried_object_id(); } elseif (\is_date()) { $type = 'date_archive'; $meta_key = 'date_archive'; $meta_value = self::get_date_archive_date(); } elseif (\is_post_type_archive()) { $type = 'post_type_archive'; $meta_key = 'post_type'; $meta_value = \get_queried_object()->name; } elseif (\is_category() || \is_tag() || \is_tax()) { $type = 'term_archive'; $meta_key = 'term_id'; $meta_value = \get_queried_object_id(); } elseif (\is_search()) { $type = 'search'; $meta_key = 'search_query'; $meta_value = \get_search_query(); } elseif (\is_home()) { $type = 'home'; $meta_key = null; $meta_value = null; } elseif (\is_404()) { $path = Request::path_relative_to_site_url(); if (\is_null($path)) { return null; } $type = '404'; $meta_key = 'not_found_url'; $meta_value = $path; } else { return null; } return new self($type, $meta_key, $meta_value); } /** * @return self|null */ public static function for_resource_being_edited() : ?self { if (!\is_admin()) { return null; } $screen = \get_current_screen(); // Check if the current screen is post editing page if (!\is_null($screen) && $screen->base === 'post') { $singular_id = \get_the_ID(); if (\is_int($singular_id)) { $singular_id = \strval($singular_id); } else { return null; } return new self('singular', 'singular_id', $singular_id); } return null; } public static function for_post_id(int $post_id) : ?self { return new self('singular', 'singular_id', $post_id); } private static function get_virtual_page_id() : ?string { if (\is_404()) { return null; } $post = \get_post(); if (\IAWPSCOPED\iawp()->is_woocommerce_support_enabled() && is_checkout() && is_wc_endpoint_url('order-received')) { return 'wc_checkout_success'; } if (\IAWPSCOPED\iawp()->is_surecart_support_enabled() && $post->post_type === 'sc_product' && \property_exists($post, 'sc_id')) { return 'sc_product_' . $post->sc_id; } if (\IAWPSCOPED\iawp()->is_surecart_support_enabled() && $post->post_type === 'sc_collection' && \property_exists($post, 'sc_id')) { return 'sc_collection_' . $post->sc_id; } if (\IAWPSCOPED\iawp()->is_surecart_support_enabled() && $post->post_type === 'sc_upsell' && \property_exists($post, 'sc_id')) { return 'sc_upsell_' . $post->sc_id; } // TODO - What's the pro slug? if (\is_plugin_active('clickwhale/clickwhale.php') && \property_exists($post, 'linkpage') && \is_array($post->linkpage)) { return 'clickwhale_link_page_' . $post->linkpage['id']; } return null; } /** * Build a date archive string with the year and possibly a month and date * * Examples would be "2023", "2023-01", or "2023-01-21" * * @return mixed|string */ private static function get_date_archive_date() { $str = \get_query_var('year'); if (\is_month() || \is_day()) { $month = \get_query_var('monthnum'); $str = $str . '-' . \str_pad($month, 2, '0', \STR_PAD_LEFT); } if (\is_day()) { $day = \get_query_var('day'); $str = $str . '-' . \str_pad($day, 2, '0', \STR_PAD_LEFT); } return $str; } private static function is_searchiq_results() { if (!\is_plugin_active('searchiq/searchiq.php')) { return \false; } if (\get_query_var(\get_option('_siq_search_query_param_name', 'q')) !== '') { $post = \get_post(\get_queried_object_id()); if (\has_shortcode($post->post_content, 'siq_ajax_search')) { return \true; } } return \false; } } IAWP/REST_API.php000064400000035574147600331220007277 0ustar00block_user_role()) { return; } // Don't track post or page previews if (\is_preview()) { return; } $payload = []; $current_resource = \IAWP\Resource_Identifier::for_resource_being_viewed(); if (\is_null($current_resource)) { return; } $payload['resource'] = $current_resource->type(); if ($current_resource->has_meta()) { $payload[$current_resource->meta_key()] = $current_resource->meta_value(); } $payload['page'] = \max(1, \get_query_var('paged')); $data = ['payload' => $payload]; $data['signature'] = \md5(Salt::request_payload_salt() . \json_encode($data['payload'])); $track_view_url = \get_rest_url(null, '/iawp/search'); $track_click_url = \IAWPSCOPED\iawp_url_to('/iawp-click-endpoint.php'); $link_rules = Link_Rule_Finder::link_rules()->filter(function (Link_Rule $link_rule) { return $link_rule->is_active(); })->map(function (Link_Rule $link_rule) { return ['type' => $link_rule->type(), 'value' => $link_rule->value()]; })->values(); $link_rules_json = \json_encode($link_rules); ?> 'POST', 'callback' => [$this, 'track_view'], 'permission_callback' => function () { return \true; }]); } public function track_view($request) { if (Device::getInstance()->is_bot() && !\defined('IAWP_TESTING')) { return; } \IAWP\Migrations\Migrations::handle_migration_18_error(); \IAWP\Migrations\Migrations::handle_migration_22_error(); \IAWP\Migrations\Migrations::handle_migration_29_error(); \IAWP\Migrations\Migrations::create_or_migrate(); if (\IAWP\Migrations\Migrations::is_migrating()) { return; } if (Request::is_ip_address_blocked()) { return; } $visitor = Visitor::fetch_current_visitor(); $signature = \md5(Salt::request_payload_salt() . \json_encode($request['payload'])); $campaign = []; if (\IAWPSCOPED\iawp_is_pro()) { $campaign = ['utm_source' => $this->decode_or_nullify($request['utm_source']), 'utm_medium' => $this->decode_or_nullify($request['utm_medium']), 'utm_campaign' => $this->decode_or_nullify($request['utm_campaign']), 'utm_term' => $this->decode_or_nullify($request['utm_term']), 'utm_content' => $this->decode_or_nullify($request['utm_content'])]; } if ($signature == $request['signature']) { new \IAWP\View($request['payload'], $this->calculate_referrer_url($request), $visitor, $campaign); return new \WP_REST_Response(['success' => \true], 200, ['X-IAWP' => 'iawp']); } else { return new \WP_REST_Response(['success' => \false], 200, ['X-IAWP' => 'iawp']); } } private function calculate_referrer_url($request) : ?string { $referrer_url = $request['referrer_url']; $url = new URL($referrer_url ?? ''); if (!\is_null($this->decode_or_nullify($request['gclid'])) && $url->get_domain() !== 'googleads.g.doubleclick.net') { $referrer_url = 'https://googleads.iawp'; } if (\is_null($referrer_url)) { return null; } return $referrer_url; } private function decode_or_nullify($string) { if (!isset($string)) { return null; } $safe_string = \trim(\urldecode($string)); $safe_string = \str_replace('+', ' ', $safe_string); $safe_string = Security::string($safe_string); if (\strlen($safe_string) === 0) { return null; } return $safe_string; } private function block_user_role() : bool { $blocked_roles = \IAWPSCOPED\iawp()->get_option('iawp_blocked_roles', ['administrator']); foreach (\wp_get_current_user()->roles as $visitor_role) { if (\in_array($visitor_role, $blocked_roles)) { return \true; } } return \false; } } IAWP/Settings.php000064400000054521147600331220007622 0ustar00run('settings.index'); if (\IAWPSCOPED\iawp_is_pro()) { $defaults = $this->email_report_colors(); $saved = \IAWPSCOPED\iawp()->get_option('iawp_email_report_colors', $defaults); // There were 6 colors and now 9, so there is a saved value but 7-9 don't exist $input_defaults = $defaults; for ($i = 0; $i < \count($saved); $i++) { $input_defaults[$i] = $saved[$i]; } $interval = Interval_Factory::from_option(); echo \IAWPSCOPED\iawp_blade()->run('settings.email-reports', ['is_scheduled' => \wp_next_scheduled('iawp_send_email_report'), 'scheduled_date' => \IAWPSCOPED\iawp()->email_reports->next_email_at_for_humans(), 'interval' => \IAWPSCOPED\iawp()->get_option('iawp_email_report_interval', 'monthly'), 'time' => \IAWPSCOPED\iawp()->get_option('iawp_email_report_time', 9), 'emails' => \IAWPSCOPED\iawp()->get_option('iawp_email_report_email_addresses', []), 'from' => \IAWPSCOPED\iawp()->get_option('iawp_email_report_from_address', \get_option('admin_email')), 'default_colors' => $defaults, 'input_default' => $input_defaults, 'timestamp' => $interval->next_interval_start()->getTimestamp()]); } $ips = \IAWPSCOPED\iawp()->get_option('iawp_blocked_ips', []); echo \IAWPSCOPED\iawp_blade()->run('settings.block-ips', ['current_ip' => Request::ip(), 'ip_is_blocked' => Request::is_ip_address_blocked(), 'ips' => $ips]); echo \IAWPSCOPED\iawp_blade()->run('settings.block-by-role', ['roles' => \wp_roles()->roles, 'blocked' => \IAWPSCOPED\iawp()->get_option('iawp_blocked_roles', ['administrator'])]); echo \IAWPSCOPED\iawp_blade()->run('settings.capabilities', ['editable_roles' => $this->get_editable_roles(), 'capabilities' => \IAWP\Capability_Manager::all_capabilities()]); echo \IAWPSCOPED\iawp_blade()->run('settings.view-counter'); if (\IAWPSCOPED\iawp()->is_woocommerce_support_enabled()) { echo \IAWPSCOPED\iawp_blade()->run('settings.woocommerce', ['statuses' => new WooCommerce_Status_Manager()]); } echo \IAWPSCOPED\iawp_blade()->run('settings.export-reports', ['report_finder' => new \IAWP\Report_Finder()]); echo \IAWPSCOPED\iawp_blade()->run('settings.export-data'); echo \IAWPSCOPED\iawp_blade()->run('settings.pruner', ['pruner' => new Pruning_Scheduler()]); echo \IAWPSCOPED\iawp_blade()->run('settings.delete', ['site_name' => \get_bloginfo('name'), 'site_url' => \site_url()]); } public function register_settings() { \add_settings_section('iawp-settings-section', \esc_html__('Basic Settings', 'independent-analytics'), function () { }, 'independent-analytics-settings'); $args = ['type' => 'boolean', 'default' => \false, 'sanitize_callback' => 'rest_sanitize_boolean']; \register_setting('iawp_settings', 'iawp_dark_mode', $args); \add_settings_field('iawp_dark_mode', \esc_html__('Dark mode', 'independent-analytics'), [$this, 'dark_mode_callback'], 'independent-analytics-settings', 'iawp-settings-section', ['class' => 'dark-mode']); \register_setting('iawp_settings', 'iawp_track_authenticated_users', $args); \add_settings_field('iawp_track_authenticated_users', \esc_html__('Track logged in users', 'independent-analytics'), [$this, 'track_authenticated_users_callback'], 'independent-analytics-settings', 'iawp-settings-section', ['class' => 'logged-in']); \register_setting('iawp_settings', 'iawp_disable_admin_toolbar_analytics', $args); \add_settings_field('iawp_disable_admin_toolbar_analytics', \esc_html__('Admin toolbar stats', 'independent-analytics'), [$this, 'disable_admin_toolbar_analytics_callback'], 'independent-analytics-settings', 'iawp-settings-section'); \register_setting('iawp_settings', 'iawp_disable_widget', $args); \add_settings_field('iawp_disable_widget', \esc_html__('Dashboard widget', 'independent-analytics'), [$this, 'disable_widget_callback'], 'independent-analytics-settings', 'iawp-settings-section'); \register_setting('iawp_settings', 'iawp_disable_views_column', $args); \add_settings_field('iawp_disable_views_column', \esc_html__('Views column', 'independent-analytics'), [$this, 'disable_views_column_callback'], 'independent-analytics-settings', 'iawp-settings-section'); $args = ['type' => 'integer', 'default' => 0, 'sanitize_callback' => 'absint']; \register_setting('iawp_settings', 'iawp_dow', $args); \add_settings_field('iawp_dow', \esc_html__('First day of week', 'independent-analytics'), [$this, 'starting_dow_callback'], 'independent-analytics-settings', 'iawp-settings-section', ['class' => 'dow']); $args = ['type' => 'boolean', 'default' => \false, 'sanitize_callback' => 'rest_sanitize_boolean']; \register_setting('iawp_settings', 'iawp_refresh_salt', $args); \add_settings_field('iawp_refresh_salt', \esc_html__('Salt refresh rate', 'independent-analytics'), [$this, 'refresh_salt_callback'], 'independent-analytics-settings', 'iawp-settings-section', ['class' => 'salt']); } public function dark_mode_callback() { echo \IAWPSCOPED\iawp_blade()->run('settings.dark-mode', ['dark_mode' => \IAWPSCOPED\iawp()->get_option('iawp_dark_mode', \false)]); } public function track_authenticated_users_callback() { echo \IAWPSCOPED\iawp_blade()->run('settings.track-authenticated-users', ['track_authenticated_users' => \IAWPSCOPED\iawp()->get_option('iawp_track_authenticated_users', \false)]); } public function disable_admin_toolbar_analytics_callback() { echo \IAWPSCOPED\iawp_blade()->run('settings.disable-admin-toolbar-analytics', ['value' => \IAWPSCOPED\iawp()->get_option('iawp_disable_admin_toolbar_analytics', \false)]); } public function disable_widget_callback() { echo \IAWPSCOPED\iawp_blade()->run('settings.disable-widget', ['value' => \IAWPSCOPED\iawp()->get_option('iawp_disable_widget', \false)]); } public function disable_views_column_callback() : void { echo \IAWPSCOPED\iawp_blade()->run('settings.disable-views-column', ['value' => \IAWPSCOPED\iawp()->get_option('iawp_disable_views_column', \false)]); } public function starting_dow_callback() { echo \IAWPSCOPED\iawp_blade()->run('settings.first-day-of-week', ['day_of_week' => \IAWPSCOPED\iawp()->get_option('iawp_dow', 0), 'days' => [0 => \esc_html__('Sunday', 'independent-analytics'), 1 => \esc_html__('Monday', 'independent-analytics'), 2 => \esc_html__('Tuesday', 'independent-analytics'), 3 => \esc_html__('Wednesday', 'independent-analytics'), 4 => \esc_html__('Thursday', 'independent-analytics'), 5 => \esc_html__('Friday', 'independent-analytics'), 6 => \esc_html__('Saturday', 'independent-analytics')]]); } public function refresh_salt_callback() { echo \IAWPSCOPED\iawp_blade()->run('settings.refresh-salt', ['refresh_salt' => \IAWPSCOPED\iawp()->get_option('iawp_refresh_salt', \false)]); } public function register_view_counter_settings() { \add_settings_section('iawp-view-counter-settings-section', \esc_html__('Public View Counter', 'independent-analytics'), function () { }, 'independent-analytics-view-counter-settings'); $args = ['type' => 'boolean', 'default' => \false, 'sanitize_callback' => 'rest_sanitize_boolean']; \register_setting('iawp_view_counter_settings', 'iawp_view_counter_enable', $args); \add_settings_field('iawp_view_counter_enable', \esc_html__('Enable the view counter', 'independent-analytics'), [$this, 'view_counter_enable_callback'], 'independent-analytics-view-counter-settings', 'iawp-view-counter-settings-section', ['class' => 'enable']); $args = ['type' => 'array', 'default' => [], 'sanitize_callback' => [$this, 'sanitize_view_counter_post_types']]; \register_setting('iawp_view_counter_settings', 'iawp_view_counter_post_types', $args); \add_settings_field('iawp_view_counter_post_types', \esc_html__('Display on these post types', 'independent-analytics'), [$this, 'view_counter_post_types_callback'], 'independent-analytics-view-counter-settings', 'iawp-view-counter-settings-section', ['class' => 'post-types']); // Position $args = ['type' => 'string', 'default' => 'after', 'sanitize_callback' => [$this, 'sanitize_view_counter_position']]; \register_setting('iawp_view_counter_settings', 'iawp_view_counter_position', $args); \add_settings_field('iawp_view_counter_position', \esc_html__('Show it in this location', 'independent-analytics'), [$this, 'view_counter_position_callback'], 'independent-analytics-view-counter-settings', 'iawp-view-counter-settings-section', ['class' => 'position']); // Views to count \register_setting('iawp_view_counter_settings', 'iawp_view_counter_views_to_count', ['type' => 'string', 'default' => 'total', 'sanitize_callback' => [$this, 'sanitize_view_counter_views_to_count']]); \add_settings_field('iawp_view_counter_views_to_count', \esc_html__('Date range to count views', 'independent-analytics'), [$this, 'view_counter_views_to_count_callback'], 'independent-analytics-view-counter-settings', 'iawp-view-counter-settings-section', ['class' => 'views-to-count']); // Exclude $args = ['type' => 'string', 'default' => '', 'sanitize_callback' => [$this, 'sanitize_view_counter_exclude']]; \register_setting('iawp_view_counter_settings', 'iawp_view_counter_exclude', $args); \add_settings_field('iawp_view_counter_exclude', \esc_html__('Exclude these pages', 'independent-analytics'), [$this, 'view_counter_exclude_callback'], 'independent-analytics-view-counter-settings', 'iawp-view-counter-settings-section', ['class' => 'exclude']); // Label $default = \function_exists('IAWPSCOPED\\pll__') ? pll__('Views:', 'independent-analytics') : \__('Views:', 'independent-analytics'); $args = ['type' => 'string', 'default' => $default, 'sanitize_callback' => 'sanitize_text_field']; \register_setting('iawp_view_counter_settings', 'iawp_view_counter_label', $args); \add_settings_field('iawp_view_counter_label', \esc_html__('Edit the label', 'independent-analytics'), [$this, 'view_counter_label_callback'], 'independent-analytics-view-counter-settings', 'iawp-view-counter-settings-section', ['class' => 'counter-label']); // Hide Label $args = ['type' => 'boolean', 'default' => \true, 'sanitize_callback' => 'rest_sanitize_boolean']; \register_setting('iawp_view_counter_settings', 'iawp_view_counter_label_show', $args); \add_settings_field('iawp_view_counter_label_show', \esc_html__('Display the label', 'independent-analytics'), [$this, 'view_counter_label_show_callback'], 'independent-analytics-view-counter-settings', 'iawp-view-counter-settings-section', ['class' => 'hide-label']); // Icon $args = ['type' => 'boolean', 'default' => \true, 'sanitize_callback' => 'rest_sanitize_boolean']; \register_setting('iawp_view_counter_settings', 'iawp_view_counter_icon', $args); \add_settings_field('iawp_view_counter_icon', \esc_html__('Display the icon', 'independent-analytics'), [$this, 'view_counter_icon_callback'], 'independent-analytics-view-counter-settings', 'iawp-view-counter-settings-section', ['class' => 'icon']); // Private \register_setting('iawp_view_counter_settings', 'iawp_view_counter_private', ['type' => 'boolean', 'default' => \false, 'sanitize_callback' => 'rest_sanitize_boolean']); \add_settings_field('iawp_view_counter_private', \esc_html__('Make the view counter private?', 'independent-analytics'), [$this, 'view_counter_private_callback'], 'independent-analytics-view-counter-settings', 'iawp-view-counter-settings-section', ['class' => 'private']); // Allow manual adjustment \register_setting('iawp_view_counter_settings', 'iawp_view_counter_manual_adjustment', ['type' => 'boolean', 'default' => \false, 'sanitize_callback' => 'rest_sanitize_boolean']); \add_settings_field('iawp_view_counter_manual_adjustment', \esc_html__('Allow manual adjustment?', 'independent-analytics'), [$this, 'view_counter_manual_adjustment_callback'], 'independent-analytics-view-counter-settings', 'iawp-view-counter-settings-section', ['class' => 'manual-adjustment']); } public function view_counter_enable_callback() { echo \IAWPSCOPED\iawp_blade()->run('settings.view-counter.enable', ['enable' => \IAWPSCOPED\iawp()->get_option('iawp_view_counter_enable', \false)]); } public function view_counter_post_types_callback() { $site_post_types = \get_post_types(['public' => \true], 'objects'); $counter = 0; foreach ($site_post_types as $post_type) { echo \IAWPSCOPED\iawp_blade()->run('settings.view-counter.post-types', ['counter' => $counter, 'post_type' => $post_type, 'saved' => \IAWPSCOPED\iawp()->get_option('iawp_view_counter_post_types', [])]); $counter++; } ?>

run('settings.view-counter.position', ['position' => \IAWPSCOPED\iawp()->get_option('iawp_view_counter_position', 'after')]); } public function view_counter_views_to_count_callback() { echo \IAWPSCOPED\iawp_blade()->run('settings.view-counter.views-to-count', ['value' => \IAWPSCOPED\iawp()->get_option('iawp_view_counter_views_to_count', 'total')]); } public function view_counter_exclude_callback() { echo \IAWPSCOPED\iawp_blade()->run('settings.view-counter.exclude', ['exclude' => \IAWPSCOPED\iawp()->get_option('iawp_view_counter_exclude', '')]); } public function view_counter_label_callback() { $default = \function_exists('IAWPSCOPED\\pll__') ? pll__('Views:', 'independent-analytics') : \__('Views:', 'independent-analytics'); echo \IAWPSCOPED\iawp_blade()->run('settings.view-counter.label', ['label' => \IAWPSCOPED\iawp()->get_option('iawp_view_counter_label', $default)]); } public function view_counter_label_show_callback() { echo \IAWPSCOPED\iawp_blade()->run('settings.view-counter.label-show', ['show' => \get_option('iawp_view_counter_label_show', \true)]); } public function view_counter_icon_callback() { echo \IAWPSCOPED\iawp_blade()->run('settings.view-counter.icon', ['icon' => \get_option('iawp_view_counter_icon', \true)]); } public function view_counter_private_callback() { echo \IAWPSCOPED\iawp_blade()->run('settings.view-counter.private', ['private' => \IAWPSCOPED\iawp()->get_option('iawp_view_counter_private', \false)]); } public function view_counter_manual_adjustment_callback() { echo \IAWPSCOPED\iawp_blade()->run('settings.view-counter.manual-adjustment', ['value' => \IAWPSCOPED\iawp()->get_option('iawp_view_counter_manual_adjustment', \false)]); } public function register_blocked_ip_settings() { \add_settings_section('iawp-blocked-ips-settings-section', \esc_html__('Block IP Addresses', 'independent-analytics'), function () { }, 'iawp-blocked-ips-settings'); $args = ['type' => 'array', 'default' => [], 'sanitize_callback' => [$this, 'sanitize_blocked_ips']]; \register_setting('iawp_blocked_ip_settings', 'iawp_blocked_ips', $args); } public function register_email_report_settings() { \add_settings_section('iawp-email-report-settings-section', \esc_html__('Scheduled Email Reports', 'independent-analytics'), function () { }, 'iawp-email-report-settings'); \register_setting('iawp_email_report_settings', 'iawp_email_report_interval', ['type' => 'string', 'default' => 'monthly', 'sanitize_callback' => [$this, 'sanitize_email_report_interval']]); \register_setting('iawp_email_report_settings', 'iawp_email_report_time', ['type' => 'number', 'default' => 9, 'sanitize_callback' => [$this, 'sanitize_email_report_time']]); \register_setting('iawp_email_report_settings', 'iawp_email_report_email_addresses', ['type' => 'array', 'default' => [], 'sanitize_callback' => [$this, 'sanitize_email_addresses']]); \register_setting('iawp_email_report_settings', 'iawp_email_report_colors', ['type' => 'array', 'default' => $this->email_report_colors(), 'sanitize_callback' => [$this, 'sanitize_email_report_colors']]); \register_setting('iawp_email_report_settings', 'iawp_email_report_from_address', ['type' => 'string', 'default' => \get_option('admin_email'), 'sanitize_callback' => [$this, 'sanitize_email_address']]); } public function register_block_by_role_settings() { \add_settings_section('iawp-block-by-role-settings-section', \esc_html__('Block by User Role', 'independent-analytics'), function () { }, 'iawp-block-by-role-settings'); $args = ['type' => 'array', 'default' => ['administrator'], 'sanitize_callback' => [$this, 'sanitize_blocked_roles']]; \register_setting('iawp_block_by_role_settings', 'iawp_blocked_roles', $args); } public function sanitize_view_counter_post_types($user_input) { if (\is_null($user_input)) { return []; } $site_post_types = \get_post_types(['public' => \true]); $to_save = []; foreach ($user_input as $post_type) { if (\in_array($post_type, $site_post_types)) { $to_save[] = $post_type; } } return $to_save; } public function sanitize_view_counter_position($user_input) { if (\in_array($user_input, ['before', 'after', 'both'])) { return $user_input; } else { return 'after'; } } public function sanitize_view_counter_views_to_count($user_input) { if (\in_array($user_input, ['total', 'today', 'yesterday', 'this_week', 'last_week', 'last_seven', 'last_thirty', 'last_sixty', 'last_ninety', 'this_month', 'last_month', 'last_three_months', 'last_six_months', 'last_twelve_months', 'this_year', 'last_year'])) { return $user_input; } else { return 'total'; } } public function sanitize_view_counter_exclude($user_input) { $user_input = \explode(',', $user_input); $to_save = []; foreach ($user_input as $id) { $save = \absint($id); if ($save != 0) { $to_save[] = $save; } } $to_save = \implode(',', $to_save); return $to_save; } public function sanitize_blocked_ips($ips) { $valid_ips = []; foreach ($ips as $ip) { $address = \IAWPSCOPED\IPLib\Factory::parseRangeString($ip); // Skip invalid ip address ranges if ($address === null) { continue; } $valid_ips[] = $ip; } return $valid_ips; } public function sanitize_email_address($email) { $save = ''; $cleaned = \sanitize_email($email); if (\is_email($cleaned)) { $save = $cleaned; } return $save; } public function sanitize_email_addresses($emails) { $to_save = []; foreach ($emails as $email) { $cleaned = \sanitize_email($email); if (\is_email($cleaned)) { $to_save[] = $cleaned; } } return $to_save; } public function sanitize_email_report_interval($input) { if (\in_array($input, ['monthly', 'weekly', 'daily'])) { return $input; } else { return 'monthly'; } } public function sanitize_email_report_time($user_time) { $accepted_times = []; for ($i = 0; $i < 24; $i++) { $accepted_times[] = $i; } if (\in_array($user_time, $accepted_times)) { return $user_time; } else { return 9; } } public function sanitize_blocked_roles($blocked_roles) { $to_save = []; $user_roles = \array_keys(\wp_roles()->roles); foreach ($blocked_roles as $blocked) { if (\in_array($blocked, $user_roles)) { $to_save[] = $blocked; } } return $to_save; } public function sanitize_email_report_colors($colors) { $to_save = []; // No idea why WP sometimes returns an array, so this is for my sanity if (\is_string($colors)) { $colors = \explode(',', $colors); } foreach ($colors as $color) { $to_save[] = \sanitize_hex_color($color); } return $to_save; } /** * @return array */ private function get_editable_roles() : array { $editable_roles = []; $wp_roles = \wp_roles()->roles; \array_walk($wp_roles, function ($role, $role_key) use(&$editable_roles) { if ($role_key === 'administrator') { return; } $capability = null; foreach (\IAWP\Capability_Manager::all_capabilities() as $key => $name) { if (\array_key_exists($key, $role['capabilities'])) { $capability = $key; } } $editable_roles[] = ['key' => $role_key, 'name' => $role['name'], 'capability' => $capability]; }); return $editable_roles; } private function email_report_colors() { return ['#5123a0', '#fafafa', '#3a1e6b', '#fafafa', '#5123a0', '#a985e6', '#ece9f2', '#f7f5fa', '#ece9f2', '#dedae6']; } } IAWP/Sort_Configuration.php000064400000001762147600331220011637 0ustar00column = $column; if (\in_array($direction, self::VALID_DIRECTIONS)) { $this->direction = $direction; } $this->is_column_nullable = $is_column_nullable; } public function column() : string { return $this->column; } public function direction() : string { return $this->direction; } public function is_column_nullable() : bool { return $this->direction === self::ASCENDING && $this->is_column_nullable; } } IAWP/Tables.php000064400000001774147600331220007236 0ustar00prefix . 'independent_analytics_' . $name; } } IAWP/Track_Resource_Changes.php000064400000004506147600331220012363 0ustar00post_type)) { return; } $post = \get_post($post_id); if (\is_null($post) || $post->post_status === 'trash') { return; } $row = (object) ['resource' => 'singular', 'singular_id' => $post_id]; $page = new Page_Singular($row); $page->update_cache(); $campaigns_table = \IAWP\Query::get_table_name(\IAWP\Query::CAMPAIGNS); $sessions_table = \IAWP\Query::get_table_name(\IAWP\Query::SESSIONS); $views_table = \IAWP\Query::get_table_name(\IAWP\Query::VIEWS); $resources_table = \IAWP\Query::get_table_name(\IAWP\Query::RESOURCES); \IAWP\Illuminate_Builder::new()->from($campaigns_table, 'campaigns')->join("{$sessions_table} AS sessions", function (JoinClause $join) { $join->on('sessions.campaign_id', '=', 'campaigns.campaign_id'); })->join("{$views_table} AS views", function (JoinClause $join) { $join->on('views.id', '=', 'sessions.initial_view_id'); })->join("{$resources_table} AS resources", function (JoinClause $join) { $join->on('resources.id', '=', 'views.resource_id'); })->where('resources.singular_id', '=', $post_id)->update(['campaigns.landing_page_title' => $page->title()]); } public function handle_updated_author($user_id) { $row = (object) ['resource' => 'author', 'author_id' => $user_id]; $page = new Page_Author_Archive($row); $page->update_cache(); // TODO - This doesn't update resources where this author is attributed such as a singular // where this author is the author. It'll have the old user data, such as the old name, // until it's viewed. } } IAWP/View.php000064400000043224147600331220006732 0ustar00payload = $payload; $this->referrer_url = \is_null($referrer_url) ? '' : \trim($referrer_url); $this->visitor = $visitor; $this->campaign_fields = $campaign_fields; $this->viewed_at = $viewed_at instanceof \DateTime ? $viewed_at : new \DateTime(); $this->resource = $this->fetch_or_create_resource(); // If a resource can't be found or created, a view cannot be recorded if (\is_null($this->resource)) { return; } $this->session = $this->fetch_or_create_session(); $view_id = $this->create_view(); $this->link_with_previous_view($view_id); $this->set_session_total_views(); $this->set_sessions_initial_view($view_id); $this->set_sessions_final_view($view_id); $this->update_postmeta($this->resource); } /** * @return int ID of newly created session */ public function create_session() : int { $sessions_table = \IAWP\Query::get_table_name(\IAWP\Query::SESSIONS); return \IAWP\Illuminate_Builder::new()->from($sessions_table)->insertGetId(['visitor_id' => $this->visitor->id(), 'referrer_id' => $this->fetch_or_create_referrer(), 'country_id' => $this->fetch_or_create_country(), 'city_id' => $this->fetch_or_create_city(), 'campaign_id' => $this->get_campaign(), 'device_type_id' => Device::getInstance()->type_id(), 'device_os_id' => Device::getInstance()->os_id(), 'device_browser_id' => Device::getInstance()->browser_id(), 'created_at' => $this->viewed_at()]); } public function fetch_or_create_country() : ?int { if (!$this->visitor->geoposition()->valid_location()) { return null; } $countries_table = \IAWP\Query::get_table_name(\IAWP\Query::COUNTRIES); $country_id = \IAWP\Illuminate_Builder::new()->from($countries_table)->where('country_code', '=', $this->visitor->geoposition()->country_code())->where('country', '=', $this->visitor->geoposition()->country())->where('continent', '=', $this->visitor->geoposition()->continent())->value('country_id'); if (!\is_null($country_id)) { return $country_id; } \IAWP\Illuminate_Builder::new()->from($countries_table)->insertOrIgnore(['country_code' => $this->visitor->geoposition()->country_code(), 'country' => $this->visitor->geoposition()->country(), 'continent' => $this->visitor->geoposition()->continent()]); return \IAWP\Illuminate_Builder::new()->from($countries_table)->where('country_code', '=', $this->visitor->geoposition()->country_code())->where('country', '=', $this->visitor->geoposition()->country())->where('continent', '=', $this->visitor->geoposition()->continent())->value('country_id'); } public function fetch_or_create_city() : ?int { if (!$this->visitor->geoposition()->valid_location()) { return null; } $country_id = $this->fetch_or_create_country(); $cities_table = \IAWP\Query::get_table_name(\IAWP\Query::CITIES); $city_id = \IAWP\Illuminate_Builder::new()->from($cities_table)->where('country_id', $country_id)->where('subdivision', '=', $this->visitor->geoposition()->subdivision())->where('city', '=', $this->visitor->geoposition()->city())->value('city_id'); if (!\is_null($city_id)) { return $city_id; } \IAWP\Illuminate_Builder::new()->from($cities_table)->insertOrIgnore(['country_id' => $country_id, 'subdivision' => $this->visitor->geoposition()->subdivision(), 'city' => $this->visitor->geoposition()->city()]); return \IAWP\Illuminate_Builder::new()->from($cities_table)->where('country_id', $country_id)->where('subdivision', '=', $this->visitor->geoposition()->subdivision())->where('city', '=', $this->visitor->geoposition()->city())->value('city_id'); } /** * Fetch the last view, if any. * * @return int|null */ private function fetch_last_viewed_resource() : ?int { global $wpdb; $views_table = \IAWP\Query::get_table_name(\IAWP\Query::VIEWS); $session = $this->fetch_current_session(); if (\is_null($session)) { return null; } $view = $wpdb->get_row($wpdb->prepare("\n SELECT * FROM {$views_table} WHERE session_id = %d ORDER BY viewed_at DESC LIMIT 1\n ", $session->session_id)); if (\is_null($view)) { return null; } return $view->resource_id; } private function viewed_at() : string { return $this->viewed_at->format('Y-m-d\\TH:i:s'); } private function link_with_previous_view($view_id) : void { global $wpdb; $views_tables = \IAWP\Query::get_table_name(\IAWP\Query::VIEWS); $sessions_tables = \IAWP\Query::get_table_name(\IAWP\Query::SESSIONS); $session = \IAWP\Illuminate_Builder::new()->from($sessions_tables)->where('session_id', '=', $this->session)->first(); if (\is_null($session)) { return; } $final_view_id = $session->final_view_id; $initial_view_id = $session->initial_view_id; if (!\is_null($final_view_id)) { $wpdb->update($views_tables, ['next_view_id' => $view_id, 'next_viewed_at' => $this->viewed_at()], ['id' => $final_view_id]); } elseif (!\is_null($initial_view_id)) { $wpdb->update($views_tables, ['next_view_id' => $view_id, 'next_viewed_at' => $this->viewed_at()], ['id' => $initial_view_id]); } } private function set_session_total_views() { global $wpdb; $sessions_table = \IAWP\Query::get_table_name(\IAWP\Query::SESSIONS); $views_table = \IAWP\Query::get_table_name(\IAWP\Query::VIEWS); $wpdb->query($wpdb->prepare("\n UPDATE {$sessions_table} AS sessions\n LEFT JOIN (\n SELECT\n session_id,\n COUNT(*) AS view_count\n FROM\n {$views_table} AS views\n WHERE\n views.session_id = %d\n GROUP BY\n session_id) AS view_counts ON sessions.session_id = view_counts.session_id\n SET\n sessions.total_views = COALESCE(view_counts.view_count, 0)\n WHERE sessions.session_id = %d\n ", $this->session, $this->session)); } private function set_sessions_initial_view(int $view_id) { global $wpdb; $sessions_table = \IAWP\Query::get_table_name(\IAWP\Query::SESSIONS); $wpdb->query($wpdb->prepare("UPDATE {$sessions_table} SET initial_view_id = %d WHERE session_id = %d AND initial_view_id IS NULL", $view_id, $this->session)); } private function set_sessions_final_view(int $view_id) { global $wpdb; $sessions_table = \IAWP\Query::get_table_name(\IAWP\Query::SESSIONS); $wpdb->query($wpdb->prepare("\n UPDATE {$sessions_table} AS sessions\n SET\n sessions.final_view_id = %d,\n sessions.ended_at = %s\n WHERE sessions.session_id = %d AND sessions.initial_view_id IS NOT NULL AND sessions.initial_view_id != %d\n ", $view_id, $this->viewed_at(), $this->session, $view_id)); } private function create_view() : int { $views_table = \IAWP\Query::get_table_name(\IAWP\Query::VIEWS); return \IAWP\Illuminate_Builder::new()->from($views_table)->insertGetId(['resource_id' => $this->resource->id(), 'viewed_at' => $this->viewed_at(), 'page' => $this->payload['page'], 'session_id' => $this->session]); } private function fetch_resource() { global $wpdb; $resources_table = \IAWP\Query::get_table_name(\IAWP\Query::RESOURCES); $query = ''; $payload_copy = \array_merge($this->payload); unset($payload_copy['page']); switch ($payload_copy['resource']) { case 'singular': $query = $wpdb->prepare("SELECT * FROM {$resources_table} WHERE resource = %s AND singular_id = %d", $payload_copy['resource'], $payload_copy['singular_id']); break; case 'author_archive': $query = $wpdb->prepare("SELECT * FROM {$resources_table} WHERE resource = %s AND author_id = %d", $payload_copy['resource'], $payload_copy['author_id']); break; case 'date_archive': $query = $wpdb->prepare("SELECT * FROM {$resources_table} WHERE resource = %s AND date_archive = %s", $payload_copy['resource'], $payload_copy['date_archive']); break; case 'post_type_archive': $query = $wpdb->prepare("SELECT * FROM {$resources_table} WHERE resource = %s AND post_type = %s", $payload_copy['resource'], $payload_copy['post_type']); break; case 'term_archive': $query = $wpdb->prepare("SELECT * FROM {$resources_table} WHERE resource = %s AND term_id = %s", $payload_copy['resource'], $payload_copy['term_id']); break; case 'search': $query = $wpdb->prepare("SELECT * FROM {$resources_table} WHERE resource = %s AND search_query = %s", $payload_copy['resource'], $payload_copy['search_query']); break; case 'home': $query = $wpdb->prepare("SELECT * FROM {$resources_table} WHERE resource = %s ", $payload_copy['resource']); break; case '404': $query = $wpdb->prepare("SELECT * FROM {$resources_table} WHERE resource = %s AND not_found_url = %s", $payload_copy['resource'], $payload_copy['not_found_url']); break; case 'virtual_page': $query = $wpdb->prepare("SELECT * FROM {$resources_table} WHERE resource = %s AND virtual_page_id = %s", $payload_copy['resource'], $payload_copy['virtual_page_id']); break; } $resource = $wpdb->get_row($query); if (\is_null($resource)) { return null; } return $resource; } private function fetch_or_create_resource() : ?Page { global $wpdb; $resources_table = \IAWP\Query::get_table_name(\IAWP\Query::RESOURCES); $resource = $this->fetch_resource(); if (\is_null($resource)) { $payload_copy = \array_merge($this->payload); unset($payload_copy['page']); $wpdb->insert($resources_table, $payload_copy); $resource = $this->fetch_resource(); } if (\is_null($resource)) { return null; } $page = Page::from_row($resource); $page->update_cache(); return $page; } /** * @return int|null ID of the session that should be used for this view */ private function fetch_or_create_session() : ?int { $session = $this->fetch_current_session(); if (\is_null($session)) { return $this->create_session(); } $is_same_referrer = $this->fetch_or_create_referrer() === $session->referrer_id; $is_same_resource = \intval($this->fetch_resource()->id) === $this->fetch_last_viewed_resource(); $same_as_previous_view = $is_same_referrer && $is_same_resource; // The goal here is to prevent opening multiple tabs to the site from creating multiple sessions if ($is_same_referrer) { return $session->session_id; } // The goal here is to prevent a page refresh from creating another session if ($this->is_internal_referrer($this->referrer_url) || $same_as_previous_view) { return $session->session_id; } return $this->create_session(); } /** * @param string|null $referrer_url * * @return bool */ private function is_internal_referrer(?string $referrer_url) : bool { return !empty($referrer_url) && String_Util::str_starts_with(\strtolower($referrer_url), \strtolower(\site_url())); } private function fetch_referrer(array $referrer) : int { $referrers_table = \IAWP\Query::get_table_name(\IAWP\Query::REFERRERS); $id = \IAWP\Illuminate_Builder::new()->select('id')->from($referrers_table)->where('domain', '=', $referrer['domain'])->value('id'); if (\is_null($id)) { $id = \IAWP\Illuminate_Builder::new()->from($referrers_table)->insertGetId(['domain' => $referrer['domain'], 'type' => $referrer['type'], 'referrer' => $referrer['referrer']]); } return $id; } private function fetch_or_create_referrer() : int { $url = new URL($this->referrer_url); if (!$url->is_valid_url() || $this->is_internal_referrer($this->referrer_url)) { return $this->fetch_referrer(['domain' => '', 'type' => 'Direct', 'referrer' => 'Direct']); } elseif (!\is_null(\IAWP\Known_Referrers::get_group_for($url->get_domain()))) { $group = \IAWP\Known_Referrers::get_group_for($url->get_domain()); return $this->fetch_referrer(['domain' => $group['domain'], 'type' => $group['type'], 'referrer' => $group['name']]); } else { return $this->fetch_referrer(['domain' => $url->get_domain(), 'type' => 'Referrer', 'referrer' => $this->strip_www($url->get_domain())]); } } private function strip_www(string $string) : string { if (\strpos($string, "www.") !== 0) { return $string; } return \substr($string, 4); } private function get_campaign() : ?int { global $wpdb; $required_fields = ['utm_source', 'utm_medium', 'utm_campaign']; $valid = \true; foreach ($required_fields as $field) { if (!isset($this->campaign_fields[$field])) { $valid = \false; } } if (!$valid) { return null; } $campaigns_table = \IAWP\Query::get_table_name(\IAWP\Query::CAMPAIGNS); $campaign = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$campaigns_table} WHERE landing_page_title = %s AND utm_source = %s AND utm_medium = %s AND utm_campaign = %s AND (utm_term = %s OR (%d = 0 AND utm_term IS NULL)) AND (utm_content = %s OR (%d = 0 AND utm_content IS NULL))", $this->resource->title(), $this->campaign_fields['utm_source'], $this->campaign_fields['utm_medium'], $this->campaign_fields['utm_campaign'], $this->campaign_fields['utm_term'], isset($this->campaign_fields['utm_term']) ? 1 : 0, $this->campaign_fields['utm_content'], isset($this->campaign_fields['utm_content']) ? 1 : 0)); if (!\is_null($campaign)) { return $campaign->campaign_id; } $wpdb->insert($campaigns_table, ['landing_page_title' => $this->resource->title(), 'utm_source' => $this->campaign_fields['utm_source'], 'utm_medium' => $this->campaign_fields['utm_medium'], 'utm_campaign' => $this->campaign_fields['utm_campaign'], 'utm_term' => $this->campaign_fields['utm_term'], 'utm_content' => $this->campaign_fields['utm_content']]); $campaign = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$campaigns_table} WHERE landing_page_title = %s AND utm_source = %s AND utm_medium = %s AND utm_campaign = %s AND (utm_term = %s OR (%d = 0 AND utm_term IS NULL)) AND (utm_content = %s OR (%d = 0 AND utm_content IS NULL))", $this->resource->title(), $this->campaign_fields['utm_source'], $this->campaign_fields['utm_medium'], $this->campaign_fields['utm_campaign'], $this->campaign_fields['utm_term'], isset($this->campaign_fields['utm_term']) ? 1 : 0, $this->campaign_fields['utm_content'], isset($this->campaign_fields['utm_content']) ? 1 : 0)); if (!\is_null($campaign)) { return $campaign->campaign_id; } return null; } private function fetch_current_session() : ?object { $sessions_table = \IAWP\Query::get_table_name(\IAWP\Query::SESSIONS); $session = \IAWP\Illuminate_Builder::new()->from($sessions_table, 'sessions')->selectRaw('IFNULL(ended_at, created_at) AS latest_view_at')->selectRaw('sessions.*')->where('visitor_id', '=', $this->visitor->id())->havingRaw('latest_view_at > DATE_SUB(UTC_TIMESTAMP(), INTERVAL 30 MINUTE)')->orderBy('latest_view_at', 'DESC')->first(); return $session; } private function update_postmeta(Page $resource) : void { $singular_id = $resource->get_singular_id(); if ($singular_id === null) { return; } $views_table = \IAWP\Query::get_table_name(\IAWP\Query::VIEWS); $resources_table = \IAWP\Query::get_table_name(\IAWP\Query::RESOURCES); $total_views = \IAWP\Illuminate_Builder::new()->selectRaw('COUNT(*) AS views')->from("{$resources_table} as resources")->join("{$views_table} AS views", function (JoinClause $join) { $join->on('resources.id', '=', 'views.resource_id'); })->where('singular_id', '=', $singular_id)->value('views'); \update_post_meta($singular_id, Views_Column::$meta_key, $total_views); } } IAWP/View_Counter.php000064400000016741147600331220010435 0ustar00passes_checks()) { return $content; } $position = \IAWPSCOPED\iawp()->get_option('iawp_view_counter_position', 'after'); $counter = $this->get_counter_html(); if ($position == 'before' || $position == 'both') { $content = $counter . $content; } if ($position == 'after' || $position == 'both') { $content .= $counter; } return $content; } public function get_counter_html($label = null, $icon = null, $range = null) { $current_resource = \IAWP\Resource_Identifier::for_resource_being_viewed(); // It's critical to check because this function is called erroneously by Gutenberg in the editor if (\is_null($current_resource)) { return; } // Get stats for individual posts in the loop if shortcode added to each post global $post; if ($post->ID != $current_resource->meta_value() && \is_main_query() && \in_the_loop()) { $current_resource = \IAWP\Resource_Identifier::for_post_id($post->ID); } if (\is_null($range)) { $range = \IAWPSCOPED\iawp()->get_option('iawp_view_counter_views_to_count', 'total'); } $view_count = $this->get_view_count($current_resource, $range); if (\IAWPSCOPED\iawp()->get_option('iawp_view_counter_manual_adjustment', \false)) { $view_count += \intval(\get_post_meta($current_resource->meta_value(), 'iawp_view_counter_adjustment', \true)); } $view_count = Number_Formatter::decimal($view_count); if (\is_null($label)) { if (!\get_option('iawp_view_counter_label_show', \true)) { $label = ''; } else { $default = \function_exists('IAWPSCOPED\\pll__') ? pll__('Views:', 'independent-analytics') : \__('Views:', 'independent-analytics'); $label = \IAWPSCOPED\iawp()->get_option('iawp_view_counter_label', $default); } } if (\is_null($icon)) { $icon = \get_option('iawp_view_counter_icon', \true); } if ($icon) { $svg = ''; $label = $svg . ' ' . $label; } return '
' . Security::svg($label) . ' ' . \esc_html($view_count) . '
'; } public function add_shortcode() { \add_shortcode('iawp_view_counter', [$this, 'shortcode']); } public function shortcode($atts) { $a = \shortcode_atts(['label' => \IAWPSCOPED\iawp()->get_option('iawp_view_counter_label', \esc_html__('Views:', 'independent-analytics')), 'icon' => \true, 'range' => \IAWPSCOPED\iawp()->get_option('iawp_view_counter_views_to_count', 'total')], $atts); return $this->get_counter_html($a['label'], $a['icon'], $a['range']); } public function maybe_add_meta_box() : void { if (!\IAWPSCOPED\iawp()->get_option('iawp_view_counter_manual_adjustment', \false)) { return; } foreach (\IAWPSCOPED\iawp()->get_option('iawp_view_counter_post_types', []) as $screen) { \add_meta_box('iawp-view-counter-adjustment', \esc_html__('View Counter Adjustment', 'independent-analytics'), [$this, 'render_meta_box_content'], $screen, 'side'); } } public function render_meta_box_content() : void { global $post; echo '

' . \esc_html__('Increase count by:', 'independent-analytics') . '

'; } public function save_metabox_settings(int $post_id) { if (\array_key_exists('iawp_view_counter_adjustment', $_POST)) { \update_post_meta($post_id, 'iawp_view_counter_adjustment', \absint($_POST['iawp_view_counter_adjustment'])); } } private function passes_checks() : bool { if (!\is_singular() || !\is_main_query()) { return \false; } if (\IAWPSCOPED\iawp()->get_option('iawp_view_counter_enable', \false) == \false) { return \false; } if (!\in_array(\get_post_type(), \IAWPSCOPED\iawp()->get_option('iawp_view_counter_post_types', []))) { return \false; } if (\IAWPSCOPED\iawp()->get_option('iawp_view_counter_private', \false) && !\is_user_logged_in()) { return \false; } $exclude = \IAWPSCOPED\iawp()->get_option('iawp_view_counter_exclude', ''); if ($exclude != '') { $exclude = \explode(',', $exclude); if (\in_array(\get_the_ID(), $exclude)) { return \false; } } return \true; } private function get_view_count(\IAWP\Resource_Identifier $resource, string $relative_range_id) : int { $relative_range_id = \strtoupper($relative_range_id); if ($relative_range_id === 'TOTAL' || !\in_array($relative_range_id, Relative_Date_Range::range_ids())) { $relative_range_id = 'ALL_TIME'; } $resources_table = \IAWP\Query::get_table_name(\IAWP\Query::RESOURCES); $views_table = \IAWP\Query::get_table_name(\IAWP\Query::VIEWS); $relative_range = new Relative_Date_Range($relative_range_id); $query = \IAWP\Illuminate_Builder::new()->selectRaw('COUNT(views.id) AS views')->from($resources_table, 'resources')->leftJoin("{$views_table} AS views", function (JoinClause $join) { $join->on('resources.id', '=', 'views.resource_id'); })->where('resource', '=', $resource->type())->when($resource->has_meta(), function (Builder $query) use($resource) { $query->where($resource->meta_key(), '=', $resource->meta_value()); })->whereBetween('viewed_at', [$relative_range->iso_start(), $relative_range->iso_end()])->groupBy('resources.id'); $views = $query->value('views'); return \is_null($views) ? 0 : $views; } } IAWP/Visitors_Over_Time_Finder.php000064400000003651147600331220013102 0ustar00date_range = $date_range; $this->interval = $interval; } public function fetch() { $rows = $this->interval->fetch($this->date_range); return $this->rows_to_class($rows); } private function rows_to_class(array $rows) : object { $date_interval = $this->interval->get_date_interval(); $date_period = new \DatePeriod($this->date_range->start(), $date_interval, $this->date_range->end()); $interval_data = []; $visitors_data = []; $views_data = []; foreach ($date_period as $index => $date) { $current_interval = $index; $current_visitors = 0; $current_views = 0; foreach ($rows as $row) { $row_interval = \intval($row->interval_ago); $row_visitors = \intval($row->visitors); $row_views = \intval($row->views); if ($row_interval === $index) { $current_interval = $row_interval; $current_visitors = $row_visitors; $current_views = $row_views; break; } } $interval_data[] = $current_interval; $visitors_data[] = $current_visitors; $views_data[] = $current_views; } return (object) ['visitors' => $visitors_data, 'views' => $views_data, 'interval_labels_short' => $this->interval->get_short_labels($interval_data), 'interval_labels_full' => $this->interval->get_full_labels($interval_data)]; } } IAWP/WP_Option_Cache_Bust.php000064400000002634147600331220011756 0ustar00option_name = $option_name; } /** * @param string|null $prefix * @return string */ private function option_name(?string $prefix = null) : string { if (\is_string($prefix)) { return $prefix . $this->option_name; } return $this->option_name; } /** * @param $default_value * @return mixed|null */ private function value($default_value) { global $wpdb; $row = $wpdb->get_row($wpdb->prepare("SELECT option_value FROM {$wpdb->options} WHERE option_name = %s LIMIT 1", $this->option_name())); if (\is_object($row)) { $value = $row->option_value; } else { $value = $default_value; } return \apply_filters($this->option_name('option_'), \maybe_unserialize($value), $this->option_name()); } /** * @param string $option_name * @return void */ public static function register(string $option_name) { $cache_bust = new self($option_name); \add_filter($cache_bust->option_name('pre_option_'), function ($default_value) use($cache_bust) { return $cache_bust->value($default_value); }); } } dist/js/click-tracking-menu.js000064400000176601147600331220012321 0ustar00!function(e,t,n,o,r){var i="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:{},a="function"==typeof i[o]&&i[o],l=a.cache||{},s="undefined"!=typeof module&&"function"==typeof module.require&&module.require.bind(module);function c(t,n){if(!l[t]){if(!e[t]){var r="function"==typeof i[o]&&i[o];if(!n&&r)return r(t,!0);if(a)return a(t,!0);if(s&&"string"==typeof t)return s(t);var u=Error("Cannot find module '"+t+"'");throw u.code="MODULE_NOT_FOUND",u}f.resolve=function(n){var o=e[t][1][n];return null!=o?o:n},f.cache={};var d=l[t]=new c.Module(t);e[t][0].call(d.exports,f,d,d.exports,this)}return l[t].exports;function f(e){var t=f.resolve(e);return!1===t?{}:c(t)}}c.isParcelRequire=!0,c.Module=function(e){this.id=e,this.bundle=c,this.exports={}},c.modules=e,c.cache=l,c.parent=a,c.register=function(t,n){e[t]=[function(e,t){t.exports=n},{}]},Object.defineProperty(c,"root",{get:function(){return i[o]}}),i[o]=c;for(var u=0;u0?(t.hideErrorMessages(e),e.after(t.errorMessages),t.errorMessages.find("."+n.data.error).addClass("visible"),e.find(".link-"+n.data.property).addClass("error"),e.find(".save-button").prop("disabled",!1),e.find(".cancel-button").prop("disabled",!1)):(n.data.shouldShowCacheMessage&&document.getElementById("click-tracking-cache-message-container").classList.add("show"),e.parent().is("#sortable-tracked-links-list")?e.replaceWith(n.data.html):(e.remove(),d("#sortable-tracked-links-list").prepend(n.data.html)),t.hideErrorMessages(e))})},archiveLinkRequest:function(e){var t=this,n=e.data("id"),o=(0,i._)((0,r._)({},iawpActions.archive_link),{id:n}),a=e.closest(".tracked-links-list").length>0;e.addClass("archiving"),jQuery.post(ajaxurl,o,function(n){(n=JSON.parse(n))&&(document.getElementById("click-tracking-cache-message-container").classList.add("show"),e.remove(),a?d("#archived-links-list").prepend(n):d("#sortable-tracked-links-list").prepend(n)),t.toggleEmptyMessage()})},deleteLinkRequest:function(e){var t=this,n=this,o=(0,i._)((0,r._)({},iawpActions.delete_link),{id:e});this.deleteButton.addClass("sending"),jQuery.post(ajaxurl,o,function(e){n.deleteButton.removeClass("sending"),d('.trackable-link[data-id="'+e.data.id+'"]').remove(),(0,s.default).close("delete-link-modal"),t.toggleEmptyMessage()}).fail(function(){})},changeVisibleInput:function(e,t){e.find(".value-container.visible").removeClass("visible"),e.find(".value-container."+t).addClass("visible")},enableEditing:function(e){e.addClass("is-editing"),this.focusOnInput(e.find(".link-name"))},cancelEditing:function(e){e.hasClass("blueprint-clone")?e.remove():e.removeClass("is-editing"),this.hideErrorMessages(e),this.errorMessages.remove(),this.toggleEmptyMessage()},toggleArchivedLinks:function(e){d("#archived-links").toggleClass("open");var t=e.text();e.text(e.data("alt-text")),e.data("alt-text",t)},addNewLinkToTable:function(){if(0===d("#tracked-links-list").find(".blueprint-clone").length){var e=d("#blueprint-link .trackable-link").clone();e.addClass("is-editing blueprint-clone"),d("#tracked-links-list").prepend(e),e.find(".link-name").focus(),this.toggleEmptyMessage()}},triggerSaveButton:function(e,t,n){t.hasClass("is-editing")&&"SELECT"!=n.get(0).tagName&&"Enter"==e.key&&t.find(".save-button").click()},focusOnInput:function(e){var t=e.focus().val();e.val("").val(t)},hideErrorMessages:function(e){e.find("input, select").removeClass("error"),this.errorMessages.find("p").removeClass("visible")},toggleEmptyMessage:function(){0===d("#tracked-links-list .trackable-link").length?d(".tracked-links-empty-message").addClass("show"):d(".tracked-links-empty-message").removeClass("show"),0===d("#archived-links-list .trackable-link").length?d(".archived-links-empty-message").addClass("show"):d(".archived-links-empty-message").removeClass("show")},sortLinks:function(e,t){var n=this,o=Array.from(t.target.querySelectorAll(".trackable-link")).map(function(e){return parseInt(e.dataset.id)}),a=(0,i._)((0,r._)({},iawpActions.sort_links),{ids:o});jQuery.post(ajaxurl,a,function(e){}).fail(function(){e.sort(n.moveArrayItem(e.toArray(),t.newIndex,t.oldIndex))})},moveArrayItem:function(e,t,n){var o=(0,a._)(e);if(t===n)return o;var r=o.splice(t,1)[0];return o.splice(n,0,r),o}};jQuery(function(e){f.setup()})},{"@swc/helpers/_/_object_spread":"kexvf","@swc/helpers/_/_object_spread_props":"c7x3p","@swc/helpers/_/_to_consumable_array":"4oNkS",micromodal:"Tlrpp",sortablejs:"9lkyr","@parcel/transformer-js/src/esmodule-helpers.js":"kPSB8"}],kexvf:[function(e,t,n){var o=e("@parcel/transformer-js/src/esmodule-helpers.js");o.defineInteropFlag(n),o.export(n,"_object_spread",function(){return i}),o.export(n,"_",function(){return i});var r=e("./_define_property.js");function i(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,o=Array(t);ne.length)&&(t=e.length);for(var n=0,o=Array(t);n0&&this.registerTriggers.apply(this,r(i)),this.onClick=this.onClick.bind(this),this.onKeydown=this.onKeydown.bind(this)}return e=[{key:"registerTriggers",value:function(){for(var e=this,t=arguments.length,n=Array(t),o=0;o0&&void 0!==arguments[0]?arguments[0]:null;(this.activeElement=document.activeElement,this.modal.setAttribute("aria-hidden","false"),this.modal.classList.add(this.config.openClass),this.scrollBehaviour("disable"),this.addEventListeners(),this.config.awaitOpenAnimation)?this.modal.addEventListener("animationend",function t(){e.modal.removeEventListener("animationend",t,!1),e.setFocusToFirstNode()},!1):this.setFocusToFirstNode(),this.config.onShow(this.modal,this.activeElement,t)}},{key:"closeModal",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,t=this.modal;if(this.modal.setAttribute("aria-hidden","true"),this.removeEventListeners(),this.scrollBehaviour("enable"),this.activeElement&&this.activeElement.focus&&this.activeElement.focus(),this.config.onClose(this.modal,this.activeElement,e),this.config.awaitCloseAnimation){var n=this.config.openClass;this.modal.addEventListener("animationend",function e(){t.classList.remove(n),t.removeEventListener("animationend",e,!1)},!1)}else t.classList.remove(this.config.openClass)}},{key:"closeModalById",value:function(e){this.modal=document.getElementById(e),this.modal&&this.closeModal()}},{key:"scrollBehaviour",value:function(e){if(this.config.disableScroll){var t=document.querySelector("body");switch(e){case"enable":Object.assign(t.style,{overflow:""});break;case"disable":Object.assign(t.style,{overflow:"hidden"})}}}},{key:"addEventListeners",value:function(){this.modal.addEventListener("touchstart",this.onClick),this.modal.addEventListener("click",this.onClick),document.addEventListener("keydown",this.onKeydown)}},{key:"removeEventListeners",value:function(){this.modal.removeEventListener("touchstart",this.onClick),this.modal.removeEventListener("click",this.onClick),document.removeEventListener("keydown",this.onKeydown)}},{key:"onClick",value:function(e){(e.target.hasAttribute(this.config.closeTrigger)||e.target.parentNode.hasAttribute(this.config.closeTrigger))&&(e.preventDefault(),e.stopPropagation(),this.closeModal(e))}},{key:"onKeydown",value:function(e){27===e.keyCode&&this.closeModal(e),9===e.keyCode&&this.retainFocus(e)}},{key:"getFocusableNodes",value:function(){return Array.apply(void 0,r(this.modal.querySelectorAll(a)))}},{key:"setFocusToFirstNode",value:function(){var e=this;if(!this.config.disableFocus){var t=this.getFocusableNodes();if(0!==t.length){var n=t.filter(function(t){return!t.hasAttribute(e.config.closeTrigger)});n.length>0&&n[0].focus(),0===n.length&&t[0].focus()}}}},{key:"retainFocus",value:function(e){var t=this.getFocusableNodes();if(0!==t.length){if(t=t.filter(function(e){return null!==e.offsetParent}),this.modal.contains(document.activeElement)){var n=t.indexOf(document.activeElement);e.shiftKey&&0===n&&(t[t.length-1].focus(),e.preventDefault()),!e.shiftKey&&t.length>0&&n===t.length-1&&(t[0].focus(),e.preventDefault())}else t[0].focus()}}}],o(n.prototype,e),t&&o(n,t),n}(),s=null,c=function(e){if(!document.getElementById(e))return console.warn("MicroModal: â—Seems like you have missed %c'".concat(e,"'"),"background-color: #f8f9fa;color: #50596c;font-weight: bold;","ID somewhere in your code. Refer example below to resolve it."),console.warn("%cExample:","background-color: #f8f9fa;color: #50596c;font-weight: bold;",'')),!1},u=function(e,t){if(e.length<=0&&(console.warn("MicroModal: â—Please specify at least one %c'micromodal-trigger'","background-color: #f8f9fa;color: #50596c;font-weight: bold;","data attribute."),console.warn("%cExample:","background-color: #f8f9fa;color: #50596c;font-weight: bold;",'')),!t)return!0;for(var n in t)c(n);return!0},{init:function(e){var t,n,o=Object.assign({},{openTrigger:"data-micromodal-trigger"},e),i=r(document.querySelectorAll("[".concat(o.openTrigger,"]"))),a=(t=o.openTrigger,n=[],i.forEach(function(e){var o=e.attributes[t].value;void 0===n[o]&&(n[o]=[]),n[o].push(e)}),n);if(!0!==o.debugMode||!1!==u(i,a))for(var c in a){var d=a[c];o.targetModal=c,o.triggers=r(d),s=new l(o)}},show:function(e,t){var n=t||{};n.targetModal=e,!0===n.debugMode&&!1===c(e)||(s&&s.removeEventListeners(),(s=new l(n)).showModal())},close:function(e){e?s.closeModalById(e):s.closeModal()}});"undefined"!=typeof window&&(window.MicroModal=d),n.default=d},{"@parcel/transformer-js/src/esmodule-helpers.js":"kPSB8"}],"9lkyr":[function(e,t,n){/**! * Sortable 1.15.2 * @author RubaXa * @author owenm * @license MIT */var o=e("@parcel/transformer-js/src/esmodule-helpers.js");function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,o)}return n}function i(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,o=Array(t);n"===t[0]&&(t=t.substring(1)),e)try{if(e.matches)return e.matches(t);if(e.msMatchesSelector)return e.msMatchesSelector(t);if(e.webkitMatchesSelector)return e.webkitMatchesSelector(t)}catch(e){}return!1}}function _(e,t,n,o){if(e){var r;n=n||document;do{if(null!=t&&(">"===t[0]?e.parentNode===n&&y(e,t):y(e,t))||o&&e===n)return e;if(e===n)break}while(e=(r=e).host&&r!==document&&r.host.nodeType?r.host:r.parentNode)}return null}var w=/\s+/g;function E(e,t,n){if(e&&t){if(e.classList)e.classList[n?"add":"remove"](t);else{var o=(" "+e.className+" ").replace(w," ").replace(" "+t+" "," ");e.className=(o+(n?" "+t:"")).replace(w," ")}}}function k(e,t,n){var o=e&&e.style;if(o){if(void 0===n)return document.defaultView&&document.defaultView.getComputedStyle?n=document.defaultView.getComputedStyle(e,""):e.currentStyle&&(n=e.currentStyle),void 0===t?n:n[t];t in o||-1!==t.indexOf("webkit")||(t="-webkit-"+t),o[t]=n+("string"==typeof n?"":"px")}}function S(e,t){var n="";if("string"==typeof e)n=e;else do{var o=k(e,"transform");o&&"none"!==o&&(n=o+" "+n)}while(!t&&(e=e.parentNode))var r=window.DOMMatrix||window.WebKitCSSMatrix||window.CSSMatrix||window.MSCSSMatrix;return r&&new r(n)}function D(e,t,n){if(e){var o=e.getElementsByTagName(t),r=0,i=o.length;if(n)for(;r=i:r<=i))return o;if(o===C())break;o=I(o,!1)}return!1}function M(e,t,n,o){for(var r=0,i=0,a=e.children;i2&&void 0!==arguments[2]?arguments[2]:{},o=n.evt,r=function(e,t){if(null==e)return{};var n,o,r=function(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}(n,W);q.pluginEvent.bind(eY)(e,t,i({dragEl:V,parentEl:$,ghostEl:Z,rootEl:J,nextEl:ee,lastDownEl:et,cloneEl:en,cloneHidden:eo,dragStarted:em,putSortable:ec,activeSortable:eY.active,originalEvent:o,oldIndex:er,oldDraggableIndex:ea,newIndex:ei,newDraggableIndex:el,hideGhostForTarget:eL,unhideGhostForTarget:eF,cloneNowHidden:function(){eo=!0},cloneNowShown:function(){eo=!1},dispatchSortableEvent:function(e){G({sortable:t,name:e,originalEvent:o})}},r))};function G(e){U(i({putSortable:ec,cloneEl:en,targetEl:V,rootEl:J,oldIndex:er,oldDraggableIndex:ea,newIndex:ei,newDraggableIndex:el},e))}var Q,V,$,Z,J,ee,et,en,eo,er,ei,ea,el,es,ec,eu,ed,ef,eh,ep,eg,em,ev,eb,ey,e_,ew=!1,eE=!1,ek=[],eS=!1,eD=!1,eC=[],ex=!1,eO=[],eM="undefined"!=typeof document,ej=d||u?"cssFloat":"float",eT=eM&&!g&&!p&&"draggable"in document.createElement("div"),eA=function(){if(eM){if(u)return!1;var e=document.createElement("x");return e.style.cssText="pointer-events:auto","auto"===e.style.pointerEvents}}(),eI=function(e,t){var n=k(e),o=parseInt(n.width)-parseInt(n.paddingLeft)-parseInt(n.paddingRight)-parseInt(n.borderLeftWidth)-parseInt(n.borderRightWidth),r=M(e,0,t),i=M(e,1,t),a=r&&k(r),l=i&&k(i),s=a&&parseInt(a.marginLeft)+parseInt(a.marginRight)+x(r).width,c=l&&parseInt(l.marginLeft)+parseInt(l.marginRight)+x(i).width;if("flex"===n.display)return"column"===n.flexDirection||"column-reverse"===n.flexDirection?"vertical":"horizontal";if("grid"===n.display)return n.gridTemplateColumns.split(" ").length<=1?"vertical":"horizontal";if(r&&a.float&&"none"!==a.float){var u="left"===a.float?"left":"right";return i&&("both"===l.clear||l.clear===u)?"vertical":"horizontal"}return r&&("block"===a.display||"flex"===a.display||"table"===a.display||"grid"===a.display||s>=o&&"none"===n[ej]||i&&"none"===n[ej]&&s+c>o)?"vertical":"horizontal"},eN=function(e,t,n){var o=n?e.left:e.top,r=n?e.right:e.bottom,i=n?e.width:e.height,a=n?t.left:t.top,l=n?t.right:t.bottom,s=n?t.width:t.height;return o===a||r===l||o+i/2===a+s/2},eP=function(e,t){var n;return ek.some(function(o){var r=o[Y].options.emptyInsertThreshold;if(!(!r||j(o))){var i=x(o),a=e>=i.left-r&&e<=i.right+r,l=t>=i.top-r&&t<=i.bottom+r;if(a&&l)return n=o}}),n},eB=function(e){function t(e,n){return function(o,r,i,a){var l=o.options.group.name&&r.options.group.name&&o.options.group.name===r.options.group.name;if(null==e&&(n||l))return!0;if(null==e||!1===e)return!1;if(n&&"clone"===e)return e;if("function"==typeof e)return t(e(o,r,i,a),n)(o,r,i,a);var s=(n?o:r).options.group.name;return!0===e||"string"==typeof e&&e===s||e.join&&e.indexOf(s)>-1}}var n={},o=e.group;o&&"object"==a(o)||(o={name:o}),n.name=o.name,n.checkPull=t(o.pull,!0),n.checkPut=t(o.put),n.revertClone=o.revertClone,e.group=n},eL=function(){!eA&&Z&&k(Z,"display","none")},eF=function(){!eA&&Z&&k(Z,"display","")};eM&&!g&&document.addEventListener("click",function(e){if(eE)return e.preventDefault(),e.stopPropagation&&e.stopPropagation(),e.stopImmediatePropagation&&e.stopImmediatePropagation(),eE=!1,!1},!0);var eR=function(e){if(V){var t=eP((e=e.touches?e.touches[0]:e).clientX,e.clientY);if(t){var n={};for(var o in e)e.hasOwnProperty(o)&&(n[o]=e[o]);n.target=n.rootEl=t,n.preventDefault=void 0,n.stopPropagation=void 0,t[Y]._onDragOver(n)}}},eX=function(e){V&&V.parentNode[Y]._isOutsideThisEl(e.target)};function eY(e,t){if(!(e&&e.nodeType&&1===e.nodeType))throw"Sortable: `el` must be an HTMLElement, not ".concat(({}).toString.call(e));this.el=e,this.options=t=l({},t),e[Y]=this;var n,o,r={group:null,sort:!0,disabled:!1,store:null,handle:null,draggable:/^[uo]l$/i.test(e.nodeName)?">li":">*",swapThreshold:1,invertSwap:!1,invertedSwapThreshold:null,removeCloneOnHide:!0,direction:function(){return eI(e,this.options)},ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,easing:null,setData:function(e,t){e.setData("Text",t.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,delayOnTouchOnly:!1,touchStartThreshold:(Number.parseInt?Number:window).parseInt(window.devicePixelRatio,10)||1,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0},supportPointer:!1!==eY.supportPointer&&"PointerEvent"in window&&!h,emptyInsertThreshold:5};for(var a in q.initializePlugins(this,e,r),r)a in t||(t[a]=r[a]);for(var s in eB(t),this)"_"===s.charAt(0)&&"function"==typeof this[s]&&(this[s]=this[s].bind(this));this.nativeDraggable=!t.forceFallback&&eT,this.nativeDraggable&&(this.options.touchStartThreshold=1),t.supportPointer?v(e,"pointerdown",this._onTapStart):(v(e,"mousedown",this._onTapStart),v(e,"touchstart",this._onTapStart)),this.nativeDraggable&&(v(e,"dragover",this),v(e,"dragenter",this)),ek.push(this.el),t.store&&t.store.get&&this.sort(t.store.get(this)||[]),l(this,(o=[],{captureAnimationState:function(){o=[],this.options.animation&&[].slice.call(this.el.children).forEach(function(e){if("none"!==k(e,"display")&&e!==eY.ghost){o.push({target:e,rect:x(e)});var t=i({},o[o.length-1].rect);if(e.thisAnimationDuration){var n=S(e,!0);n&&(t.top-=n.f,t.left-=n.e)}e.fromRect=t}})},addAnimationState:function(e){o.push(e)},removeAnimationState:function(e){o.splice(function(e,t){for(var n in e)if(e.hasOwnProperty(n)){for(var o in t)if(t.hasOwnProperty(o)&&t[o]===e[n][o])return Number(n)}return -1}(o,{target:e}),1)},animateAll:function(e){var t=this;if(!this.options.animation){clearTimeout(n),"function"==typeof e&&e();return}var r=!1,i=0;o.forEach(function(e){var n,o=0,a=e.target,l=a.fromRect,s=x(a),c=a.prevFromRect,u=a.prevToRect,d=e.rect,f=S(a,!0);f&&(s.top-=f.f,s.left-=f.e),a.toRect=s,a.thisAnimationDuration&&N(c,s)&&!N(l,s)&&(d.top-s.top)/(d.left-s.left)==(l.top-s.top)/(l.left-s.left)&&(n=t.options,o=Math.sqrt(Math.pow(c.top-d.top,2)+Math.pow(c.left-d.left,2))/Math.sqrt(Math.pow(c.top-u.top,2)+Math.pow(c.left-u.left,2))*n.animation),N(s,l)||(a.prevFromRect=l,a.prevToRect=s,o||(o=t.options.animation),t.animate(a,d,s,o)),o&&(r=!0,i=Math.max(i,o),clearTimeout(a.animationResetTimer),a.animationResetTimer=setTimeout(function(){a.animationTime=0,a.prevFromRect=null,a.fromRect=null,a.prevToRect=null,a.thisAnimationDuration=null},o),a.thisAnimationDuration=o)}),clearTimeout(n),r?n=setTimeout(function(){"function"==typeof e&&e()},i):"function"==typeof e&&e(),o=[]},animate:function(e,t,n,o){if(o){k(e,"transition",""),k(e,"transform","");var r=S(this.el),i=r&&r.a,a=r&&r.d,l=(t.left-n.left)/(i||1),s=(t.top-n.top)/(a||1);e.animatingX=!!l,e.animatingY=!!s,k(e,"transform","translate3d("+l+"px,"+s+"px,0)"),this.forRepaintDummy=e.offsetWidth,k(e,"transition","transform "+o+"ms"+(this.options.easing?" "+this.options.easing:"")),k(e,"transform","translate3d(0,0,0)"),"number"==typeof e.animated&&clearTimeout(e.animated),e.animated=setTimeout(function(){k(e,"transition",""),k(e,"transform",""),e.animated=!1,e.animatingX=!1,e.animatingY=!1},o)}}}))}function eH(e,t,n,o,r,i,a,l){var s,c,f=e[Y],h=f.options.onMove;return!window.CustomEvent||u||d?(s=document.createEvent("Event")).initEvent("move",!0,!0):s=new CustomEvent("move",{bubbles:!0,cancelable:!0}),s.to=t,s.from=e,s.dragged=n,s.draggedRect=o,s.related=r||t,s.relatedRect=i||x(t),s.willInsertAfter=l,s.originalEvent=a,e.dispatchEvent(s),h&&(c=h.call(f,s,a)),c}function eK(e){e.draggable=!1}function eq(){ex=!1}function eU(e){return setTimeout(e,0)}function eW(e){return clearTimeout(e)}eY.prototype={constructor:eY,_isOutsideThisEl:function(e){this.el.contains(e)||e===this.el||(ev=null)},_getDirection:function(e,t){return"function"==typeof this.options.direction?this.options.direction.call(this,e,t,V):this.options.direction},_onTapStart:function(e){if(e.cancelable){var t=this,n=this.el,o=this.options,r=o.preventOnFilter,i=e.type,a=e.touches&&e.touches[0]||e.pointerType&&"touch"===e.pointerType&&e,l=(a||e).target,s=e.target.shadowRoot&&(e.path&&e.path[0]||e.composedPath&&e.composedPath()[0])||l,c=o.filter;if(function(e){eO.length=0;for(var t=e.getElementsByTagName("input"),n=t.length;n--;){var o=t[n];o.checked&&eO.push(o)}}(n),!(V||/mousedown|pointerdown/.test(i)&&0!==e.button||o.disabled||s.isContentEditable||!this.nativeDraggable&&h&&l&&"SELECT"===l.tagName.toUpperCase()||(l=_(l,o.draggable,n,!1))&&l.animated)&&et!==l){if(er=T(l),ea=T(l,o.draggable),"function"==typeof c){if(c.call(this,e,l,this)){G({sortable:t,rootEl:s,name:"filter",targetEl:l,toEl:n,fromEl:n}),z("filter",t,{evt:e}),r&&e.cancelable&&e.preventDefault();return}}else if(c&&(c=c.split(",").some(function(o){if(o=_(s,o.trim(),n,!1))return G({sortable:t,rootEl:o,name:"filter",targetEl:l,fromEl:n,toEl:n}),z("filter",t,{evt:e}),!0}))){r&&e.cancelable&&e.preventDefault();return}(!o.handle||_(s,o.handle,n,!1))&&this._prepareDragStart(e,a,l)}}},_prepareDragStart:function(e,t,n){var o,r=this,i=r.el,a=r.options,l=i.ownerDocument;if(n&&!V&&n.parentNode===i){var s=x(n);if(J=i,$=(V=n).parentNode,ee=V.nextSibling,et=n,es=a.group,eY.dragged=V,ep=(eu={target:V,clientX:(t||e).clientX,clientY:(t||e).clientY}).clientX-s.left,eg=eu.clientY-s.top,this._lastX=(t||e).clientX,this._lastY=(t||e).clientY,V.style["will-change"]="all",o=function(){if(z("delayEnded",r,{evt:e}),eY.eventCanceled){r._onDrop();return}r._disableDelayedDragEvents(),!f&&r.nativeDraggable&&(V.draggable=!0),r._triggerDragStart(e,t),G({sortable:r,name:"choose",originalEvent:e}),E(V,a.chosenClass,!0)},a.ignore.split(",").forEach(function(e){D(V,e.trim(),eK)}),v(l,"dragover",eR),v(l,"mousemove",eR),v(l,"touchmove",eR),v(l,"mouseup",r._onDrop),v(l,"touchend",r._onDrop),v(l,"touchcancel",r._onDrop),f&&this.nativeDraggable&&(this.options.touchStartThreshold=4,V.draggable=!0),z("delayStart",this,{evt:e}),!a.delay||a.delayOnTouchOnly&&!t||this.nativeDraggable&&(d||u))o();else{if(eY.eventCanceled){this._onDrop();return}v(l,"mouseup",r._disableDelayedDrag),v(l,"touchend",r._disableDelayedDrag),v(l,"touchcancel",r._disableDelayedDrag),v(l,"mousemove",r._delayedDragTouchMoveHandler),v(l,"touchmove",r._delayedDragTouchMoveHandler),a.supportPointer&&v(l,"pointermove",r._delayedDragTouchMoveHandler),r._dragStartTimer=setTimeout(o,a.delay)}}},_delayedDragTouchMoveHandler:function(e){var t=e.touches?e.touches[0]:e;Math.max(Math.abs(t.clientX-this._lastX),Math.abs(t.clientY-this._lastY))>=Math.floor(this.options.touchStartThreshold/(this.nativeDraggable&&window.devicePixelRatio||1))&&this._disableDelayedDrag()},_disableDelayedDrag:function(){V&&eK(V),clearTimeout(this._dragStartTimer),this._disableDelayedDragEvents()},_disableDelayedDragEvents:function(){var e=this.el.ownerDocument;b(e,"mouseup",this._disableDelayedDrag),b(e,"touchend",this._disableDelayedDrag),b(e,"touchcancel",this._disableDelayedDrag),b(e,"mousemove",this._delayedDragTouchMoveHandler),b(e,"touchmove",this._delayedDragTouchMoveHandler),b(e,"pointermove",this._delayedDragTouchMoveHandler)},_triggerDragStart:function(e,t){t=t||"touch"==e.pointerType&&e,!this.nativeDraggable||t?this.options.supportPointer?v(document,"pointermove",this._onTouchMove):t?v(document,"touchmove",this._onTouchMove):v(document,"mousemove",this._onTouchMove):(v(V,"dragend",this),v(J,"dragstart",this._onDragStart));try{document.selection?eU(function(){document.selection.empty()}):window.getSelection().removeAllRanges()}catch(e){}},_dragStarted:function(e,t){if(ew=!1,J&&V){z("dragStarted",this,{evt:t}),this.nativeDraggable&&v(document,"dragover",eX);var n=this.options;e||E(V,n.dragClass,!1),E(V,n.ghostClass,!0),eY.active=this,e&&this._appendGhost(),G({sortable:this,name:"start",originalEvent:t})}else this._nulling()},_emulateDragOver:function(){if(ed){this._lastX=ed.clientX,this._lastY=ed.clientY,eL();for(var e=document.elementFromPoint(ed.clientX,ed.clientY),t=e;e&&e.shadowRoot&&(e=e.shadowRoot.elementFromPoint(ed.clientX,ed.clientY))!==t;)t=e;if(V.parentNode[Y]._isOutsideThisEl(e),t)do{if(t[Y]&&t[Y]._onDragOver({clientX:ed.clientX,clientY:ed.clientY,target:e,rootEl:t})&&!this.options.dragoverBubble)break;e=t}while(t=t.parentNode)eF()}},_onTouchMove:function(e){if(eu){var t=this.options,n=t.fallbackTolerance,o=t.fallbackOffset,r=e.touches?e.touches[0]:e,i=Z&&S(Z,!0),a=Z&&i&&i.a,l=Z&&i&&i.d,s=p&&e_&&A(e_),c=(r.clientX-eu.clientX+o.x)/(a||1)+(s?s[0]-eC[0]:0)/(a||1),u=(r.clientY-eu.clientY+o.y)/(l||1)+(s?s[1]-eC[1]:0)/(l||1);if(!eY.active&&!ew){if(n&&Math.max(Math.abs(r.clientX-this._lastX),Math.abs(r.clientY-this._lastY))w.right+10||e.clientY>y.bottom&&e.clientX>y.left:e.clientY>w.bottom+10||e.clientX>y.right&&e.clientY>y.top)&&!m.animated)){if(m===V)return en(!1);if(m&&a===e.target&&(l=m),l&&(n=x(l)),!1!==eH(J,a,V,t,l,n,e,!!l))return et(),m&&m.nextSibling?a.insertBefore(V,m.nextSibling):a.appendChild(V),$=a,eo(),en(!0)}else if(m&&(S=r,D=x(M(this.el,0,this.options,!0)),C=X(this.el,this.options,Z),S?e.clientXu+c*i/2:sd-ey)return-eb}else if(s>u+c*(1-r)/2&&sd-c*i/2)?s>u+c/2?1:-1:0}(e,l,n,r,L?1:s.swapThreshold,null==s.invertedSwapThreshold?s.swapThreshold:s.invertedSwapThreshold,eD,ev===l))){var K=T(V);do K-=N,A=$.children[K];while(A&&("none"===k(A,"display")||A===Z))}if(0===N||A===l)return en(!1);ev=l,eb=N;var q=l.nextElementSibling,U=!1,W=eH(J,a,V,t,l,n,e,U=1===N);if(!1!==W)return(1===W||-1===W)&&(U=1===W),ex=!0,setTimeout(eq,30),et(),U&&!q?a.appendChild(V):l.parentNode.insertBefore(V,U?q:l),R&&B(R,0,H-R.scrollTop),$=V.parentNode,void 0===I||eD||(ey=Math.abs(I-x(l)[F])),eo(),en(!0)}if(a.contains(V))return en(!1)}return!1}function Q(s,c){z(s,p,i({evt:e,isOwner:d,axis:r?"vertical":"horizontal",revert:o,dragRect:t,targetRect:n,canSort:f,fromSortable:h,target:l,completed:en,onMove:function(n,o){return eH(J,a,V,t,n,x(n),e,o)},changed:eo},c))}function et(){Q("dragOverAnimationCapture"),p.captureAnimationState(),p!==h&&h.captureAnimationState()}function en(t){return Q("dragOverCompleted",{insertion:t}),t&&(d?u._hideClone():u._showClone(p),p!==h&&(E(V,ec?ec.options.ghostClass:u.options.ghostClass,!1),E(V,s.ghostClass,!0)),ec!==p&&p!==eY.active?ec=p:p===eY.active&&ec&&(ec=null),h===p&&(p._ignoreWhileAnimating=l),p.animateAll(function(){Q("dragOverAnimationComplete"),p._ignoreWhileAnimating=null}),p!==h&&(h.animateAll(),h._ignoreWhileAnimating=null)),(l!==V||V.animated)&&(l!==a||l.animated)||(ev=null),s.dragoverBubble||e.rootEl||l===document||(V.parentNode[Y]._isOutsideThisEl(e.target),t||eR(e)),!s.dragoverBubble&&e.stopPropagation&&e.stopPropagation(),g=!0}function eo(){ei=T(V),el=T(V,s.draggable),G({sortable:p,name:"change",toEl:a,newIndex:ei,newDraggableIndex:el,originalEvent:e})}},_ignoreWhileAnimating:null,_offMoveEvents:function(){b(document,"mousemove",this._onTouchMove),b(document,"touchmove",this._onTouchMove),b(document,"pointermove",this._onTouchMove),b(document,"dragover",eR),b(document,"mousemove",eR),b(document,"touchmove",eR)},_offUpEvents:function(){var e=this.el.ownerDocument;b(e,"mouseup",this._onDrop),b(e,"touchend",this._onDrop),b(e,"pointerup",this._onDrop),b(e,"touchcancel",this._onDrop),b(document,"selectstart",this)},_onDrop:function(e){var t=this.el,n=this.options;if(ei=T(V),el=T(V,n.draggable),z("drop",this,{evt:e}),$=V&&V.parentNode,ei=T(V),el=T(V,n.draggable),eY.eventCanceled){this._nulling();return}ew=!1,eD=!1,eS=!1,clearInterval(this._loopId),clearTimeout(this._dragStartTimer),eW(this.cloneId),eW(this._dragStartId),this.nativeDraggable&&(b(document,"drop",this),b(t,"dragstart",this._onDragStart)),this._offMoveEvents(),this._offUpEvents(),h&&k(document.body,"user-select",""),k(V,"transform",""),e&&(em&&(e.cancelable&&e.preventDefault(),n.dropBubble||e.stopPropagation()),Z&&Z.parentNode&&Z.parentNode.removeChild(Z),(J===$||ec&&"clone"!==ec.lastPutMode)&&en&&en.parentNode&&en.parentNode.removeChild(en),V&&(this.nativeDraggable&&b(V,"dragend",this),eK(V),V.style["will-change"]="",em&&!ew&&E(V,ec?ec.options.ghostClass:this.options.ghostClass,!1),E(V,this.options.chosenClass,!1),G({sortable:this,name:"unchoose",toEl:$,newIndex:null,newDraggableIndex:null,originalEvent:e}),J!==$?(ei>=0&&(G({rootEl:$,name:"add",toEl:$,fromEl:J,originalEvent:e}),G({sortable:this,name:"remove",toEl:$,originalEvent:e}),G({rootEl:$,name:"sort",toEl:$,fromEl:J,originalEvent:e}),G({sortable:this,name:"sort",toEl:$,originalEvent:e})),ec&&ec.save()):ei!==er&&ei>=0&&(G({sortable:this,name:"update",toEl:$,originalEvent:e}),G({sortable:this,name:"sort",toEl:$,originalEvent:e})),eY.active&&((null==ei||-1===ei)&&(ei=er,el=ea),G({sortable:this,name:"end",toEl:$,originalEvent:e}),this.save()))),this._nulling()},_nulling:function(){z("nulling",this),J=V=$=Z=ee=en=et=eo=eu=ed=em=ei=el=er=ea=ev=eb=ec=es=eY.dragged=eY.ghost=eY.clone=eY.active=null,eO.forEach(function(e){e.checked=!0}),eO.length=ef=eh=0},handleEvent:function(e){switch(e.type){case"drop":case"dragend":this._onDrop(e);break;case"dragenter":case"dragover":V&&(this._onDragOver(e),e.dataTransfer&&(e.dataTransfer.dropEffect="move"),e.cancelable&&e.preventDefault());break;case"selectstart":e.preventDefault()}},toArray:function(){for(var e,t=[],n=this.el.children,o=0,r=n.length,i=this.options;o1&&(tr.forEach(function(e){r.addAnimationState({target:e,rect:tl?x(e):i}),R(e),e.fromRect=i,n.removeAnimationState(e)}),tl=!1,t=!this.options.removeCloneOnHide,tr.forEach(function(e,n){var r=o.children[e.sortableIndex+(t?Number(n):0)];r?o.insertBefore(e,r):o.appendChild(e)}))},dragOverCompleted:function(e){var t=e.sortable,n=e.isOwner,o=e.insertion,r=e.activeSortable,i=e.parentEl,a=e.putSortable,l=this.options;if(o){if(n&&r._hideClone(),ta=!1,l.animation&&tr.length>1&&(tl||!n&&!r.options.sort&&!a)){var s=x(tt,!1,!0,!0);tr.forEach(function(e){e!==tt&&(F(e,s),i.appendChild(e))}),tl=!0}if(!n){if(tl||td(),tr.length>1){var c=to;r._showClone(t),r.options.animation&&!to&&c&&ti.forEach(function(e){r.addAnimationState({target:e,rect:tn}),e.fromRect=tn,e.thisAnimationDuration=null})}else r._showClone(t)}}},dragOverAnimationCapture:function(e){var t=e.dragRect,n=e.isOwner,o=e.activeSortable;if(tr.forEach(function(e){e.thisAnimationDuration=null}),o.options.animation&&!n&&o.multiDrag.isMultiDrag){tn=l({},t);var r=S(tt,!0);tn.top-=r.f,tn.left-=r.e}},dragOverAnimationComplete:function(){tl&&(tl=!1,td())},drop:function(e){var t=e.originalEvent,n=e.rootEl,o=e.parentEl,r=e.sortable,i=e.dispatchSortableEvent,a=e.oldIndex,l=e.putSortable,s=l||this.sortable;if(t){var c=this.options,u=o.children;if(!ts){if(c.multiDragKey&&!this.multiDragKeyDown&&this._deselectMultiDrag(),E(tt,c.selectedClass,!~tr.indexOf(tt)),~tr.indexOf(tt))tr.splice(tr.indexOf(tt),1),e4=null,U({sortable:r,rootEl:n,name:"deselect",targetEl:tt,originalEvent:t});else{if(tr.push(tt),U({sortable:r,rootEl:n,name:"select",targetEl:tt,originalEvent:t}),t.shiftKey&&e4&&r.el.contains(e4)){var d,f,h=T(e4),p=T(tt);if(~h&&~p&&h!==p)for(p>h?(f=h,d=p):(f=p,d=h+1);f1){var g=x(tt),m=T(tt,":not(."+this.options.selectedClass+")");if(!ta&&c.animation&&(tt.thisAnimationDuration=null),s.captureAnimationState(),!ta&&(c.animation&&(tt.fromRect=g,tr.forEach(function(e){if(e.thisAnimationDuration=null,e!==tt){var t=tl?x(e):g;e.fromRect=t,s.addAnimationState({target:e,rect:t})}})),td(),tr.forEach(function(e){u[m]?o.insertBefore(e,u[m]):o.appendChild(e),m++}),a===T(tt))){var v=!1;tr.forEach(function(e){if(e.sortableIndex!==T(e)){v=!0;return}}),v&&(i("update"),i("sort"))}tr.forEach(function(e){R(e)}),s.animateAll()}te=s}(n===o||l&&"clone"!==l.lastPutMode)&&ti.forEach(function(e){e.parentNode&&e.parentNode.removeChild(e)})}},nullingGlobal:function(){this.isMultiDrag=ts=!1,ti.length=0},destroyGlobal:function(){this._deselectMultiDrag(),b(document,"pointerup",this._deselectMultiDrag),b(document,"mouseup",this._deselectMultiDrag),b(document,"touchend",this._deselectMultiDrag),b(document,"keydown",this._checkKeyDown),b(document,"keyup",this._checkKeyUp)},_deselectMultiDrag:function(e){if(!(void 0!==ts&&ts||te!==this.sortable||e&&_(e.target,this.options.draggable,this.sortable.el,!1))&&(!e||0===e.button))for(;tr.length;){var t=tr[0];E(t,this.options.selectedClass,!1),tr.shift(),U({sortable:this.sortable,rootEl:this.sortable.el,name:"deselect",targetEl:t,originalEvent:e})}},_checkKeyDown:function(e){e.key===this.options.multiDragKey&&(this.multiDragKeyDown=!0)},_checkKeyUp:function(e){e.key===this.options.multiDragKey&&(this.multiDragKeyDown=!1)}},l(e,{pluginName:"multiDrag",utils:{select:function(e){var t=e.parentNode[Y];!t||!t.options.multiDrag||~tr.indexOf(e)||(te&&te!==t&&(te.multiDrag._deselectMultiDrag(),te=t),E(e,t.options.selectedClass,!0),tr.push(e))},deselect:function(e){var t=e.parentNode[Y],n=tr.indexOf(e);t&&t.options.multiDrag&&~n&&(E(e,t.options.selectedClass,!1),tr.splice(n,1))}},eventProperties:function(){var e,t=this,n=[],o=[];return tr.forEach(function(e){var r;n.push({multiDragElement:e,index:e.sortableIndex}),r=tl&&e!==tt?-1:tl?T(e,":not(."+t.options.selectedClass+")"):T(e),o.push({multiDragElement:e,index:r})}),{items:function(e){if(Array.isArray(e))return s(e)}(e=tr)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(e){if("string"==typeof e)return s(e,void 0);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return s(e,void 0)}}(e)||function(){throw TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(),clones:[].concat(ti),oldIndicies:n,newIndicies:o}},optionListeners:{multiDragKey:function(e){return"ctrl"===(e=e.toLowerCase())?e="Control":e.length>1&&(e=e.charAt(0).toUpperCase()+e.substr(1)),e}}})}function tu(e,t){ti.forEach(function(n,o){var r=t.children[n.sortableIndex+(e?Number(o):0)];r?t.insertBefore(n,r):t.appendChild(n)})}function td(){tr.forEach(function(e){e!==tt&&e.parentNode&&e.parentNode.removeChild(e)})}eY.mount(new function(){function e(){for(var e in this.defaults={scroll:!0,forceAutoScrollFallback:!1,scrollSensitivity:30,scrollSpeed:10,bubbleScroll:!0},this)"_"===e.charAt(0)&&"function"==typeof this[e]&&(this[e]=this[e].bind(this))}return e.prototype={dragStarted:function(e){var t=e.originalEvent;this.sortable.nativeDraggable?v(document,"dragover",this._handleAutoScroll):this.options.supportPointer?v(document,"pointermove",this._handleFallbackAutoScroll):t.touches?v(document,"touchmove",this._handleFallbackAutoScroll):v(document,"mousemove",this._handleFallbackAutoScroll)},dragOverCompleted:function(e){var t=e.originalEvent;this.options.dragOverBubble||t.rootEl||this._handleAutoScroll(t)},drop:function(){this.sortable.nativeDraggable?b(document,"dragover",this._handleAutoScroll):(b(document,"pointermove",this._handleFallbackAutoScroll),b(document,"touchmove",this._handleFallbackAutoScroll),b(document,"mousemove",this._handleFallbackAutoScroll)),e2(),e1(),clearTimeout(Q),Q=void 0},nulling:function(){e$=eG=ez=e0=eZ=eQ=eV=null,eJ.length=0},_handleFallbackAutoScroll:function(e){this._handleAutoScroll(e,!0)},_handleAutoScroll:function(e,t){var n=this,o=(e.touches?e.touches[0]:e).clientX,r=(e.touches?e.touches[0]:e).clientY,i=document.elementFromPoint(o,r);if(e$=e,t||this.options.forceAutoScrollFallback||d||u||h){e8(e,this.options,i,t);var a=I(i,!0);e0&&(!eZ||o!==eQ||r!==eV)&&(eZ&&e2(),eZ=setInterval(function(){var i=I(document.elementFromPoint(o,r),!0);i!==a&&(a=i,e1()),e8(e,n.options,i,t)},10),eQ=o,eV=r)}else{if(!this.options.bubbleScroll||I(i,!0)===C()){e1();return}e8(e,this.options,I(i,!1),!1)}}},l(e,{pluginName:"scroll",initializeByDefault:!0})}),eY.mount(e9,e5),n.default=eY},{"@parcel/transformer-js/src/esmodule-helpers.js":"kPSB8"}]},["1pQVs"],"1pQVs","parcelRequirec571");dist/js/dashboard_widget.js000064400001275446147600331220011774 0ustar00!function(t,e,r,n,i){var a="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:{},o="function"==typeof a[n]&&a[n],s=o.cache||{},l="undefined"!=typeof module&&"function"==typeof module.require&&module.require.bind(module);function u(e,r){if(!s[e]){if(!t[e]){var i="function"==typeof a[n]&&a[n];if(!r&&i)return i(e,!0);if(o)return o(e,!0);if(l&&"string"==typeof e)return l(e);var c=Error("Cannot find module '"+e+"'");throw c.code="MODULE_NOT_FOUND",c}f.resolve=function(r){var n=t[e][1][r];return null!=n?n:r},f.cache={};var h=s[e]=new u.Module(e);t[e][0].call(h.exports,f,h,h.exports,this)}return s[e].exports;function f(t){var e=f.resolve(t);return!1===e?{}:u(e)}}u.isParcelRequire=!0,u.Module=function(t){this.id=t,this.bundle=u,this.exports={}},u.modules=t,u.cache=s,u.parent=o,u.register=function(e,r){t[e]=[function(t,e){e.exports=r},{}]},Object.defineProperty(u,"root",{get:function(){return a[n]}}),a[n]=u;for(var c=0;c0}},{key:"bindings",get:function(){return Array.from(this.unorderedBindings).sort(function(t,e){var r=t.index,n=e.index;return rn?1:0})}}]),t}(),y=function(){function t(e){(0,a._)(this,t),this.application=e,this.eventListenerMaps=new Map,this.started=!1}return(0,o._)(t,[{key:"start",value:function(){this.started||(this.started=!0,this.eventListeners.forEach(function(t){return t.connect()}))}},{key:"stop",value:function(){this.started&&(this.started=!1,this.eventListeners.forEach(function(t){return t.disconnect()}))}},{key:"eventListeners",get:function(){return Array.from(this.eventListenerMaps.values()).reduce(function(t,e){return t.concat(Array.from(e.values()))},[])}},{key:"bindingConnected",value:function(t){this.fetchEventListenerForBinding(t).bindingConnected(t)}},{key:"bindingDisconnected",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];this.fetchEventListenerForBinding(t).bindingDisconnected(t),e&&this.clearEventListenersForBinding(t)}},{key:"handleError",value:function(t,e){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};this.application.handleError(t,"Error ".concat(e),r)}},{key:"clearEventListenersForBinding",value:function(t){var e=this.fetchEventListenerForBinding(t);e.hasBindings()||(e.disconnect(),this.removeMappedEventListenerFor(t))}},{key:"removeMappedEventListenerFor",value:function(t){var e=t.eventTarget,r=t.eventName,n=t.eventOptions,i=this.fetchEventListenerMapForEventTarget(e),a=this.cacheKey(r,n);i.delete(a),0==i.size&&this.eventListenerMaps.delete(e)}},{key:"fetchEventListenerForBinding",value:function(t){var e=t.eventTarget,r=t.eventName,n=t.eventOptions;return this.fetchEventListener(e,r,n)}},{key:"fetchEventListener",value:function(t,e,r){var n=this.fetchEventListenerMapForEventTarget(t),i=this.cacheKey(e,r),a=n.get(i);return a||(a=this.createEventListener(t,e,r),n.set(i,a)),a}},{key:"createEventListener",value:function(t,e,r){var n=new g(t,e,r);return this.started&&n.connect(),n}},{key:"fetchEventListenerMapForEventTarget",value:function(t){var e=this.eventListenerMaps.get(t);return e||(e=new Map,this.eventListenerMaps.set(t,e)),e}},{key:"cacheKey",value:function(t,e){var r=[t];return Object.keys(e).sort().forEach(function(t){r.push("".concat(e[t]?"":"!").concat(t))}),r.join(":")}}]),t}(),m={stop:function(t){var e=t.event;return t.value&&e.stopPropagation(),!0},prevent:function(t){var e=t.event;return t.value&&e.preventDefault(),!0},self:function(t){var e=t.event,r=t.value,n=t.element;return!r||n===e.target}},b=/^(?:(?:([^.]+?)\+)?(.+?)(?:\.(.+?))?(?:@(window|document))?->)?(.+?)(?:#([^:]+?))(?::(.+))?$/;function _(t){return t.replace(/(?:[_-])([a-z0-9])/g,function(t,e){return e.toUpperCase()})}function x(t){return _(t.replace(/--/g,"-").replace(/__/g,"_"))}function k(t){return t.charAt(0).toUpperCase()+t.slice(1)}function w(t){return t.replace(/([A-Z])/g,function(t,e){return"-".concat(e.toLowerCase())})}function M(t,e){return Object.prototype.hasOwnProperty.call(t,e)}var S=["meta","ctrl","alt","shift"],O=function(){function t(e,r,n,i){(0,a._)(this,t),this.element=e,this.index=r,this.eventTarget=n.eventTarget||e,this.eventName=n.eventName||function(t){var e=t.tagName.toLowerCase();if(e in A)return A[e](t)}(e)||E("missing event name"),this.eventOptions=n.eventOptions||{},this.identifier=n.identifier||E("missing identifier"),this.methodName=n.methodName||E("missing method name"),this.keyFilter=n.keyFilter||"",this.schema=i}return(0,o._)(t,[{key:"toString",value:function(){var t=this.keyFilter?".".concat(this.keyFilter):"",e=this.eventTargetName?"@".concat(this.eventTargetName):"";return"".concat(this.eventName).concat(t).concat(e,"->").concat(this.identifier,"#").concat(this.methodName)}},{key:"shouldIgnoreKeyboardEvent",value:function(t){if(!this.keyFilter)return!1;var e=this.keyFilter.split("+");if(this.keyFilterDissatisfied(t,e))return!0;var r=e.filter(function(t){return!S.includes(t)})[0];return!!r&&(M(this.keyMappings,r)||E("contains unknown key filter: ".concat(this.keyFilter)),this.keyMappings[r].toLowerCase()!==t.key.toLowerCase())}},{key:"shouldIgnoreMouseEvent",value:function(t){if(!this.keyFilter)return!1;var e=[this.keyFilter];return!!this.keyFilterDissatisfied(t,e)}},{key:"params",get:function(){var t={},e=RegExp("^data-".concat(this.identifier,"-(.+)-param$"),"i"),r=!0,n=!1,i=void 0;try{for(var a,o=Array.from(this.element.attributes)[Symbol.iterator]();!(r=(a=o.next()).done);r=!0){var s=a.value,l=s.name,u=s.value,c=l.match(e),h=c&&c[1];h&&(t[_(h)]=function(t){try{return JSON.parse(t)}catch(e){return t}}(u))}}catch(t){n=!0,i=t}finally{try{r||null==o.return||o.return()}finally{if(n)throw i}}return t}},{key:"eventTargetName",get:function(){var t;return(t=this.eventTarget)==window?"window":t==document?"document":void 0}},{key:"keyMappings",get:function(){return this.schema.keyMappings}},{key:"keyFilterDissatisfied",value:function(t,e){var r=(0,h._)(S.map(function(t){return e.includes(t)}),4),n=r[0],i=r[1],a=r[2],o=r[3];return t.metaKey!==n||t.ctrlKey!==i||t.altKey!==a||t.shiftKey!==o}}],[{key:"forToken",value:function(t,e){var r,n,i,a;return new this(t.element,t.index,(n=(r=t.content.trim().match(b)||[])[2],(i=r[3])&&!["keydown","keyup","keypress"].includes(n)&&(n+=".".concat(i),i=""),{eventTarget:"window"==(a=r[4])?window:"document"==a?document:void 0,eventName:n,eventOptions:r[7]?r[7].split(":").reduce(function(t,e){return Object.assign(t,(0,s._)({},e.replace(/^!/,""),!/^!/.test(e)))},{}):{},identifier:r[5],methodName:r[6],keyFilter:r[1]||i}),e)}}]),t}(),A={a:function(){return"click"},button:function(){return"click"},form:function(){return"submit"},details:function(){return"toggle"},input:function(t){return"submit"==t.getAttribute("type")?"click":"input"},select:function(){return"change"},textarea:function(){return"input"}};function E(t){throw Error(t)}var C=function(){function t(e,r){(0,a._)(this,t),this.context=e,this.action=r}return(0,o._)(t,[{key:"index",get:function(){return this.action.index}},{key:"eventTarget",get:function(){return this.action.eventTarget}},{key:"eventOptions",get:function(){return this.action.eventOptions}},{key:"identifier",get:function(){return this.context.identifier}},{key:"handleEvent",value:function(t){var e=this.prepareActionEvent(t);this.willBeInvokedByEvent(t)&&this.applyEventModifiers(e)&&this.invokeWithEvent(e)}},{key:"eventName",get:function(){return this.action.eventName}},{key:"method",get:function(){var t=this.controller[this.methodName];if("function"==typeof t)return t;throw Error('Action "'.concat(this.action,'" references undefined method "').concat(this.methodName,'"'))}},{key:"applyEventModifiers",value:function(t){var e=this.action.element,r=this.context.application.actionDescriptorFilters,n=this.context.controller,i=!0,a=!0,o=!1,s=void 0;try{for(var l,u=Object.entries(this.eventOptions)[Symbol.iterator]();!(a=(l=u.next()).done);a=!0){var c=(0,h._)(l.value,2),f=c[0],d=c[1];if(f in r){var p=r[f];i=i&&p({name:f,value:d,event:t,element:e,controller:n})}}}catch(t){o=!0,s=t}finally{try{a||null==u.return||u.return()}finally{if(o)throw s}}return i}},{key:"prepareActionEvent",value:function(t){return Object.assign(t,{params:this.action.params})}},{key:"invokeWithEvent",value:function(t){var e=t.target,r=t.currentTarget;try{this.method.call(this.controller,t),this.context.logDebugActivity(this.methodName,{event:t,target:e,currentTarget:r,action:this.methodName})}catch(e){var n=this.identifier,i=this.controller,a=this.element,o=this.index;this.context.handleError(e,'invoking action "'.concat(this.action,'"'),{identifier:n,controller:i,element:a,index:o,event:t})}}},{key:"willBeInvokedByEvent",value:function(t){var e=t.target;return!(t instanceof KeyboardEvent&&this.action.shouldIgnoreKeyboardEvent(t)||t instanceof MouseEvent&&this.action.shouldIgnoreMouseEvent(t))&&(this.element===e||(e instanceof Element&&this.element.contains(e)?this.scope.containsElement(e):this.scope.containsElement(this.action.element)))}},{key:"controller",get:function(){return this.context.controller}},{key:"methodName",get:function(){return this.action.methodName}},{key:"element",get:function(){return this.scope.element}},{key:"scope",get:function(){return this.context.scope}}]),t}(),P=function(){function t(e,r){var n=this;(0,a._)(this,t),this.mutationObserverInit={attributes:!0,childList:!0,subtree:!0},this.element=e,this.started=!1,this.delegate=r,this.elements=new Set,this.mutationObserver=new MutationObserver(function(t){return n.processMutations(t)})}return(0,o._)(t,[{key:"start",value:function(){this.started||(this.started=!0,this.mutationObserver.observe(this.element,this.mutationObserverInit),this.refresh())}},{key:"pause",value:function(t){this.started&&(this.mutationObserver.disconnect(),this.started=!1),t(),this.started||(this.mutationObserver.observe(this.element,this.mutationObserverInit),this.started=!0)}},{key:"stop",value:function(){this.started&&(this.mutationObserver.takeRecords(),this.mutationObserver.disconnect(),this.started=!1)}},{key:"refresh",value:function(){if(this.started){var t=new Set(this.matchElementsInTree()),e=!0,r=!1,n=void 0;try{for(var i,a=Array.from(this.elements)[Symbol.iterator]();!(e=(i=a.next()).done);e=!0){var o=i.value;t.has(o)||this.removeElement(o)}}catch(t){r=!0,n=t}finally{try{e||null==a.return||a.return()}finally{if(r)throw n}}var s=!0,l=!1,u=void 0;try{for(var c,h=Array.from(t)[Symbol.iterator]();!(s=(c=h.next()).done);s=!0){var f=c.value;this.addElement(f)}}catch(t){l=!0,u=t}finally{try{s||null==h.return||h.return()}finally{if(l)throw u}}}}},{key:"processMutations",value:function(t){var e=!0,r=!1,n=void 0;if(this.started)try{for(var i,a=t[Symbol.iterator]();!(e=(i=a.next()).done);e=!0){var o=i.value;this.processMutation(o)}}catch(t){r=!0,n=t}finally{try{e||null==a.return||a.return()}finally{if(r)throw n}}}},{key:"processMutation",value:function(t){"attributes"==t.type?this.processAttributeChange(t.target,t.attributeName):"childList"==t.type&&(this.processRemovedNodes(t.removedNodes),this.processAddedNodes(t.addedNodes))}},{key:"processAttributeChange",value:function(t,e){this.elements.has(t)?this.delegate.elementAttributeChanged&&this.matchElement(t)?this.delegate.elementAttributeChanged(t,e):this.removeElement(t):this.matchElement(t)&&this.addElement(t)}},{key:"processRemovedNodes",value:function(t){var e=!0,r=!1,n=void 0;try{for(var i,a=Array.from(t)[Symbol.iterator]();!(e=(i=a.next()).done);e=!0){var o=i.value,s=this.elementFromNode(o);s&&this.processTree(s,this.removeElement)}}catch(t){r=!0,n=t}finally{try{e||null==a.return||a.return()}finally{if(r)throw n}}}},{key:"processAddedNodes",value:function(t){var e=!0,r=!1,n=void 0;try{for(var i,a=Array.from(t)[Symbol.iterator]();!(e=(i=a.next()).done);e=!0){var o=i.value,s=this.elementFromNode(o);s&&this.elementIsActive(s)&&this.processTree(s,this.addElement)}}catch(t){r=!0,n=t}finally{try{e||null==a.return||a.return()}finally{if(r)throw n}}}},{key:"matchElement",value:function(t){return this.delegate.matchElement(t)}},{key:"matchElementsInTree",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.element;return this.delegate.matchElementsInTree(t)}},{key:"processTree",value:function(t,e){var r=!0,n=!1,i=void 0;try{for(var a,o=this.matchElementsInTree(t)[Symbol.iterator]();!(r=(a=o.next()).done);r=!0){var s=a.value;e.call(this,s)}}catch(t){n=!0,i=t}finally{try{r||null==o.return||o.return()}finally{if(n)throw i}}}},{key:"elementFromNode",value:function(t){if(t.nodeType==Node.ELEMENT_NODE)return t}},{key:"elementIsActive",value:function(t){return t.isConnected==this.element.isConnected&&this.element.contains(t)}},{key:"addElement",value:function(t){!this.elements.has(t)&&this.elementIsActive(t)&&(this.elements.add(t),this.delegate.elementMatched&&this.delegate.elementMatched(t))}},{key:"removeElement",value:function(t){this.elements.has(t)&&(this.elements.delete(t),this.delegate.elementUnmatched&&this.delegate.elementUnmatched(t))}}]),t}(),D=function(){function t(e,r,n){(0,a._)(this,t),this.attributeName=r,this.delegate=n,this.elementObserver=new P(e,this)}return(0,o._)(t,[{key:"element",get:function(){return this.elementObserver.element}},{key:"selector",get:function(){return"[".concat(this.attributeName,"]")}},{key:"start",value:function(){this.elementObserver.start()}},{key:"pause",value:function(t){this.elementObserver.pause(t)}},{key:"stop",value:function(){this.elementObserver.stop()}},{key:"refresh",value:function(){this.elementObserver.refresh()}},{key:"started",get:function(){return this.elementObserver.started}},{key:"matchElement",value:function(t){return t.hasAttribute(this.attributeName)}},{key:"matchElementsInTree",value:function(t){var e=this.matchElement(t)?[t]:[],r=Array.from(t.querySelectorAll(this.selector));return e.concat(r)}},{key:"elementMatched",value:function(t){this.delegate.elementMatchedAttribute&&this.delegate.elementMatchedAttribute(t,this.attributeName)}},{key:"elementUnmatched",value:function(t){this.delegate.elementUnmatchedAttribute&&this.delegate.elementUnmatchedAttribute(t,this.attributeName)}},{key:"elementAttributeChanged",value:function(t,e){this.delegate.elementAttributeValueChanged&&this.attributeName==e&&this.delegate.elementAttributeValueChanged(t,e)}}]),t}();function j(t,e,r){F(t,e).add(r)}function T(t,e,r){F(t,e).delete(r),I(t,e)}function F(t,e){var r=t.get(e);return r||(r=new Set,t.set(e,r)),r}function I(t,e){var r=t.get(e);null!=r&&0==r.size&&t.delete(e)}var L=function(){function t(){(0,a._)(this,t),this.valuesByKey=new Map}return(0,o._)(t,[{key:"keys",get:function(){return Array.from(this.valuesByKey.keys())}},{key:"values",get:function(){return Array.from(this.valuesByKey.values()).reduce(function(t,e){return t.concat(Array.from(e))},[])}},{key:"size",get:function(){return Array.from(this.valuesByKey.values()).reduce(function(t,e){return t+e.size},0)}},{key:"add",value:function(t,e){j(this.valuesByKey,t,e)}},{key:"delete",value:function(t,e){T(this.valuesByKey,t,e)}},{key:"has",value:function(t,e){var r=this.valuesByKey.get(t);return null!=r&&r.has(e)}},{key:"hasKey",value:function(t){return this.valuesByKey.has(t)}},{key:"hasValue",value:function(t){return Array.from(this.valuesByKey.values()).some(function(e){return e.has(t)})}},{key:"getValuesForKey",value:function(t){var e=this.valuesByKey.get(t);return e?Array.from(e):[]}},{key:"getKeysForValue",value:function(t){return Array.from(this.valuesByKey).filter(function(e){var r=(0,h._)(e,2);return(r[0],r[1]).has(t)}).map(function(t){var e=(0,h._)(t,2),r=e[0];return e[1],r})}}]),t}(),B=function(t){(0,c._)(r,t);var e=(0,p._)(r);function r(){var t;return(0,a._)(this,r),(t=e.call(this)).keysByValue=new Map,t}return(0,o._)(r,[{key:"values",get:function(){return Array.from(this.keysByValue.keys())}},{key:"add",value:function(t,e){(0,l._)((0,u._)(r.prototype),"add",this).call(this,t,e),j(this.keysByValue,e,t)}},{key:"delete",value:function(t,e){(0,l._)((0,u._)(r.prototype),"delete",this).call(this,t,e),T(this.keysByValue,e,t)}},{key:"hasValue",value:function(t){return this.keysByValue.has(t)}},{key:"getKeysForValue",value:function(t){var e=this.keysByValue.get(t);return e?Array.from(e):[]}}]),r}(L),R=function(){function t(e,r,n,i){(0,a._)(this,t),this._selector=r,this.details=i,this.elementObserver=new P(e,this),this.delegate=n,this.matchesByElement=new L}return(0,o._)(t,[{key:"started",get:function(){return this.elementObserver.started}},{key:"selector",get:function(){return this._selector},set:function(t){this._selector=t,this.refresh()}},{key:"start",value:function(){this.elementObserver.start()}},{key:"pause",value:function(t){this.elementObserver.pause(t)}},{key:"stop",value:function(){this.elementObserver.stop()}},{key:"refresh",value:function(){this.elementObserver.refresh()}},{key:"element",get:function(){return this.elementObserver.element}},{key:"matchElement",value:function(t){var e=this.selector;if(!e)return!1;var r=t.matches(e);return this.delegate.selectorMatchElement?r&&this.delegate.selectorMatchElement(t,this.details):r}},{key:"matchElementsInTree",value:function(t){var e=this,r=this.selector;if(!r)return[];var n=this.matchElement(t)?[t]:[],i=Array.from(t.querySelectorAll(r)).filter(function(t){return e.matchElement(t)});return n.concat(i)}},{key:"elementMatched",value:function(t){var e=this.selector;e&&this.selectorMatched(t,e)}},{key:"elementUnmatched",value:function(t){var e=this.matchesByElement.getKeysForValue(t),r=!0,n=!1,i=void 0;try{for(var a,o=e[Symbol.iterator]();!(r=(a=o.next()).done);r=!0){var s=a.value;this.selectorUnmatched(t,s)}}catch(t){n=!0,i=t}finally{try{r||null==o.return||o.return()}finally{if(n)throw i}}}},{key:"elementAttributeChanged",value:function(t,e){var r=this.selector;if(r){var n=this.matchElement(t),i=this.matchesByElement.has(r,t);n&&!i?this.selectorMatched(t,r):!n&&i&&this.selectorUnmatched(t,r)}}},{key:"selectorMatched",value:function(t,e){this.delegate.selectorMatched(t,e,this.details),this.matchesByElement.add(e,t)}},{key:"selectorUnmatched",value:function(t,e){this.delegate.selectorUnmatched(t,e,this.details),this.matchesByElement.delete(e,t)}}]),t}(),N=function(){function t(e,r){var n=this;(0,a._)(this,t),this.element=e,this.delegate=r,this.started=!1,this.stringMap=new Map,this.mutationObserver=new MutationObserver(function(t){return n.processMutations(t)})}return(0,o._)(t,[{key:"start",value:function(){this.started||(this.started=!0,this.mutationObserver.observe(this.element,{attributes:!0,attributeOldValue:!0}),this.refresh())}},{key:"stop",value:function(){this.started&&(this.mutationObserver.takeRecords(),this.mutationObserver.disconnect(),this.started=!1)}},{key:"refresh",value:function(){var t=!0,e=!1,r=void 0;if(this.started)try{for(var n,i=this.knownAttributeNames[Symbol.iterator]();!(t=(n=i.next()).done);t=!0){var a=n.value;this.refreshAttribute(a,null)}}catch(t){e=!0,r=t}finally{try{t||null==i.return||i.return()}finally{if(e)throw r}}}},{key:"processMutations",value:function(t){var e=!0,r=!1,n=void 0;if(this.started)try{for(var i,a=t[Symbol.iterator]();!(e=(i=a.next()).done);e=!0){var o=i.value;this.processMutation(o)}}catch(t){r=!0,n=t}finally{try{e||null==a.return||a.return()}finally{if(r)throw n}}}},{key:"processMutation",value:function(t){var e=t.attributeName;e&&this.refreshAttribute(e,t.oldValue)}},{key:"refreshAttribute",value:function(t,e){var r=this.delegate.getStringMapKeyForAttribute(t);if(null!=r){this.stringMap.has(t)||this.stringMapKeyAdded(r,t);var n=this.element.getAttribute(t);if(this.stringMap.get(t)!=n&&this.stringMapValueChanged(n,r,e),null==n){var i=this.stringMap.get(t);this.stringMap.delete(t),i&&this.stringMapKeyRemoved(r,t,i)}else this.stringMap.set(t,n)}}},{key:"stringMapKeyAdded",value:function(t,e){this.delegate.stringMapKeyAdded&&this.delegate.stringMapKeyAdded(t,e)}},{key:"stringMapValueChanged",value:function(t,e,r){this.delegate.stringMapValueChanged&&this.delegate.stringMapValueChanged(t,e,r)}},{key:"stringMapKeyRemoved",value:function(t,e,r){this.delegate.stringMapKeyRemoved&&this.delegate.stringMapKeyRemoved(t,e,r)}},{key:"knownAttributeNames",get:function(){return Array.from(new Set(this.currentAttributeNames.concat(this.recordedAttributeNames)))}},{key:"currentAttributeNames",get:function(){return Array.from(this.element.attributes).map(function(t){return t.name})}},{key:"recordedAttributeNames",get:function(){return Array.from(this.stringMap.keys())}}]),t}(),V=function(){function t(e,r,n){(0,a._)(this,t),this.attributeObserver=new D(e,r,this),this.delegate=n,this.tokensByElement=new L}return(0,o._)(t,[{key:"started",get:function(){return this.attributeObserver.started}},{key:"start",value:function(){this.attributeObserver.start()}},{key:"pause",value:function(t){this.attributeObserver.pause(t)}},{key:"stop",value:function(){this.attributeObserver.stop()}},{key:"refresh",value:function(){this.attributeObserver.refresh()}},{key:"element",get:function(){return this.attributeObserver.element}},{key:"attributeName",get:function(){return this.attributeObserver.attributeName}},{key:"elementMatchedAttribute",value:function(t){this.tokensMatched(this.readTokensForElement(t))}},{key:"elementAttributeValueChanged",value:function(t){var e=(0,h._)(this.refreshTokensForElement(t),2),r=e[0],n=e[1];this.tokensUnmatched(r),this.tokensMatched(n)}},{key:"elementUnmatchedAttribute",value:function(t){this.tokensUnmatched(this.tokensByElement.getValuesForKey(t))}},{key:"tokensMatched",value:function(t){var e=this;t.forEach(function(t){return e.tokenMatched(t)})}},{key:"tokensUnmatched",value:function(t){var e=this;t.forEach(function(t){return e.tokenUnmatched(t)})}},{key:"tokenMatched",value:function(t){this.delegate.tokenMatched(t),this.tokensByElement.add(t.element,t)}},{key:"tokenUnmatched",value:function(t){this.delegate.tokenUnmatched(t),this.tokensByElement.delete(t.element,t)}},{key:"refreshTokensForElement",value:function(t){var e=this.tokensByElement.getValuesForKey(t),r=this.readTokensForElement(t),n=Array.from({length:Math.max(e.length,r.length)},function(t,n){return[e[n],r[n]]}).findIndex(function(t){var e,r,n=(0,h._)(t,2);return e=n[0],r=n[1],!e||!r||e.index!=r.index||e.content!=r.content});return -1==n?[[],[]]:[e.slice(n),r.slice(n)]}},{key:"readTokensForElement",value:function(t){var e=this.attributeName;return(t.getAttribute(e)||"").trim().split(/\s+/).filter(function(t){return t.length}).map(function(r,n){return{element:t,attributeName:e,content:r,index:n}})}}]),t}(),z=function(){function t(e,r,n){(0,a._)(this,t),this.tokenListObserver=new V(e,r,this),this.delegate=n,this.parseResultsByToken=new WeakMap,this.valuesByTokenByElement=new WeakMap}return(0,o._)(t,[{key:"started",get:function(){return this.tokenListObserver.started}},{key:"start",value:function(){this.tokenListObserver.start()}},{key:"stop",value:function(){this.tokenListObserver.stop()}},{key:"refresh",value:function(){this.tokenListObserver.refresh()}},{key:"element",get:function(){return this.tokenListObserver.element}},{key:"attributeName",get:function(){return this.tokenListObserver.attributeName}},{key:"tokenMatched",value:function(t){var e=t.element,r=this.fetchParseResultForToken(t).value;r&&(this.fetchValuesByTokenForElement(e).set(t,r),this.delegate.elementMatchedValue(e,r))}},{key:"tokenUnmatched",value:function(t){var e=t.element,r=this.fetchParseResultForToken(t).value;r&&(this.fetchValuesByTokenForElement(e).delete(t),this.delegate.elementUnmatchedValue(e,r))}},{key:"fetchParseResultForToken",value:function(t){var e=this.parseResultsByToken.get(t);return e||(e=this.parseToken(t),this.parseResultsByToken.set(t,e)),e}},{key:"fetchValuesByTokenForElement",value:function(t){var e=this.valuesByTokenByElement.get(t);return e||(e=new Map,this.valuesByTokenByElement.set(t,e)),e}},{key:"parseToken",value:function(t){try{return{value:this.delegate.parseValueForToken(t)}}catch(t){return{error:t}}}}]),t}(),W=function(){function t(e,r){(0,a._)(this,t),this.context=e,this.delegate=r,this.bindingsByAction=new Map}return(0,o._)(t,[{key:"start",value:function(){this.valueListObserver||(this.valueListObserver=new z(this.element,this.actionAttribute,this),this.valueListObserver.start())}},{key:"stop",value:function(){this.valueListObserver&&(this.valueListObserver.stop(),delete this.valueListObserver,this.disconnectAllActions())}},{key:"element",get:function(){return this.context.element}},{key:"identifier",get:function(){return this.context.identifier}},{key:"actionAttribute",get:function(){return this.schema.actionAttribute}},{key:"schema",get:function(){return this.context.schema}},{key:"bindings",get:function(){return Array.from(this.bindingsByAction.values())}},{key:"connectAction",value:function(t){var e=new C(this.context,t);this.bindingsByAction.set(t,e),this.delegate.bindingConnected(e)}},{key:"disconnectAction",value:function(t){var e=this.bindingsByAction.get(t);e&&(this.bindingsByAction.delete(t),this.delegate.bindingDisconnected(e))}},{key:"disconnectAllActions",value:function(){var t=this;this.bindings.forEach(function(e){return t.delegate.bindingDisconnected(e,!0)}),this.bindingsByAction.clear()}},{key:"parseValueForToken",value:function(t){var e=O.forToken(t,this.schema);if(e.identifier==this.identifier)return e}},{key:"elementMatchedValue",value:function(t,e){this.connectAction(e)}},{key:"elementUnmatchedValue",value:function(t,e){this.disconnectAction(e)}}]),t}(),H=function(){function t(e,r){(0,a._)(this,t),this.context=e,this.receiver=r,this.stringMapObserver=new N(this.element,this),this.valueDescriptorMap=this.controller.valueDescriptorMap}return(0,o._)(t,[{key:"start",value:function(){this.stringMapObserver.start(),this.invokeChangedCallbacksForDefaultValues()}},{key:"stop",value:function(){this.stringMapObserver.stop()}},{key:"element",get:function(){return this.context.element}},{key:"controller",get:function(){return this.context.controller}},{key:"getStringMapKeyForAttribute",value:function(t){if(t in this.valueDescriptorMap)return this.valueDescriptorMap[t].name}},{key:"stringMapKeyAdded",value:function(t,e){var r=this.valueDescriptorMap[e];this.hasValue(t)||this.invokeChangedCallback(t,r.writer(this.receiver[t]),r.writer(r.defaultValue))}},{key:"stringMapValueChanged",value:function(t,e,r){var n=this.valueDescriptorNameMap[e];null!==t&&(null===r&&(r=n.writer(n.defaultValue)),this.invokeChangedCallback(e,t,r))}},{key:"stringMapKeyRemoved",value:function(t,e,r){var n=this.valueDescriptorNameMap[t];this.hasValue(t)?this.invokeChangedCallback(t,n.writer(this.receiver[t]),r):this.invokeChangedCallback(t,n.writer(n.defaultValue),r)}},{key:"invokeChangedCallbacksForDefaultValues",value:function(){var t=!0,e=!1,r=void 0;try{for(var n,i=this.valueDescriptors[Symbol.iterator]();!(t=(n=i.next()).done);t=!0){var a=n.value,o=a.key,s=a.name,l=a.defaultValue,u=a.writer;void 0==l||this.controller.data.has(o)||this.invokeChangedCallback(s,u(l),void 0)}}catch(t){e=!0,r=t}finally{try{t||null==i.return||i.return()}finally{if(e)throw r}}}},{key:"invokeChangedCallback",value:function(t,e,r){var n=this.receiver["".concat(t,"Changed")];if("function"==typeof n){var i=this.valueDescriptorNameMap[t];try{var a=i.reader(e),o=r;r&&(o=i.reader(r)),n.call(this.receiver,a,o)}catch(t){throw t instanceof TypeError&&(t.message='Stimulus Value "'.concat(this.context.identifier,".").concat(i.name,'" - ').concat(t.message)),t}}}},{key:"valueDescriptors",get:function(){var t=this.valueDescriptorMap;return Object.keys(t).map(function(e){return t[e]})}},{key:"valueDescriptorNameMap",get:function(){var t=this,e={};return Object.keys(this.valueDescriptorMap).forEach(function(r){var n=t.valueDescriptorMap[r];e[n.name]=n}),e}},{key:"hasValue",value:function(t){var e=this.valueDescriptorNameMap[t],r="has".concat(k(e.name));return this.receiver[r]}}]),t}(),U=function(){function t(e,r){(0,a._)(this,t),this.context=e,this.delegate=r,this.targetsByName=new L}return(0,o._)(t,[{key:"start",value:function(){this.tokenListObserver||(this.tokenListObserver=new V(this.element,this.attributeName,this),this.tokenListObserver.start())}},{key:"stop",value:function(){this.tokenListObserver&&(this.disconnectAllTargets(),this.tokenListObserver.stop(),delete this.tokenListObserver)}},{key:"tokenMatched",value:function(t){var e=t.element,r=t.content;this.scope.containsElement(e)&&this.connectTarget(e,r)}},{key:"tokenUnmatched",value:function(t){var e=t.element,r=t.content;this.disconnectTarget(e,r)}},{key:"connectTarget",value:function(t,e){var r,n=this;this.targetsByName.has(e,t)||(this.targetsByName.add(e,t),null===(r=this.tokenListObserver)||void 0===r||r.pause(function(){return n.delegate.targetConnected(t,e)}))}},{key:"disconnectTarget",value:function(t,e){var r,n=this;this.targetsByName.has(e,t)&&(this.targetsByName.delete(e,t),null===(r=this.tokenListObserver)||void 0===r||r.pause(function(){return n.delegate.targetDisconnected(t,e)}))}},{key:"disconnectAllTargets",value:function(){var t=!0,e=!1,r=void 0,n=!0,i=!1,a=void 0;try{for(var o,s=this.targetsByName.keys[Symbol.iterator]();!(n=(o=s.next()).done);n=!0){var l=o.value;try{for(var u,c=this.targetsByName.getValuesForKey(l)[Symbol.iterator]();!(t=(u=c.next()).done);t=!0){var h=u.value;this.disconnectTarget(h,l)}}catch(t){e=!0,r=t}finally{try{t||null==c.return||c.return()}finally{if(e)throw r}}}}catch(t){i=!0,a=t}finally{try{n||null==s.return||s.return()}finally{if(i)throw a}}}},{key:"attributeName",get:function(){return"data-".concat(this.context.identifier,"-target")}},{key:"element",get:function(){return this.context.element}},{key:"scope",get:function(){return this.context.scope}}]),t}();function K(t,e){return Array.from(Y(t).reduce(function(t,r){var n;return(Array.isArray(n=r[e])?n:[]).forEach(function(e){return t.add(e)}),t},new Set))}function Y(t){for(var e=[];t;)e.push(t),t=Object.getPrototypeOf(t);return e.reverse()}var X=function(){function t(e,r){(0,a._)(this,t),this.started=!1,this.context=e,this.delegate=r,this.outletsByName=new L,this.outletElementsByName=new L,this.selectorObserverMap=new Map,this.attributeObserverMap=new Map}return(0,o._)(t,[{key:"start",value:function(){var t=this;this.started||(this.outletDefinitions.forEach(function(e){t.setupSelectorObserverForOutlet(e),t.setupAttributeObserverForOutlet(e)}),this.started=!0,this.dependentContexts.forEach(function(t){return t.refresh()}))}},{key:"refresh",value:function(){this.selectorObserverMap.forEach(function(t){return t.refresh()}),this.attributeObserverMap.forEach(function(t){return t.refresh()})}},{key:"stop",value:function(){this.started&&(this.started=!1,this.disconnectAllOutlets(),this.stopSelectorObservers(),this.stopAttributeObservers())}},{key:"stopSelectorObservers",value:function(){this.selectorObserverMap.size>0&&(this.selectorObserverMap.forEach(function(t){return t.stop()}),this.selectorObserverMap.clear())}},{key:"stopAttributeObservers",value:function(){this.attributeObserverMap.size>0&&(this.attributeObserverMap.forEach(function(t){return t.stop()}),this.attributeObserverMap.clear())}},{key:"selectorMatched",value:function(t,e,r){var n=r.outletName,i=this.getOutlet(t,n);i&&this.connectOutlet(i,t,n)}},{key:"selectorUnmatched",value:function(t,e,r){var n=r.outletName,i=this.getOutletFromMap(t,n);i&&this.disconnectOutlet(i,t,n)}},{key:"selectorMatchElement",value:function(t,e){var r=e.outletName,n=this.selector(r),i=this.hasOutlet(t,r),a=t.matches("[".concat(this.schema.controllerAttribute,"~=").concat(r,"]"));return!!n&&i&&a&&t.matches(n)}},{key:"elementMatchedAttribute",value:function(t,e){var r=this.getOutletNameFromOutletAttributeName(e);r&&this.updateSelectorObserverForOutlet(r)}},{key:"elementAttributeValueChanged",value:function(t,e){var r=this.getOutletNameFromOutletAttributeName(e);r&&this.updateSelectorObserverForOutlet(r)}},{key:"elementUnmatchedAttribute",value:function(t,e){var r=this.getOutletNameFromOutletAttributeName(e);r&&this.updateSelectorObserverForOutlet(r)}},{key:"connectOutlet",value:function(t,e,r){var n,i=this;this.outletElementsByName.has(r,e)||(this.outletsByName.add(r,t),this.outletElementsByName.add(r,e),null===(n=this.selectorObserverMap.get(r))||void 0===n||n.pause(function(){return i.delegate.outletConnected(t,e,r)}))}},{key:"disconnectOutlet",value:function(t,e,r){var n,i=this;this.outletElementsByName.has(r,e)&&(this.outletsByName.delete(r,t),this.outletElementsByName.delete(r,e),null===(n=this.selectorObserverMap.get(r))||void 0===n||n.pause(function(){return i.delegate.outletDisconnected(t,e,r)}))}},{key:"disconnectAllOutlets",value:function(){var t=!0,e=!1,r=void 0;try{for(var n,i=this.outletElementsByName.keys[Symbol.iterator]();!(t=(n=i.next()).done);t=!0){var a=n.value,o=!0,s=!1,l=void 0,u=!0,c=!1,h=void 0;try{for(var f,d=this.outletElementsByName.getValuesForKey(a)[Symbol.iterator]();!(u=(f=d.next()).done);u=!0){var p=f.value;try{for(var v,g=this.outletsByName.getValuesForKey(a)[Symbol.iterator]();!(o=(v=g.next()).done);o=!0){var y=v.value;this.disconnectOutlet(y,p,a)}}catch(t){s=!0,l=t}finally{try{o||null==g.return||g.return()}finally{if(s)throw l}}}}catch(t){c=!0,h=t}finally{try{u||null==d.return||d.return()}finally{if(c)throw h}}}}catch(t){e=!0,r=t}finally{try{t||null==i.return||i.return()}finally{if(e)throw r}}}},{key:"updateSelectorObserverForOutlet",value:function(t){var e=this.selectorObserverMap.get(t);e&&(e.selector=this.selector(t))}},{key:"setupSelectorObserverForOutlet",value:function(t){var e=this.selector(t),r=new R(document.body,e,this,{outletName:t});this.selectorObserverMap.set(t,r),r.start()}},{key:"setupAttributeObserverForOutlet",value:function(t){var e=this.attributeNameForOutletName(t),r=new D(this.scope.element,e,this);this.attributeObserverMap.set(t,r),r.start()}},{key:"selector",value:function(t){return this.scope.outlets.getSelectorForOutletName(t)}},{key:"attributeNameForOutletName",value:function(t){return this.scope.schema.outletAttributeForScope(this.identifier,t)}},{key:"getOutletNameFromOutletAttributeName",value:function(t){var e=this;return this.outletDefinitions.find(function(r){return e.attributeNameForOutletName(r)===t})}},{key:"outletDependencies",get:function(){var t=new L;return this.router.modules.forEach(function(e){K(e.definition.controllerConstructor,"outlets").forEach(function(r){return t.add(r,e.identifier)})}),t}},{key:"outletDefinitions",get:function(){return this.outletDependencies.getKeysForValue(this.identifier)}},{key:"dependentControllerIdentifiers",get:function(){return this.outletDependencies.getValuesForKey(this.identifier)}},{key:"dependentContexts",get:function(){var t=this.dependentControllerIdentifiers;return this.router.contexts.filter(function(e){return t.includes(e.identifier)})}},{key:"hasOutlet",value:function(t,e){return!!this.getOutlet(t,e)||!!this.getOutletFromMap(t,e)}},{key:"getOutlet",value:function(t,e){return this.application.getControllerForElementAndIdentifier(t,e)}},{key:"getOutletFromMap",value:function(t,e){return this.outletsByName.getValuesForKey(e).find(function(e){return e.element===t})}},{key:"scope",get:function(){return this.context.scope}},{key:"schema",get:function(){return this.context.schema}},{key:"identifier",get:function(){return this.context.identifier}},{key:"application",get:function(){return this.context.application}},{key:"router",get:function(){return this.application.router}}]),t}(),q=function(){function t(e,r){var n=this;(0,a._)(this,t),this.logDebugActivity=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};e=Object.assign({identifier:n.identifier,controller:n.controller,element:n.element},e),n.application.logDebugActivity(n.identifier,t,e)},this.module=e,this.scope=r,this.controller=new e.controllerConstructor(this),this.bindingObserver=new W(this,this.dispatcher),this.valueObserver=new H(this,this.controller),this.targetObserver=new U(this,this),this.outletObserver=new X(this,this);try{this.controller.initialize(),this.logDebugActivity("initialize")}catch(t){this.handleError(t,"initializing controller")}}return(0,o._)(t,[{key:"connect",value:function(){this.bindingObserver.start(),this.valueObserver.start(),this.targetObserver.start(),this.outletObserver.start();try{this.controller.connect(),this.logDebugActivity("connect")}catch(t){this.handleError(t,"connecting controller")}}},{key:"refresh",value:function(){this.outletObserver.refresh()}},{key:"disconnect",value:function(){try{this.controller.disconnect(),this.logDebugActivity("disconnect")}catch(t){this.handleError(t,"disconnecting controller")}this.outletObserver.stop(),this.targetObserver.stop(),this.valueObserver.stop(),this.bindingObserver.stop()}},{key:"application",get:function(){return this.module.application}},{key:"identifier",get:function(){return this.module.identifier}},{key:"schema",get:function(){return this.application.schema}},{key:"dispatcher",get:function(){return this.application.dispatcher}},{key:"element",get:function(){return this.scope.element}},{key:"parentElement",get:function(){return this.element.parentElement}},{key:"handleError",value:function(t,e){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};r=Object.assign({identifier:this.identifier,controller:this.controller,element:this.element},r),this.application.handleError(t,"Error ".concat(e),r)}},{key:"targetConnected",value:function(t,e){this.invokeControllerMethod("".concat(e,"TargetConnected"),t)}},{key:"targetDisconnected",value:function(t,e){this.invokeControllerMethod("".concat(e,"TargetDisconnected"),t)}},{key:"outletConnected",value:function(t,e,r){this.invokeControllerMethod("".concat(x(r),"OutletConnected"),t,e)}},{key:"outletDisconnected",value:function(t,e,r){this.invokeControllerMethod("".concat(x(r),"OutletDisconnected"),t,e)}},{key:"invokeControllerMethod",value:function(t){for(var e=arguments.length,r=Array(e>1?e-1:0),n=1;n0&&void 0!==arguments[0]?arguments[0]:document.documentElement,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:ts,n=this;(0,a._)(this,t),this.logger=console,this.debug=!1,this.logDebugActivity=function(t,e){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};n.debug&&n.logFormattedMessage(t,e,r)},this.element=e,this.schema=r,this.dispatcher=new y(this),this.router=new to(this),this.actionDescriptorFilters=Object.assign({},m)}return(0,o._)(t,[{key:"start",value:function(){var t=this;return(0,i._)(function(){return(0,v._)(this,function(e){switch(e.label){case 0:return[4,new Promise(function(t){"loading"==document.readyState?document.addEventListener("DOMContentLoaded",function(){return t()}):t()})];case 1:return e.sent(),t.logDebugActivity("application","starting"),t.dispatcher.start(),t.router.start(),t.logDebugActivity("application","start"),[2]}})})()}},{key:"stop",value:function(){this.logDebugActivity("application","stopping"),this.dispatcher.stop(),this.router.stop(),this.logDebugActivity("application","stop")}},{key:"register",value:function(t,e){this.load({identifier:t,controllerConstructor:e})}},{key:"registerActionOption",value:function(t,e){this.actionDescriptorFilters[t]=e}},{key:"load",value:function(t){for(var e=this,r=arguments.length,n=Array(r>1?r-1:0),i=1;i1?r-1:0),i=1;i2&&void 0!==arguments[2]?arguments[2]:{};r=Object.assign({application:this},r),this.logger.groupCollapsed("".concat(t," #").concat(e)),this.logger.log("details:",Object.assign({},r)),this.logger.groupEnd()}}],[{key:"start",value:function(t,e){var r=new this(t,e);return r.start(),r}}]),t}();function tc(t,e,r){return t.application.getControllerForElementAndIdentifier(e,r)}function th(t,e,r){var n=tc(t,e,r);return n||((t.application.router.proposeToConnectScopeForElementAndIdentifier(e,r),n=tc(t,e,r))?n:void 0)}function tf(t,e){var r,n,i,a,o,s=(0,h._)(t,2);return n=(r={controller:e,token:s[0],typeDefinition:s[1]}).token,i=r.typeDefinition,a="".concat(w(n),"-value"),{type:o=function(t){var e=t.controller,r=t.token,n=t.typeDefinition,i=function(t){var e=t.controller,r=t.token,n=t.typeObject,i=null!=n.type,a=null!=n.default,o=td(n.type),s=tp(t.typeObject.default);if(i&&!a)return o;if(!i&&a)return s;if(o!==s){var l=e?"".concat(e,".").concat(r):r;throw Error('The specified default value for the Stimulus Value "'.concat(l,'" must match the defined type "').concat(o,'". The provided default value of "').concat(n.default,'" is of type "').concat(s,'".'))}if(i&&a)return o}({controller:e,token:r,typeObject:n}),a=tp(n),o=td(n),s=i||a||o;if(s)return s;var l=e?"".concat(e,".").concat(n):r;throw Error('Unknown value type "'.concat(l,'" for "').concat(r,'" value'))}(r),key:a,name:_(a),get defaultValue(){return function(t){var e=td(t);if(e)return tv[e];var r=M(t,"default"),n=M(t,"type");if(r)return t.default;if(n){var i=td(t.type);if(i)return tv[i]}return t}(i)},get hasCustomDefaultValue(){return void 0!==tp(i)},reader:tg[o],writer:ty[o]||ty.default}}function td(t){switch(t){case Array:return"array";case Boolean:return"boolean";case Number:return"number";case Object:return"object";case String:return"string"}}function tp(t){switch(void 0===t?"undefined":(0,d._)(t)){case"boolean":return"boolean";case"number":return"number";case"string":return"string"}return Array.isArray(t)?"array":"[object Object]"===Object.prototype.toString.call(t)?"object":void 0}var tv={get array(){return[]},boolean:!1,number:0,get object(){return{}},string:""},tg={array:function(t){var e=JSON.parse(t);if(!Array.isArray(e))throw TypeError('expected value of type "array" but instead got value "'.concat(t,'" of type "').concat(tp(e),'"'));return e},boolean:function(t){return!("0"==t||"false"==String(t).toLowerCase())},number:function(t){return Number(t.replace(/_/g,""))},object:function(t){var e=JSON.parse(t);if(null===e||"object"!=typeof e||Array.isArray(e))throw TypeError('expected value of type "object" but instead got value "'.concat(t,'" of type "').concat(tp(e),'"'));return e},string:function(t){return t}},ty={default:function(t){return"".concat(t)},array:tm,object:tm};function tm(t){return JSON.stringify(t)}var tb=function(){function t(e){(0,a._)(this,t),this.context=e}return(0,o._)(t,[{key:"application",get:function(){return this.context.application}},{key:"scope",get:function(){return this.context.scope}},{key:"element",get:function(){return this.scope.element}},{key:"identifier",get:function(){return this.scope.identifier}},{key:"targets",get:function(){return this.scope.targets}},{key:"outlets",get:function(){return this.scope.outlets}},{key:"classes",get:function(){return this.scope.classes}},{key:"data",get:function(){return this.scope.data}},{key:"initialize",value:function(){}},{key:"connect",value:function(){}},{key:"disconnect",value:function(){}},{key:"dispatch",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=e.target,n=void 0===r?this.element:r,i=e.detail,a=e.prefix,o=void 0===a?this.identifier:a,s=e.bubbles,l=e.cancelable,u=new CustomEvent(o?"".concat(o,":").concat(t):t,{detail:void 0===i?{}:i,bubbles:void 0===s||s,cancelable:void 0===l||l});return n.dispatchEvent(u),u}}],[{key:"shouldLoad",get:function(){return!0}},{key:"afterLoad",value:function(t,e){}}]),t}();tb.blessings=[function(t){return K(t,"classes").reduce(function(t,e){var r;return Object.assign(t,(r={},(0,s._)(r,"".concat(e,"Class"),{get:function(){var t=this.classes;if(t.has(e))return t.get(e);var r=t.getAttributeName(e);throw Error('Missing attribute "'.concat(r,'"'))}}),(0,s._)(r,"".concat(e,"Classes"),{get:function(){return this.classes.getAll(e)}}),(0,s._)(r,"has".concat(k(e),"Class"),{get:function(){return this.classes.has(e)}}),r))},{})},function(t){return K(t,"targets").reduce(function(t,e){var r;return Object.assign(t,(r={},(0,s._)(r,"".concat(e,"Target"),{get:function(){var t=this.targets.find(e);if(t)return t;throw Error('Missing target element "'.concat(e,'" for "').concat(this.identifier,'" controller'))}}),(0,s._)(r,"".concat(e,"Targets"),{get:function(){return this.targets.findAll(e)}}),(0,s._)(r,"has".concat(k(e),"Target"),{get:function(){return this.targets.has(e)}}),r))},{})},function(t){var e,r=(e="values",Y(t).reduce(function(t,r){var n;return t.push.apply(t,(0,f._)((n=r[e])?Object.keys(n).map(function(t){return[t,n[t]]}):[])),t},[]));return r.reduce(function(t,e){var r,n,i,a,o,l;return Object.assign(t,(i=(n=tf(e,void 0)).key,a=n.name,o=n.reader,l=n.writer,r={},(0,s._)(r,a,{get:function(){var t=this.data.get(i);return null!==t?o(t):n.defaultValue},set:function(t){void 0===t?this.data.delete(i):this.data.set(i,l(t))}}),(0,s._)(r,"has".concat(k(a)),{get:function(){return this.data.has(i)||n.hasCustomDefaultValue}}),r))},{valueDescriptorMap:{get:function(){var t=this;return r.reduce(function(e,r){var n=tf(r,t.identifier),i=t.data.getAttributeNameForKey(n.key);return Object.assign(e,(0,s._)({},i,n))},{})}}})},function(t){return K(t,"outlets").reduce(function(t,e){var r,n;return Object.assign(t,(n=x(e),r={},(0,s._)(r,"".concat(n,"Outlet"),{get:function(){var t=this.outlets.find(e),r=this.outlets.getSelectorForOutletName(e);if(t){var n=th(this,t,e);if(n)return n;throw Error('The provided outlet element is missing an outlet controller "'.concat(e,'" instance for host controller "').concat(this.identifier,'"'))}throw Error('Missing outlet element "'.concat(e,'" for host controller "').concat(this.identifier,'". Stimulus couldn\'t find a matching outlet element using selector "').concat(r,'".'))}}),(0,s._)(r,"".concat(n,"Outlets"),{get:function(){var t=this,r=this.outlets.findAll(e);return r.length>0?r.map(function(r){var n=th(t,r,e);if(n)return n;console.warn('The provided outlet element is missing an outlet controller "'.concat(e,'" instance for host controller "').concat(t.identifier,'"'),r)}).filter(function(t){return t}):[]}}),(0,s._)(r,"".concat(n,"OutletElement"),{get:function(){var t=this.outlets.find(e),r=this.outlets.getSelectorForOutletName(e);if(t)return t;throw Error('Missing outlet element "'.concat(e,'" for host controller "').concat(this.identifier,'". Stimulus couldn\'t find a matching outlet element using selector "').concat(r,'".'))}}),(0,s._)(r,"".concat(n,"OutletElements"),{get:function(){return this.outlets.findAll(e)}}),(0,s._)(r,"has".concat(k(n),"Outlet"),{get:function(){return this.outlets.has(e)}}),r))},{})}],tb.targets=[],tb.outlets=[],tb.values={}},{"@swc/helpers/_/_async_to_generator":"6Tpxj","@swc/helpers/_/_class_call_check":"2HOGN","@swc/helpers/_/_create_class":"8oe8p","@swc/helpers/_/_define_property":"27c3O","@swc/helpers/_/_get":"6FgjI","@swc/helpers/_/_get_prototype_of":"4Pl3E","@swc/helpers/_/_inherits":"7gHjg","@swc/helpers/_/_sliced_to_array":"hefcy","@swc/helpers/_/_to_consumable_array":"4oNkS","@swc/helpers/_/_type_of":"2bRX5","@swc/helpers/_/_create_super":"a37Ru","@swc/helpers/_/_ts_generator":"lwj56","@parcel/transformer-js/src/esmodule-helpers.js":"kPSB8"}],"6Tpxj":[function(t,e,r){var n=t("@parcel/transformer-js/src/esmodule-helpers.js");function i(t,e,r,n,i,a,o){try{var s=t[a](o),l=s.value}catch(t){r(t);return}s.done?e(l):Promise.resolve(l).then(n,i)}function a(t){return function(){var e=this,r=arguments;return new Promise(function(n,a){var o=t.apply(e,r);function s(t){i(o,n,a,s,l,"next",t)}function l(t){i(o,n,a,s,l,"throw",t)}s(void 0)})}}n.defineInteropFlag(r),n.export(r,"_async_to_generator",function(){return a}),n.export(r,"_",function(){return a})},{"@parcel/transformer-js/src/esmodule-helpers.js":"kPSB8"}],kPSB8:[function(t,e,r){r.interopDefault=function(t){return t&&t.__esModule?t:{default:t}},r.defineInteropFlag=function(t){Object.defineProperty(t,"__esModule",{value:!0})},r.exportAll=function(t,e){return Object.keys(t).forEach(function(r){"default"===r||"__esModule"===r||Object.prototype.hasOwnProperty.call(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:function(){return t[r]}})}),e},r.export=function(t,e,r){Object.defineProperty(t,e,{enumerable:!0,get:r})}},{}],"2HOGN":[function(t,e,r){var n=t("@parcel/transformer-js/src/esmodule-helpers.js");function i(t,e){if(!(t instanceof e))throw TypeError("Cannot call a class as a function")}n.defineInteropFlag(r),n.export(r,"_class_call_check",function(){return i}),n.export(r,"_",function(){return i})},{"@parcel/transformer-js/src/esmodule-helpers.js":"kPSB8"}],"8oe8p":[function(t,e,r){var n=t("@parcel/transformer-js/src/esmodule-helpers.js");function i(t,e){for(var r=0;rt.length)&&(e=t.length);for(var r=0,n=Array(e);re.indexOf(n)&&(r[n]=t[n]);if(null!=t&&"function"==typeof Object.getOwnPropertySymbols)for(var i=0,n=Object.getOwnPropertySymbols(t);ie.indexOf(n[i])&&Object.prototype.propertyIsEnumerable.call(t,n[i])&&(r[n[i]]=t[n[i]]);return r}function u(t,e,r,n){var i,a=arguments.length,o=a<3?e:null===n?n=Object.getOwnPropertyDescriptor(e,r):n;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(t,e,r,n);else for(var s=t.length-1;s>=0;s--)(i=t[s])&&(o=(a<3?i(o):a>3?i(e,r,o):i(e,r))||o);return a>3&&o&&Object.defineProperty(e,r,o),o}function c(t,e){return function(r,n){e(r,n,t)}}function h(t,e,r,n,i,a){function o(t){if(void 0!==t&&"function"!=typeof t)throw TypeError("Function expected");return t}for(var s,l=n.kind,u="getter"===l?"get":"setter"===l?"set":"value",c=!e&&t?n.static?t:t.prototype:null,h=e||(c?Object.getOwnPropertyDescriptor(c,n.name):{}),f=!1,d=r.length-1;d>=0;d--){var p={};for(var v in n)p[v]="access"===v?{}:n[v];for(var v in n.access)p.access[v]=n.access[v];p.addInitializer=function(t){if(f)throw TypeError("Cannot add initializers after decoration has completed");a.push(o(t||null))};var g=(0,r[d])("accessor"===l?{get:h.get,set:h.set}:h[u],p);if("accessor"===l){if(void 0===g)continue;if(null===g||"object"!=typeof g)throw TypeError("Object expected");(s=o(g.get))&&(h.get=s),(s=o(g.set))&&(h.set=s),(s=o(g.init))&&i.unshift(s)}else(s=o(g))&&("field"===l?i.unshift(s):h[u]=s)}c&&Object.defineProperty(c,n.name,h),f=!0}function f(t,e,r){for(var n=arguments.length>2,i=0;i0&&i[i.length-1])&&(6===s[0]||2===s[0])){o=0;continue}if(3===s[0]&&(!i||s[1]>i[0]&&s[1]=t.length&&(t=void 0),{value:t&&t[n++],done:!t}}};throw TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")}function x(t,e){var r="function"==typeof Symbol&&t[Symbol.iterator];if(!r)return t;var n,i,a=r.call(t),o=[];try{for(;(void 0===e||e-- >0)&&!(n=a.next()).done;)o.push(n.value)}catch(t){i={error:t}}finally{try{n&&!n.done&&(r=a.return)&&r.call(a)}finally{if(i)throw i.error}}return o}function k(){for(var t=[],e=0;e1||s(t,e)})})}function s(t,e){try{var r;(r=i[t](e)).value instanceof S?Promise.resolve(r.value.v).then(l,u):c(a[0][2],r)}catch(t){c(a[0][3],t)}}function l(t){s("next",t)}function u(t){s("throw",t)}function c(t,e){t(e),a.shift(),a.length&&s(a[0][0],a[0][1])}}function A(t){var e,r;return e={},n("next"),n("throw",function(t){throw t}),n("return"),e[Symbol.iterator]=function(){return this},e;function n(n,i){e[n]=t[n]?function(e){return(r=!r)?{value:S(t[n](e)),done:!1}:i?i(e):e}:i}}function E(t){if(!Symbol.asyncIterator)throw TypeError("Symbol.asyncIterator is not defined.");var e,r=t[Symbol.asyncIterator];return r?r.call(t):(t=_(t),e={},n("next"),n("throw"),n("return"),e[Symbol.asyncIterator]=function(){return this},e);function n(r){e[r]=t[r]&&function(e){return new Promise(function(n,i){!function(t,e,r,n){Promise.resolve(n).then(function(e){t({value:e,done:r})},e)}(n,i,(e=t[r](e)).done,e.value)})}}}function C(t,e){return Object.defineProperty?Object.defineProperty(t,"raw",{value:e}):t.raw=e,t}var P=Object.create?function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}:function(t,e){t.default=e};function D(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)"default"!==r&&Object.prototype.hasOwnProperty.call(t,r)&&m(e,t,r);return P(e,t),e}function j(t){return t&&t.__esModule?t:{default:t}}function T(t,e,r,n){if("a"===r&&!n)throw TypeError("Private accessor was defined without a getter");if("function"==typeof e?t!==e||!n:!e.has(t))throw TypeError("Cannot read private member from an object whose class did not declare it");return"m"===r?n:"a"===r?n.call(t):n?n.value:e.get(t)}function F(t,e,r,n,i){if("m"===n)throw TypeError("Private method is not writable");if("a"===n&&!i)throw TypeError("Private accessor was defined without a setter");if("function"==typeof e?t!==e||!i:!e.has(t))throw TypeError("Cannot write private member to an object whose class did not declare it");return"a"===n?i.call(t,r):i?i.value=r:e.set(t,r),r}function I(t,e){if(null===e||"object"!=typeof e&&"function"!=typeof e)throw TypeError("Cannot use 'in' operator on non-object");return"function"==typeof t?e===t:t.has(e)}function L(t,e,r){if(null!=e){var n;if("object"!=typeof e&&"function"!=typeof e)throw TypeError("Object expected.");if(r){if(!Symbol.asyncDispose)throw TypeError("Symbol.asyncDispose is not defined.");n=e[Symbol.asyncDispose]}if(void 0===n){if(!Symbol.dispose)throw TypeError("Symbol.dispose is not defined.");n=e[Symbol.dispose]}if("function"!=typeof n)throw TypeError("Object not disposable.");t.stack.push({value:e,dispose:n,async:r})}else r&&t.stack.push({async:!0});return e}var B="function"==typeof SuppressedError?SuppressedError:function(t,e,r){var n=Error(r);return n.name="SuppressedError",n.error=t,n.suppressed=e,n};function R(t){function e(e){t.error=t.hasError?new B(e,t.error,"An error was suppressed during disposal."):e,t.hasError=!0}return function r(){for(;t.stack.length;){var n=t.stack.pop();try{var i=n.dispose&&n.dispose.call(n.value);if(n.async)return Promise.resolve(i).then(r,function(t){return e(t),r()})}catch(t){e(t)}}if(t.hasError)throw t.error}()}r.default={__extends:o,__assign:s,__rest:l,__decorate:u,__param:c,__metadata:v,__awaiter:g,__generator:y,__createBinding:m,__exportStar:b,__values:_,__read:x,__spread:k,__spreadArrays:w,__spreadArray:M,__await:S,__asyncGenerator:O,__asyncDelegator:A,__asyncValues:E,__makeTemplateObject:C,__importStar:D,__importDefault:j,__classPrivateFieldGet:T,__classPrivateFieldSet:F,__classPrivateFieldIn:I,__addDisposableResource:L,__disposeResources:R}},{"@swc/helpers/_/_type_of":"2bRX5","@parcel/transformer-js/src/esmodule-helpers.js":"kPSB8"}],"78XDv":[function(t,e,r){var n,i=t("@parcel/transformer-js/src/esmodule-helpers.js");i.defineInteropFlag(r),i.export(r,"default",function(){return m});var a=t("@swc/helpers/_/_assert_this_initialized"),o=t("@swc/helpers/_/_class_call_check"),s=t("@swc/helpers/_/_create_class"),l=t("@swc/helpers/_/_define_property"),u=t("@swc/helpers/_/_inherits"),c=t("@swc/helpers/_/_to_consumable_array"),h=t("@swc/helpers/_/_create_super"),f=t("@hotwired/stimulus"),d=t("../chart_plugins/corsair_plugin"),p=i.interopDefault(d),v=t("chart.js"),g=t("color"),y=i.interopDefault(g);(n=v.Chart).register.apply(n,(0,c._)(v.registerables));var m=function(t){(0,u._)(r,t);var e=(0,h._)(r);function r(){var t;return(0,o._)(this,r),t=e.apply(this,arguments),(0,l._)((0,a._)(t),"metricGroups",[{metrics:["views","visitors","sessions"],format:"int"},{metrics:["clicks"],format:"int"},{metrics:["average_session_duration"],format:"time"},{metrics:["bounce_rate"],format:"percent"},{metrics:["views_per_session"],format:"float"},{metrics:["wc_orders","wc_refunds"],format:"int"},{metrics:["wc_gross_sales","wc_refunded_amount","wc_net_sales"],format:"whole_currency"},{metrics:["wc_conversion_rate"],format:"percent"},{metrics:["wc_earnings_per_visitor"],format:"currency"},{metrics:["wc_average_order_volume"],format:"whole_currency"},{metrics:["form_submissions"],prefix_to_include:"form_submissions_for_",format:"int"},{metrics:["form_conversion_rate"],prefix_to_include:"form_conversion_rate_for_",format:"percent"}]),(0,l._)((0,a._)(t),"tooltipLabel",function(e){return"function"==typeof e.dataset.tooltipLabel?e.dataset.tooltipLabel(e):e.dataset.label+": "+t.formatValueForMetric(e.dataset.id,e.raw)}),t}return(0,s._)(r,[{key:"getLocale",value:function(){try{return new Intl.NumberFormat(this.localeValue),this.localeValue}catch(t){return"en-US"}}},{key:"hasSecondaryMetric",value:function(){return this.hasSecondaryChartMetricIdValue&&this.secondaryChartMetricIdValue&&"no_comparison"!==this.secondaryChartMetricIdValue}},{key:"tooltipTitle",value:function(t){return JSON.parse(t[0].label).tooltipLabel}},{key:"getGroupByMetricId",value:function(t){return this.metricGroups.find(function(e){return e.metrics.includes(t)||e.prefix_to_include&&t.startsWith(e.prefix_to_include)})}},{key:"formatValueForMetric",value:function(t,e){switch(this.getGroupByMetricId(t).format){case"whole_currency":return new Intl.NumberFormat(this.localeValue,{style:"currency",currency:this.currencyValue,currencyDisplay:"narrowSymbol",minimumFractionDigits:0,maximumFractionDigits:0}).format(e/100);case"currency":return new Intl.NumberFormat(this.localeValue,{style:"currency",currency:this.currencyValue,currencyDisplay:"narrowSymbol",minimumFractionDigits:2,maximumFractionDigits:2}).format(e/100);case"percent":return new Intl.NumberFormat(this.localeValue,{style:"percent",maximumFractionDigits:2}).format(e/100);case"time":var r=Math.floor(e/60),n=e%60;return r.toString().padStart(2,"0")+":"+n.toString().padStart(2,"0");case"int":return new Intl.NumberFormat(this.localeValue,{maximumFractionDigits:0}).format(e);case"float":return new Intl.NumberFormat(this.localeValue,{maximumFractionDigits:2}).format(e);default:return e}}},{key:"tickText",value:function(t){return JSON.parse(this.getLabelForValue(t)).tick}},{key:"updateMetricSelectWidth",value:function(t){var e=t.options[t.selectedIndex];this.adaptiveWidthSelectTarget[0].innerHTML=e.innerText,t.style.width=this.adaptiveWidthSelectTarget.getBoundingClientRect().width+"px",t.parentElement.classList.add("visible")}},{key:"hasSharedAxis",value:function(t,e){var r=this.getGroupByMetricId(t),n=this.getGroupByMetricId(e);return JSON.stringify(r)===JSON.stringify(n)}},{key:"connect",value:function(){this.isPreviewValue||(this.updateMetricSelectWidth(this.primaryMetricSelectTarget),1===this.hasMultipleDatasetsValue&&this.updateMetricSelectWidth(this.secondaryMetricSelectTarget)),this.createChart(),this.updateChart()}},{key:"changePrimaryMetric",value:function(t){var e=t.target;this.primaryChartMetricIdValue=e.value,this.primaryChartMetricNameValue=e.options[e.selectedIndex].innerText,this.updateMetricSelectWidth(e),this.updateChart(),Array.from(this.secondaryMetricSelectTarget.querySelectorAll("option")).forEach(function(t){t.toggleAttribute("disabled",t.value===e.value)}),document.dispatchEvent(new CustomEvent("iawp:changePrimaryChartMetric",{detail:{primaryChartMetricId:e.value}}))}},{key:"changeSecondaryMetric",value:function(t){var e=t.target,r=""!==e.value;r?(this.secondaryChartMetricIdValue=e.value,this.secondaryChartMetricNameValue=e.options[e.selectedIndex].innerText):(this.secondaryChartMetricIdValue="",this.secondaryChartMetricNameValue=""),this.updateMetricSelectWidth(e),this.updateChart(),Array.from(this.primaryMetricSelectTarget.querySelectorAll("option")).forEach(function(t){t.toggleAttribute("disabled",t.value===e.value)}),document.dispatchEvent(new CustomEvent("iawp:changeSecondaryChartMetric",{detail:{secondaryChartMetricId:r?e.value:null}}))}},{key:"updateChart",value:function(){var t=window.iawp_chart.data.datasets[0];t.id=this.primaryChartMetricIdValue,t.data=this.dataValue[this.primaryChartMetricIdValue],t.label=this.primaryChartMetricNameValue;var e=t.data.every(function(t){return 0===t});if(window.iawp_chart.options.scales.y.suggestedMax=e?10:null,window.iawp_chart.options.scales.y.beginAtZero="bounce_rate"!==t.id,window.iawp_chart.data.datasets.length>1&&window.iawp_chart.data.datasets.pop(),this.hasSecondaryMetric()){var r=this.secondaryChartMetricIdValue,n=this.secondaryChartMetricNameValue,i=this.dataValue[r],a=this.hasSharedAxis(this.primaryChartMetricIdValue,r)?"y":"defaultRight";window.iawp_chart.data.datasets.push(this.makeDataset(r,n,i,a,"rgba(246,157,10)"));var o=i.every(function(t){return 0===t});window.iawp_chart.options.scales.defaultRight.suggestedMax=o?10:null,window.iawp_chart.options.scales.defaultRight.beginAtZero="bounce_rate"!==r}window.iawp_chart.update()}},{key:"makeDataset",value:function(t,e,r,n,i){var a=arguments.length>5&&void 0!==arguments[5]&&arguments[5],o=(0,y.default)(i);return{id:t,label:e,data:r,borderColor:o.string(),backgroundColor:o.alpha(.1).string(),pointBackgroundColor:o.string(),tension:.4,yAxisID:n,fill:!0,order:a?1:0}}},{key:"shouldUseDarkMode",value:function(){return document.body.classList.contains("iawp-dark-mode")&&!this.isPreviewValue}},{key:"createChart",value:function(){var t=this;v.Chart.defaults.font.family='-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"';var e=document.getElementById("independent-analytics-chart"),r={type:"line",data:{labels:this.labelsValue,datasets:[this.makeDataset(this.primaryChartMetricIdValue,this.primaryChartMetricNameValue,this.dataValue[this.primaryChartMetricIdValue],"y","rgba(108,70,174)",!0)].filter(function(t){return null!==t})},options:{locale:this.getLocale(),interaction:{intersect:!1,mode:"index"},scales:{y:{grid:{color:this.shouldUseDarkMode()?"#676173":"#DEDAE6",borderColor:"#DEDAE6",tickColor:"#DEDAE6",display:!0,drawOnChartArea:!0,borderDash:[2,4]},beginAtZero:!0,suggestedMax:null,ticks:{color:this.shouldUseDarkMode()?"#ffffff":"#6D6A73",font:{size:14,weight:400},precision:0,callback:function(e,r,n){return t.formatValueForMetric(t.primaryChartMetricIdValue,e)}}},defaultRight:{position:"right",display:"auto",grid:{color:this.shouldUseDarkMode()?"#9a95a6":"#DEDAE6",borderColor:"#DEDAE6",tickColor:"#DEDAE6",display:!0,drawOnChartArea:!1,borderDash:[2,4]},beginAtZero:!0,suggestedMax:null,ticks:{color:this.shouldUseDarkMode()?"#ffffff":"#6D6A73",font:{size:14,weight:400},precision:0,callback:function(e,r,n){return t.hasSecondaryMetric()?t.formatValueForMetric(t.secondaryChartMetricIdValue,e):e}}},x:{grid:{borderColor:"#DEDAE6",tickColor:"#DEDAE6",display:!0,drawOnChartArea:!1},ticks:{color:this.shouldUseDarkMode()?"#ffffff":"#6D6A73",autoSkip:!0,autoSkipPadding:16,maxRotation:0,font:{size:14,weight:400},callback:this.tickText}}},plugins:{mode:String,legend:{display:!1},corsair:{dash:[2,4],color:"#777",width:1},tooltip:{itemSort:function(t,e){return t.datasetIndexs||ca){t.corsair={x:u,y:c,draw:!1},t.draw();return}t.corsair={x:u,y:c,draw:!0},t.draw()}},afterDatasetsDraw:function(t,e,r){if(!r.disabled){var n=t.ctx,i=t.chartArea,a=i.top,o=i.bottom;i.left,i.right;var s=t.corsair,l=s.x;s.y,s.draw&&(l=t.tooltip.caretX,n.lineWidth=r.width||0,n.setLineDash(r.dash||[]),n.strokeStyle=r.color||"black",n.save(),n.beginPath(),n.moveTo(l,o),n.lineTo(l,a),n.stroke(),n.restore(),n.setLineDash([]))}}}},{}],"1stGI":[function(t,e,r){/*! * Chart.js v3.9.1 * https://www.chartjs.org * (c) 2022 Chart.js Contributors * Released under the MIT License */var n=t("@parcel/transformer-js/src/esmodule-helpers.js");n.defineInteropFlag(r),n.export(r,"defaults",function(){return m.d}),n.export(r,"Animation",function(){return k}),n.export(r,"Animations",function(){return M}),n.export(r,"ArcElement",function(){return en}),n.export(r,"BarController",function(){return z}),n.export(r,"BarElement",function(){return eb}),n.export(r,"BasePlatform",function(){return tS}),n.export(r,"BasicPlatform",function(){return tO}),n.export(r,"BubbleController",function(){return W}),n.export(r,"CategoryScale",function(){return eZ}),n.export(r,"Chart",function(){return t7}),n.export(r,"DatasetController",function(){return I}),n.export(r,"Decimation",function(){return ew}),n.export(r,"DomPlatform",function(){return tV}),n.export(r,"DoughnutController",function(){return H}),n.export(r,"Element",function(){return q}),n.export(r,"Filler",function(){return eF}),n.export(r,"Interaction",function(){return tp}),n.export(r,"Legend",function(){return eB}),n.export(r,"LineController",function(){return U}),n.export(r,"LineElement",function(){return eh}),n.export(r,"LinearScale",function(){return e2}),n.export(r,"LogarithmicScale",function(){return e3}),n.export(r,"PieController",function(){return Y}),n.export(r,"PointElement",function(){return ed}),n.export(r,"PolarAreaController",function(){return K}),n.export(r,"RadarController",function(){return X}),n.export(r,"RadialLinearScale",function(){return e7}),n.export(r,"Scale",function(){return tr}),n.export(r,"ScatterController",function(){return ta}),n.export(r,"SubTitle",function(){return ez}),n.export(r,"Ticks",function(){return Q}),n.export(r,"TimeScale",function(){return ro}),n.export(r,"TimeSeriesScale",function(){return rl}),n.export(r,"Title",function(){return eN}),n.export(r,"Tooltip",function(){return eG}),n.export(r,"_adapters",function(){return tu}),n.export(r,"_detectPlatform",function(){return tz}),n.export(r,"animator",function(){return b}),n.export(r,"controllers",function(){return to}),n.export(r,"elements",function(){return e_}),n.export(r,"layouts",function(){return tM}),n.export(r,"plugins",function(){return eJ}),n.export(r,"registerables",function(){return rc}),n.export(r,"registry",function(){return ti}),n.export(r,"scales",function(){return ru});var i=t("@swc/helpers/_/_assert_this_initialized"),a=t("@swc/helpers/_/_class_call_check"),o=t("@swc/helpers/_/_create_class"),s=t("@swc/helpers/_/_define_property"),l=t("@swc/helpers/_/_get"),u=t("@swc/helpers/_/_get_prototype_of"),c=t("@swc/helpers/_/_inherits"),h=t("@swc/helpers/_/_object_spread"),f=t("@swc/helpers/_/_object_spread_props"),d=t("@swc/helpers/_/_sliced_to_array"),p=t("@swc/helpers/_/_to_consumable_array"),v=t("@swc/helpers/_/_type_of"),g=t("@swc/helpers/_/_wrap_native_super"),y=t("@swc/helpers/_/_create_super"),m=t("./chunks/helpers.segment.mjs"),b=new(function(){function t(){(0,a._)(this,t),this._request=null,this._charts=new Map,this._running=!1,this._lastDate=void 0}return(0,o._)(t,[{key:"_notify",value:function(t,e,r,n){var i=e.listeners[n],a=e.duration;i.forEach(function(n){return n({chart:t,initial:e.initial,numSteps:a,currentStep:Math.min(r-e.start,a)})})}},{key:"_refresh",value:function(){var t=this;this._request||(this._running=!0,this._request=(0,m.r).call(window,function(){t._update(),t._request=null,t._running&&t._refresh()}))}},{key:"_update",value:function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:Date.now(),r=0;this._charts.forEach(function(n,i){if(n.running&&n.items.length){for(var a,o=n.items,s=o.length-1,l=!1;s>=0;--s)(a=o[s])._active?(a._total>n.duration&&(n.duration=a._total),a.tick(e),l=!0):(o[s]=o[o.length-1],o.pop());l&&(i.draw(),t._notify(i,n,e,"progress")),o.length||(n.running=!1,t._notify(i,n,e,"complete"),n.initial=!1),r+=o.length}}),this._lastDate=e,0===r&&(this._running=!1)}},{key:"_getAnims",value:function(t){var e=this._charts,r=e.get(t);return r||(r={running:!1,initial:!0,items:[],listeners:{complete:[],progress:[]}},e.set(t,r)),r}},{key:"listen",value:function(t,e,r){this._getAnims(t).listeners[e].push(r)}},{key:"add",value:function(t,e){var r;e&&e.length&&(r=this._getAnims(t).items).push.apply(r,(0,p._)(e))}},{key:"has",value:function(t){return this._getAnims(t).items.length>0}},{key:"start",value:function(t){var e=this._charts.get(t);e&&(e.running=!0,e.start=Date.now(),e.duration=e.items.reduce(function(t,e){return Math.max(t,e._duration)},0),this._refresh())}},{key:"running",value:function(t){if(!this._running)return!1;var e=this._charts.get(t);return!!e&&!!e.running&&!!e.items.length}},{key:"stop",value:function(t){var e=this._charts.get(t);if(e&&e.items.length){for(var r=e.items,n=r.length-1;n>=0;--n)r[n].cancel();e.items=[],this._notify(t,e,Date.now(),"complete")}}},{key:"remove",value:function(t){return this._charts.delete(t)}}]),t}()),_="transparent",x={boolean:function(t,e,r){return r>.5?e:t},color:function(t,e,r){var n=(0,m.c)(t||_),i=n.valid&&(0,m.c)(e||_);return i&&i.valid?i.mix(n,r).hexString():e},number:function(t,e,r){return t+(e-t)*r}},k=function(){function t(e,r,n,i){(0,a._)(this,t);var o=r[n];i=(0,m.a)([e.to,i,o,e.from]);var s=(0,m.a)([e.from,o,i]);this._active=!0,this._fn=e.fn||x[e.type||(void 0===s?"undefined":(0,v._)(s))],this._easing=m.e[e.easing]||m.e.linear,this._start=Math.floor(Date.now()+(e.delay||0)),this._duration=this._total=Math.floor(e.duration),this._loop=!!e.loop,this._target=r,this._prop=n,this._from=s,this._to=i,this._promises=void 0}return(0,o._)(t,[{key:"active",value:function(){return this._active}},{key:"update",value:function(t,e,r){if(this._active){this._notify(!1);var n=this._target[this._prop],i=r-this._start,a=this._duration-i;this._start=r,this._duration=Math.floor(Math.max(a,t.duration)),this._total+=i,this._loop=!!t.loop,this._to=(0,m.a)([t.to,e,n,t.from]),this._from=(0,m.a)([t.from,n,e])}}},{key:"cancel",value:function(){this._active&&(this.tick(Date.now()),this._active=!1,this._notify(!1))}},{key:"tick",value:function(t){var e,r=t-this._start,n=this._duration,i=this._prop,a=this._from,o=this._loop,s=this._to;if(this._active=a!==s&&(o||r1?2-e:e,e=this._easing(Math.min(1,Math.max(0,e))),this._target[i]=this._fn(a,s,e)}},{key:"wait",value:function(){var t=this._promises||(this._promises=[]);return new Promise(function(e,r){t.push({res:e,rej:r})})}},{key:"_notify",value:function(t){for(var e=t?"res":"rej",r=this._promises||[],n=0;n=0;--s){var s,l=a[s];if("$"!==l.charAt(0)){if("options"===l){n.push.apply(n,(0,p._)(this._animateOptions(t,e)));continue}var u=e[l],c=i[l],h=r.get(l);if(c){if(h&&c.active()){c.update(h,u,o);continue}c.cancel()}if(!h||!h.duration){t[l]=u;continue}i[l]=c=new k(h,t,l,u),n.push(c)}}return n}},{key:"update",value:function(t,e){if(0===this._properties.size){Object.assign(t,e);return}var r=this._createAnimations(t,e);if(r.length)return b.add(this._chart,r),!0}}]),t}();function S(t,e){var r=t&&t.options||{},n=r.reverse,i=void 0===r.min?e:0,a=void 0===r.max?e:0;return{start:n?a:i,end:n?i:a}}function O(t,e){var r,n,i=[],a=t._getSortedDatasetMetas(e);for(r=0,n=a.length;r3&&void 0!==arguments[3]?arguments[3]:{},l=t.keys,u="single"===s.mode;if(null!==e){for(n=0,i=l.length;n0||!r&&c<0)return u.index}}catch(t){a=!0,o=t}finally{try{i||null==l.return||l.return()}finally{if(a)throw o}}return null}function P(t,e){for(var r,n=t.chart,i=t._cachedMeta,a=n._stacks||(n._stacks={}),o=i.iScale,s=i.vScale,l=i.index,u=o.axis,c=s.axis,h="".concat(o.id,".").concat(s.id,".").concat(i.stack||i.type),f=e.length,d=0;d0&&a._parsed[t-1];if(!1===this._parsing)a._parsed=o,a._sorted=!0,i=o;else{for(r=0,i=(0,m.b)(o[t])?this.parseArrayData(a,o,t,e):(0,m.i)(o[t])?this.parseObjectData(a,o,t,e):this.parsePrimitiveData(a,o,t,e);re||y=0;--o)if(!b()){this.updateRangeFromParsed(p,t,s,d);break}}return p}},{key:"getAllParsedValues",value:function(t){var e,r,n,i=this._cachedMeta._parsed,a=[];for(e=0,r=i.length;e=0&&t1&&void 0!==arguments[1]?arguments[1]:"default",n=arguments.length>2?arguments[2]:void 0,i="active"===r,a=this._cachedDataOpts,o=t+"-"+r,s=a[o],l=this.enableOptionSharing&&(0,m.j)(n);if(s)return F(s,l);var u=this.chart.config,c=u.datasetElementScopeKeys(this._type,t),h=u.getOptionScopes(this.getDataset(),c),f=Object.keys(m.d.elements[t]),d=u.resolveNamedOptions(h,f,function(){return e.getContext(n,i)},i?["".concat(t,"Hover"),"hover",t,""]:[t,""]);return d.$shared&&(d.$shared=l,a[o]=Object.freeze(F(d,l))),d}},{key:"_resolveAnimations",value:function(t,e,r){var n,i=this.chart,a=this._cachedDataOpts,o="animation-".concat(e),s=a[o];if(s)return s;if(!1!==i.options.animation){var l=this.chart.config,u=l.datasetAnimationScopeKeys(this._type,e),c=l.getOptionScopes(this.getDataset(),u);n=l.createResolver(c,this.getContext(t,r,e))}var h=new M(i,n&&n.animations);return n&&n._cacheable&&(a[o]=Object.freeze(h)),h}},{key:"getSharedOptions",value:function(t){if(t.$shared)return this._sharedOptions||(this._sharedOptions=Object.assign({},t))}},{key:"includeOptions",value:function(t,e){return!e||T(t)||this.chart._animationsDisabled}},{key:"_getSharedOptions",value:function(t,e){var r=this.resolveDataElementOptions(t,e),n=this._sharedOptions,i=this.getSharedOptions(r),a=this.includeOptions(e,i)||i!==n;return this.updateSharedOptions(i,e,r),{sharedOptions:i,includeOptions:a}}},{key:"updateElement",value:function(t,e,r,n){T(n)?Object.assign(t,r):this._resolveAnimations(e,n).update(t,r)}},{key:"updateSharedOptions",value:function(t,e,r){t&&!T(e)&&this._resolveAnimations(void 0,e).update(t,r)}},{key:"_setStyle",value:function(t,e,r,n){t.active=n;var i=this.getStyle(e,n);this._resolveAnimations(e,r,n).update(t,{options:!n&&this.getSharedOptions(i)||i})}},{key:"removeHoverStyle",value:function(t,e,r){this._setStyle(t,r,"active",!1)}},{key:"setHoverStyle",value:function(t,e,r){this._setStyle(t,r,"active",!0)}},{key:"_removeDatasetHoverStyle",value:function(){var t=this._cachedMeta.dataset;t&&this._setStyle(t,void 0,"active",!1)}},{key:"_setDatasetHoverStyle",value:function(){var t=this._cachedMeta.dataset;t&&this._setStyle(t,void 0,"active",!0)}},{key:"_resyncElements",value:function(t){var e=this._data,r=this._cachedMeta.data,n=!0,i=!1,a=void 0;try{for(var o,s=this._syncList[Symbol.iterator]();!(n=(o=s.next()).done);n=!0){var l=(0,d._)(o.value,3),u=l[0],c=l[1],h=l[2];this[u](c,h)}}catch(t){i=!0,a=t}finally{try{n||null==s.return||s.return()}finally{if(i)throw a}}this._syncList=[];var f=r.length,p=e.length,v=Math.min(p,f);v&&this.parse(0,v),p>f?this._insertElements(f,p-f,t):p2)||void 0===arguments[2]||arguments[2],i=this._cachedMeta,a=i.data,o=t+e,s=function(t){for(t.length+=e,r=t.length-1;r>=o;r--)t[r]=t[r-e]};for(s(a),r=t;rMath.abs(s)&&(l=s,u=o),e[r.axis]=u,e._custom={barStart:l,barEnd:u,start:i,end:a,min:o,max:s}}else e[r.axis]=r.parse(t,n);return e}function B(t,e,r,n){var i,a,o,s,l=t.iScale,u=t.vScale,c=l.getLabels(),h=l===u,f=[];for(i=r,a=r+n;it.x,a="left",o="right"):(i=t.base=u?1:-1))*l,d===u&&(y-=r/2);var b,_=i.getPixelForDecimal(0),x=i.getPixelForDecimal(1);e=(y=Math.max(Math.min(y,Math.max(_,x)),Math.min(_,x)))+r}if(y===i.getPixelForValue(u)){var k=(0,m.s)(r)*i.getLineWidthForValue(u)/2;y+=k,r-=k}return{size:r,base:y,head:e,center:e+r/2}}},{key:"_calculateBarIndexPixels",value:function(t,e){var r,n,i=e.scale,a=this.options,o=a.skipNull,s=(0,m.v)(a.maxBarThickness,1/0);if(e.grouped){var l,u,c,h,f,d,p,v,g,y=o?this._getStackCount(t):e.stackCount,b="flex"===a.barThickness?(u=(l=e.pixels)[t],c=t>0?l[t-1]:null,h=t=0;--r)e=Math.max(e,t[r].size(this.resolveDataElementOptions(r))/2);return e>0&&e}},{key:"getLabelAndValue",value:function(t){var e=this._cachedMeta,r=e.xScale,n=e.yScale,i=this.getParsed(t),a=r.getLabelForValue(i.x),o=n.getLabelForValue(i.y),s=i._custom;return{label:e.label,value:"("+a+", "+o+(s?", "+s:"")+")"}}},{key:"update",value:function(t){var e=this._cachedMeta.data;this.updateElements(e,0,e.length,t)}},{key:"updateElements",value:function(t,e,r,n){for(var i="reset"===n,a=this._cachedMeta,o=a.iScale,s=a.vScale,l=this._getSharedOptions(e,n),u=l.sharedOptions,c=l.includeOptions,h=o.axis,f=s.axis,d=e;d0&&!isNaN(t)?m.T*(Math.abs(t)/e):0}},{key:"getLabelAndValue",value:function(t){var e=this._cachedMeta,r=this.chart,n=r.data.labels||[],i=(0,m.o)(e._parsed[t],r.options.locale);return{label:n[t]||"",value:i}}},{key:"getMaxBorderWidth",value:function(t){var e,r,n,i,a,o=0,s=this.chart;if(!t){for(e=0,r=s.data.datasets.length;e0&&this.getParsed(e-1),k=e;k0&&Math.abs(M[d]-x[d])>b,y&&(S.parsed=M,S.raw=u.data[k]),f&&(S.options=h||this.resolveDataElementOptions(k,w.active?"active":n)),_||this.updateElement(w,k,S,n),x=M}}},{key:"getMaxOverflow",value:function(){var t=this._cachedMeta,e=t.dataset,r=e.options&&e.options.borderWidth||0,n=t.data||[];return n.length?Math.max(r,n[0].size(this.resolveDataElementOptions(0)),n[n.length-1].size(this.resolveDataElementOptions(n.length-1)))/2:r}},{key:"draw",value:function(){var t=this._cachedMeta;t.dataset.updateControlPoints(this.chart.chartArea,t.iScale.axis),(0,l._)((0,u._)(r.prototype),"draw",this).call(this)}}]),r}(I);U.id="line",U.defaults={datasetElementType:"line",dataElementType:"point",showLine:!0,spanGaps:!1},U.overrides={scales:{_index_:{type:"category"},_value_:{type:"linear"}}};var K=function(t){(0,c._)(r,t);var e=(0,y._)(r);function r(t,n){var i;return(0,a._)(this,r),(i=e.call(this,t,n)).innerRadius=void 0,i.outerRadius=void 0,i}return(0,o._)(r,[{key:"getLabelAndValue",value:function(t){var e=this._cachedMeta,r=this.chart,n=r.data.labels||[],i=(0,m.o)(e._parsed[t].r,r.options.locale);return{label:n[t]||"",value:i}}},{key:"parseObjectData",value:function(t,e,r,n){return(0,m.y).bind(this)(t,e,r,n)}},{key:"update",value:function(t){var e=this._cachedMeta.data;this._updateRadius(),this.updateElements(e,0,e.length,t)}},{key:"getMinMax",value:function(){var t=this,e=this._cachedMeta,r={min:Number.POSITIVE_INFINITY,max:Number.NEGATIVE_INFINITY};return e.data.forEach(function(e,n){var i=t.getParsed(n).r;!isNaN(i)&&t.chart.getDataVisibility(n)&&(ir.max&&(r.max=i))}),r}},{key:"_updateRadius",value:function(){var t=this.chart,e=t.chartArea,r=t.options,n=Math.max(Math.min(e.right-e.left,e.bottom-e.top)/2,0),i=Math.max(r.cutoutPercentage?n/100*r.cutoutPercentage:1,0),a=(n-i)/t.getVisibleDatasetCount();this.outerRadius=n-a*this.index,this.innerRadius=this.outerRadius-a}},{key:"updateElements",value:function(t,e,r,n){var i,a="reset"===n,o=this.chart,s=o.options.animation,l=this._cachedMeta.rScale,u=l.xCenter,c=l.yCenter,h=l.getIndexAngle(0)-.5*m.P,f=h,d=360/this.countVisibleElements();for(i=0;i1){var o,s=Math.max(Math.abs(r[0].value),Math.abs(r[r.length-1].value));(s<1e-4||s>1e15)&&(n="scientific"),Math.abs(o=r.length>3?r[2].value-r[1].value:r[1].value-r[0].value)>=1&&t!==Math.floor(t)&&(o=t-Math.floor(t)),a=o}var l=Math.max(Math.min(-1*Math.floor((0,m.z)(Math.abs(a))),20),0),u={notation:n,minimumFractionDigits:l,maximumFractionDigits:l};return Object.assign(u,this.options.ticks.format),(0,m.o)(t,i,u)},logarithmic:function(t,e,r){if(0===t)return"0";var n=t/Math.pow(10,Math.floor((0,m.z)(t)));return 1===n||2===n||5===n?$.numeric.call(this,t,e,r):""}},Q={formatters:$};function G(t,e,r,n,i){var a,o,s,l=(0,m.v)(n,0),u=Math.min((0,m.v)(i,t.length),t.length),c=0;for(r=Math.ceil(r),i&&(r=(a=i-n)/Math.floor(a/r)),s=l;s<0;)s=Math.round(l+ ++c*r);for(o=Math.max(l,0);oi?i:n,i=a&&n>i?n:i,{min:(0,m.B)(n,(0,m.B)(i,n)),max:(0,m.B)(i,(0,m.B)(n,i))}}},{key:"getPadding",value:function(){return{left:this.paddingLeft||0,top:this.paddingTop||0,right:this.paddingRight||0,bottom:this.paddingBottom||0}}},{key:"getTicks",value:function(){return this.ticks}},{key:"getLabels",value:function(){var t=this.chart.data;return this.options.labels||(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels||[]}},{key:"beforeLayout",value:function(){this._cache={},this._dataLimitsCached=!1}},{key:"beforeUpdate",value:function(){(0,m.C)(this.options.beforeUpdate,[this])}},{key:"update",value:function(t,e,r){var n=this.options,i=n.beginAtZero,a=n.grace,o=n.ticks,s=o.sampleSize;this.beforeUpdate(),this.maxWidth=t,this.maxHeight=e,this._margins=r=Object.assign({left:0,right:0,top:0,bottom:0},r),this.ticks=null,this._labelSizes=null,this._gridLineItems=null,this._labelItems=null,this.beforeSetDimensions(),this.setDimensions(),this.afterSetDimensions(),this._maxLength=this.isHorizontal()?this.width+r.left+r.right:this.height+r.top+r.bottom,this._dataLimitsCached||(this.beforeDataLimits(),this.determineDataLimits(),this.afterDataLimits(),this._range=(0,m.D)(this,a,i),this._dataLimitsCached=!0),this.beforeBuildTicks(),this.ticks=this.buildTicks()||[],this.afterBuildTicks();var l=sn)return function(t,e,r,n){var i,a=0,o=r[0];for(i=0,n=Math.ceil(n);ii)return l}return Math.max(i,1)}(i,e,n);if(a>0){var c,h,f,d,p=a>1?Math.round((s-o)/(a-1)):null;for(G(e,l,u,(0,m.k)(p)?0:o-p,o),f=0,d=a-1;f=s||a<=1||!this.isHorizontal()){this.labelRotation=o;return}var u=this._getLabelSizes(),c=u.widest.width,h=u.highest.height,f=(0,m.E)(this.chart.width-c,0,this.maxWidth);c+6>(t=n.offset?this.maxWidth/a:f/(a-1))&&(t=f/(a-(n.offset?.5:1)),e=this.maxHeight-tt(n.grid)-i.padding-te(n.title,this.chart.options.font),r=Math.sqrt(c*c+h*h),l=Math.max(o,Math.min(s,l=(0,m.F)(Math.min(Math.asin((0,m.E)((u.highest.height+6)/t,-1,1)),Math.asin((0,m.E)(e/r,-1,1))-Math.asin((0,m.E)(h/r,-1,1))))))),this.labelRotation=l}},{key:"afterCalculateLabelRotation",value:function(){(0,m.C)(this.options.afterCalculateLabelRotation,[this])}},{key:"afterAutoSkip",value:function(){}},{key:"beforeFit",value:function(){(0,m.C)(this.options.beforeFit,[this])}},{key:"fit",value:function(){var t={width:0,height:0},e=this.chart,r=this.options,n=r.ticks,i=r.title,a=r.grid,o=this._isVisible(),s=this.isHorizontal();if(o){var l=te(i,e.options.font);if(s?(t.width=this.maxWidth,t.height=tt(a)+l):(t.height=this.maxHeight,t.width=tt(a)+l),n.display&&this.ticks.length){var u=this._getLabelSizes(),c=u.first,h=u.last,f=u.widest,d=u.highest,p=2*n.padding,v=(0,m.t)(this.labelRotation),g=Math.cos(v),y=Math.sin(v);if(s){var b=n.mirror?0:y*f.width+g*d.height;t.height=Math.min(this.maxHeight,t.height+b+p)}else{var _=n.mirror?0:g*f.width+y*d.height;t.width=Math.min(this.maxWidth,t.width+_+p)}this._calculatePadding(c,h,y,g)}}this._handleMargins(),s?(this.width=this._length=e.width-this._margins.left-this._margins.right,this.height=t.height):(this.width=t.width,this.height=this._length=e.height-this._margins.top-this._margins.bottom)}},{key:"_calculatePadding",value:function(t,e,r,n){var i=this.options,a=i.ticks,o=a.align,s=a.padding,l=i.position,u=0!==this.labelRotation,c="top"!==l&&"x"===this.axis;if(this.isHorizontal()){var h=this.getPixelForTick(0)-this.left,f=this.right-this.getPixelForTick(this.ticks.length-1),d=0,p=0;u?c?(d=n*t.width,p=r*e.height):(d=r*t.height,p=n*e.width):"start"===o?p=e.width:"end"===o?d=t.width:"inner"!==o&&(d=t.width/2,p=e.width/2),this.paddingLeft=Math.max((d-h+s)*this.width/(this.width-h),0),this.paddingRight=Math.max((p-f+s)*this.width/(this.width-f),0)}else{var v=e.height/2,g=t.height/2;"start"===o?(v=0,g=t.height):"end"===o&&(v=e.height,g=0),this.paddingTop=v+s,this.paddingBottom=g+s}}},{key:"_handleMargins",value:function(){this._margins&&(this._margins.left=Math.max(this.paddingLeft,this._margins.left),this._margins.top=Math.max(this.paddingTop,this._margins.top),this._margins.right=Math.max(this.paddingRight,this._margins.right),this._margins.bottom=Math.max(this.paddingBottom,this._margins.bottom))}},{key:"afterFit",value:function(){(0,m.C)(this.options.afterFit,[this])}},{key:"isHorizontal",value:function(){var t=this.options,e=t.axis,r=t.position;return"top"===r||"bottom"===r||"x"===e}},{key:"isFullSize",value:function(){return this.options.fullSize}},{key:"_convertTicksToLabels",value:function(t){var e,r;for(this.beforeTickToLabelConversion(),this.generateTickLabels(t),e=0,r=t.length;ee){for(r=0;re.length-1?null:this.getPixelForValue(e[t].value)}},{key:"getPixelForDecimal",value:function(t){this._reversePixels&&(t=1-t);var e=this._startPixel+t*this._length;return(0,m.I)(this._alignToPixels?(0,m.J)(this.chart,e,0):e)}},{key:"getDecimalForPixel",value:function(t){var e=(t-this._startPixel)/this._length;return this._reversePixels?1-e:e}},{key:"getBasePixel",value:function(){return this.getPixelForValue(this.getBaseValue())}},{key:"getBaseValue",value:function(){var t=this.min,e=this.max;return t<0&&e<0?e:t>0&&e>0?t:0}},{key:"getContext",value:function(t){var e,r=this.ticks||[];if(t>=0&&to*n?o/r:s/n:s*n0}},{key:"_computeGridLineItems",value:function(t){var e,r,n,i,a,o,s,l,u,c,h,f,d=this.axis,p=this.chart,v=this.options,g=v.grid,y=v.position,b=g.offset,_=this.isHorizontal(),x=this.ticks.length+(b?1:0),k=tt(g),w=[],M=g.setContext(this.getContext()),S=M.drawBorder?M.borderWidth:0,O=S/2,A=function(t){return(0,m.J)(p,t,S)};if("top"===y)e=A(this.bottom),o=this.bottom-k,l=e-O,c=A(t.top)+O,f=t.bottom;else if("bottom"===y)e=A(this.top),c=t.top,f=A(t.bottom)-O,o=e+O,l=this.top+k;else if("left"===y)e=A(this.right),a=this.right-k,s=e-O,u=A(t.left)+O,h=t.right;else if("right"===y)e=A(this.left),u=t.left,h=A(t.right)-O,a=e+O,s=this.left+k;else if("x"===d){if("center"===y)e=A((t.top+t.bottom)/2+.5);else if((0,m.i)(y)){var E=Object.keys(y)[0],C=y[E];e=A(this.chart.scales[E].getPixelForValue(C))}c=t.top,f=t.bottom,l=(o=e+O)+k}else if("y"===d){if("center"===y)e=A((t.left+t.right)/2);else if((0,m.i)(y)){var P=Object.keys(y)[0],D=y[P];e=A(this.chart.scales[P].getPixelForValue(D))}s=(a=e-O)-k,u=t.left,h=t.right}var j=(0,m.v)(v.ticks.maxTicksLimit,x),T=Math.max(1,Math.ceil(x/j));for(r=0;rs+1e-6)))return l}(this,r,b))&&(i=(0,m.J)(p,n,I),_?a=s=u=h=i:o=l=c=f=i,w.push({tx1:a,ty1:o,tx2:s,ty2:l,x1:u,y1:c,x2:h,y2:f,width:I,color:L,borderDash:B,borderDashOffset:R,tickWidth:N,tickColor:V,tickBorderDash:z,tickBorderDashOffset:W}))}return this._ticksLength=x,this._borderValue=e,w}},{key:"_computeLabelItems",value:function(t){var e,r,n,i,a,o,s,l,u,c,h,f=this.axis,d=this.options,p=d.position,v=d.ticks,g=this.isHorizontal(),y=this.ticks,b=v.align,_=v.crossAlign,x=v.padding,k=v.mirror,w=tt(d.grid),M=w+x,S=k?-x:M,O=-(0,m.t)(this.labelRotation),A=[],E="middle";if("top"===p)a=this.bottom-S,o=this._getXAxisLabelAlignment();else if("bottom"===p)a=this.top+S,o=this._getXAxisLabelAlignment();else if("left"===p){var C=this._getYAxisLabelAlignment(w);o=C.textAlign,i=C.x}else if("right"===p){var P=this._getYAxisLabelAlignment(w);o=P.textAlign,i=P.x}else if("x"===f){if("center"===p)a=(t.top+t.bottom)/2+M;else if((0,m.i)(p)){var D=Object.keys(p)[0],j=p[D];a=this.chart.scales[D].getPixelForValue(j)+M}o=this._getXAxisLabelAlignment()}else if("y"===f){if("center"===p)i=(t.left+t.right)/2-M;else if((0,m.i)(p)){var T=Object.keys(p)[0],F=p[T];i=this.chart.scales[T].getPixelForValue(F)}o=this._getYAxisLabelAlignment(w).textAlign}"y"===f&&("start"===b?E="top":"end"===b&&(E="bottom"));var I=this._getLabelSizes();for(e=0,r=y.length;e=0?e.setContext(this.getContext(r)).lineWidth:0}},{key:"drawGrid",value:function(t){var e,r,n=this.options.grid,i=this.ctx,a=this._gridLineItems||(this._gridLineItems=this._computeGridLineItems(t)),o=function(t,e,r){r.width&&r.color&&(i.save(),i.lineWidth=r.width,i.strokeStyle=r.color,i.setLineDash(r.borderDash||[]),i.lineDashOffset=r.borderDashOffset,i.beginPath(),i.moveTo(t.x,t.y),i.lineTo(e.x,e.y),i.stroke(),i.restore())};if(n.display)for(e=0,r=a.length;e0&&this.getParsed(e-1),k=e;k0&&Math.abs(M[d]-x[d])>b,y&&(S.parsed=M,S.raw=u.data[k]),f&&(S.options=h||this.resolveDataElementOptions(k,w.active?"active":n)),_||this.updateElement(w,k,S,n),x=M}this.updateSharedOptions(h,n,c)}},{key:"getMaxOverflow",value:function(){var t=this._cachedMeta,e=t.data||[];if(!this.options.showLine){for(var r=0,n=e.length-1;n>=0;--n)r=Math.max(r,e[n].size(this.resolveDataElementOptions(n))/2);return r>0&&r}var i=t.dataset,a=i.options&&i.options.borderWidth||0;return e.length?Math.max(a,e[0].size(this.resolveDataElementOptions(0)),e[e.length-1].size(this.resolveDataElementOptions(e.length-1)))/2:a}}]),r}(I);ta.id="scatter",ta.defaults={datasetElementType:!1,dataElementType:"point",showLine:!1,fill:!1},ta.overrides={interaction:{mode:"point"},plugins:{tooltip:{callbacks:{title:function(){return""},label:function(t){return"("+t.label+", "+t.formattedValue+")"}}}},scales:{x:{type:"linear"},y:{type:"linear"}}};var to=Object.freeze({__proto__:null,BarController:z,BubbleController:W,DoughnutController:H,LineController:U,PolarAreaController:K,PieController:Y,RadarController:X,ScatterController:ta});function ts(){throw Error("This method is not implemented: Check that a complete date adapter is provided.")}var tl=function(){function t(e){(0,a._)(this,t),this.options=e||{}}return(0,o._)(t,[{key:"init",value:function(t){}},{key:"formats",value:function(){return ts()}},{key:"parse",value:function(t,e){return ts()}},{key:"format",value:function(t,e){return ts()}},{key:"add",value:function(t,e,r){return ts()}},{key:"diff",value:function(t,e,r){return ts()}},{key:"startOf",value:function(t,e,r){return ts()}},{key:"endOf",value:function(t,e){return ts()}}]),t}();tl.override=function(t){Object.assign(tl.prototype,t)};var tu={_date:tl};function tc(t,e,r,n,i){for(var a=t.getSortedVisibleDatasetMetas(),o=r[e],s=0,l=a.length;s0){var l=s[0].datasetIndex,u=t.getDatasetMeta(l).data;s=[];for(var c=0;c3&&void 0!==arguments[3]?arguments[3]:[""],i={$shared:!0},a=tJ(this._resolverCache,t,n),o=a.resolver,s=a.subPrefixes,l=o;if(function(t,e){var r=(0,m.ab)(t),n=r.isScriptable,i=r.isIndexable,a=!0,o=!1,s=void 0;try{for(var l,u=e[Symbol.iterator]();!(a=(l=u.next()).done);a=!0){var c=l.value,h=n(c),f=i(c),d=(f||h)&&t[c];if(h&&((0,m.a8)(d)||tZ(d))||f&&(0,m.b)(d))return!0}}catch(t){o=!0,s=t}finally{try{a||null==u.return||u.return()}finally{if(o)throw s}}return!1}(o,e)){i.$shared=!1,r=(0,m.a8)(r)?r():r;var u=this.createResolver(t,r,s);l=(0,m.a9)(o,r,u)}var c=!0,h=!1,f=void 0;try{for(var d,p=e[Symbol.iterator]();!(c=(d=p.next()).done);c=!0){var v=d.value;i[v]=l[v]}}catch(t){h=!0,f=t}finally{try{c||null==p.return||p.return()}finally{if(h)throw f}}return i}},{key:"createResolver",value:function(t,e){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[""],n=arguments.length>3?arguments[3]:void 0,i=tJ(this._resolverCache,t,r).resolver;return(0,m.i)(e)?(0,m.a9)(i,e,void 0,n):i}}]),t}();function tJ(t,e,r){var n=t.get(e);n||(n=new Map,t.set(e,n));var i=r.join(),a=n.get(i);return a||(a={resolver:(0,m.aa)(e,r),subPrefixes:r.filter(function(t){return!t.toLowerCase().includes("hover")})},n.set(i,a)),a}var tZ=function(t){return(0,m.i)(t)&&Object.getOwnPropertyNames(t).reduce(function(e,r){return e||(0,m.a8)(t[r])},!1)},t0=["top","bottom","left","right","chartArea"];function t1(t,e){return"top"===t||"bottom"===t||-1===t0.indexOf(t)&&"x"===e}function t2(t,e){return function(r,n){return r[t]===n[t]?r[e]-n[e]:r[t]-n[t]}}function t5(t){var e=t.chart,r=e.options.animation;e.notifyPlugins("afterRender"),(0,m.C)(r&&r.onComplete,[t],e)}function t3(t){var e=t.chart,r=e.options.animation;(0,m.C)(r&&r.onProgress,[t],e)}function t6(t){return(0,m.a6)()&&"string"==typeof t?t=document.getElementById(t):t&&t.length&&(t=t[0]),t&&t.canvas&&(t=t.canvas),t}var t8={},t4=function(t){var e=t6(t);return Object.values(t8).filter(function(t){return t.canvas===e}).pop()},t7=function(){function t(e,r){var n=this;(0,a._)(this,t);var i=this.config=new tG(r),o=t6(e),s=t4(o);if(s)throw Error("Canvas is already in use. Chart with ID '"+s.id+"' must be destroyed before the canvas with ID '"+s.canvas.id+"' can be reused.");var l=i.createResolver(i.chartOptionScopes(),this.getContext());this.platform=new(i.platform||tz(o)),this.platform.updateConfig(i);var u=this.platform.acquireContext(o,l.aspectRatio),c=u&&u.canvas,h=c&&c.height,f=c&&c.width;if(this.id=(0,m.ad)(),this.ctx=u,this.canvas=c,this.width=f,this.height=h,this._options=l,this._aspectRatio=this.aspectRatio,this._layers=[],this._metasets=[],this._stacks=void 0,this.boxes=[],this.currentDevicePixelRatio=void 0,this.chartArea=void 0,this._active=[],this._lastEvent=void 0,this._listeners={},this._responsiveListeners=void 0,this._sortedMetasets=[],this.scales={},this._plugins=new tW,this.$proxies={},this._hiddenIndices={},this.attached=!1,this._animationsDisabled=void 0,this.$context=void 0,this._doResize=(0,m.ae)(function(t){return n.update(t)},l.resizeDelay||0),this._dataChanges=[],t8[this.id]=this,!u||!c){console.error("Failed to create chart: can't acquire context from the given item");return}b.listen(this,"complete",t5),b.listen(this,"progress",t3),this._initialize(),this.attached&&this.update()}return(0,o._)(t,[{key:"aspectRatio",get:function(){var t=this.options,e=t.aspectRatio,r=t.maintainAspectRatio,n=this.width,i=this.height,a=this._aspectRatio;return(0,m.k)(e)?r&&a?a:i?n/i:null:e}},{key:"data",get:function(){return this.config.data},set:function(t){this.config.data=t}},{key:"options",get:function(){return this._options},set:function(t){this.config.options=t}},{key:"_initialize",value:function(){return this.notifyPlugins("beforeInit"),this.options.responsive?this.resize():(0,m.af)(this,this.options.devicePixelRatio),this.bindEvents(),this.notifyPlugins("afterInit"),this}},{key:"clear",value:function(){return(0,m.ag)(this.canvas,this.ctx),this}},{key:"stop",value:function(){return b.stop(this),this}},{key:"resize",value:function(t,e){b.running(this)?this._resizeBeforeDraw={width:t,height:e}:this._resize(t,e)}},{key:"_resize",value:function(t,e){var r=this.options,n=this.canvas,i=r.maintainAspectRatio&&this.aspectRatio,a=this.platform.getMaximumSize(n,t,e,i),o=r.devicePixelRatio||this.platform.getDevicePixelRatio(),s=this.width?"resize":"attach";this.width=a.width,this.height=a.height,this._aspectRatio=this.aspectRatio,(0,m.af)(this,o,!0)&&(this.notifyPlugins("resize",{size:a}),(0,m.C)(r.onResize,[this,a],this),this.attached&&this._doResize(s)&&this.render())}},{key:"ensureScalesHaveIDs",value:function(){var t=this.options.scales||{};(0,m.Q)(t,function(t,e){t.id=e})}},{key:"buildOrUpdateScales",value:function(){var t=this,e=this.options,r=e.scales,n=this.scales,i=Object.keys(n).reduce(function(t,e){return t[e]=!1,t},{}),a=[];r&&(a=a.concat(Object.keys(r).map(function(t){var e=r[t],n=tU(t,e),i="r"===n,a="x"===n;return{options:e,dposition:i?"chartArea":a?"bottom":"left",dtype:i?"radialLinear":a?"category":"linear"}}))),(0,m.Q)(a,function(r){var a=r.options,o=a.id,s=tU(o,a),l=(0,m.v)(a.type,r.dtype);(void 0===a.position||t1(a.position,s)!==t1(r.dposition))&&(a.position=r.dposition),i[o]=!0;var u=null;o in n&&n[o].type===l?u=n[o]:n[(u=new(ti.getScale(l))({id:o,type:l,ctx:t.ctx,chart:t})).id]=u,u.init(a,e)}),(0,m.Q)(i,function(t,e){t||delete n[e]}),(0,m.Q)(n,function(e){tM.configure(t,e,e.options),tM.addBox(t,e)})}},{key:"_updateMetasets",value:function(){var t=this._metasets,e=this.data.datasets.length,r=t.length;if(t.sort(function(t,e){return t.index-e.index}),r>e){for(var n=e;nr.length&&delete this._stacks,e.forEach(function(e,n){0===r.filter(function(t){return t===e._dataset}).length&&t._destroyDatasetMeta(n)})}},{key:"buildOrUpdateControllers",value:function(){var t,e,r=[],n=this.data.datasets;for(this._removeUnreferencedMetasets(),t=0,e=n.length;t=e){var h=t[u];delete t[u],(r>0||c>e)&&(t[c+r]=h)}}}catch(t){a=!0,o=t}finally{try{i||null==l.return||l.return()}finally{if(a)throw o}}}(t,u,h)}}catch(t){n=!0,i=t}finally{try{r||null==o.return||o.return()}finally{if(n)throw i}}}},{key:"_getUniformDataChanges",value:function(){var t=this._dataChanges;if(t&&t.length){this._dataChanges=[];for(var e=this.data.datasets.length,r=function(e){return new Set(t.filter(function(t){return t[0]===e}).map(function(t,e){return e+","+t.splice(1).join(",")}))},n=r(0),i=1;i=0;--e)this._drawDataset(t[e]);this.notifyPlugins("afterDatasetsDraw")}}},{key:"_drawDataset",value:function(t){var e=this.ctx,r=t._clip,n=!r.disabled,i=this.chartArea,a={meta:t,index:t.index,cancelable:!0};!1!==this.notifyPlugins("beforeDatasetDraw",a)&&(n&&(0,m.L)(e,{left:!1===r.left?0:i.left-r.left,right:!1===r.right?this.width:i.right+r.right,top:!1===r.top?0:i.top-r.top,bottom:!1===r.bottom?this.height:i.bottom+r.bottom}),t.controller.draw(),n&&(0,m.N)(e),a.cancelable=!1,this.notifyPlugins("afterDatasetDraw",a))}},{key:"isPointInArea",value:function(t){return(0,m.$)(t,this.chartArea,this._minPadding)}},{key:"getElementsAtEventForMode",value:function(t,e,r,n){var i=tp.modes[e];return"function"==typeof i?i(this,t,r,n):[]}},{key:"getDatasetMeta",value:function(t){var e=this.data.datasets[t],r=this._metasets,n=r.filter(function(t){return t&&t._dataset===e}).pop();return n||(n={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null,order:e&&e.order||0,index:t,_dataset:e,_parsed:[],_sorted:!1},r.push(n)),n}},{key:"getContext",value:function(){return this.$context||(this.$context=(0,m.h)(null,{chart:this,type:"chart"}))}},{key:"getVisibleDatasetCount",value:function(){return this.getSortedVisibleDatasetMetas().length}},{key:"isDatasetVisible",value:function(t){var e=this.data.datasets[t];if(!e)return!1;var r=this.getDatasetMeta(t);return"boolean"==typeof r.hidden?!r.hidden:!e.hidden}},{key:"setDatasetVisibility",value:function(t,e){this.getDatasetMeta(t).hidden=!e}},{key:"toggleDataVisibility",value:function(t){this._hiddenIndices[t]=!this._hiddenIndices[t]}},{key:"getDataVisibility",value:function(t){return!this._hiddenIndices[t]}},{key:"_updateVisibility",value:function(t,e,r){var n=r?"show":"hide",i=this.getDatasetMeta(t),a=i.controller._resolveAnimations(void 0,n);(0,m.j)(e)?(i.data[e].hidden=!r,this.update()):(this.setDatasetVisibility(t,r),a.update(i,{visible:r}),this.update(function(e){return e.datasetIndex===t?n:void 0}))}},{key:"hide",value:function(t,e){this._updateVisibility(t,e,!1)}},{key:"show",value:function(t,e){this._updateVisibility(t,e,!0)}},{key:"_destroyDatasetMeta",value:function(t){var e=this._metasets[t];e&&e.controller&&e.controller._destroy(),delete this._metasets[t]}},{key:"_stop",value:function(){var t,e;for(this.stop(),b.remove(this),t=0,e=this.data.datasets.length;ti?(u=i/l,t.arc(a,o,l,r+u,n-u,!0)):t.arc(a,o,i,r+m.H,n-m.H),t.closePath(),t.clip()}function ee(t,e,r,n){return{x:r+t*Math.cos(e),y:n+t*Math.sin(e)}}function er(t,e,r,n,i,a){var o,s,l,u,c,h,f=e.x,d=e.y,p=e.startAngle,v=e.pixelMargin,g=e.innerRadius,y=Math.max(e.outerRadius+n+r-v,0),b=g>0?g+n+r+v:0,_=0,x=i-p;if(n){var k=y>0?y-n:0,w=((g>0?g-n:0)+k)/2;_=(x-(0!==w?x*w/(w+n):x))/2}var M=Math.max(.001,x*y-r/m.P)/y,S=(x-M)/2,O=p+S+_,A=i-S-_,E=(o=A-O,s=e.options.borderRadius,l=(0,m.al)(s,["outerStart","outerEnd","innerStart","innerEnd"]),c=Math.min(u=(y-b)/2,o*b/2),{outerStart:(h=function(t){var e=(y-Math.min(u,t))*o/2;return(0,m.E)(t,0,Math.min(u,e))})(l.outerStart),outerEnd:h(l.outerEnd),innerStart:(0,m.E)(l.innerStart,0,c),innerEnd:(0,m.E)(l.innerEnd,0,c)}),C=E.outerStart,P=E.outerEnd,D=E.innerStart,j=E.innerEnd,T=y-C,F=y-P,I=O+C/T,L=A-P/F,B=b+D,R=b+j,N=O+D/B,V=A-j/R;if(t.beginPath(),a){if(t.arc(f,d,y,I,L),P>0){var z=ee(F,L,f,d);t.arc(z.x,z.y,P,L,A+m.H)}var W=ee(R,A,f,d);if(t.lineTo(W.x,W.y),j>0){var H=ee(R,V,f,d);t.arc(H.x,H.y,j,A+m.H,V+Math.PI)}if(t.arc(f,d,b,A-j/b,O+D/b,!0),D>0){var U=ee(B,N,f,d);t.arc(U.x,U.y,D,N+Math.PI,O-m.H)}var K=ee(T,O,f,d);if(t.lineTo(K.x,K.y),C>0){var Y=ee(T,I,f,d);t.arc(Y.x,Y.y,C,O-m.H,I)}}else{t.moveTo(f,d);var X=Math.cos(I)*y+f,q=Math.sin(I)*y+d;t.lineTo(X,q);var $=Math.cos(L)*y+f,Q=Math.sin(L)*y+d;t.lineTo($,Q)}t.closePath()}Object.defineProperties(t7,{defaults:{enumerable:!0,value:m.d},instances:{enumerable:!0,value:t8},overrides:{enumerable:!0,value:m.U},registry:{enumerable:!0,value:ti},version:{enumerable:!0,value:"3.9.1"},getChart:{enumerable:!0,value:t4},register:{enumerable:!0,value:function(){for(var t=arguments.length,e=Array(t),r=0;r=m.T||(0,m.p)(a,l,u),v=(0,m.ak)(o,c+d,h+d);return p&&v}},{key:"getCenterPoint",value:function(t){var e=this.getProps(["x","y","startAngle","endAngle","innerRadius","outerRadius","circumference"],t),r=e.x,n=e.y,i=e.startAngle,a=e.endAngle,o=e.innerRadius,s=e.outerRadius,l=this.options,u=l.offset,c=l.spacing,h=(i+a)/2,f=(o+s+c+u)/2;return{x:r+Math.cos(h)*f,y:n+Math.sin(h)*f}}},{key:"tooltipPosition",value:function(t){return this.getCenterPoint(t)}},{key:"draw",value:function(t){var e=this.options,r=this.circumference,n=(e.offset||0)/2,i=(e.spacing||0)/2,a=e.circular;if(this.pixelMargin="inner"===e.borderAlign?.33:0,this.fullCircles=r>m.T?Math.floor(r/m.T):0,0!==r&&!(this.innerRadius<0)&&!(this.outerRadius<0)){t.save();var o,s,l,u,c,h=0;if(n){h=n/2;var f=(this.startAngle+this.endAngle)/2;t.translate(Math.cos(f)*h,Math.sin(f)*h),this.circumference>=m.P&&(h=n)}t.fillStyle=e.backgroundColor,t.strokeStyle=e.borderColor;var d=function(t,e,r,n,i){var a=e.fullCircles,o=e.startAngle,s=e.circumference,l=e.endAngle;if(a){er(t,e,r,n,o+m.T,i);for(var u=0;u2&&void 0!==arguments[2]?arguments[2]:e;t.lineCap=(0,m.v)(r.borderCapStyle,e.borderCapStyle),t.setLineDash((0,m.v)(r.borderDash,e.borderDash)),t.lineDashOffset=(0,m.v)(r.borderDashOffset,e.borderDashOffset),t.lineJoin=(0,m.v)(r.borderJoinStyle,e.borderJoinStyle),t.lineWidth=(0,m.v)(r.borderWidth,e.borderWidth),t.strokeStyle=(0,m.v)(r.borderColor,e.borderColor)}function ea(t,e,r){t.lineTo(r.x,r.y)}function eo(t,e){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},n=t.length,i=r.start,a=void 0===i?0:i,o=r.end,s=void 0===o?n-1:o,l=e.start,u=e.end,c=Math.max(a,l),h=Math.min(s,u);return{count:n,start:c,loop:e.loop,ilen:hu&&s>u)?n+h-c:h-c}}function es(t,e,r,n){var i,a,o,s=e.points,l=e.options,u=eo(s,r,n),c=u.count,h=u.start,f=u.loop,d=u.ilen,p=l.stepped?m.as:l.tension||"monotone"===l.cubicInterpolationMode?m.at:ea,v=n||{},g=v.move,y=void 0===g||g,b=v.reverse;for(i=0;i<=d;++i)(a=s[(h+(b?d-i:i))%c]).skip||(y?(t.moveTo(a.x,a.y),y=!1):p(t,o,a,b,l.stepped),o=a);return f&&p(t,o,a=s[(h+(b?d:0))%c],b,l.stepped),!!f}function el(t,e,r,n){var i,a,o,s,l,u,c=e.points,h=eo(c,r,n),f=h.count,d=h.start,p=h.ilen,v=n||{},g=v.move,y=v.reverse,m=0,b=0,_=function(t){return(d+(y?p-t:t))%f},x=function(){s!==l&&(t.lineTo(m,l),t.lineTo(m,s),t.lineTo(m,u))};for((void 0===g||g)&&(a=c[_(0)],t.moveTo(a.x,a.y)),i=0;i<=p;++i)if(!(a=c[_(i)]).skip){var k=a.x,w=a.y,M=0|k;M===o?(wl&&(l=w),m=(b*m+k)/++b):(x(),t.lineTo(k,w),o=M,b=0,s=l=w),u=w}x()}function eu(t){var e=t.options,r=e.borderDash&&e.borderDash.length;return t._decimated||t._loop||e.tension||"monotone"===e.cubicInterpolationMode||e.stepped||r?es:el}en.id="arc",en.defaults={borderAlign:"center",borderColor:"#fff",borderJoinStyle:void 0,borderRadius:0,borderWidth:2,offset:0,spacing:0,angle:void 0,circular:!0},en.defaultRoutes={backgroundColor:"backgroundColor"};var ec="function"==typeof Path2D,eh=function(t){(0,c._)(r,t);var e=(0,y._)(r);function r(t){var n;return(0,a._)(this,r),(n=e.call(this)).animated=!0,n.options=void 0,n._chart=void 0,n._loop=void 0,n._fullLoop=void 0,n._path=void 0,n._points=void 0,n._segments=void 0,n._decimated=!1,n._pointsUpdated=!1,n._datasetIndex=void 0,t&&Object.assign((0,i._)(n),t),n}return(0,o._)(r,[{key:"updateControlPoints",value:function(t,e){var r=this.options;if((r.tension||"monotone"===r.cubicInterpolationMode)&&!r.stepped&&!this._pointsUpdated){var n=r.spanGaps?this._loop:this._fullLoop;(0,m.am)(this._points,r,t,n,e),this._pointsUpdated=!0}}},{key:"points",get:function(){return this._points},set:function(t){this._points=t,delete this._segments,delete this._path,this._pointsUpdated=!1}},{key:"segments",get:function(){return this._segments||(this._segments=(0,m.an)(this,this.options.segment))}},{key:"first",value:function(){var t=this.segments,e=this.points;return t.length&&e[t[0].start]}},{key:"last",value:function(){var t=this.segments,e=this.points,r=t.length;return r&&e[t[r-1].end]}},{key:"interpolate",value:function(t,e){var r,n,i=this.options,a=t[e],o=this.points,s=(0,m.ao)(this,{property:e,start:a,end:a});if(s.length){var l=[],u=i.stepped?m.ap:i.tension||"monotone"===i.cubicInterpolationMode?m.aq:m.ar;for(r=0,n=s.length;r2&&void 0!==arguments[2]?arguments[2]:{},n=t.x!==r.x?-e:0,i=t.y!==r.y?-e:0,a=(t.x+t.w!==r.x+r.w?e:0)-n,o=(t.y+t.h!==r.y+r.h?e:0)-i;return{x:t.x+n,y:t.y+i,w:t.w+a,h:t.h+o,radius:t.radius}}ed.id="point",ed.defaults={borderWidth:1,hitRadius:1,hoverBorderWidth:1,hoverRadius:4,pointStyle:"circle",radius:3,rotation:0},ed.defaultRoutes={backgroundColor:"backgroundColor",borderColor:"borderColor"};var eb=function(t){(0,c._)(r,t);var e=(0,y._)(r);function r(t){var n;return(0,a._)(this,r),(n=e.call(this)).options=void 0,n.horizontal=void 0,n.base=void 0,n.width=void 0,n.height=void 0,n.inflateAmount=void 0,t&&Object.assign((0,i._)(n),t),n}return(0,o._)(r,[{key:"draw",value:function(t){var e,r,n,i,a,o,s,l,u,c,h,f,d,p,v,g,y,b,_,x=this.inflateAmount,k=this.options,w=k.borderColor,M=k.backgroundColor,S=(r=(e=ep(this)).right-e.left,n=e.bottom-e.top,i=r/2,a=n/2,o=this.options.borderWidth,s=this.borderSkipped,l=(0,m.aw)(o),u={t:ev(s.top,l.top,0,a),r:ev(s.right,l.right,0,i),b:ev(s.bottom,l.bottom,0,a),l:ev(s.left,l.left,0,i)},c=r/2,h=n/2,f=this.getProps(["enableBorderRadius"]).enableBorderRadius,d=this.options.borderRadius,p=(0,m.ax)(d),v=Math.min(c,h),g=this.borderSkipped,b={topLeft:ev(!(y=f||(0,m.i)(d))||g.top||g.left,p.topLeft,0,v),topRight:ev(!y||g.top||g.right,p.topRight,0,v),bottomLeft:ev(!y||g.bottom||g.left,p.bottomLeft,0,v),bottomRight:ev(!y||g.bottom||g.right,p.bottomRight,0,v)},{outer:{x:e.left,y:e.top,w:r,h:n,radius:b},inner:{x:e.left+u.l,y:e.top+u.t,w:r-u.l-u.r,h:n-u.t-u.b,radius:{topLeft:Math.max(0,b.topLeft-Math.max(u.t,u.l)),topRight:Math.max(0,b.topRight-Math.max(u.t,u.r)),bottomLeft:Math.max(0,b.bottomLeft-Math.max(u.b,u.l)),bottomRight:Math.max(0,b.bottomRight-Math.max(u.b,u.r))}}}),O=S.inner,A=S.outer,E=(_=A.radius).topLeft||_.topRight||_.bottomLeft||_.bottomRight?m.av:ey;t.save(),(A.w!==O.w||A.h!==O.h)&&(t.beginPath(),E(t,em(A,x,O)),t.clip(),E(t,em(O,-x,A)),t.fillStyle=w,t.fill("evenodd")),t.beginPath(),E(t,em(O,x)),t.fillStyle=M,t.fill(),t.restore()}},{key:"inRange",value:function(t,e,r){return eg(this,t,e,r)}},{key:"inXRange",value:function(t,e){return eg(this,t,null,e)}},{key:"inYRange",value:function(t,e){return eg(this,null,t,e)}},{key:"getCenterPoint",value:function(t){var e=this.getProps(["x","y","base","horizontal"],t),r=e.x,n=e.y,i=e.base,a=e.horizontal;return{x:a?(r+i)/2:r,y:a?n:(n+i)/2}}},{key:"getRange",value:function(t){return"x"===t?this.width/2:this.height/2}}]),r}((0,g._)(q));eb.id="bar",eb.defaults={borderSkipped:"start",borderWidth:0,borderRadius:0,inflateAmount:"auto",pointStyle:void 0},eb.defaultRoutes={backgroundColor:"backgroundColor",borderColor:"borderColor"};var e_=Object.freeze({__proto__:null,ArcElement:en,LineElement:eh,PointElement:ed,BarElement:eb});function ex(t){if(t._decimated){var e=t._data;delete t._decimated,delete t._data,Object.defineProperty(t,"data",{value:e})}}function ek(t){t.data.datasets.forEach(function(t){ex(t)})}var ew={id:"decimation",defaults:{algorithm:"min-max",enabled:!1},beforeElementsUpdate:function(t,e,r){if(!r.enabled){ek(t);return}var n=t.width;t.data.datasets.forEach(function(e,i){var a,o=e._data,s=e.indexAxis,l=t.getDatasetMeta(i),u=o||e.data;if("y"!==(0,m.a)([s,t.options.indexAxis])&&l.controller.supportsDecimation){var c=t.scales[l.xAxisID];if(("linear"===c.type||"time"===c.type)&&!t.options.parsing){var d,p,v,g,y,b,_,x,k,w=(p=u.length,v=0,b=(y=(g=l.iScale).getUserBounds()).min,_=y.max,x=y.minDefined,k=y.maxDefined,x&&(v=(0,m.E)((0,m.Z)(u,g.axis,b).lo,0,p-1)),d=k?(0,m.E)((0,m.Z)(u,g.axis,_).hi+1,v,p)-v:p-v,{start:v,count:d}),M=w.start,S=w.count;if(S<=(r.threshold||4*n)){ex(e);return}switch((0,m.k)(o)&&(e._data=u,delete e.data,Object.defineProperty(e,"data",{configurable:!0,enumerable:!0,get:function(){return this._decimated},set:function(t){this._data=t}})),r.algorithm){case"lttb":a=function(t,e,r,n,i){var a,o,s,l,u,c=i.samples||n;if(c>=r)return t.slice(e,e+r);var h=[],f=(r-2)/(c-2),d=0,p=e+r-1,v=e;for(a=0,h[d++]=t[v];as&&(s=l,o=t[m],u=m);h[d++]=o,v=u}return h[d++]=t[p],h}(u,M,S,n,r);break;case"min-max":a=function(t,e,r,n){var i,a,o,s,l,u,c,d,p,v,g=0,y=0,b=[],_=t[e].x,x=t[e+r-1].x-_;for(i=e;iv&&(v=s,c=i),g=(y*g+a.x)/++y;else{var w=i-1;if(!(0,m.k)(u)&&!(0,m.k)(c)){var M=Math.min(u,c),S=Math.max(u,c);M!==d&&M!==w&&b.push((0,f._)((0,h._)({},t[M]),{x:g})),S!==d&&S!==w&&b.push((0,f._)((0,h._)({},t[S]),{x:g}))}i>0&&w!==d&&b.push(t[w]),b.push(a),l=k,y=0,p=v=s,u=c=d=i}}return b}(u,M,S,n);break;default:throw Error("Unsupported decimation algorithm '".concat(r.algorithm,"'"))}e._decimated=a}}})},destroy:function(t){ek(t)}};function eM(t,e,r,n){if(!n){var i=e[t],a=r[t];return"angle"===t&&(i=(0,m.az)(i),a=(0,m.az)(a)),{property:t,start:i,end:a}}}function eS(t,e,r){for(;e>t;e--){var n=r[e];if(!isNaN(n.x)&&!isNaN(n.y))break}return e}function eO(t,e,r,n){return t&&e?n(t[r],e[r]):t?t[r]:e?e[r]:0}function eA(t,e){var r,n,i,a,o,s,l,u=[],c=!1;return(0,m.b)(t)?(c=!0,u=t):(i=void 0===(n=(r=t||{}).x)?null:n,o=void 0===(a=r.y)?null:a,s=e.points,l=[],e.segments.forEach(function(t){var e=t.start,r=t.end;r=eS(e,r,s);var n=s[e],a=s[r];null!==o?(l.push({x:n.x,y:o}),l.push({x:a.x,y:o})):null!==i&&(l.push({x:i,y:n.y}),l.push({x:i,y:a.y}))}),u=l),u.length?new eh({points:u,options:{tension:0},_loop:c,_fullLoop:c}):null}function eE(t){return t&&!1!==t.fill}var eC=function(){function t(e){(0,a._)(this,t),this.x=e.x,this.y=e.y,this.radius=e.radius}return(0,o._)(t,[{key:"pathSegment",value:function(t,e,r){var n=this.x,i=this.y,a=this.radius;return e=e||{start:0,end:m.T},t.arc(n,i,a,e.end,e.start,!0),!r.bounds}},{key:"interpolate",value:function(t){var e=this.x,r=this.y,n=this.radius,i=t.angle;return{x:e+Math.cos(i)*n,y:r+Math.sin(i)*n,angle:i}}}]),t}();function eP(t,e,r){var n,i,a,o,s,l,u,c,h=function(t){var e,r=t.chart,n=t.fill,i=t.line;if((0,m.g)(n))return(e=r.getDatasetMeta(n))&&r.isDatasetVisible(n)?e.dataset:null;if("stack"===n)return function(t){var e=t.scale,r=t.index,n=t.line,i=[],a=n.segments,o=n.points,s=function(t,e){for(var r=[],n=t.getMatchingVisibleMetas("line"),i=0;i=r)&&i):["origin","start","end","stack","shape"].indexOf(a)>=0&&a}(a,i,s),chart:t,axis:n.controller.options.indexAxis,scale:n.vScale,line:a}),n.$filler=o,l.push(o);for(i=0;i=0;--o){var s=i[o].$filler;s&&(s.line.updateControlPoints(a,s.axis),n&&s.fill&&eP(t.ctx,s,a))}},beforeDatasetsDraw:function(t,e,r){if("beforeDatasetsDraw"===r.drawTime)for(var n=t.getSortedVisibleDatasetMetas(),i=n.length-1;i>=0;--i){var a=n[i].$filler;eE(a)&&eP(t.ctx,a,t.chartArea)}},beforeDatasetDraw:function(t,e,r){var n=e.meta.$filler;eE(n)&&"beforeDatasetDraw"===r.drawTime&&eP(t.ctx,n,t.chartArea)},defaults:{propagate:!0,drawTime:"beforeDatasetDraw"}},eI=function(t,e){var r=t.boxHeight,n=void 0===r?e:r,i=t.boxWidth,a=void 0===i?e:i;return t.usePointStyle&&(n=Math.min(n,e),a=t.pointStyleWidth||Math.min(a,e)),{boxWidth:a,boxHeight:n,itemHeight:Math.max(e,n)}},eL=function(t){(0,c._)(r,t);var e=(0,y._)(r);function r(t){var n;return(0,a._)(this,r),(n=e.call(this))._added=!1,n.legendHitBoxes=[],n._hoveredItem=null,n.doughnutMode=!1,n.chart=t.chart,n.options=t.options,n.ctx=t.ctx,n.legendItems=void 0,n.columnSizes=void 0,n.lineWidths=void 0,n.maxHeight=void 0,n.maxWidth=void 0,n.top=void 0,n.bottom=void 0,n.left=void 0,n.right=void 0,n.height=void 0,n.width=void 0,n._margins=void 0,n.position=void 0,n.weight=void 0,n.fullSize=void 0,n}return(0,o._)(r,[{key:"update",value:function(t,e,r){this.maxWidth=t,this.maxHeight=e,this._margins=r,this.setDimensions(),this.buildLabels(),this.fit()}},{key:"setDimensions",value:function(){this.isHorizontal()?(this.width=this.maxWidth,this.left=this._margins.left,this.right=this.width):(this.height=this.maxHeight,this.top=this._margins.top,this.bottom=this.height)}},{key:"buildLabels",value:function(){var t=this,e=this.options.labels||{},r=(0,m.C)(e.generateLabels,[this.chart],this)||[];e.filter&&(r=r.filter(function(r){return e.filter(r,t.chart.data)})),e.sort&&(r=r.sort(function(r,n){return e.sort(r,n,t.chart.data)})),this.options.reverse&&r.reverse(),this.legendItems=r}},{key:"fit",value:function(){var t,e,r=this.options,n=this.ctx;if(!r.display){this.width=this.height=0;return}var i=r.labels,a=(0,m.O)(i.font),o=a.size,s=this._computeTitleHeight(),l=eI(i,o),u=l.boxWidth,c=l.itemHeight;n.font=a.string,this.isHorizontal()?(t=this.maxWidth,e=this._fitRows(s,o,u,c)+10):(e=this.maxHeight,t=this._fitCols(s,o,u,c)+10),this.width=Math.min(t,r.maxWidth||this.maxWidth),this.height=Math.min(e,r.maxHeight||this.maxHeight)}},{key:"_fitRows",value:function(t,e,r,n){var i=this.ctx,a=this.maxWidth,o=this.options.labels.padding,s=this.legendHitBoxes=[],l=this.lineWidths=[0],u=n+o,c=t;i.textAlign="left",i.textBaseline="middle";var h=-1,f=-u;return this.legendItems.forEach(function(t,d){var p=r+e/2+i.measureText(t.text).width;(0===d||l[l.length-1]+p+2*o>a)&&(c+=u,l[l.length-(d>0?0:1)]=0,f+=u,h++),s[d]={left:0,top:f,row:h,width:p,height:n},l[l.length-1]+=p+o}),c}},{key:"_fitCols",value:function(t,e,r,n){var i=this.ctx,a=this.maxHeight,o=this.options.labels.padding,s=this.legendHitBoxes=[],l=this.columnSizes=[],u=a-t,c=o,h=0,f=0,d=0,p=0;return this.legendItems.forEach(function(t,a){var v=r+e/2+i.measureText(t.text).width;a>0&&f+n+2*o>u&&(c+=h+o,l.push({width:h,height:f}),d+=h+o,p++,h=f=0),s[a]={left:d,top:f,col:p,width:v,height:n},h=Math.max(h,v),f+=n+o}),c+=h,l.push({width:h,height:f}),c}},{key:"adjustHitBoxes",value:function(){if(this.options.display){var t=this._computeTitleHeight(),e=this.legendHitBoxes,r=this.options,n=r.align,i=r.labels.padding,a=r.rtl,o=(0,m.aA)(a,this.left,this.width);if(this.isHorizontal()){var s=0,l=(0,m.S)(n,this.left+i,this.right-this.lineWidths[s]),u=!0,c=!1,h=void 0;try{for(var f,d=e[Symbol.iterator]();!(u=(f=d.next()).done);u=!0){var p=f.value;s!==p.row&&(s=p.row,l=(0,m.S)(n,this.left+i,this.right-this.lineWidths[s])),p.top+=this.top+t+i,p.left=o.leftForLtr(o.x(l),p.width),l+=p.width+i}}catch(t){c=!0,h=t}finally{try{u||null==d.return||d.return()}finally{if(c)throw h}}}else{var v=0,g=(0,m.S)(n,this.top+t+i,this.bottom-this.columnSizes[v].height),y=!0,b=!1,_=void 0;try{for(var x,k=e[Symbol.iterator]();!(y=(x=k.next()).done);y=!0){var w=x.value;w.col!==v&&(v=w.col,g=(0,m.S)(n,this.top+t+i,this.bottom-this.columnSizes[v].height)),w.top=g,w.left+=this.left+i,w.left=o.leftForLtr(o.x(w.left),w.width),g+=w.height+i}}catch(t){b=!0,_=t}finally{try{y||null==k.return||k.return()}finally{if(b)throw _}}}}}},{key:"isHorizontal",value:function(){return"top"===this.options.position||"bottom"===this.options.position}},{key:"draw",value:function(){if(this.options.display){var t=this.ctx;(0,m.L)(t,this),this._draw(),(0,m.N)(t)}}},{key:"_draw",value:function(){var t,e=this,r=this.options,n=this.columnSizes,i=this.lineWidths,a=this.ctx,o=r.align,s=r.labels,l=m.d.color,u=(0,m.aA)(r.rtl,this.left,this.width),c=(0,m.O)(s.font),h=s.color,f=s.padding,d=c.size,p=d/2;this.drawTitle(),a.textAlign=u.textAlign("left"),a.textBaseline="middle",a.lineWidth=.5,a.font=c.string;var v=eI(s,d),g=v.boxWidth,y=v.boxHeight,b=v.itemHeight,_=function(t,e,r){if(!(isNaN(g)||g<=0||isNaN(y))&&!(y<0)){a.save();var n=(0,m.v)(r.lineWidth,1);if(a.fillStyle=(0,m.v)(r.fillStyle,l),a.lineCap=(0,m.v)(r.lineCap,"butt"),a.lineDashOffset=(0,m.v)(r.lineDashOffset,0),a.lineJoin=(0,m.v)(r.lineJoin,"miter"),a.lineWidth=n,a.strokeStyle=(0,m.v)(r.strokeStyle,l),a.setLineDash((0,m.v)(r.lineDash,[])),s.usePointStyle){var i={radius:y*Math.SQRT2/2,pointStyle:r.pointStyle,rotation:r.rotation,borderWidth:n},o=u.xPlus(t,g/2);(0,m.aE)(a,i,o,e+p,s.pointStyleWidth&&g)}else{var c=e+Math.max((d-y)/2,0),h=u.leftForLtr(t,g),f=(0,m.ax)(r.borderRadius);a.beginPath(),Object.values(f).some(function(t){return 0!==t})?(0,m.av)(a,{x:h,y:c,w:g,h:y,radius:f}):a.rect(h,c,g,y),a.fill(),0!==n&&a.stroke()}a.restore()}},x=function(t,e,r){(0,m.M)(a,r.text,t,e+b/2,c,{strikethrough:r.hidden,textAlign:u.textAlign(r.textAlign)})},k=this.isHorizontal(),w=this._computeTitleHeight();t=k?{x:(0,m.S)(o,this.left+f,this.right-i[0]),y:this.top+f+w,line:0}:{x:this.left+f,y:(0,m.S)(o,this.top+w+f,this.bottom-n[0].height),line:0},(0,m.aB)(this.ctx,r.textDirection);var M=b+f;this.legendItems.forEach(function(l,c){a.strokeStyle=l.fontColor||h,a.fillStyle=l.fontColor||h;var d=a.measureText(l.text).width,v=u.textAlign(l.textAlign||(l.textAlign=s.textAlign)),y=g+p+d,b=t.x,S=t.y;u.setWidth(e.width),k?c>0&&b+y+f>e.right&&(S=t.y+=M,t.line++,b=t.x=(0,m.S)(o,e.left+f,e.right-i[t.line])):c>0&&S+M>e.bottom&&(b=t.x=b+n[t.line].width+f,t.line++,S=t.y=(0,m.S)(o,e.top+w+f,e.bottom-n[t.line].height)),_(u.x(b),S,l),b=(0,m.aC)(v,b+g+p,k?b+y:e.right,r.rtl),x(u.x(b),S,l),k?t.x+=y+f:t.y+=M}),(0,m.aD)(this.ctx,r.textDirection)}},{key:"drawTitle",value:function(){var t,e,r=this.options,n=r.title,i=(0,m.O)(n.font),a=(0,m.K)(n.padding);if(n.display){var o=(0,m.aA)(r.rtl,this.left,this.width),s=this.ctx,l=n.position,u=i.size/2,c=a.top+u,h=this.left,f=this.width;if(this.isHorizontal())f=(e=Math).max.apply(e,(0,p._)(this.lineWidths)),t=this.top+c,h=(0,m.S)(r.align,h,this.right-f);else{var d=this.columnSizes.reduce(function(t,e){return Math.max(t,e.height)},0);t=c+(0,m.S)(r.align,this.top,this.bottom-d-r.labels.padding-this._computeTitleHeight())}var v=(0,m.S)(l,h,h+f);s.textAlign=o.textAlign((0,m.R)(l)),s.textBaseline="middle",s.strokeStyle=n.color,s.fillStyle=n.color,s.font=i.string,(0,m.M)(s,n.text,v,t,i)}}},{key:"_computeTitleHeight",value:function(){var t=this.options.title,e=(0,m.O)(t.font),r=(0,m.K)(t.padding);return t.display?e.lineHeight+r.height:0}},{key:"_getLegendItemAt",value:function(t,e){var r,n,i;if((0,m.ak)(t,this.left,this.right)&&(0,m.ak)(e,this.top,this.bottom)){for(r=0,i=this.legendHitBoxes;r-1?t.split("\n"):t}function eK(t,e){var r=t.chart.ctx,n=t.body,i=t.footer,a=t.title,o=e.boxWidth,s=e.boxHeight,l=(0,m.O)(e.bodyFont),u=(0,m.O)(e.titleFont),c=(0,m.O)(e.footerFont),h=a.length,f=i.length,d=n.length,p=(0,m.K)(e.padding),v=p.height,g=0,y=n.reduce(function(t,e){return t+e.before.length+e.lines.length+e.after.length},0);y+=t.beforeBody.length+t.afterBody.length,h&&(v+=h*u.lineHeight+(h-1)*e.titleSpacing+e.titleMarginBottom),y&&(v+=d*(e.displayColors?Math.max(s,l.lineHeight):l.lineHeight)+(y-d)*l.lineHeight+(y-1)*e.bodySpacing),f&&(v+=e.footerMarginTop+f*c.lineHeight+(f-1)*e.footerSpacing);var b=0,_=function(t){g=Math.max(g,r.measureText(t).width+b)};return r.save(),r.font=u.string,(0,m.Q)(t.title,_),r.font=l.string,(0,m.Q)(t.beforeBody.concat(t.afterBody),_),b=e.displayColors?o+2+e.boxPadding:0,(0,m.Q)(n,function(t){(0,m.Q)(t.before,_),(0,m.Q)(t.lines,_),(0,m.Q)(t.after,_)}),b=0,r.font=c.string,(0,m.Q)(t.footer,_),r.restore(),{width:g+=p.width,height:v}}function eY(t,e,r){var n,i,a,o,s,l,u,c,h,f=r.yAlign||e.yAlign||((n=r.y)<(i=r.height)/2?"top":n>t.height-i/2?"bottom":"center");return{xAlign:r.xAlign||e.xAlign||(a=r.x,o=r.width,s=t.width,u=(l=t.chartArea).left,c=l.right,h="center","center"===f?h=a<=(u+c)/2?"left":"right":a<=o/2?h="left":a>=s-o/2&&(h="right"),function(t,e,r,n){var i=n.x,a=n.width,o=r.caretSize+r.caretPadding;if("left"===t&&i+a+o>e.width||"right"===t&&i-a-o<0)return!0}(h,t,e,r)&&(h="center"),h),yAlign:f}}function eX(t,e,r,n){var i,a,o,s,l=t.caretSize,u=t.caretPadding,c=t.cornerRadius,h=r.xAlign,f=r.yAlign,d=l+u,p=(0,m.ax)(c),v=p.topLeft,g=p.topRight,y=p.bottomLeft,b=p.bottomRight,_=(i=e.x,a=e.width,"right"===h?i-=a:"center"===h&&(i-=a/2),i),x=(o=e.y,s=e.height,"top"===f?o+=d:"bottom"===f?o-=s+d:o-=s/2,o);return"center"===f?"left"===h?_+=d:"right"===h&&(_-=d):"left"===h?_-=Math.max(v,y)+l:"right"===h&&(_+=Math.max(g,b)+l),{x:(0,m.E)(_,0,n.width-e.width),y:(0,m.E)(x,0,n.height-e.height)}}function eq(t,e,r){var n=(0,m.K)(r.padding);return"center"===e?t.x+t.width/2:"right"===e?t.x+t.width-n.right:t.x+n.left}function e$(t,e){var r=e&&e.dataset&&e.dataset.tooltip&&e.dataset.tooltip.callbacks;return r?t.override(r):t}var eQ=function(t){(0,c._)(r,t);var e=(0,y._)(r);function r(t){var n;return(0,a._)(this,r),(n=e.call(this)).opacity=0,n._active=[],n._eventPosition=void 0,n._size=void 0,n._cachedAnimations=void 0,n._tooltipItems=[],n.$animations=void 0,n.$context=void 0,n.chart=t.chart||t._chart,n._chart=n.chart,n.options=t.options,n.dataPoints=void 0,n.title=void 0,n.beforeBody=void 0,n.body=void 0,n.afterBody=void 0,n.footer=void 0,n.xAlign=void 0,n.yAlign=void 0,n.x=void 0,n.y=void 0,n.height=void 0,n.width=void 0,n.caretX=void 0,n.caretY=void 0,n.labelColors=void 0,n.labelPointStyles=void 0,n.labelTextColors=void 0,n}return(0,o._)(r,[{key:"initialize",value:function(t){this.options=t,this._cachedAnimations=void 0,this.$context=void 0}},{key:"_resolveAnimations",value:function(){var t=this._cachedAnimations;if(t)return t;var e=this.chart,r=this.options.setContext(this.getContext()),n=r.enabled&&e.options.animation&&r.animations,i=new M(this.chart,n);return n._cacheable&&(this._cachedAnimations=Object.freeze(i)),i}},{key:"getContext",value:function(){var t,e;return this.$context||(this.$context=(t=this.chart.getContext(),e=this._tooltipItems,(0,m.h)(t,{tooltip:this,tooltipItems:e,type:"tooltip"})))}},{key:"getTitle",value:function(t,e){var r=e.callbacks,n=r.beforeTitle.apply(this,[t]),i=r.title.apply(this,[t]),a=r.afterTitle.apply(this,[t]),o=[];return o=eH(o,eU(n)),o=eH(o,eU(i)),o=eH(o,eU(a))}},{key:"getBeforeBody",value:function(t,e){return eH([],eU(e.callbacks.beforeBody.apply(this,[t])))}},{key:"getBody",value:function(t,e){var r=this,n=e.callbacks,i=[];return(0,m.Q)(t,function(t){var e={before:[],lines:[],after:[]},a=e$(n,t);eH(e.before,eU(a.beforeLabel.call(r,t))),eH(e.lines,a.label.call(r,t)),eH(e.after,eU(a.afterLabel.call(r,t))),i.push(e)}),i}},{key:"getAfterBody",value:function(t,e){return eH([],eU(e.callbacks.afterBody.apply(this,[t])))}},{key:"getFooter",value:function(t,e){var r=e.callbacks,n=r.beforeFooter.apply(this,[t]),i=r.footer.apply(this,[t]),a=r.afterFooter.apply(this,[t]),o=[];return o=eH(o,eU(n)),o=eH(o,eU(i)),o=eH(o,eU(a))}},{key:"_createItems",value:function(t){var e,r,n=this,i=this._active,a=this.chart.data,o=[],s=[],l=[],u=[];for(e=0,r=i.length;e0&&e.stroke()}},{key:"_updateAnimationTarget",value:function(t){var e=this.chart,r=this.$animations,n=r&&r.x,i=r&&r.y;if(n||i){var a=eW[t.position].call(this,this._active,this._eventPosition);if(!a)return;var o=this._size=eK(this,t),s=Object.assign({},a,this._size),l=eY(e,t,s),u=eX(t,s,l,e);(n._to!==u.x||i._to!==u.y)&&(this.xAlign=l.xAlign,this.yAlign=l.yAlign,this.width=o.width,this.height=o.height,this.caretX=a.x,this.caretY=a.y,this._resolveAnimations().update(this,u))}}},{key:"_willRender",value:function(){return!!this.opacity}},{key:"draw",value:function(t){var e=this.options.setContext(this.getContext()),r=this.opacity;if(r){this._updateAnimationTarget(e);var n={width:this.width,height:this.height},i={x:this.x,y:this.y};r=.001>Math.abs(r)?0:r;var a=(0,m.K)(e.padding),o=this.title.length||this.beforeBody.length||this.body.length||this.afterBody.length||this.footer.length;e.enabled&&o&&(t.save(),t.globalAlpha=r,this.drawBackground(i,t,n,e),(0,m.aB)(t,e.textDirection),i.y+=a.top,this.drawTitle(i,t,e),this.drawBody(i,t,e),this.drawFooter(i,t,e),(0,m.aD)(t,e.textDirection),t.restore())}}},{key:"getActiveElements",value:function(){return this._active||[]}},{key:"setActiveElements",value:function(t,e){var r=this,n=this._active,i=t.map(function(t){var e=t.datasetIndex,n=t.index,i=r.chart.getDatasetMeta(e);if(!i)throw Error("Cannot find a dataset at index "+e);return{datasetIndex:e,element:i.data[n],index:n}}),a=!(0,m.ai)(n,i),o=this._positionChanged(i,e);(a||o)&&(this._active=i,this._eventPosition=e,this._ignoreReplayEvents=!0,this.update(!0))}},{key:"handleEvent",value:function(t,e){var r=!(arguments.length>2)||void 0===arguments[2]||arguments[2];if(e&&this._ignoreReplayEvents)return!1;this._ignoreReplayEvents=!1;var n=this.options,i=this._active||[],a=this._getActiveElements(t,i,e,r),o=this._positionChanged(a,t),s=e||!(0,m.ai)(a,i)||o;return s&&(this._active=a,(n.enabled||n.external)&&(this._eventPosition={x:t.x,y:t.y},this.update(!0,e))),s}},{key:"_getActiveElements",value:function(t,e,r,n){var i=this.options;if("mouseout"===t.type)return[];if(!n)return e;var a=this.chart.getElementsAtEventForMode(t,i.mode,i,r);return i.reverse&&a.reverse(),a}},{key:"_positionChanged",value:function(t,e){var r=this.caretX,n=this.caretY,i=eW[this.options.position].call(this,t,e);return!1!==i&&(r!==i.x||n!==i.y)}}]),r}((0,g._)(q));eQ.positioners=eW;var eG={id:"tooltip",_element:eQ,positioners:eW,afterInit:function(t,e,r){r&&(t.tooltip=new eQ({chart:t,options:r}))},beforeUpdate:function(t,e,r){t.tooltip&&t.tooltip.initialize(r)},reset:function(t,e,r){t.tooltip&&t.tooltip.initialize(r)},afterDraw:function(t){var e=t.tooltip;if(e&&e._willRender()){var r={tooltip:e};if(!1===t.notifyPlugins("beforeTooltipDraw",r))return;e.draw(t.ctx),t.notifyPlugins("afterTooltipDraw",r)}},afterEvent:function(t,e){if(t.tooltip){var r=e.replay;t.tooltip.handleEvent(e.event,r,e.inChartArea)&&(e.changed=!0)}},defaults:{enabled:!0,external:null,position:"average",backgroundColor:"rgba(0,0,0,0.8)",titleColor:"#fff",titleFont:{weight:"bold"},titleSpacing:2,titleMarginBottom:6,titleAlign:"left",bodyColor:"#fff",bodySpacing:2,bodyFont:{},bodyAlign:"left",footerColor:"#fff",footerSpacing:2,footerMarginTop:6,footerFont:{weight:"bold"},footerAlign:"left",padding:6,caretPadding:2,caretSize:5,cornerRadius:6,boxHeight:function(t,e){return e.bodyFont.size},boxWidth:function(t,e){return e.bodyFont.size},multiKeyBackground:"#fff",displayColors:!0,boxPadding:0,borderColor:"rgba(0,0,0,0)",borderWidth:0,animation:{duration:400,easing:"easeOutQuart"},animations:{numbers:{type:"number",properties:["x","y","width","height","caretX","caretY"]},opacity:{easing:"linear",duration:200}},callbacks:{beforeTitle:m.aF,title:function(t){if(t.length>0){var e=t[0],r=e.chart.data.labels,n=r?r.length:0;if(this&&this.options&&"dataset"===this.options.mode)return e.dataset.label||"";if(e.label)return e.label;if(n>0&&e.dataIndex=0&&te.length-1?null:this.getPixelForValue(e[t].value)}},{key:"getValueForPixel",value:function(t){return Math.round(this._startValue+this.getDecimalForPixel(t)*this._valueRange)}},{key:"getBasePixel",value:function(){return this.bottom}}]),r}(tr);function e0(t,e,r){var n=r.horizontal,i=r.minRotation,a=(0,m.t)(i),o=.75*e*(""+t).length;return Math.min(e/((n?Math.sin(a):Math.cos(a))||.001),o)}eZ.id="category",eZ.defaults={ticks:{callback:eZ.prototype.getLabelForValue}};var e1=function(t){(0,c._)(r,t);var e=(0,y._)(r);function r(t){var n;return(0,a._)(this,r),(n=e.call(this,t)).start=void 0,n.end=void 0,n._startValue=void 0,n._endValue=void 0,n._valueRange=0,n}return(0,o._)(r,[{key:"parse",value:function(t,e){return(0,m.k)(t)||("number"==typeof t||t instanceof Number)&&!isFinite(+t)?null:+t}},{key:"handleTickRangeOptions",value:function(){var t=this.options.beginAtZero,e=this.getUserBounds(),r=e.minDefined,n=e.maxDefined,i=this.min,a=this.max,o=function(t){return i=r?i:t},s=function(t){return a=n?a:t};if(t){var l=(0,m.s)(i),u=(0,m.s)(a);l<0&&u<0?s(0):l>0&&u>0&&o(0)}if(i===a){var c=1;(a>=Number.MAX_SAFE_INTEGER||i<=Number.MIN_SAFE_INTEGER)&&(c=Math.abs(.05*a)),s(a+c),t||o(i-c)}this.min=i,this.max=a}},{key:"getTickLimit",value:function(){var t,e=this.options.ticks,r=e.maxTicksLimit,n=e.stepSize;return n?(t=Math.ceil(this.max/n)-Math.floor(this.min/n)+1)>1e3&&(console.warn("scales.".concat(this.id,".ticks.stepSize: ").concat(n," would result generating up to ").concat(t," ticks. Limiting to 1000.")),t=1e3):(t=this.computeTickLimit(),r=r||11),r&&(t=Math.min(r,t)),t}},{key:"computeTickLimit",value:function(){return Number.POSITIVE_INFINITY}},{key:"buildTicks",value:function(){var t=this.options,e=t.ticks,r=this.getTickLimit(),n=function(t,e){var r,n,i,a,o=[],s=t.bounds,l=t.step,u=t.min,c=t.max,h=t.precision,f=t.count,d=t.maxTicks,p=t.maxDigits,v=t.includeBounds,g=l||1,y=d-1,b=e.min,_=e.max,x=!(0,m.k)(u),k=!(0,m.k)(c),w=!(0,m.k)(f),M=(_-b)/(p+1),S=(0,m.aI)((_-b)/y/g)*g;if(S<1e-14&&!x&&!k)return[{value:b},{value:_}];(a=Math.ceil(_/S)-Math.floor(b/S))>y&&(S=(0,m.aI)(a*S/y/g)*g),(0,m.k)(h)||(S=Math.ceil(S*(r=Math.pow(10,h)))/r),"ticks"===s?(n=Math.floor(b/S)*S,i=Math.ceil(_/S)*S):(n=b,i=_),x&&k&&l&&(0,m.aJ)((c-u)/l,S/1e3)?(a=Math.round(Math.min((c-u)/S,d)),S=(c-u)/a,n=u,i=c):w?(n=x?u:n,S=((i=k?c:i)-n)/(a=f-1)):(a=(i-n)/S,a=(0,m.aK)(a,Math.round(a),S/1e3)?Math.round(a):Math.ceil(a));var O=Math.max((0,m.aL)(S),(0,m.aL)(n));n=Math.round(n*(r=Math.pow(10,(0,m.k)(h)?O:h)))/r,i=Math.round(i*r)/r;var A=0;for(x&&(v&&n!==u?(o.push({value:u}),n0?r:null}},{key:"determineDataLimits",value:function(){var t=this.getMinMax(!0),e=t.min,r=t.max;this.min=(0,m.g)(e)?Math.max(0,e):null,this.max=(0,m.g)(r)?Math.max(0,r):null,this.options.beginAtZero&&(this._zero=!0),this.handleTickRangeOptions()}},{key:"handleTickRangeOptions",value:function(){var t=this.getUserBounds(),e=t.minDefined,r=t.maxDefined,n=this.min,i=this.max,a=function(t){return n=e?n:t},o=function(t){return i=r?i:t},s=function(t,e){return Math.pow(10,Math.floor((0,m.z)(t))+e)};n===i&&(n<=0?(a(1),o(10)):(a(s(n,-1)),o(s(i,1)))),n<=0&&a(s(i,-1)),i<=0&&o(s(n,1)),this._zero&&this.min!==this._suggestedMin&&n===s(this.min,0)&&a(s(n,-1)),this.min=n,this.max=i}},{key:"buildTicks",value:function(){var t=this.options,e=function(t,e){var r=Math.floor((0,m.z)(e.max)),n=Math.ceil(e.max/Math.pow(10,r)),i=[],a=(0,m.B)(t.min,Math.pow(10,Math.floor((0,m.z)(e.min)))),o=Math.floor((0,m.z)(a)),s=Math.floor(a/Math.pow(10,o)),l=o<0?Math.pow(10,Math.abs(o)):1;do i.push({value:a,major:e5(a)}),10==++s&&(s=1,l=++o>=0?1:l),a=Math.round(s*Math.pow(10,o)*l)/l;while(oi?{start:e-r,end:e}:{start:e,end:e+r}}function e4(t,e,r,n){var i=t.ctx;if(r)i.arc(t.xCenter,t.yCenter,e,0,m.T);else{var a=t.getPointPosition(0,e);i.moveTo(a.x,a.y);for(var o=1;oe.r&&(s=(n.end-e.r)/a,t.r=Math.max(t.r,e.r+s)),i.starte.b&&(l=(i.end-e.b)/o,t.b=Math.max(t.b,e.b+l))})(r,e,v,e8(g,f.x,p.w,0,180),e8(g,f.y,p.h,90,270))}t.setCenterPoint(e.l-r.l,r.r-e.r,e.t-r.t,r.b-e.b),t._pointLabelItems=function(t,e,r){for(var n=[],i=t._pointLabels.length,a=t.options,o=e6(a)/2,s=t.drawingArea,l=a.pointLabels.centerPointLabels?m.P/i:0,u=0;u270||v<90)&&(c-=h),c),b=0===v||180===v?"center":v<180?"left":"right",_=(f=p.x,d=g.w,"right"===b?f-=d:"center"===b&&(f-=d/2),f);n.push({x:p.x,y:y,textAlign:b,left:_,top:y,right:_+g.w,bottom:y+g.h})}return n}(t,n,i)}(this):this.setCenterPoint(0,0,0,0)}},{key:"setCenterPoint",value:function(t,e,r,n){this.xCenter+=Math.floor((t-e)/2),this.yCenter+=Math.floor((r-n)/2),this.drawingArea-=Math.min(this.drawingArea/2,Math.max(t,e,r,n))}},{key:"getIndexAngle",value:function(t){var e=m.T/(this._pointLabels.length||1),r=this.options.startAngle||0;return(0,m.az)(t*e+(0,m.t)(r))}},{key:"getDistanceFromCenterForValue",value:function(t){if((0,m.k)(t))return NaN;var e=this.drawingArea/(this.max-this.min);return this.options.reverse?(this.max-t)*e:(t-this.min)*e}},{key:"getValueForDistanceFromCenter",value:function(t){if((0,m.k)(t))return NaN;var e=t/(this.drawingArea/(this.max-this.min));return this.options.reverse?this.max-e:this.min+e}},{key:"getPointLabelContext",value:function(t){var e=this._pointLabels||[];if(t>=0&&t2&&void 0!==arguments[2]?arguments[2]:0,n=this.getIndexAngle(t)-m.H+r;return{x:Math.cos(n)*e+this.xCenter,y:Math.sin(n)*e+this.yCenter,angle:n}}},{key:"getPointPositionForValue",value:function(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))}},{key:"getBasePosition",value:function(t){return this.getPointPositionForValue(t||0,this.getBaseValue())}},{key:"getPointLabelPosition",value:function(t){var e=this._pointLabelItems[t];return{left:e.left,top:e.top,right:e.right,bottom:e.bottom}}},{key:"drawBackground",value:function(){var t=this.options,e=t.backgroundColor,r=t.grid.circular;if(e){var n=this.ctx;n.save(),n.beginPath(),e4(this,this.getDistanceFromCenterForValue(this._endValue),r,this._pointLabels.length),n.closePath(),n.fillStyle=e,n.fill(),n.restore()}}},{key:"drawGrid",value:function(){var t,e,r,n=this,i=this.ctx,a=this.options,o=a.angleLines,s=a.grid,l=this._pointLabels.length;if(a.pointLabels.display&&function(t,e){for(var r=t.ctx,n=t.options.pointLabels,i=e-1;i>=0;i--){var a=n.setContext(t.getPointLabelContext(i)),o=(0,m.O)(a.font),s=t._pointLabelItems[i],l=s.x,u=s.y,c=s.textAlign,h=s.left,f=s.top,d=s.right,p=s.bottom,v=a.backdropColor;if(!(0,m.k)(v)){var g=(0,m.ax)(a.borderRadius),y=(0,m.K)(a.backdropPadding);r.fillStyle=v;var b=h-y.left,_=f-y.top,x=d-h+y.width,k=p-f+y.height;Object.values(g).some(function(t){return 0!==t})?(r.beginPath(),(0,m.av)(r,{x:b,y:_,w:x,h:k,radius:g}),r.fill()):r.fillRect(b,_,x,k)}(0,m.M)(r,t._pointLabels[i],l,u+o.lineHeight/2,o,{color:a.color,textAlign:c,textBaseline:"middle"})}}(this,l),s.display&&this.ticks.forEach(function(t,r){if(0!==r){e=n.getDistanceFromCenterForValue(t.value);var i,a,o,u,c,h=s.setContext(n.getContext(r-1));i=e,a=n.ctx,o=h.circular,u=h.color,c=h.lineWidth,(o||l)&&u&&c&&!(i<0)&&(a.save(),a.strokeStyle=u,a.lineWidth=c,a.setLineDash(h.borderDash),a.lineDashOffset=h.borderDashOffset,a.beginPath(),e4(n,i,o,l),a.closePath(),a.stroke(),a.restore())}}),o.display){for(i.save(),t=l-1;t>=0;t--){var u=o.setContext(this.getPointLabelContext(t)),c=u.color,h=u.lineWidth;h&&c&&(i.lineWidth=h,i.strokeStyle=c,i.setLineDash(u.borderDash),i.lineDashOffset=u.borderDashOffset,e=this.getDistanceFromCenterForValue(a.ticks.reverse?this.min:this.max),r=this.getPointPosition(t,e),i.beginPath(),i.moveTo(this.xCenter,this.yCenter),i.lineTo(r.x,r.y),i.stroke())}i.restore()}}},{key:"drawBorder",value:function(){}},{key:"drawLabels",value:function(){var t,e,r=this,n=this.ctx,i=this.options,a=i.ticks;if(a.display){var o=this.getIndexAngle(0);n.save(),n.translate(this.xCenter,this.yCenter),n.rotate(o),n.textAlign="center",n.textBaseline="middle",this.ticks.forEach(function(o,s){if(0!==s||i.reverse){var l=a.setContext(r.getContext(s)),u=(0,m.O)(l.font);if(t=r.getDistanceFromCenterForValue(r.ticks[s].value),l.showLabelBackdrop){n.font=u.string,e=n.measureText(o.label).width,n.fillStyle=l.backdropColor;var c=(0,m.K)(l.backdropPadding);n.fillRect(-e/2-c.left,-t-u.size/2-c.top,e+c.width,u.size+c.height)}(0,m.M)(n,o.label,0,-t,u,{color:l.color})}}),n.restore()}}},{key:"drawTitle",value:function(){}}]),r}(e1);e7.id="radialLinear",e7.defaults={display:!0,animate:!0,position:"chartArea",angleLines:{display:!0,lineWidth:1,borderDash:[],borderDashOffset:0},grid:{circular:!1},startAngle:0,ticks:{showLabelBackdrop:!0,callback:Q.formatters.numeric},pointLabels:{backdropColor:void 0,backdropPadding:2,display:!0,font:{size:10},callback:function(t){return t},padding:5,centerPointLabels:!1}},e7.defaultRoutes={"angleLines.color":"borderColor","pointLabels.color":"color","ticks.color":"color"},e7.descriptors={angleLines:{_fallback:"grid"}};var e9={millisecond:{common:!0,size:1,steps:1e3},second:{common:!0,size:1e3,steps:60},minute:{common:!0,size:6e4,steps:60},hour:{common:!0,size:36e5,steps:24},day:{common:!0,size:864e5,steps:30},week:{common:!1,size:6048e5,steps:4},month:{common:!0,size:2628e6,steps:12},quarter:{common:!1,size:7884e6,steps:4},year:{common:!0,size:3154e7}},rt=Object.keys(e9);function re(t,e){return t-e}function rr(t,e){if((0,m.k)(e))return null;var r=t._adapter,n=t._parseOpts,i=n.parser,a=n.round,o=n.isoWeekday,s=e;return("function"==typeof i&&(s=i(s)),(0,m.g)(s)||(s="string"==typeof i?r.parse(s,i):r.parse(s)),null===s)?null:(a&&(s="week"===a&&((0,m.x)(o)||!0===o)?r.startOf(s,"isoWeek",o):r.startOf(s,a)),+s)}function rn(t,e,r,n){for(var i=rt.length,a=rt.indexOf(t);a=e?r[i]:r[a]]=!0}}else t[e]=!0}function ra(t,e,r){var n,i,a=[],o={},s=e.length;for(n=0;n=0&&(e[a].major=!0);return e}(t,a,o,r):a}var ro=function(t){(0,c._)(r,t);var e=(0,y._)(r);function r(t){var n;return(0,a._)(this,r),(n=e.call(this,t))._cache={data:[],labels:[],all:[]},n._unit="day",n._majorUnit=void 0,n._offsets={},n._normalized=!1,n._parseOpts=void 0,n}return(0,o._)(r,[{key:"init",value:function(t,e){var n=t.time||(t.time={}),i=this._adapter=new tu._date(t.adapters.date);i.init(e),(0,m.ac)(n.displayFormats,i.formats()),this._parseOpts={parser:n.parser,round:n.round,isoWeekday:n.isoWeekday},(0,l._)((0,u._)(r.prototype),"init",this).call(this,t),this._normalized=e.normalized}},{key:"parse",value:function(t,e){return void 0===t?null:rr(this,t)}},{key:"beforeLayout",value:function(){(0,l._)((0,u._)(r.prototype),"beforeLayout",this).call(this),this._cache={data:[],labels:[],all:[]}}},{key:"determineDataLimits",value:function(){var t=this.options,e=this._adapter,r=t.time.unit||"day",n=this.getUserBounds(),i=n.min,a=n.max,o=n.minDefined,s=n.maxDefined;function l(t){o||isNaN(t.min)||(i=Math.min(i,t.min)),s||isNaN(t.max)||(a=Math.max(a,t.max))}o&&s||(l(this._getLabelBounds()),("ticks"!==t.bounds||"labels"!==t.ticks.source)&&l(this.getMinMax(!1))),i=(0,m.g)(i)&&!isNaN(i)?i:+e.startOf(Date.now(),r),a=(0,m.g)(a)&&!isNaN(a)?a:+e.endOf(Date.now(),r)+1,this.min=Math.min(i,a-1),this.max=Math.max(i+1,a)}},{key:"_getLabelBounds",value:function(){var t=this.getLabelTimestamps(),e=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY;return t.length&&(e=t[0],r=t[t.length-1]),{min:e,max:r}}},{key:"buildTicks",value:function(){var t=this.options,e=t.time,r=t.ticks,n="labels"===r.source?this.getLabelTimestamps():this._generate();"ticks"===t.bounds&&n.length&&(this.min=this._userMin||n[0],this.max=this._userMax||n[n.length-1]);var i=this.min,a=this.max,o=(0,m.aN)(n,i,a);return this._unit=e.unit||(r.autoSkip?rn(e.minUnit,this.min,this.max,this._getLabelCapacity(i)):function(t,e,r,n,i){for(var a=rt.length-1;a>=rt.indexOf(r);a--){var o=rt[a];if(e9[o].common&&t._adapter.diff(i,n,o)>=e-1)return o}return rt[r?rt.indexOf(r):0]}(this,o.length,e.minUnit,this.min,this.max)),this._majorUnit=r.major.enabled&&"year"!==this._unit?function(t){for(var e=rt.indexOf(t)+1,r=rt.length;e1e5*l)throw Error(n+" and "+i+" are too far apart with stepSize of "+l+" "+s);var d="data"===a.ticks.source&&this.getDataTimestamps();for(t=f,e=0;t0?o:1}},{key:"getDataTimestamps",value:function(){var t,e,r=this._cache.data||[];if(r.length)return r;var n=this.getMatchingVisibleMetas();if(this._normalized&&n.length)return this._cache.data=n[0].controller.getAllParsedValues(this);for(t=0,e=n.length;t=t[d].pos&&e<=t[p].pos&&(d=(s=(0,m.Z)(t,"pos",e)).lo,p=s.hi),n=(l=t[d]).pos,a=l.time,i=(u=t[p]).pos,o=u.time):(e>=t[d].time&&e<=t[p].time&&(d=(c=(0,m.Z)(t,"time",e)).lo,p=c.hi),n=(h=t[d]).time,a=h.pos,i=(f=t[p]).time,o=f.pos);var v=i-n;return v?a+(o-a)*(e-n)/v:a}ro.id="time",ro.defaults={bounds:"data",adapters:{},time:{parser:!1,unit:!1,round:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{}},ticks:{source:"auto",major:{enabled:!1}}};var rl=function(t){(0,c._)(r,t);var e=(0,y._)(r);function r(t){var n;return(0,a._)(this,r),(n=e.call(this,t))._table=[],n._minPos=void 0,n._tableRange=void 0,n}return(0,o._)(r,[{key:"initOffsets",value:function(){var t=this._getTimestampsForTable(),e=this._table=this.buildLookupTable(t);this._minPos=rs(e,this.min),this._tableRange=rs(e,this.max)-this._minPos,(0,l._)((0,u._)(r.prototype),"initOffsets",this).call(this,t)}},{key:"buildLookupTable",value:function(t){var e,r,n,i=this.min,a=this.max,o=[],s=[];for(e=0,r=t.length;e=i&&n<=a&&o.push(n);if(o.length<2)return[{time:i,pos:0},{time:a,pos:1}];for(e=0,r=o.length;e")+"->"+t);return s.add(t),e=e(a,o||n),s.delete(t),eD(t,e)&&(e=eT(i._scopes,i,t,e)),e}(r,l,e,n)),p(l)&&l.length&&(l=function(e,r,n,i){var a=n._proxy,o=n._context,s=n._subProxy,l=n._descriptors;if(I(o.index)&&i(e))r=r[o.index%r.length];else if(v(r[0])){var u=r,c=a._scopes.filter(function(t){return t!==u});r=[];var h=!0,f=!1,d=void 0;try{for(var p,g=u[Symbol.iterator]();!(h=(p=g.next()).done);h=!0){var y=p.value,m=eT(c,a,e,y);r.push(t(m,o,s&&s[e],l))}}catch(t){f=!0,d=t}finally{try{h||null==g.return||g.return()}finally{if(f)throw d}}}return r}(r,l,e,s.isIndexable)),eD(r,l)&&(l=t(l,a,o&&o[r],s)),l})},getOwnPropertyDescriptor:function(t,r){return t._descriptors.allKeys?Reflect.has(e,r)?{enumerable:!0,configurable:!0}:void 0:Reflect.getOwnPropertyDescriptor(e,r)},getPrototypeOf:function(){return Reflect.getPrototypeOf(e)},has:function(t,r){return Reflect.has(e,r)},ownKeys:function(){return Reflect.ownKeys(e)},set:function(t,r,n){return e[r]=n,delete t[r],!0}})}}),a.export(r,"aA",function(){return e9}),a.export(r,"aB",function(){return rt}),a.export(r,"aC",function(){return tO}),a.export(r,"aD",function(){return re}),a.export(r,"aE",function(){return ec}),a.export(r,"aF",function(){return h}),a.export(r,"aG",function(){return ta}),a.export(r,"aH",function(){return tt}),a.export(r,"aI",function(){return $}),a.export(r,"aJ",function(){return Z}),a.export(r,"aK",function(){return J}),a.export(r,"aL",function(){return tn}),a.export(r,"aM",function(){return eo}),a.export(r,"aN",function(){return tv}),a.export(r,"aO",function(){return tf}),a.export(r,"aP",function(){return t8}),a.export(r,"aQ",function(){return t7}),a.export(r,"aR",function(){return M}),a.export(r,"aS",function(){return O}),a.export(r,"aT",function(){return C}),a.export(r,"aU",function(){return P}),a.export(r,"aV",function(){return T}),a.export(r,"aW",function(){return ei}),a.export(r,"aX",function(){return ez}),a.export(r,"aY",function(){return eW}),a.export(r,"aZ",function(){return e$}),a.export(r,"a_",function(){return t_}),a.export(r,"aa",function(){return eC}),a.export(r,"ab",function(){return eP}),a.export(r,"ac",function(){return E}),a.export(r,"ad",function(){return f}),a.export(r,"ae",function(){return tw}),a.export(r,"af",function(){return e1}),a.export(r,"ag",function(){return el}),a.export(r,"ah",function(){return B}),a.export(r,"ai",function(){return w}),a.export(r,"aj",function(){return R}),a.export(r,"ak",function(){return th}),a.export(r,"al",function(){return ex}),a.export(r,"am",function(){return eU}),a.export(r,"an",function(){return ro}),a.export(r,"ao",function(){return ra}),a.export(r,"ap",function(){return e6}),a.export(r,"aq",function(){return e8}),a.export(r,"ar",function(){return e3}),a.export(r,"as",function(){return ep}),a.export(r,"at",function(){return ev}),a.export(r,"au",function(){return eu}),a.export(r,"av",function(){return ey}),a.export(r,"aw",function(){return ek}),a.export(r,"ax",function(){return ew}),a.export(r,"ay",function(){return ri}),a.export(r,"az",function(){return ts}),a.export(r,"b",function(){return p}),a.export(r,"b0",function(){return z}),a.export(r,"b1",function(){return W}),a.export(r,"b2",function(){return H}),a.export(r,"b3",function(){return K}),a.export(r,"b4",function(){return Y}),a.export(r,"b5",function(){return to}),a.export(r,"c",function(){return t4}),a.export(r,"d",function(){return en}),a.export(r,"e",function(){return tj}),a.export(r,"f",function(){return j}),a.export(r,"g",function(){return g}),a.export(r,"h",function(){return eE}),a.export(r,"i",function(){return v}),a.export(r,"j",function(){return I}),a.export(r,"k",function(){return d}),a.export(r,"l",function(){return ty}),a.export(r,"m",function(){return b}),a.export(r,"n",function(){return _}),a.export(r,"o",function(){return e7}),a.export(r,"p",function(){return tl}),a.export(r,"q",function(){return tA}),a.export(r,"r",function(){return tx}),a.export(r,"s",function(){return q}),a.export(r,"t",function(){return te}),a.export(r,"u",function(){return tm}),a.export(r,"v",function(){return m}),a.export(r,"w",function(){return tE}),a.export(r,"x",function(){return G}),a.export(r,"y",function(){return eB}),a.export(r,"z",function(){return X});var o=t("@swc/helpers/_/_class_call_check"),s=t("@swc/helpers/_/_create_class"),l=t("@swc/helpers/_/_define_property"),u=t("@swc/helpers/_/_to_consumable_array"),c=t("@swc/helpers/_/_type_of");function h(){}var f=(n=0,function(){return n++});function d(t){return null==t}function p(t){if(Array.isArray&&Array.isArray(t))return!0;var e=Object.prototype.toString.call(t);return"[object"===e.slice(0,7)&&"Array]"===e.slice(-6)}function v(t){return null!==t&&"[object Object]"===Object.prototype.toString.call(t)}var g=function(t){return("number"==typeof t||t instanceof Number)&&isFinite(+t)};function y(t,e){return g(t)?t:e}function m(t,e){return void 0===t?e:t}var b=function(t,e){return"string"==typeof t&&t.endsWith("%")?parseFloat(t)/100:t/e},_=function(t,e){return"string"==typeof t&&t.endsWith("%")?parseFloat(t)/100*e:+t};function x(t,e,r){if(t&&"function"==typeof t.call)return t.apply(r,e)}function k(t,e,r,n){var i,a,o;if(p(t)){if(a=t.length,n)for(i=a-1;i>=0;i--)e.call(r,t[i],i);else for(i=0;i=t}function tt(t,e,r){var n,i,a;for(n=0,i=t.length;nl&&u3&&void 0!==arguments[3]?arguments[3]:1e-6;return t>=Math.min(e,r)-n&&t<=Math.max(e,r)+n}function tf(t,e,r){r=r||function(r){return t[r]1;)r(n=a+i>>1)?a=n:i=n;return{lo:a,hi:i}}var td=function(t,e,r,n){return tf(t,r,n?function(n){return t[n][e]<=r}:function(n){return t[n][e]=r})};function tv(t,e,r){for(var n=0,i=t.length;nn&&t[i-1]>r;)i--;return n>0||i0||(tg.forEach(function(e){delete t[e]}),delete t._chartjs)}}function tb(t){var e,r,n=new Set;for(e=0,r=t.length;e=1?t:-(Math.sqrt(1-t*t)-1)},easeOutCirc:function(t){return Math.sqrt(1-(t-=1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){return tC(t)?t:tP(t,.075,.3)},easeOutElastic:function(t){return tC(t)?t:tD(t,.075,.3)},easeInOutElastic:function(t){return tC(t)?t:t<.5?.5*tP(2*t,.1125,.45):.5+.5*tD(2*t-1,.1125,.45)},easeInBack:function(t){return t*t*(2.70158*t-1.70158)},easeOutBack:function(t){return(t-=1)*t*(2.70158*t+1.70158)+1},easeInOutBack:function(t){var e=1.70158;return(t/=.5)<1?t*t*(((e*=1.525)+1)*t-e)*.5:.5*((t-=2)*t*(((e*=1.525)+1)*t+e)+2)},easeInBounce:function(t){return 1-tj.easeOutBounce(1-t)},easeOutBounce:function(t){return t<.36363636363636365?7.5625*t*t:t<.7272727272727273?7.5625*(t-=.5454545454545454)*t+.75:t<.9090909090909091?7.5625*(t-=.8181818181818182)*t+.9375:7.5625*(t-=.9545454545454546)*t+.984375},easeInOutBounce:function(t){return t<.5?.5*tj.easeInBounce(2*t):.5*tj.easeOutBounce(2*t-1)+.5}};/*! * @kurkle/color v0.2.1 * https://github.com/kurkle/color#readme * (c) 2022 Jukka Kurkela * Released under the MIT License */function tT(t){return t+.5|0}var tF=function(t,e,r){return Math.max(Math.min(t,r),e)};function tI(t){return tF(tT(2.55*t),0,255)}function tL(t){return tF(tT(255*t),0,255)}function tB(t){return tF(tT(t/2.55)/100,0,1)}function tR(t){return tF(tT(100*t),0,100)}var tN={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,A:10,B:11,C:12,D:13,E:14,F:15,a:10,b:11,c:12,d:13,e:14,f:15},tV=Array.from("0123456789ABCDEF"),tz=function(t){return tV[15&t]},tW=function(t){return tV[(240&t)>>4]+tV[15&t]},tH=function(t){return(240&t)>>4==(15&t)},tU=/^(hsla?|hwb|hsv)\(\s*([-+.e\d]+)(?:deg)?[\s,]+([-+.e\d]+)%[\s,]+([-+.e\d]+)%(?:[\s,]+([-+.e\d]+)(%)?)?\s*\)$/;function tK(t,e,r){var n=e*Math.min(r,1-r),i=function(e){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:(e+t/30)%12;return r-n*Math.max(Math.min(i-3,9-i,1),-1)};return[i(0),i(8),i(4)]}function tY(t,e,r){var n=function(n){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:(n+t/60)%6;return r-r*e*Math.max(Math.min(i,4-i,1),0)};return[n(5),n(3),n(1)]}function tX(t,e,r){var n,i=tK(t,1,.5);for(e+r>1&&(n=1/(e+r),e*=n,r*=n),n=0;n<3;n++)i[n]*=1-e-r,i[n]+=e;return i}function tq(t){var e,r,n,i=t.r/255,a=t.g/255,o=t.b/255,s=Math.max(i,a,o),l=Math.min(i,a,o),u=(s+l)/2;return s!==l&&(n=s-l,r=u>.5?n/(2-s-l):n/(s+l),e=60*(e=i===s?(a-o)/n+(a=3&&(e={r:t[0],g:t[1],b:t[2],a:255},t.length>3&&(e.a=tL(t[3]))):(e=t5(t,{r:0,g:0,b:0,a:1})).a=tL(e.a),e}var t6=function(){function t(e){if((0,o._)(this,t),e instanceof t)return e;var r,n,a,s,l=void 0===e?"undefined":(0,c._)(e);"object"===l?s=t3(e):"string"===l&&(n=e.length,"#"===e[0]&&(4===n||5===n?r={r:255&17*tN[e[1]],g:255&17*tN[e[2]],b:255&17*tN[e[3]],a:5===n?17*tN[e[4]]:255}:(7===n||9===n)&&(r={r:tN[e[1]]<<4|tN[e[2]],g:tN[e[3]]<<4|tN[e[4]],b:tN[e[5]]<<4|tN[e[6]],a:9===n?tN[e[7]]<<4|tN[e[8]]:255})),s=r||(i||((i=function(){var t,e,r,n,i,a={},o=Object.keys(tJ),s=Object.keys(tG);for(t=0;t>16&255,r>>8&255,255&r]}return a}()).transparent=[0,0,0,0]),(a=i[e.toLowerCase()])&&{r:a[0],g:a[1],b:a[2],a:4===a.length?a[3]:255})||("r"===e.charAt(0)?function(t){var e,r,n,i=tZ.exec(t),a=255;if(i){if(i[7]!==e){var o=+i[7];a=i[8]?tI(o):tF(255*o,0,255)}return e=+i[1],r=+i[3],n=+i[5],{r:e=255&(i[2]?tI(e):tF(e,0,255)),g:r=255&(i[4]?tI(r):tF(r,0,255)),b:n=255&(i[6]?tI(n):tF(n,0,255)),a:a}}}(e):function(t){var e,r=tU.exec(t),n=255;if(r){r[5]!==e&&(n=r[6]?tI(+r[5]):tL(+r[5]));var i=tQ(+r[2]),a=+r[3]/100,o=+r[4]/100;return{r:(e="hwb"===r[1]?t$(tX,i,a,o):"hsv"===r[1]?t$(tY,i,a,o):t$(tK,i,a,o))[0],g:e[1],b:e[2],a:n}}}(e))),this._rgb=s,this._valid=!!s}return(0,s._)(t,[{key:"valid",get:function(){return this._valid}},{key:"rgb",get:function(){var t=t5(this._rgb);return t&&(t.a=tB(t.a)),t},set:function(t){this._rgb=t3(t)}},{key:"rgbString",value:function(){var t;return this._valid?(t=this._rgb)&&(t.a<255?"rgba(".concat(t.r,", ").concat(t.g,", ").concat(t.b,", ").concat(tB(t.a),")"):"rgb(".concat(t.r,", ").concat(t.g,", ").concat(t.b,")")):void 0}},{key:"hexString",value:function(){var t,e,r,n;return this._valid?(r=tH((e=t=this._rgb).r)&&tH(e.g)&&tH(e.b)&&tH(e.a)?tz:tW,t?"#"+r(t.r)+r(t.g)+r(t.b)+((n=t.a)<255?r(n):""):void 0):void 0}},{key:"hslString",value:function(){return this._valid?function(t){if(t){var e=tq(t),r=e[0],n=tR(e[1]),i=tR(e[2]);return t.a<255?"hsla(".concat(r,", ").concat(n,"%, ").concat(i,"%, ").concat(tB(t.a),")"):"hsl(".concat(r,", ").concat(n,"%, ").concat(i,"%)")}}(this._rgb):void 0}},{key:"mix",value:function(t,e){if(t){var r,n=this.rgb,i=t.rgb,a=e===r?.5:e,o=2*a-1,s=n.a-i.a,l=((o*s==-1?o:(o+s)/(1+o*s))+1)/2;r=1-l,n.r=255&l*n.r+r*i.r+.5,n.g=255&l*n.g+r*i.g+.5,n.b=255&l*n.b+r*i.b+.5,n.a=a*n.a+(1-a)*i.a,this.rgb=n}return this}},{key:"interpolate",value:function(t,e){if(t){var r,n,i,a,o;this._rgb=(r=this._rgb,n=t._rgb,i=t1(tB(r.r)),a=t1(tB(r.g)),o=t1(tB(r.b)),{r:tL(t0(i+e*(t1(tB(n.r))-i))),g:tL(t0(a+e*(t1(tB(n.g))-a))),b:tL(t0(o+e*(t1(tB(n.b))-o))),a:r.a+e*(n.a-r.a)})}return this}},{key:"clone",value:function(){return new t(this.rgb)}},{key:"alpha",value:function(t){return this._rgb.a=tL(t),this}},{key:"clearer",value:function(t){var e=this._rgb;return e.a*=1-t,this}},{key:"greyscale",value:function(){var t=this._rgb,e=tT(.3*t.r+.59*t.g+.11*t.b);return t.r=t.g=t.b=e,this}},{key:"opaquer",value:function(t){var e=this._rgb;return e.a*=1+t,this}},{key:"negate",value:function(){var t=this._rgb;return t.r=255-t.r,t.g=255-t.g,t.b=255-t.b,this}},{key:"lighten",value:function(t){return t2(this._rgb,2,t),this}},{key:"darken",value:function(t){return t2(this._rgb,2,-t),this}},{key:"saturate",value:function(t){return t2(this._rgb,1,t),this}},{key:"desaturate",value:function(t){return t2(this._rgb,1,-t),this}},{key:"rotate",value:function(t){var e,r;return(r=tq(e=this._rgb))[0]=tQ(r[0]+t),r=t$(tK,r,void 0,void 0),e.r=r[0],e.g=r[1],e.b=r[2],this}}]),t}();function t8(t){if(t&&"object"==typeof t){var e=t.toString();return"[object CanvasPattern]"===e||"[object CanvasGradient]"===e}return!1}function t4(t){return t8(t)?t:new t6(t)}function t7(t){return t8(t)?t:new t6(t).saturate(.5).darken(.1).hexString()}var t9=Object.create(null),et=Object.create(null);function ee(t,e){if(!e)return t;for(var r=e.split("."),n=0,i=r.length;nn&&(n=a),n}function eo(t,e,r,n){var i,a,o,s,l,u=(n=n||{}).data=n.data||{},c=n.garbageCollect=n.garbageCollect||[];n.font!==e&&(u=n.data={},c=n.garbageCollect=[],n.font=e),t.save(),t.font=e;var h=0,f=r.length;for(i=0;ir.length){for(i=0;i0&&t.stroke()}}function eh(t,e,r){return r=r||.5,!e||t&&t.x>e.left-r&&t.xe.top-r&&t.y5&&void 0!==arguments[5]?arguments[5]:{},l=p(e)?e:[e],u=s.strokeWidth>0&&""!==s.strokeColor;for(t.save(),t.font=i.string,s.translation&&t.translate(s.translation[0],s.translation[1]),d(s.rotation)||t.rotate(s.rotation),s.color&&(t.fillStyle=s.color),s.textAlign&&(t.textAlign=s.textAlign),s.textBaseline&&(t.textBaseline=s.textBaseline),a=0;a1&&void 0!==arguments[1]?arguments[1]:[""],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:t,i=arguments.length>3?arguments[3]:void 0,a=arguments.length>4&&void 0!==arguments[4]?arguments[4]:function(){return t[0]};return I(i)||(i=eI("_fallback",t)),new Proxy((e={},(0,l._)(e,Symbol.toStringTag,"Object"),(0,l._)(e,"_cacheable",!0),(0,l._)(e,"_scopes",t),(0,l._)(e,"_rootScopes",n),(0,l._)(e,"_fallback",i),(0,l._)(e,"_getTarget",a),(0,l._)(e,"override",function(e){return eC([e].concat((0,u._)(t)),r,n,i)}),e),{deleteProperty:function(e,r){return delete e[r],delete e._keys,delete t[0][r],!0},get:function(e,n){return ej(e,n,function(){return function(t,e,r,n){var i=!0,a=!1,o=void 0;try{for(var s,l,u=e[Symbol.iterator]();!(i=(l=u.next()).done);i=!0){var c=l.value;if(s=eI(c?c+F(t):t,r),I(s))return eD(t,s)?eT(r,n,t,s):s}}catch(t){a=!0,o=t}finally{try{i||null==u.return||u.return()}finally{if(a)throw o}}}(n,r,t,e)})},getOwnPropertyDescriptor:function(t,e){return Reflect.getOwnPropertyDescriptor(t._scopes[0],e)},getPrototypeOf:function(){return Reflect.getPrototypeOf(t[0])},has:function(t,e){return eL(t).includes(e)},ownKeys:function(t){return eL(t)},set:function(t,e,r){var n=t._storage||(t._storage=a());return t[e]=n[e]=r,delete t._keys,!0}})}function eP(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{scriptable:!0,indexable:!0},r=t._scriptable,n=void 0===r?e.scriptable:r,i=t._indexable,a=void 0===i?e.indexable:i,o=t._allKeys;return{allKeys:void 0===o?e.allKeys:o,scriptable:n,indexable:a,isScriptable:L(n)?n:function(){return n},isIndexable:L(a)?a:function(){return a}}}var eD=function(t,e){return v(e)&&"adapters"!==t&&(null===Object.getPrototypeOf(e)||e.constructor===Object)};function ej(t,e,r){if(Object.prototype.hasOwnProperty.call(t,e))return t[e];var n=r();return t[e]=n,n}function eT(t,e,r,n){var i,a=e._rootScopes,o=L(i=e._fallback)?i(r,n):i,s=(0,u._)(t).concat((0,u._)(a)),l=new Set;l.add(n);var c=eF(l,s,r,o||r,n);return!(null===c||I(o)&&o!==r&&null===(c=eF(l,s,o,c,n)))&&eC(Array.from(l),[""],a,o,function(){var t,i;return r in(t=e._getTarget())||(t[r]={}),p(i=t[r])&&v(n)?n:i})}function eF(t,e,r,n,i){for(;r;)r=function(t,e,r,n,i){var a=!0,o=!1,s=void 0;try{for(var l,u=e[Symbol.iterator]();!(a=(l=u.next()).done);a=!0){var c=l.value,h=!0===r?c:"string"==typeof r?j(c,r):void 0;if(h){t.add(h);var f,d=(f=h._fallback,L(f)?f(r,i):f);if(I(d)&&d!==r&&d!==n)return d}else if(!1===h&&I(n)&&r!==n)return null}}catch(t){o=!0,s=t}finally{try{a||null==u.return||u.return()}finally{if(o)throw s}}return!1}(t,e,r,n,i);return r}function eI(t,e){var r=!0,n=!1,i=void 0;try{for(var a,o=e[Symbol.iterator]();!(r=(a=o.next()).done);r=!0){var s=a.value;if(s){var l=s[t];if(I(l))return l}}}catch(t){n=!0,i=t}finally{try{r||null==o.return||o.return()}finally{if(n)throw i}}}function eL(t){var e=t._keys;return e||(e=t._keys=function(t){var e=new Set,r=!0,n=!1,i=void 0,a=!0,o=!1,s=void 0;try{for(var l,u=t[Symbol.iterator]();!(a=(l=u.next()).done);a=!0){var c=l.value;try{for(var h,f=Object.keys(c).filter(function(t){return!t.startsWith("_")})[Symbol.iterator]();!(r=(h=f.next()).done);r=!0){var d=h.value;e.add(d)}}catch(t){n=!0,i=t}finally{try{r||null==f.return||f.return()}finally{if(n)throw i}}}}catch(t){o=!0,s=t}finally{try{a||null==u.return||u.return()}finally{if(o)throw s}}return Array.from(e)}(t._scopes)),e}function eB(t,e,r,n){var i,a,o,s=t.iScale,l=this._parsing.key,u=void 0===l?"r":l,c=Array(n);for(i=0;i1&&void 0!==arguments[1]?arguments[1]:"x",a=eV(i),o=t.length,s=Array(o).fill(0),l=Array(o),u=eN(t,0);for(e=0;e2&&void 0!==arguments[2]?arguments[2]:"x",o=eV(a),s=t.length,l=eN(t,0),u=0;u0||l>0)&&(!r||!r.shadowRoot))n=s,i=l;else{var c=e.getBoundingClientRect();n=o.clientX-c.left,i=o.clientY-c.top,u=!0}return{x:n,y:i,box:u}}(t,r),u=l.x,c=l.y,h=l.box,f=o.left+(h&&s.left),d=o.top+(h&&s.top),p=e.width,v=e.height;return a&&(p-=o.width+s.width,v-=o.height+s.height),{x:Math.round((u-f)/p*r.width/n),y:Math.round((c-d)/v*r.height/n)}}var eZ=function(t){return Math.round(10*t)/10};function e0(t,e,r,n){var i=eq(t),a=eG(i,"margin"),o=eX(i.maxWidth,t,"clientWidth")||W,s=eX(i.maxHeight,t,"clientHeight")||W,l=function(t,e,r){var n,i;if(void 0===e||void 0===r){var a=eY(t);if(a){var o=a.getBoundingClientRect(),s=eq(a),l=eG(s,"border","width"),u=eG(s,"padding");e=o.width-u.width-l.width,r=o.height-u.height-l.height,n=eX(s.maxWidth,a,"clientWidth"),i=eX(s.maxHeight,a,"clientHeight")}else e=t.clientWidth,r=t.clientHeight}return{width:e,height:r,maxWidth:n||W,maxHeight:i||W}}(t,e,r),u=l.width,c=l.height;if("content-box"===i.boxSizing){var h=eG(i,"border","width"),f=eG(i,"padding");u-=f.width+h.width,c-=f.height+h.height}return u=Math.max(0,u-a.width),c=Math.max(0,n?Math.floor(u/n):c-a.height),u=eZ(Math.min(u,o,l.maxWidth)),c=eZ(Math.min(c,s,l.maxHeight)),u&&!c&&(c=eZ(u/2)),{width:u,height:c}}function e1(t,e,r){var n=e||1,i=Math.floor(t.height*n),a=Math.floor(t.width*n);t.height=i/n,t.width=a/n;var o=t.canvas;return o.style&&(r||!o.style.height&&!o.style.width)&&(o.style.height="".concat(t.height,"px"),o.style.width="".concat(t.width,"px")),(t.currentDevicePixelRatio!==n||o.height!==i||o.width!==a)&&(t.currentDevicePixelRatio=n,o.height=i,o.width=a,t.ctx.setTransform(n,0,0,n,0,0),!0)}var e2=function(){var t=!1;try{var e={get passive(){return t=!0,!1}};window.addEventListener("test",null,e),window.removeEventListener("test",null,e)}catch(t){}return t}();function e5(t,e){var r=e$(t,e),n=r&&r.match(/^(\d+)(\.\d+)?px$/);return n?+n[1]:void 0}function e3(t,e,r,n){return{x:t.x+r*(e.x-t.x),y:t.y+r*(e.y-t.y)}}function e6(t,e,r,n){return{x:t.x+r*(e.x-t.x),y:"middle"===n?r<.5?t.y:e.y:"after"===n?r<1?t.y:e.y:r>0?e.y:t.y}}function e8(t,e,r,n){var i={x:t.cp2x,y:t.cp2y},a={x:e.cp1x,y:e.cp1y},o=e3(t,i,r),s=e3(i,a,r),l=e3(a,e,r),u=e3(o,s,r),c=e3(s,l,r);return e3(u,c,r)}var e4=new Map;function e7(t,e,r){var n,i,a;return(i=e+JSON.stringify(n=(n=r)||{}),(a=e4.get(i))||(a=new Intl.NumberFormat(e,n),e4.set(i,a)),a).format(t)}function e9(t,e,r){var n;return t?(n=r,{x:function(t){return e+e+n-t},setWidth:function(t){n=t},textAlign:function(t){return"center"===t?t:"right"===t?"left":"right"},xPlus:function(t,e){return t-e},leftForLtr:function(t,e){return t-e}}):{x:function(t){return t},setWidth:function(t){},textAlign:function(t){return t},xPlus:function(t,e){return t+e},leftForLtr:function(t,e){return t}}}function rt(t,e){var r,n;("ltr"===e||"rtl"===e)&&(n=[(r=t.canvas.style).getPropertyValue("direction"),r.getPropertyPriority("direction")],r.setProperty("direction",e,"important"),t.prevTextDirection=n)}function re(t,e){void 0!==e&&(delete t.prevTextDirection,t.canvas.style.setProperty("direction",e[0],e[1]))}function rr(t){return"angle"===t?{between:tl,compare:to,normalize:ts}:{between:th,compare:function(t,e){return t-e},normalize:function(t){return t}}}function rn(t){var e=t.start,r=t.end,n=t.count;return{start:e%n,end:r%n,loop:t.loop&&(r-e+1)%n==0,style:t.style}}function ri(t,e,r){if(!r)return[t];for(var n,i,a,o=r.property,s=r.start,l=r.end,u=e.length,c=rr(o),h=c.compare,f=c.between,d=c.normalize,p=function(t,e,r){var n,i=r.property,a=r.start,o=r.end,s=rr(i),l=s.between,u=s.normalize,c=e.length,h=t.start,f=t.end,d=t.loop;if(d){for(h+=c,f+=c,n=0;ni&&t[a%e].skip;)a--;return{start:i,end:a%=e}}(r,i,a,n),s=o.start,l=o.end;if(!0===n)return rs(t,[{start:s,end:l,loop:a}],r,e);var u=l0){this.model=e||"rgb",n=s[this.model].channels;var c=Array.prototype.slice.call(t,0,n);this.color=S(c,n),this.valpha="number"==typeof t[n]?t[n]:1}else if("number"==typeof t)this.model="rgb",this.color=[t>>16&255,t>>8&255,255&t],this.valpha=1;else{this.valpha=1;var h=Object.keys(t);"alpha"in t&&(h.splice(h.indexOf("alpha"),1),this.valpha="number"==typeof t.alpha?t.alpha:0);var f=h.sort().join("");if(!(f in u))throw Error("Unable to parse color from object: "+JSON.stringify(t));this.model=u[f];var d=s[this.model].labels,p=[];for(r=0;rr?(e+.05)/(r+.05):(r+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return e>=7?"AAA":e>=4.5?"AA":""},isDark:function(){var t=this.rgb().color;return(2126*t[0]+7152*t[1]+722*t[2])/1e4<128},isLight:function(){return!this.isDark()},negate:function(){for(var t=this.rgb(),e=0;e<3;e++)t.color[e]=255-t.color[e];return t},lighten:function(t){var e=this.hsl();return e.color[2]+=e.color[2]*t,e},darken:function(t){var e=this.hsl();return e.color[2]-=e.color[2]*t,e},saturate:function(t){var e=this.hsl();return e.color[1]+=e.color[1]*t,e},desaturate:function(t){var e=this.hsl();return e.color[1]-=e.color[1]*t,e},whiten:function(t){var e=this.hwb();return e.color[1]+=e.color[1]*t,e},blacken:function(t){var e=this.hwb();return e.color[2]+=e.color[2]*t,e},grayscale:function(){var t=this.rgb().color,e=.3*t[0]+.59*t[1]+.11*t[2];return y.rgb(e,e,e)},fade:function(t){return this.alpha(this.valpha-this.valpha*t)},opaquer:function(t){return this.alpha(this.valpha+this.valpha*t)},rotate:function(t){var e=this.hsl(),r=e.color[0];return r=(r=(r+t)%360)<0?360+r:r,e.color[0]=r,e},mix:function(t,e){if(!t||!t.rgb)throw Error('Argument to "mix" was not a Color instance, but rather an instance of '+(void 0===t?"undefined":(0,a._)(t)));var r=t.rgb(),n=this.rgb(),i=void 0===e?.5:e,o=2*i-1,s=r.alpha()-n.alpha(),l=((o*s==-1?o:(o+s)/(1+o*s))+1)/2,u=1-l;return y.rgb(l*r.red()+u*n.red(),l*r.green()+u*n.green(),l*r.blue()+u*n.blue(),r.alpha()*i+n.alpha()*(1-i))}};var m=!0,b=!1,_=void 0;try{for(var x,k=Object.keys(s)[Symbol.iterator]();!(m=(x=k.next()).done);m=!0)!function(){var t=x.value;if(!l.includes(t)){var e=s[t].channels;y.prototype[t]=function(){for(var e,r=arguments.length,n=Array(r),a=0;a0?new y(n,t):new y((0,i._)((e=s[this.model][t].raw(this.color),Array.isArray(e)?e:[e])).concat([this.valpha]),t)},y[t]=function(){for(var r=arguments.length,n=Array(r),i=0;i=4&&1!==t[3]&&(e=", "+t[3]),"hwb("+t[0]+", "+t[1]+"%, "+t[2]+"%"+e+")"},l.to.keyword=function(t){return o[t.slice(0,3)]}},{d7a6eeb7388b4bb:"9CRqC","248ce9e419a8df53":"7SGVb"}],"9CRqC":[function(t,e,r){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]}},{}],"7SGVb":[function(t,e,r){var n=t("ce0bf6d0bc000d24"),i=Array.prototype.concat,a=Array.prototype.slice,o=e.exports=function(t){for(var e=[],r=0,o=t.length;r=0&&(t.splice instanceof Function||Object.getOwnPropertyDescriptor(t,t.length-1)&&"String"!==t.constructor.name))}},{}],b0bZu:[function(t,e,r){var n=t("739980f7990d3c32"),i=t("30ea0c7ee5f3dd94"),a={};Object.keys(n).forEach(function(t){a[t]={},Object.defineProperty(a[t],"channels",{value:n[t].channels}),Object.defineProperty(a[t],"labels",{value:n[t].labels});var e=i(t);Object.keys(e).forEach(function(r){var n,i,o=e[r];a[t][r]=(n=function(){for(var t=arguments.length,e=Array(t),r=0;r1&&(e=n);var i=o(e);if("object"==typeof i)for(var a=i.length,s=0;s1&&(e=n),o(e))},"conversion"in o&&(i.conversion=o.conversion),i)})}),e.exports=a},{"739980f7990d3c32":"bLCsr","30ea0c7ee5f3dd94":"B0afd"}],bLCsr:[function(t,e,r){var n=t("@swc/helpers/_/_sliced_to_array"),i=t("efc99055946c4df8"),a={},o=!0,s=!1,l=void 0;try{for(var u,c=Object.keys(i)[Symbol.iterator]();!(o=(u=c.next()).done);o=!0){var h=u.value;a[i[h]]=h}}catch(t){s=!0,l=t}finally{try{o||null==c.return||c.return()}finally{if(s)throw l}}var f={rgb:{channels:3,labels:"rgb"},hsl:{channels:3,labels:"hsl"},hsv:{channels:3,labels:"hsv"},hwb:{channels:3,labels:"hwb"},cmyk:{channels:4,labels:"cmyk"},xyz:{channels:3,labels:"xyz"},lab:{channels:3,labels:"lab"},lch:{channels:3,labels:"lch"},hex:{channels:1,labels:["hex"]},keyword:{channels:1,labels:["keyword"]},ansi16:{channels:1,labels:["ansi16"]},ansi256:{channels:1,labels:["ansi256"]},hcg:{channels:3,labels:["h","c","g"]},apple:{channels:3,labels:["r16","g16","b16"]},gray:{channels:1,labels:["gray"]}};e.exports=f;var d=!0,p=!1,v=void 0;try{for(var g,y=Object.keys(f)[Symbol.iterator]();!(d=(g=y.next()).done);d=!0){var m=g.value;if(!("channels"in f[m]))throw Error("missing channels property: "+m);if(!("labels"in f[m]))throw Error("missing channel labels property: "+m);if(f[m].labels.length!==f[m].channels)throw Error("channel and label counts mismatch: "+m);var b=f[m],_=b.channels,x=b.labels;delete f[m].channels,delete f[m].labels,Object.defineProperty(f[m],"channels",{value:_}),Object.defineProperty(f[m],"labels",{value:x})}}catch(t){p=!0,v=t}finally{try{d||null==y.return||y.return()}finally{if(p)throw v}}f.rgb.hsl=function(t){var e,r=t[0]/255,n=t[1]/255,i=t[2]/255,a=Math.min(r,n,i),o=Math.max(r,n,i),s=o-a;o===a?e=0:r===o?e=(n-i)/s:n===o?e=2+(i-r)/s:i===o&&(e=4+(r-n)/s),(e=Math.min(60*e,360))<0&&(e+=360);var l=(a+o)/2;return[e,100*(o===a?0:l<=.5?s/(o+a):s/(2-o-a)),100*l]},f.rgb.hsv=function(t){var e,r,n,i,a,o=t[0]/255,s=t[1]/255,l=t[2]/255,u=Math.max(o,s,l),c=u-Math.min(o,s,l),h=function(t){return(u-t)/6/c+.5};return 0===c?(i=0,a=0):(a=c/u,e=h(o),r=h(s),n=h(l),o===u?i=n-r:s===u?i=1/3+e-n:l===u&&(i=2/3+r-e),i<0?i+=1:i>1&&(i-=1)),[360*i,100*a,100*u]},f.rgb.hwb=function(t){var e=t[0],r=t[1],n=t[2];return[f.rgb.hsl(t)[0],1/255*Math.min(e,Math.min(r,n))*100,100*(n=1-1/255*Math.max(e,Math.max(r,n)))]},f.rgb.cmyk=function(t){var e=t[0]/255,r=t[1]/255,n=t[2]/255,i=Math.min(1-e,1-r,1-n);return[100*((1-e-i)/(1-i)||0),100*((1-r-i)/(1-i)||0),100*((1-n-i)/(1-i)||0),100*i]},f.rgb.keyword=function(t){var e=a[t];if(e)return e;var r=1/0,n=!0,o=!1,s=void 0;try{for(var l,u,c=Object.keys(i)[Symbol.iterator]();!(n=(u=c.next()).done);n=!0){var h=u.value,f=i[h],d=Math.pow(t[0]-f[0],2)+Math.pow(t[1]-f[1],2)+Math.pow(t[2]-f[2],2);d.04045?Math.pow((e+.055)/1.055,2.4):e/12.92)+.3576*(r=r>.04045?Math.pow((r+.055)/1.055,2.4):r/12.92)+.1805*(n=n>.04045?Math.pow((n+.055)/1.055,2.4):n/12.92)),100*(.2126*e+.7152*r+.0722*n),100*(.0193*e+.1192*r+.9505*n)]},f.rgb.lab=function(t){var e=f.rgb.xyz(t),r=e[0],n=e[1],i=e[2];return r/=95.047,n/=100,i/=108.883,r=r>.008856?Math.pow(r,1/3):7.787*r+16/116,[116*(n=n>.008856?Math.pow(n,1/3):7.787*n+16/116)-16,500*(r-n),200*(n-(i=i>.008856?Math.pow(i,1/3):7.787*i+16/116))]},f.hsl.rgb=function(t){var e,r,n,i=t[0]/360,a=t[1]/100,o=t[2]/100;if(0===a)return[n=255*o,n,n];e=o<.5?o*(1+a):o+a-o*a;for(var s=2*o-e,l=[0,0,0],u=0;u<3;u++)(r=i+-(1/3*(u-1)))<0&&r++,r>1&&r--,n=6*r<1?s+(e-s)*6*r:2*r<1?e:3*r<2?s+(e-s)*(2/3-r)*6:s,l[u]=255*n;return l},f.hsl.hsv=function(t){var e=t[0],r=t[1]/100,n=t[2]/100,i=r,a=Math.max(n,.01);n*=2,r*=n<=1?n:2-n,i*=a<=1?a:2-a;var o=(n+r)/2;return[e,100*(0===n?2*i/(a+i):2*r/(n+r)),100*o]},f.hsv.rgb=function(t){var e=t[0]/60,r=t[1]/100,n=t[2]/100,i=e-Math.floor(e),a=255*n*(1-r),o=255*n*(1-r*i),s=255*n*(1-r*(1-i));switch(n*=255,Math.floor(e)%6){case 0:return[n,s,a];case 1:return[o,n,a];case 2:return[a,n,s];case 3:return[a,o,n];case 4:return[s,a,n];case 5:return[n,a,o]}},f.hsv.hsl=function(t){var e,r,n=t[0],i=t[1]/100,a=t[2]/100,o=Math.max(a,.01);r=(2-i)*a;var s=(2-i)*o;return[n,100*(i*o/(s<=1?s:2-s)||0),100*(r/=2)]},f.hwb.rgb=function(t){var e,r,n,i,a=t[0]/360,o=t[1]/100,s=t[2]/100,l=o+s;l>1&&(o/=l,s/=l);var u=Math.floor(6*a),c=1-s;e=6*a-u,(1&u)!=0&&(e=1-e);var h=o+e*(c-o);switch(u){default:case 6:case 0:r=c,n=h,i=o;break;case 1:r=h,n=c,i=o;break;case 2:r=o,n=c,i=h;break;case 3:r=o,n=h,i=c;break;case 4:r=h,n=o,i=c;break;case 5:r=c,n=o,i=h}return[255*r,255*n,255*i]},f.cmyk.rgb=function(t){var e=t[0]/100,r=t[1]/100,n=t[2]/100,i=t[3]/100;return[255*(1-Math.min(1,e*(1-i)+i)),255*(1-Math.min(1,r*(1-i)+i)),255*(1-Math.min(1,n*(1-i)+i))]},f.xyz.rgb=function(t){var e,r,n,i=t[0]/100,a=t[1]/100,o=t[2]/100;return e=3.2406*i+-1.5372*a+-.4986*o,r=-.9689*i+1.8758*a+.0415*o,n=.0557*i+-.204*a+1.057*o,e=e>.0031308?1.055*Math.pow(e,1/2.4)-.055:12.92*e,r=r>.0031308?1.055*Math.pow(r,1/2.4)-.055:12.92*r,n=n>.0031308?1.055*Math.pow(n,1/2.4)-.055:12.92*n,[255*(e=Math.min(Math.max(0,e),1)),255*(r=Math.min(Math.max(0,r),1)),255*(n=Math.min(Math.max(0,n),1))]},f.xyz.lab=function(t){var e=t[0],r=t[1],n=t[2];return e/=95.047,r/=100,n/=108.883,e=e>.008856?Math.pow(e,1/3):7.787*e+16/116,[116*(r=r>.008856?Math.pow(r,1/3):7.787*r+16/116)-16,500*(e-r),200*(r-(n=n>.008856?Math.pow(n,1/3):7.787*n+16/116))]},f.lab.xyz=function(t){var e,r,n,i=t[0],a=t[1],o=t[2];e=a/500+(r=(i+16)/116),n=r-o/200;var s=Math.pow(r,3),l=Math.pow(e,3),u=Math.pow(n,3);return r=(s>.008856?s:(r-16/116)/7.787)*100,[e=(l>.008856?l:(e-16/116)/7.787)*95.047,r,n=(u>.008856?u:(n-16/116)/7.787)*108.883]},f.lab.lch=function(t){var e,r=t[0],n=t[1],i=t[2];return(e=360*Math.atan2(i,n)/2/Math.PI)<0&&(e+=360),[r,Math.sqrt(n*n+i*i),e]},f.lch.lab=function(t){var e=t[0],r=t[1],n=t[2]/360*2*Math.PI;return[e,r*Math.cos(n),r*Math.sin(n)]},f.rgb.ansi16=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,r=(0,n._)(t,3),i=r[0],a=r[1],o=r[2],s=null===e?f.rgb.hsv(t)[2]:e;if(0===(s=Math.round(s/50)))return 30;var l=30+(Math.round(o/255)<<2|Math.round(a/255)<<1|Math.round(i/255));return 2===s&&(l+=60),l},f.hsv.ansi16=function(t){return f.rgb.ansi16(f.hsv.rgb(t),t[2])},f.rgb.ansi256=function(t){var e=t[0],r=t[1],n=t[2];return e===r&&r===n?e<8?16:e>248?231:Math.round((e-8)/247*24)+232:16+36*Math.round(e/255*5)+6*Math.round(r/255*5)+Math.round(n/255*5)},f.ansi16.rgb=function(t){var e=t%10;if(0===e||7===e)return t>50&&(e+=3.5),[e=e/10.5*255,e,e];var r=(~~(t>50)+1)*.5;return[(1&e)*r*255,(e>>1&1)*r*255,(e>>2&1)*r*255]},f.ansi256.rgb=function(t){if(t>=232){var e,r=(t-232)*10+8;return[r,r,r]}return[Math.floor((t-=16)/36)/5*255,Math.floor((e=t%36)/6)/5*255,e%6/5*255]},f.rgb.hex=function(t){var e=(((255&Math.round(t[0]))<<16)+((255&Math.round(t[1]))<<8)+(255&Math.round(t[2]))).toString(16).toUpperCase();return"000000".substring(e.length)+e},f.hex.rgb=function(t){var e=t.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!e)return[0,0,0];var r=e[0];3===e[0].length&&(r=r.split("").map(function(t){return t+t}).join(""));var n=parseInt(r,16);return[n>>16&255,n>>8&255,255&n]},f.rgb.hcg=function(t){var e,r=t[0]/255,n=t[1]/255,i=t[2]/255,a=Math.max(Math.max(r,n),i),o=Math.min(Math.min(r,n),i),s=a-o;return e=s<1?o/(1-s):0,[(s<=0?0:a===r?(n-i)/s%6:a===n?2+(i-r)/s:4+(r-n)/s)/6%1*360,100*s,100*e]},f.hsl.hcg=function(t){var e=t[1]/100,r=t[2]/100,n=r<.5?2*e*r:2*e*(1-r),i=0;return n<1&&(i=(r-.5*n)/(1-n)),[t[0],100*n,100*i]},f.hsv.hcg=function(t){var e=t[1]/100,r=t[2]/100,n=e*r,i=0;return n<1&&(i=(r-n)/(1-n)),[t[0],100*n,100*i]},f.hcg.rgb=function(t){var e=t[0]/360,r=t[1]/100,n=t[2]/100;if(0===r)return[255*n,255*n,255*n];var i=[0,0,0],a=e%1*6,o=a%1,s=1-o,l=0;switch(Math.floor(a)){case 0:i[0]=1,i[1]=o,i[2]=0;break;case 1:i[0]=s,i[1]=1,i[2]=0;break;case 2:i[0]=0,i[1]=1,i[2]=o;break;case 3:i[0]=0,i[1]=s,i[2]=1;break;case 4:i[0]=o,i[1]=0,i[2]=1;break;default:i[0]=1,i[1]=0,i[2]=s}return l=(1-r)*n,[(r*i[0]+l)*255,(r*i[1]+l)*255,(r*i[2]+l)*255]},f.hcg.hsv=function(t){var e=t[1]/100,r=e+t[2]/100*(1-e),n=0;return r>0&&(n=e/r),[t[0],100*n,100*r]},f.hcg.hsl=function(t){var e=t[1]/100,r=t[2]/100*(1-e)+.5*e,n=0;return r>0&&r<.5?n=e/(2*r):r>=.5&&r<1&&(n=e/(2*(1-r))),[t[0],100*n,100*r]},f.hcg.hwb=function(t){var e=t[1]/100,r=e+t[2]/100*(1-e);return[t[0],(r-e)*100,(1-r)*100]},f.hwb.hcg=function(t){var e=t[1]/100,r=1-t[2]/100,n=r-e,i=0;return n<1&&(i=(r-n)/(1-n)),[t[0],100*n,100*i]},f.apple.rgb=function(t){return[t[0]/65535*255,t[1]/65535*255,t[2]/65535*255]},f.rgb.apple=function(t){return[t[0]/255*65535,t[1]/255*65535,t[2]/255*65535]},f.gray.rgb=function(t){return[t[0]/100*255,t[0]/100*255,t[0]/100*255]},f.gray.hsl=function(t){return[0,0,t[0]]},f.gray.hsv=f.gray.hsl,f.gray.hwb=function(t){return[0,100,t[0]]},f.gray.cmyk=function(t){return[0,0,0,t[0]]},f.gray.lab=function(t){return[t[0],0,0]},f.gray.hex=function(t){var e=255&Math.round(t[0]/100*255),r=((e<<16)+(e<<8)+e).toString(16).toUpperCase();return"000000".substring(r.length)+r},f.rgb.gray=function(t){return[(t[0]+t[1]+t[2])/3/255*100]}},{"@swc/helpers/_/_sliced_to_array":"hefcy",efc99055946c4df8:"9CRqC"}],B0afd:[function(t,e,r){var n=t("22442592002c5ac3");e.exports=function(t){for(var e=function(t){var e=function(){for(var t={},e=Object.keys(n),r=e.length,i=0;i0}},{key:"bindings",get:function(){return Array.from(this.unorderedBindings).sort(function(t,e){var n=t.index,r=e.index;return nr?1:0})}}]),t}(),m=function(){function t(e){(0,A._)(this,t),this.application=e,this.eventListenerMaps=new Map,this.started=!1}return(0,o._)(t,[{key:"start",value:function(){this.started||(this.started=!0,this.eventListeners.forEach(function(t){return t.connect()}))}},{key:"stop",value:function(){this.started&&(this.started=!1,this.eventListeners.forEach(function(t){return t.disconnect()}))}},{key:"eventListeners",get:function(){return Array.from(this.eventListenerMaps.values()).reduce(function(t,e){return t.concat(Array.from(e.values()))},[])}},{key:"bindingConnected",value:function(t){this.fetchEventListenerForBinding(t).bindingConnected(t)}},{key:"bindingDisconnected",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];this.fetchEventListenerForBinding(t).bindingDisconnected(t),e&&this.clearEventListenersForBinding(t)}},{key:"handleError",value:function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};this.application.handleError(t,"Error ".concat(e),n)}},{key:"clearEventListenersForBinding",value:function(t){var e=this.fetchEventListenerForBinding(t);e.hasBindings()||(e.disconnect(),this.removeMappedEventListenerFor(t))}},{key:"removeMappedEventListenerFor",value:function(t){var e=t.eventTarget,n=t.eventName,r=t.eventOptions,i=this.fetchEventListenerMapForEventTarget(e),A=this.cacheKey(n,r);i.delete(A),0==i.size&&this.eventListenerMaps.delete(e)}},{key:"fetchEventListenerForBinding",value:function(t){var e=t.eventTarget,n=t.eventName,r=t.eventOptions;return this.fetchEventListener(e,n,r)}},{key:"fetchEventListener",value:function(t,e,n){var r=this.fetchEventListenerMapForEventTarget(t),i=this.cacheKey(e,n),A=r.get(i);return A||(A=this.createEventListener(t,e,n),r.set(i,A)),A}},{key:"createEventListener",value:function(t,e,n){var r=new g(t,e,n);return this.started&&r.connect(),r}},{key:"fetchEventListenerMapForEventTarget",value:function(t){var e=this.eventListenerMaps.get(t);return e||(e=new Map,this.eventListenerMaps.set(t,e)),e}},{key:"cacheKey",value:function(t,e){var n=[t];return Object.keys(e).sort().forEach(function(t){n.push("".concat(e[t]?"":"!").concat(t))}),n.join(":")}}]),t}(),v={stop:function(t){var e=t.event;return t.value&&e.stopPropagation(),!0},prevent:function(t){var e=t.event;return t.value&&e.preventDefault(),!0},self:function(t){var e=t.event,n=t.value,r=t.element;return!n||r===e.target}},y=/^(?:(?:([^.]+?)\+)?(.+?)(?:\.(.+?))?(?:@(window|document))?->)?(.+?)(?:#([^:]+?))(?::(.+))?$/;function w(t){return t.replace(/(?:[_-])([a-z0-9])/g,function(t,e){return e.toUpperCase()})}function b(t){return w(t.replace(/--/g,"-").replace(/__/g,"_"))}function B(t){return t.charAt(0).toUpperCase()+t.slice(1)}function _(t){return t.replace(/([A-Z])/g,function(t,e){return"-".concat(e.toLowerCase())})}function C(t,e){return Object.prototype.hasOwnProperty.call(t,e)}var x=["meta","ctrl","alt","shift"],k=function(){function t(e,n,r,i){(0,A._)(this,t),this.element=e,this.index=n,this.eventTarget=r.eventTarget||e,this.eventName=r.eventName||function(t){var e=t.tagName.toLowerCase();if(e in F)return F[e](t)}(e)||Q("missing event name"),this.eventOptions=r.eventOptions||{},this.identifier=r.identifier||Q("missing identifier"),this.methodName=r.methodName||Q("missing method name"),this.keyFilter=r.keyFilter||"",this.schema=i}return(0,o._)(t,[{key:"toString",value:function(){var t=this.keyFilter?".".concat(this.keyFilter):"",e=this.eventTargetName?"@".concat(this.eventTargetName):"";return"".concat(this.eventName).concat(t).concat(e,"->").concat(this.identifier,"#").concat(this.methodName)}},{key:"shouldIgnoreKeyboardEvent",value:function(t){if(!this.keyFilter)return!1;var e=this.keyFilter.split("+");if(this.keyFilterDissatisfied(t,e))return!0;var n=e.filter(function(t){return!x.includes(t)})[0];return!!n&&(C(this.keyMappings,n)||Q("contains unknown key filter: ".concat(this.keyFilter)),this.keyMappings[n].toLowerCase()!==t.key.toLowerCase())}},{key:"shouldIgnoreMouseEvent",value:function(t){if(!this.keyFilter)return!1;var e=[this.keyFilter];return!!this.keyFilterDissatisfied(t,e)}},{key:"params",get:function(){var t={},e=RegExp("^data-".concat(this.identifier,"-(.+)-param$"),"i"),n=!0,r=!1,i=void 0;try{for(var A,o=Array.from(this.element.attributes)[Symbol.iterator]();!(n=(A=o.next()).done);n=!0){var s=A.value,a=s.name,l=s.value,c=a.match(e),u=c&&c[1];u&&(t[w(u)]=function(t){try{return JSON.parse(t)}catch(e){return t}}(l))}}catch(t){r=!0,i=t}finally{try{n||null==o.return||o.return()}finally{if(r)throw i}}return t}},{key:"eventTargetName",get:function(){var t;return(t=this.eventTarget)==window?"window":t==document?"document":void 0}},{key:"keyMappings",get:function(){return this.schema.keyMappings}},{key:"keyFilterDissatisfied",value:function(t,e){var n=(0,u._)(x.map(function(t){return e.includes(t)}),4),r=n[0],i=n[1],A=n[2],o=n[3];return t.metaKey!==r||t.ctrlKey!==i||t.altKey!==A||t.shiftKey!==o}}],[{key:"forToken",value:function(t,e){var n,r,i,A;return new this(t.element,t.index,(r=(n=t.content.trim().match(y)||[])[2],(i=n[3])&&!["keydown","keyup","keypress"].includes(r)&&(r+=".".concat(i),i=""),{eventTarget:"window"==(A=n[4])?window:"document"==A?document:void 0,eventName:r,eventOptions:n[7]?n[7].split(":").reduce(function(t,e){return Object.assign(t,(0,s._)({},e.replace(/^!/,""),!/^!/.test(e)))},{}):{},identifier:n[5],methodName:n[6],keyFilter:n[1]||i}),e)}}]),t}(),F={a:function(){return"click"},button:function(){return"click"},form:function(){return"submit"},details:function(){return"toggle"},input:function(t){return"submit"==t.getAttribute("type")?"click":"input"},select:function(){return"change"},textarea:function(){return"input"}};function Q(t){throw Error(t)}var E=function(){function t(e,n){(0,A._)(this,t),this.context=e,this.action=n}return(0,o._)(t,[{key:"index",get:function(){return this.action.index}},{key:"eventTarget",get:function(){return this.action.eventTarget}},{key:"eventOptions",get:function(){return this.action.eventOptions}},{key:"identifier",get:function(){return this.context.identifier}},{key:"handleEvent",value:function(t){var e=this.prepareActionEvent(t);this.willBeInvokedByEvent(t)&&this.applyEventModifiers(e)&&this.invokeWithEvent(e)}},{key:"eventName",get:function(){return this.action.eventName}},{key:"method",get:function(){var t=this.controller[this.methodName];if("function"==typeof t)return t;throw Error('Action "'.concat(this.action,'" references undefined method "').concat(this.methodName,'"'))}},{key:"applyEventModifiers",value:function(t){var e=this.action.element,n=this.context.application.actionDescriptorFilters,r=this.context.controller,i=!0,A=!0,o=!1,s=void 0;try{for(var a,l=Object.entries(this.eventOptions)[Symbol.iterator]();!(A=(a=l.next()).done);A=!0){var c=(0,u._)(a.value,2),h=c[0],d=c[1];if(h in n){var f=n[h];i=i&&f({name:h,value:d,event:t,element:e,controller:r})}}}catch(t){o=!0,s=t}finally{try{A||null==l.return||l.return()}finally{if(o)throw s}}return i}},{key:"prepareActionEvent",value:function(t){return Object.assign(t,{params:this.action.params})}},{key:"invokeWithEvent",value:function(t){var e=t.target,n=t.currentTarget;try{this.method.call(this.controller,t),this.context.logDebugActivity(this.methodName,{event:t,target:e,currentTarget:n,action:this.methodName})}catch(e){var r=this.identifier,i=this.controller,A=this.element,o=this.index;this.context.handleError(e,'invoking action "'.concat(this.action,'"'),{identifier:r,controller:i,element:A,index:o,event:t})}}},{key:"willBeInvokedByEvent",value:function(t){var e=t.target;return!(t instanceof KeyboardEvent&&this.action.shouldIgnoreKeyboardEvent(t)||t instanceof MouseEvent&&this.action.shouldIgnoreMouseEvent(t))&&(this.element===e||(e instanceof Element&&this.element.contains(e)?this.scope.containsElement(e):this.scope.containsElement(this.action.element)))}},{key:"controller",get:function(){return this.context.controller}},{key:"methodName",get:function(){return this.action.methodName}},{key:"element",get:function(){return this.scope.element}},{key:"scope",get:function(){return this.context.scope}}]),t}(),S=function(){function t(e,n){var r=this;(0,A._)(this,t),this.mutationObserverInit={attributes:!0,childList:!0,subtree:!0},this.element=e,this.started=!1,this.delegate=n,this.elements=new Set,this.mutationObserver=new MutationObserver(function(t){return r.processMutations(t)})}return(0,o._)(t,[{key:"start",value:function(){this.started||(this.started=!0,this.mutationObserver.observe(this.element,this.mutationObserverInit),this.refresh())}},{key:"pause",value:function(t){this.started&&(this.mutationObserver.disconnect(),this.started=!1),t(),this.started||(this.mutationObserver.observe(this.element,this.mutationObserverInit),this.started=!0)}},{key:"stop",value:function(){this.started&&(this.mutationObserver.takeRecords(),this.mutationObserver.disconnect(),this.started=!1)}},{key:"refresh",value:function(){if(this.started){var t=new Set(this.matchElementsInTree()),e=!0,n=!1,r=void 0;try{for(var i,A=Array.from(this.elements)[Symbol.iterator]();!(e=(i=A.next()).done);e=!0){var o=i.value;t.has(o)||this.removeElement(o)}}catch(t){n=!0,r=t}finally{try{e||null==A.return||A.return()}finally{if(n)throw r}}var s=!0,a=!1,l=void 0;try{for(var c,u=Array.from(t)[Symbol.iterator]();!(s=(c=u.next()).done);s=!0){var h=c.value;this.addElement(h)}}catch(t){a=!0,l=t}finally{try{s||null==u.return||u.return()}finally{if(a)throw l}}}}},{key:"processMutations",value:function(t){var e=!0,n=!1,r=void 0;if(this.started)try{for(var i,A=t[Symbol.iterator]();!(e=(i=A.next()).done);e=!0){var o=i.value;this.processMutation(o)}}catch(t){n=!0,r=t}finally{try{e||null==A.return||A.return()}finally{if(n)throw r}}}},{key:"processMutation",value:function(t){"attributes"==t.type?this.processAttributeChange(t.target,t.attributeName):"childList"==t.type&&(this.processRemovedNodes(t.removedNodes),this.processAddedNodes(t.addedNodes))}},{key:"processAttributeChange",value:function(t,e){this.elements.has(t)?this.delegate.elementAttributeChanged&&this.matchElement(t)?this.delegate.elementAttributeChanged(t,e):this.removeElement(t):this.matchElement(t)&&this.addElement(t)}},{key:"processRemovedNodes",value:function(t){var e=!0,n=!1,r=void 0;try{for(var i,A=Array.from(t)[Symbol.iterator]();!(e=(i=A.next()).done);e=!0){var o=i.value,s=this.elementFromNode(o);s&&this.processTree(s,this.removeElement)}}catch(t){n=!0,r=t}finally{try{e||null==A.return||A.return()}finally{if(n)throw r}}}},{key:"processAddedNodes",value:function(t){var e=!0,n=!1,r=void 0;try{for(var i,A=Array.from(t)[Symbol.iterator]();!(e=(i=A.next()).done);e=!0){var o=i.value,s=this.elementFromNode(o);s&&this.elementIsActive(s)&&this.processTree(s,this.addElement)}}catch(t){n=!0,r=t}finally{try{e||null==A.return||A.return()}finally{if(n)throw r}}}},{key:"matchElement",value:function(t){return this.delegate.matchElement(t)}},{key:"matchElementsInTree",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.element;return this.delegate.matchElementsInTree(t)}},{key:"processTree",value:function(t,e){var n=!0,r=!1,i=void 0;try{for(var A,o=this.matchElementsInTree(t)[Symbol.iterator]();!(n=(A=o.next()).done);n=!0){var s=A.value;e.call(this,s)}}catch(t){r=!0,i=t}finally{try{n||null==o.return||o.return()}finally{if(r)throw i}}}},{key:"elementFromNode",value:function(t){if(t.nodeType==Node.ELEMENT_NODE)return t}},{key:"elementIsActive",value:function(t){return t.isConnected==this.element.isConnected&&this.element.contains(t)}},{key:"addElement",value:function(t){!this.elements.has(t)&&this.elementIsActive(t)&&(this.elements.add(t),this.delegate.elementMatched&&this.delegate.elementMatched(t))}},{key:"removeElement",value:function(t){this.elements.has(t)&&(this.elements.delete(t),this.delegate.elementUnmatched&&this.delegate.elementUnmatched(t))}}]),t}(),U=function(){function t(e,n,r){(0,A._)(this,t),this.attributeName=n,this.delegate=r,this.elementObserver=new S(e,this)}return(0,o._)(t,[{key:"element",get:function(){return this.elementObserver.element}},{key:"selector",get:function(){return"[".concat(this.attributeName,"]")}},{key:"start",value:function(){this.elementObserver.start()}},{key:"pause",value:function(t){this.elementObserver.pause(t)}},{key:"stop",value:function(){this.elementObserver.stop()}},{key:"refresh",value:function(){this.elementObserver.refresh()}},{key:"started",get:function(){return this.elementObserver.started}},{key:"matchElement",value:function(t){return t.hasAttribute(this.attributeName)}},{key:"matchElementsInTree",value:function(t){var e=this.matchElement(t)?[t]:[],n=Array.from(t.querySelectorAll(this.selector));return e.concat(n)}},{key:"elementMatched",value:function(t){this.delegate.elementMatchedAttribute&&this.delegate.elementMatchedAttribute(t,this.attributeName)}},{key:"elementUnmatched",value:function(t){this.delegate.elementUnmatchedAttribute&&this.delegate.elementUnmatchedAttribute(t,this.attributeName)}},{key:"elementAttributeChanged",value:function(t,e){this.delegate.elementAttributeValueChanged&&this.attributeName==e&&this.delegate.elementAttributeValueChanged(t,e)}}]),t}();function L(t,e,n){j(t,e).add(n)}function I(t,e,n){j(t,e).delete(n),M(t,e)}function j(t,e){var n=t.get(e);return n||(n=new Set,t.set(e,n)),n}function M(t,e){var n=t.get(e);null!=n&&0==n.size&&t.delete(e)}var D=function(){function t(){(0,A._)(this,t),this.valuesByKey=new Map}return(0,o._)(t,[{key:"keys",get:function(){return Array.from(this.valuesByKey.keys())}},{key:"values",get:function(){return Array.from(this.valuesByKey.values()).reduce(function(t,e){return t.concat(Array.from(e))},[])}},{key:"size",get:function(){return Array.from(this.valuesByKey.values()).reduce(function(t,e){return t+e.size},0)}},{key:"add",value:function(t,e){L(this.valuesByKey,t,e)}},{key:"delete",value:function(t,e){I(this.valuesByKey,t,e)}},{key:"has",value:function(t,e){var n=this.valuesByKey.get(t);return null!=n&&n.has(e)}},{key:"hasKey",value:function(t){return this.valuesByKey.has(t)}},{key:"hasValue",value:function(t){return Array.from(this.valuesByKey.values()).some(function(e){return e.has(t)})}},{key:"getValuesForKey",value:function(t){var e=this.valuesByKey.get(t);return e?Array.from(e):[]}},{key:"getKeysForValue",value:function(t){return Array.from(this.valuesByKey).filter(function(e){var n=(0,u._)(e,2);return(n[0],n[1]).has(t)}).map(function(t){var e=(0,u._)(t,2),n=e[0];return e[1],n})}}]),t}(),N=function(t){(0,c._)(n,t);var e=(0,f._)(n);function n(){var t;return(0,A._)(this,n),(t=e.call(this)).keysByValue=new Map,t}return(0,o._)(n,[{key:"values",get:function(){return Array.from(this.keysByValue.keys())}},{key:"add",value:function(t,e){(0,a._)((0,l._)(n.prototype),"add",this).call(this,t,e),L(this.keysByValue,e,t)}},{key:"delete",value:function(t,e){(0,a._)((0,l._)(n.prototype),"delete",this).call(this,t,e),I(this.keysByValue,e,t)}},{key:"hasValue",value:function(t){return this.keysByValue.has(t)}},{key:"getKeysForValue",value:function(t){var e=this.keysByValue.get(t);return e?Array.from(e):[]}}]),n}(D),P=function(){function t(e,n,r,i){(0,A._)(this,t),this._selector=n,this.details=i,this.elementObserver=new S(e,this),this.delegate=r,this.matchesByElement=new D}return(0,o._)(t,[{key:"started",get:function(){return this.elementObserver.started}},{key:"selector",get:function(){return this._selector},set:function(t){this._selector=t,this.refresh()}},{key:"start",value:function(){this.elementObserver.start()}},{key:"pause",value:function(t){this.elementObserver.pause(t)}},{key:"stop",value:function(){this.elementObserver.stop()}},{key:"refresh",value:function(){this.elementObserver.refresh()}},{key:"element",get:function(){return this.elementObserver.element}},{key:"matchElement",value:function(t){var e=this.selector;if(!e)return!1;var n=t.matches(e);return this.delegate.selectorMatchElement?n&&this.delegate.selectorMatchElement(t,this.details):n}},{key:"matchElementsInTree",value:function(t){var e=this,n=this.selector;if(!n)return[];var r=this.matchElement(t)?[t]:[],i=Array.from(t.querySelectorAll(n)).filter(function(t){return e.matchElement(t)});return r.concat(i)}},{key:"elementMatched",value:function(t){var e=this.selector;e&&this.selectorMatched(t,e)}},{key:"elementUnmatched",value:function(t){var e=this.matchesByElement.getKeysForValue(t),n=!0,r=!1,i=void 0;try{for(var A,o=e[Symbol.iterator]();!(n=(A=o.next()).done);n=!0){var s=A.value;this.selectorUnmatched(t,s)}}catch(t){r=!0,i=t}finally{try{n||null==o.return||o.return()}finally{if(r)throw i}}}},{key:"elementAttributeChanged",value:function(t,e){var n=this.selector;if(n){var r=this.matchElement(t),i=this.matchesByElement.has(n,t);r&&!i?this.selectorMatched(t,n):!r&&i&&this.selectorUnmatched(t,n)}}},{key:"selectorMatched",value:function(t,e){this.delegate.selectorMatched(t,e,this.details),this.matchesByElement.add(e,t)}},{key:"selectorUnmatched",value:function(t,e){this.delegate.selectorUnmatched(t,e,this.details),this.matchesByElement.delete(e,t)}}]),t}(),O=function(){function t(e,n){var r=this;(0,A._)(this,t),this.element=e,this.delegate=n,this.started=!1,this.stringMap=new Map,this.mutationObserver=new MutationObserver(function(t){return r.processMutations(t)})}return(0,o._)(t,[{key:"start",value:function(){this.started||(this.started=!0,this.mutationObserver.observe(this.element,{attributes:!0,attributeOldValue:!0}),this.refresh())}},{key:"stop",value:function(){this.started&&(this.mutationObserver.takeRecords(),this.mutationObserver.disconnect(),this.started=!1)}},{key:"refresh",value:function(){var t=!0,e=!1,n=void 0;if(this.started)try{for(var r,i=this.knownAttributeNames[Symbol.iterator]();!(t=(r=i.next()).done);t=!0){var A=r.value;this.refreshAttribute(A,null)}}catch(t){e=!0,n=t}finally{try{t||null==i.return||i.return()}finally{if(e)throw n}}}},{key:"processMutations",value:function(t){var e=!0,n=!1,r=void 0;if(this.started)try{for(var i,A=t[Symbol.iterator]();!(e=(i=A.next()).done);e=!0){var o=i.value;this.processMutation(o)}}catch(t){n=!0,r=t}finally{try{e||null==A.return||A.return()}finally{if(n)throw r}}}},{key:"processMutation",value:function(t){var e=t.attributeName;e&&this.refreshAttribute(e,t.oldValue)}},{key:"refreshAttribute",value:function(t,e){var n=this.delegate.getStringMapKeyForAttribute(t);if(null!=n){this.stringMap.has(t)||this.stringMapKeyAdded(n,t);var r=this.element.getAttribute(t);if(this.stringMap.get(t)!=r&&this.stringMapValueChanged(r,n,e),null==r){var i=this.stringMap.get(t);this.stringMap.delete(t),i&&this.stringMapKeyRemoved(n,t,i)}else this.stringMap.set(t,r)}}},{key:"stringMapKeyAdded",value:function(t,e){this.delegate.stringMapKeyAdded&&this.delegate.stringMapKeyAdded(t,e)}},{key:"stringMapValueChanged",value:function(t,e,n){this.delegate.stringMapValueChanged&&this.delegate.stringMapValueChanged(t,e,n)}},{key:"stringMapKeyRemoved",value:function(t,e,n){this.delegate.stringMapKeyRemoved&&this.delegate.stringMapKeyRemoved(t,e,n)}},{key:"knownAttributeNames",get:function(){return Array.from(new Set(this.currentAttributeNames.concat(this.recordedAttributeNames)))}},{key:"currentAttributeNames",get:function(){return Array.from(this.element.attributes).map(function(t){return t.name})}},{key:"recordedAttributeNames",get:function(){return Array.from(this.stringMap.keys())}}]),t}(),H=function(){function t(e,n,r){(0,A._)(this,t),this.attributeObserver=new U(e,n,this),this.delegate=r,this.tokensByElement=new D}return(0,o._)(t,[{key:"started",get:function(){return this.attributeObserver.started}},{key:"start",value:function(){this.attributeObserver.start()}},{key:"pause",value:function(t){this.attributeObserver.pause(t)}},{key:"stop",value:function(){this.attributeObserver.stop()}},{key:"refresh",value:function(){this.attributeObserver.refresh()}},{key:"element",get:function(){return this.attributeObserver.element}},{key:"attributeName",get:function(){return this.attributeObserver.attributeName}},{key:"elementMatchedAttribute",value:function(t){this.tokensMatched(this.readTokensForElement(t))}},{key:"elementAttributeValueChanged",value:function(t){var e=(0,u._)(this.refreshTokensForElement(t),2),n=e[0],r=e[1];this.tokensUnmatched(n),this.tokensMatched(r)}},{key:"elementUnmatchedAttribute",value:function(t){this.tokensUnmatched(this.tokensByElement.getValuesForKey(t))}},{key:"tokensMatched",value:function(t){var e=this;t.forEach(function(t){return e.tokenMatched(t)})}},{key:"tokensUnmatched",value:function(t){var e=this;t.forEach(function(t){return e.tokenUnmatched(t)})}},{key:"tokenMatched",value:function(t){this.delegate.tokenMatched(t),this.tokensByElement.add(t.element,t)}},{key:"tokenUnmatched",value:function(t){this.delegate.tokenUnmatched(t),this.tokensByElement.delete(t.element,t)}},{key:"refreshTokensForElement",value:function(t){var e=this.tokensByElement.getValuesForKey(t),n=this.readTokensForElement(t),r=Array.from({length:Math.max(e.length,n.length)},function(t,r){return[e[r],n[r]]}).findIndex(function(t){var e,n,r=(0,u._)(t,2);return e=r[0],n=r[1],!e||!n||e.index!=n.index||e.content!=n.content});return -1==r?[[],[]]:[e.slice(r),n.slice(r)]}},{key:"readTokensForElement",value:function(t){var e=this.attributeName;return(t.getAttribute(e)||"").trim().split(/\s+/).filter(function(t){return t.length}).map(function(n,r){return{element:t,attributeName:e,content:n,index:r}})}}]),t}(),T=function(){function t(e,n,r){(0,A._)(this,t),this.tokenListObserver=new H(e,n,this),this.delegate=r,this.parseResultsByToken=new WeakMap,this.valuesByTokenByElement=new WeakMap}return(0,o._)(t,[{key:"started",get:function(){return this.tokenListObserver.started}},{key:"start",value:function(){this.tokenListObserver.start()}},{key:"stop",value:function(){this.tokenListObserver.stop()}},{key:"refresh",value:function(){this.tokenListObserver.refresh()}},{key:"element",get:function(){return this.tokenListObserver.element}},{key:"attributeName",get:function(){return this.tokenListObserver.attributeName}},{key:"tokenMatched",value:function(t){var e=t.element,n=this.fetchParseResultForToken(t).value;n&&(this.fetchValuesByTokenForElement(e).set(t,n),this.delegate.elementMatchedValue(e,n))}},{key:"tokenUnmatched",value:function(t){var e=t.element,n=this.fetchParseResultForToken(t).value;n&&(this.fetchValuesByTokenForElement(e).delete(t),this.delegate.elementUnmatchedValue(e,n))}},{key:"fetchParseResultForToken",value:function(t){var e=this.parseResultsByToken.get(t);return e||(e=this.parseToken(t),this.parseResultsByToken.set(t,e)),e}},{key:"fetchValuesByTokenForElement",value:function(t){var e=this.valuesByTokenByElement.get(t);return e||(e=new Map,this.valuesByTokenByElement.set(t,e)),e}},{key:"parseToken",value:function(t){try{return{value:this.delegate.parseValueForToken(t)}}catch(t){return{error:t}}}}]),t}(),R=function(){function t(e,n){(0,A._)(this,t),this.context=e,this.delegate=n,this.bindingsByAction=new Map}return(0,o._)(t,[{key:"start",value:function(){this.valueListObserver||(this.valueListObserver=new T(this.element,this.actionAttribute,this),this.valueListObserver.start())}},{key:"stop",value:function(){this.valueListObserver&&(this.valueListObserver.stop(),delete this.valueListObserver,this.disconnectAllActions())}},{key:"element",get:function(){return this.context.element}},{key:"identifier",get:function(){return this.context.identifier}},{key:"actionAttribute",get:function(){return this.schema.actionAttribute}},{key:"schema",get:function(){return this.context.schema}},{key:"bindings",get:function(){return Array.from(this.bindingsByAction.values())}},{key:"connectAction",value:function(t){var e=new E(this.context,t);this.bindingsByAction.set(t,e),this.delegate.bindingConnected(e)}},{key:"disconnectAction",value:function(t){var e=this.bindingsByAction.get(t);e&&(this.bindingsByAction.delete(t),this.delegate.bindingDisconnected(e))}},{key:"disconnectAllActions",value:function(){var t=this;this.bindings.forEach(function(e){return t.delegate.bindingDisconnected(e,!0)}),this.bindingsByAction.clear()}},{key:"parseValueForToken",value:function(t){var e=k.forToken(t,this.schema);if(e.identifier==this.identifier)return e}},{key:"elementMatchedValue",value:function(t,e){this.connectAction(e)}},{key:"elementUnmatchedValue",value:function(t,e){this.disconnectAction(e)}}]),t}(),K=function(){function t(e,n){(0,A._)(this,t),this.context=e,this.receiver=n,this.stringMapObserver=new O(this.element,this),this.valueDescriptorMap=this.controller.valueDescriptorMap}return(0,o._)(t,[{key:"start",value:function(){this.stringMapObserver.start(),this.invokeChangedCallbacksForDefaultValues()}},{key:"stop",value:function(){this.stringMapObserver.stop()}},{key:"element",get:function(){return this.context.element}},{key:"controller",get:function(){return this.context.controller}},{key:"getStringMapKeyForAttribute",value:function(t){if(t in this.valueDescriptorMap)return this.valueDescriptorMap[t].name}},{key:"stringMapKeyAdded",value:function(t,e){var n=this.valueDescriptorMap[e];this.hasValue(t)||this.invokeChangedCallback(t,n.writer(this.receiver[t]),n.writer(n.defaultValue))}},{key:"stringMapValueChanged",value:function(t,e,n){var r=this.valueDescriptorNameMap[e];null!==t&&(null===n&&(n=r.writer(r.defaultValue)),this.invokeChangedCallback(e,t,n))}},{key:"stringMapKeyRemoved",value:function(t,e,n){var r=this.valueDescriptorNameMap[t];this.hasValue(t)?this.invokeChangedCallback(t,r.writer(this.receiver[t]),n):this.invokeChangedCallback(t,r.writer(r.defaultValue),n)}},{key:"invokeChangedCallbacksForDefaultValues",value:function(){var t=!0,e=!1,n=void 0;try{for(var r,i=this.valueDescriptors[Symbol.iterator]();!(t=(r=i.next()).done);t=!0){var A=r.value,o=A.key,s=A.name,a=A.defaultValue,l=A.writer;void 0==a||this.controller.data.has(o)||this.invokeChangedCallback(s,l(a),void 0)}}catch(t){e=!0,n=t}finally{try{t||null==i.return||i.return()}finally{if(e)throw n}}}},{key:"invokeChangedCallback",value:function(t,e,n){var r=this.receiver["".concat(t,"Changed")];if("function"==typeof r){var i=this.valueDescriptorNameMap[t];try{var A=i.reader(e),o=n;n&&(o=i.reader(n)),r.call(this.receiver,A,o)}catch(t){throw t instanceof TypeError&&(t.message='Stimulus Value "'.concat(this.context.identifier,".").concat(i.name,'" - ').concat(t.message)),t}}}},{key:"valueDescriptors",get:function(){var t=this.valueDescriptorMap;return Object.keys(t).map(function(e){return t[e]})}},{key:"valueDescriptorNameMap",get:function(){var t=this,e={};return Object.keys(this.valueDescriptorMap).forEach(function(n){var r=t.valueDescriptorMap[n];e[r.name]=r}),e}},{key:"hasValue",value:function(t){var e=this.valueDescriptorNameMap[t],n="has".concat(B(e.name));return this.receiver[n]}}]),t}(),V=function(){function t(e,n){(0,A._)(this,t),this.context=e,this.delegate=n,this.targetsByName=new D}return(0,o._)(t,[{key:"start",value:function(){this.tokenListObserver||(this.tokenListObserver=new H(this.element,this.attributeName,this),this.tokenListObserver.start())}},{key:"stop",value:function(){this.tokenListObserver&&(this.disconnectAllTargets(),this.tokenListObserver.stop(),delete this.tokenListObserver)}},{key:"tokenMatched",value:function(t){var e=t.element,n=t.content;this.scope.containsElement(e)&&this.connectTarget(e,n)}},{key:"tokenUnmatched",value:function(t){var e=t.element,n=t.content;this.disconnectTarget(e,n)}},{key:"connectTarget",value:function(t,e){var n,r=this;this.targetsByName.has(e,t)||(this.targetsByName.add(e,t),null===(n=this.tokenListObserver)||void 0===n||n.pause(function(){return r.delegate.targetConnected(t,e)}))}},{key:"disconnectTarget",value:function(t,e){var n,r=this;this.targetsByName.has(e,t)&&(this.targetsByName.delete(e,t),null===(n=this.tokenListObserver)||void 0===n||n.pause(function(){return r.delegate.targetDisconnected(t,e)}))}},{key:"disconnectAllTargets",value:function(){var t=!0,e=!1,n=void 0,r=!0,i=!1,A=void 0;try{for(var o,s=this.targetsByName.keys[Symbol.iterator]();!(r=(o=s.next()).done);r=!0){var a=o.value;try{for(var l,c=this.targetsByName.getValuesForKey(a)[Symbol.iterator]();!(t=(l=c.next()).done);t=!0){var u=l.value;this.disconnectTarget(u,a)}}catch(t){e=!0,n=t}finally{try{t||null==c.return||c.return()}finally{if(e)throw n}}}}catch(t){i=!0,A=t}finally{try{r||null==s.return||s.return()}finally{if(i)throw A}}}},{key:"attributeName",get:function(){return"data-".concat(this.context.identifier,"-target")}},{key:"element",get:function(){return this.context.element}},{key:"scope",get:function(){return this.context.scope}}]),t}();function z(t,e){return Array.from(G(t).reduce(function(t,n){var r;return(Array.isArray(r=n[e])?r:[]).forEach(function(e){return t.add(e)}),t},new Set))}function G(t){for(var e=[];t;)e.push(t),t=Object.getPrototypeOf(t);return e.reverse()}var q=function(){function t(e,n){(0,A._)(this,t),this.started=!1,this.context=e,this.delegate=n,this.outletsByName=new D,this.outletElementsByName=new D,this.selectorObserverMap=new Map,this.attributeObserverMap=new Map}return(0,o._)(t,[{key:"start",value:function(){var t=this;this.started||(this.outletDefinitions.forEach(function(e){t.setupSelectorObserverForOutlet(e),t.setupAttributeObserverForOutlet(e)}),this.started=!0,this.dependentContexts.forEach(function(t){return t.refresh()}))}},{key:"refresh",value:function(){this.selectorObserverMap.forEach(function(t){return t.refresh()}),this.attributeObserverMap.forEach(function(t){return t.refresh()})}},{key:"stop",value:function(){this.started&&(this.started=!1,this.disconnectAllOutlets(),this.stopSelectorObservers(),this.stopAttributeObservers())}},{key:"stopSelectorObservers",value:function(){this.selectorObserverMap.size>0&&(this.selectorObserverMap.forEach(function(t){return t.stop()}),this.selectorObserverMap.clear())}},{key:"stopAttributeObservers",value:function(){this.attributeObserverMap.size>0&&(this.attributeObserverMap.forEach(function(t){return t.stop()}),this.attributeObserverMap.clear())}},{key:"selectorMatched",value:function(t,e,n){var r=n.outletName,i=this.getOutlet(t,r);i&&this.connectOutlet(i,t,r)}},{key:"selectorUnmatched",value:function(t,e,n){var r=n.outletName,i=this.getOutletFromMap(t,r);i&&this.disconnectOutlet(i,t,r)}},{key:"selectorMatchElement",value:function(t,e){var n=e.outletName,r=this.selector(n),i=this.hasOutlet(t,n),A=t.matches("[".concat(this.schema.controllerAttribute,"~=").concat(n,"]"));return!!r&&i&&A&&t.matches(r)}},{key:"elementMatchedAttribute",value:function(t,e){var n=this.getOutletNameFromOutletAttributeName(e);n&&this.updateSelectorObserverForOutlet(n)}},{key:"elementAttributeValueChanged",value:function(t,e){var n=this.getOutletNameFromOutletAttributeName(e);n&&this.updateSelectorObserverForOutlet(n)}},{key:"elementUnmatchedAttribute",value:function(t,e){var n=this.getOutletNameFromOutletAttributeName(e);n&&this.updateSelectorObserverForOutlet(n)}},{key:"connectOutlet",value:function(t,e,n){var r,i=this;this.outletElementsByName.has(n,e)||(this.outletsByName.add(n,t),this.outletElementsByName.add(n,e),null===(r=this.selectorObserverMap.get(n))||void 0===r||r.pause(function(){return i.delegate.outletConnected(t,e,n)}))}},{key:"disconnectOutlet",value:function(t,e,n){var r,i=this;this.outletElementsByName.has(n,e)&&(this.outletsByName.delete(n,t),this.outletElementsByName.delete(n,e),null===(r=this.selectorObserverMap.get(n))||void 0===r||r.pause(function(){return i.delegate.outletDisconnected(t,e,n)}))}},{key:"disconnectAllOutlets",value:function(){var t=!0,e=!1,n=void 0;try{for(var r,i=this.outletElementsByName.keys[Symbol.iterator]();!(t=(r=i.next()).done);t=!0){var A=r.value,o=!0,s=!1,a=void 0,l=!0,c=!1,u=void 0;try{for(var h,d=this.outletElementsByName.getValuesForKey(A)[Symbol.iterator]();!(l=(h=d.next()).done);l=!0){var f=h.value;try{for(var p,g=this.outletsByName.getValuesForKey(A)[Symbol.iterator]();!(o=(p=g.next()).done);o=!0){var m=p.value;this.disconnectOutlet(m,f,A)}}catch(t){s=!0,a=t}finally{try{o||null==g.return||g.return()}finally{if(s)throw a}}}}catch(t){c=!0,u=t}finally{try{l||null==d.return||d.return()}finally{if(c)throw u}}}}catch(t){e=!0,n=t}finally{try{t||null==i.return||i.return()}finally{if(e)throw n}}}},{key:"updateSelectorObserverForOutlet",value:function(t){var e=this.selectorObserverMap.get(t);e&&(e.selector=this.selector(t))}},{key:"setupSelectorObserverForOutlet",value:function(t){var e=this.selector(t),n=new P(document.body,e,this,{outletName:t});this.selectorObserverMap.set(t,n),n.start()}},{key:"setupAttributeObserverForOutlet",value:function(t){var e=this.attributeNameForOutletName(t),n=new U(this.scope.element,e,this);this.attributeObserverMap.set(t,n),n.start()}},{key:"selector",value:function(t){return this.scope.outlets.getSelectorForOutletName(t)}},{key:"attributeNameForOutletName",value:function(t){return this.scope.schema.outletAttributeForScope(this.identifier,t)}},{key:"getOutletNameFromOutletAttributeName",value:function(t){var e=this;return this.outletDefinitions.find(function(n){return e.attributeNameForOutletName(n)===t})}},{key:"outletDependencies",get:function(){var t=new D;return this.router.modules.forEach(function(e){z(e.definition.controllerConstructor,"outlets").forEach(function(n){return t.add(n,e.identifier)})}),t}},{key:"outletDefinitions",get:function(){return this.outletDependencies.getKeysForValue(this.identifier)}},{key:"dependentControllerIdentifiers",get:function(){return this.outletDependencies.getValuesForKey(this.identifier)}},{key:"dependentContexts",get:function(){var t=this.dependentControllerIdentifiers;return this.router.contexts.filter(function(e){return t.includes(e.identifier)})}},{key:"hasOutlet",value:function(t,e){return!!this.getOutlet(t,e)||!!this.getOutletFromMap(t,e)}},{key:"getOutlet",value:function(t,e){return this.application.getControllerForElementAndIdentifier(t,e)}},{key:"getOutletFromMap",value:function(t,e){return this.outletsByName.getValuesForKey(e).find(function(e){return e.element===t})}},{key:"scope",get:function(){return this.context.scope}},{key:"schema",get:function(){return this.context.schema}},{key:"identifier",get:function(){return this.context.identifier}},{key:"application",get:function(){return this.context.application}},{key:"router",get:function(){return this.application.router}}]),t}(),W=function(){function t(e,n){var r=this;(0,A._)(this,t),this.logDebugActivity=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};e=Object.assign({identifier:r.identifier,controller:r.controller,element:r.element},e),r.application.logDebugActivity(r.identifier,t,e)},this.module=e,this.scope=n,this.controller=new e.controllerConstructor(this),this.bindingObserver=new R(this,this.dispatcher),this.valueObserver=new K(this,this.controller),this.targetObserver=new V(this,this),this.outletObserver=new q(this,this);try{this.controller.initialize(),this.logDebugActivity("initialize")}catch(t){this.handleError(t,"initializing controller")}}return(0,o._)(t,[{key:"connect",value:function(){this.bindingObserver.start(),this.valueObserver.start(),this.targetObserver.start(),this.outletObserver.start();try{this.controller.connect(),this.logDebugActivity("connect")}catch(t){this.handleError(t,"connecting controller")}}},{key:"refresh",value:function(){this.outletObserver.refresh()}},{key:"disconnect",value:function(){try{this.controller.disconnect(),this.logDebugActivity("disconnect")}catch(t){this.handleError(t,"disconnecting controller")}this.outletObserver.stop(),this.targetObserver.stop(),this.valueObserver.stop(),this.bindingObserver.stop()}},{key:"application",get:function(){return this.module.application}},{key:"identifier",get:function(){return this.module.identifier}},{key:"schema",get:function(){return this.application.schema}},{key:"dispatcher",get:function(){return this.application.dispatcher}},{key:"element",get:function(){return this.scope.element}},{key:"parentElement",get:function(){return this.element.parentElement}},{key:"handleError",value:function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};n=Object.assign({identifier:this.identifier,controller:this.controller,element:this.element},n),this.application.handleError(t,"Error ".concat(e),n)}},{key:"targetConnected",value:function(t,e){this.invokeControllerMethod("".concat(e,"TargetConnected"),t)}},{key:"targetDisconnected",value:function(t,e){this.invokeControllerMethod("".concat(e,"TargetDisconnected"),t)}},{key:"outletConnected",value:function(t,e,n){this.invokeControllerMethod("".concat(b(n),"OutletConnected"),t,e)}},{key:"outletDisconnected",value:function(t,e,n){this.invokeControllerMethod("".concat(b(n),"OutletDisconnected"),t,e)}},{key:"invokeControllerMethod",value:function(t){for(var e=arguments.length,n=Array(e>1?e-1:0),r=1;r0&&void 0!==arguments[0]?arguments[0]:document.documentElement,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:ts,r=this;(0,A._)(this,t),this.logger=console,this.debug=!1,this.logDebugActivity=function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};r.debug&&r.logFormattedMessage(t,e,n)},this.element=e,this.schema=n,this.dispatcher=new m(this),this.router=new to(this),this.actionDescriptorFilters=Object.assign({},v)}return(0,o._)(t,[{key:"start",value:function(){var t=this;return(0,i._)(function(){return(0,p._)(this,function(e){switch(e.label){case 0:return[4,new Promise(function(t){"loading"==document.readyState?document.addEventListener("DOMContentLoaded",function(){return t()}):t()})];case 1:return e.sent(),t.logDebugActivity("application","starting"),t.dispatcher.start(),t.router.start(),t.logDebugActivity("application","start"),[2]}})})()}},{key:"stop",value:function(){this.logDebugActivity("application","stopping"),this.dispatcher.stop(),this.router.stop(),this.logDebugActivity("application","stop")}},{key:"register",value:function(t,e){this.load({identifier:t,controllerConstructor:e})}},{key:"registerActionOption",value:function(t,e){this.actionDescriptorFilters[t]=e}},{key:"load",value:function(t){for(var e=this,n=arguments.length,r=Array(n>1?n-1:0),i=1;i1?n-1:0),i=1;i2&&void 0!==arguments[2]?arguments[2]:{};n=Object.assign({application:this},n),this.logger.groupCollapsed("".concat(t," #").concat(e)),this.logger.log("details:",Object.assign({},n)),this.logger.groupEnd()}}],[{key:"start",value:function(t,e){var n=new this(t,e);return n.start(),n}}]),t}();function tc(t,e,n){return t.application.getControllerForElementAndIdentifier(e,n)}function tu(t,e,n){var r=tc(t,e,n);return r||((t.application.router.proposeToConnectScopeForElementAndIdentifier(e,n),r=tc(t,e,n))?r:void 0)}function th(t,e){var n,r,i,A,o,s=(0,u._)(t,2);return r=(n={controller:e,token:s[0],typeDefinition:s[1]}).token,i=n.typeDefinition,A="".concat(_(r),"-value"),{type:o=function(t){var e=t.controller,n=t.token,r=t.typeDefinition,i=function(t){var e=t.controller,n=t.token,r=t.typeObject,i=null!=r.type,A=null!=r.default,o=td(r.type),s=tf(t.typeObject.default);if(i&&!A)return o;if(!i&&A)return s;if(o!==s){var a=e?"".concat(e,".").concat(n):n;throw Error('The specified default value for the Stimulus Value "'.concat(a,'" must match the defined type "').concat(o,'". The provided default value of "').concat(r.default,'" is of type "').concat(s,'".'))}if(i&&A)return o}({controller:e,token:n,typeObject:r}),A=tf(r),o=td(r),s=i||A||o;if(s)return s;var a=e?"".concat(e,".").concat(r):n;throw Error('Unknown value type "'.concat(a,'" for "').concat(n,'" value'))}(n),key:A,name:w(A),get defaultValue(){return function(t){var e=td(t);if(e)return tp[e];var n=C(t,"default"),r=C(t,"type");if(n)return t.default;if(r){var i=td(t.type);if(i)return tp[i]}return t}(i)},get hasCustomDefaultValue(){return void 0!==tf(i)},reader:tg[o],writer:tm[o]||tm.default}}function td(t){switch(t){case Array:return"array";case Boolean:return"boolean";case Number:return"number";case Object:return"object";case String:return"string"}}function tf(t){switch(void 0===t?"undefined":(0,d._)(t)){case"boolean":return"boolean";case"number":return"number";case"string":return"string"}return Array.isArray(t)?"array":"[object Object]"===Object.prototype.toString.call(t)?"object":void 0}var tp={get array(){return[]},boolean:!1,number:0,get object(){return{}},string:""},tg={array:function(t){var e=JSON.parse(t);if(!Array.isArray(e))throw TypeError('expected value of type "array" but instead got value "'.concat(t,'" of type "').concat(tf(e),'"'));return e},boolean:function(t){return!("0"==t||"false"==String(t).toLowerCase())},number:function(t){return Number(t.replace(/_/g,""))},object:function(t){var e=JSON.parse(t);if(null===e||"object"!=typeof e||Array.isArray(e))throw TypeError('expected value of type "object" but instead got value "'.concat(t,'" of type "').concat(tf(e),'"'));return e},string:function(t){return t}},tm={default:function(t){return"".concat(t)},array:tv,object:tv};function tv(t){return JSON.stringify(t)}var ty=function(){function t(e){(0,A._)(this,t),this.context=e}return(0,o._)(t,[{key:"application",get:function(){return this.context.application}},{key:"scope",get:function(){return this.context.scope}},{key:"element",get:function(){return this.scope.element}},{key:"identifier",get:function(){return this.scope.identifier}},{key:"targets",get:function(){return this.scope.targets}},{key:"outlets",get:function(){return this.scope.outlets}},{key:"classes",get:function(){return this.scope.classes}},{key:"data",get:function(){return this.scope.data}},{key:"initialize",value:function(){}},{key:"connect",value:function(){}},{key:"disconnect",value:function(){}},{key:"dispatch",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=e.target,r=void 0===n?this.element:n,i=e.detail,A=e.prefix,o=void 0===A?this.identifier:A,s=e.bubbles,a=e.cancelable,l=new CustomEvent(o?"".concat(o,":").concat(t):t,{detail:void 0===i?{}:i,bubbles:void 0===s||s,cancelable:void 0===a||a});return r.dispatchEvent(l),l}}],[{key:"shouldLoad",get:function(){return!0}},{key:"afterLoad",value:function(t,e){}}]),t}();ty.blessings=[function(t){return z(t,"classes").reduce(function(t,e){var n;return Object.assign(t,(n={},(0,s._)(n,"".concat(e,"Class"),{get:function(){var t=this.classes;if(t.has(e))return t.get(e);var n=t.getAttributeName(e);throw Error('Missing attribute "'.concat(n,'"'))}}),(0,s._)(n,"".concat(e,"Classes"),{get:function(){return this.classes.getAll(e)}}),(0,s._)(n,"has".concat(B(e),"Class"),{get:function(){return this.classes.has(e)}}),n))},{})},function(t){return z(t,"targets").reduce(function(t,e){var n;return Object.assign(t,(n={},(0,s._)(n,"".concat(e,"Target"),{get:function(){var t=this.targets.find(e);if(t)return t;throw Error('Missing target element "'.concat(e,'" for "').concat(this.identifier,'" controller'))}}),(0,s._)(n,"".concat(e,"Targets"),{get:function(){return this.targets.findAll(e)}}),(0,s._)(n,"has".concat(B(e),"Target"),{get:function(){return this.targets.has(e)}}),n))},{})},function(t){var e,n=(e="values",G(t).reduce(function(t,n){var r;return t.push.apply(t,(0,h._)((r=n[e])?Object.keys(r).map(function(t){return[t,r[t]]}):[])),t},[]));return n.reduce(function(t,e){var n,r,i,A,o,a;return Object.assign(t,(i=(r=th(e,void 0)).key,A=r.name,o=r.reader,a=r.writer,n={},(0,s._)(n,A,{get:function(){var t=this.data.get(i);return null!==t?o(t):r.defaultValue},set:function(t){void 0===t?this.data.delete(i):this.data.set(i,a(t))}}),(0,s._)(n,"has".concat(B(A)),{get:function(){return this.data.has(i)||r.hasCustomDefaultValue}}),n))},{valueDescriptorMap:{get:function(){var t=this;return n.reduce(function(e,n){var r=th(n,t.identifier),i=t.data.getAttributeNameForKey(r.key);return Object.assign(e,(0,s._)({},i,r))},{})}}})},function(t){return z(t,"outlets").reduce(function(t,e){var n,r;return Object.assign(t,(r=b(e),n={},(0,s._)(n,"".concat(r,"Outlet"),{get:function(){var t=this.outlets.find(e),n=this.outlets.getSelectorForOutletName(e);if(t){var r=tu(this,t,e);if(r)return r;throw Error('The provided outlet element is missing an outlet controller "'.concat(e,'" instance for host controller "').concat(this.identifier,'"'))}throw Error('Missing outlet element "'.concat(e,'" for host controller "').concat(this.identifier,'". Stimulus couldn\'t find a matching outlet element using selector "').concat(n,'".'))}}),(0,s._)(n,"".concat(r,"Outlets"),{get:function(){var t=this,n=this.outlets.findAll(e);return n.length>0?n.map(function(n){var r=tu(t,n,e);if(r)return r;console.warn('The provided outlet element is missing an outlet controller "'.concat(e,'" instance for host controller "').concat(t.identifier,'"'),n)}).filter(function(t){return t}):[]}}),(0,s._)(n,"".concat(r,"OutletElement"),{get:function(){var t=this.outlets.find(e),n=this.outlets.getSelectorForOutletName(e);if(t)return t;throw Error('Missing outlet element "'.concat(e,'" for host controller "').concat(this.identifier,'". Stimulus couldn\'t find a matching outlet element using selector "').concat(n,'".'))}}),(0,s._)(n,"".concat(r,"OutletElements"),{get:function(){return this.outlets.findAll(e)}}),(0,s._)(n,"has".concat(B(r),"Outlet"),{get:function(){return this.outlets.has(e)}}),n))},{})}],ty.targets=[],ty.outlets=[],ty.values={}},{"@swc/helpers/_/_async_to_generator":"6Tpxj","@swc/helpers/_/_class_call_check":"2HOGN","@swc/helpers/_/_create_class":"8oe8p","@swc/helpers/_/_define_property":"27c3O","@swc/helpers/_/_get":"6FgjI","@swc/helpers/_/_get_prototype_of":"4Pl3E","@swc/helpers/_/_inherits":"7gHjg","@swc/helpers/_/_sliced_to_array":"hefcy","@swc/helpers/_/_to_consumable_array":"4oNkS","@swc/helpers/_/_type_of":"2bRX5","@swc/helpers/_/_create_super":"a37Ru","@swc/helpers/_/_ts_generator":"lwj56","@parcel/transformer-js/src/esmodule-helpers.js":"kPSB8"}],"6Tpxj":[function(t,e,n){var r=t("@parcel/transformer-js/src/esmodule-helpers.js");function i(t,e,n,r,i,A,o){try{var s=t[A](o),a=s.value}catch(t){n(t);return}s.done?e(a):Promise.resolve(a).then(r,i)}function A(t){return function(){var e=this,n=arguments;return new Promise(function(r,A){var o=t.apply(e,n);function s(t){i(o,r,A,s,a,"next",t)}function a(t){i(o,r,A,s,a,"throw",t)}s(void 0)})}}r.defineInteropFlag(n),r.export(n,"_async_to_generator",function(){return A}),r.export(n,"_",function(){return A})},{"@parcel/transformer-js/src/esmodule-helpers.js":"kPSB8"}],kPSB8:[function(t,e,n){n.interopDefault=function(t){return t&&t.__esModule?t:{default:t}},n.defineInteropFlag=function(t){Object.defineProperty(t,"__esModule",{value:!0})},n.exportAll=function(t,e){return Object.keys(t).forEach(function(n){"default"===n||"__esModule"===n||Object.prototype.hasOwnProperty.call(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:function(){return t[n]}})}),e},n.export=function(t,e,n){Object.defineProperty(t,e,{enumerable:!0,get:n})}},{}],"2HOGN":[function(t,e,n){var r=t("@parcel/transformer-js/src/esmodule-helpers.js");function i(t,e){if(!(t instanceof e))throw TypeError("Cannot call a class as a function")}r.defineInteropFlag(n),r.export(n,"_class_call_check",function(){return i}),r.export(n,"_",function(){return i})},{"@parcel/transformer-js/src/esmodule-helpers.js":"kPSB8"}],"8oe8p":[function(t,e,n){var r=t("@parcel/transformer-js/src/esmodule-helpers.js");function i(t,e){for(var n=0;nt.length)&&(e=t.length);for(var n=0,r=Array(e);ne.indexOf(r)&&(n[r]=t[r]);if(null!=t&&"function"==typeof Object.getOwnPropertySymbols)for(var i=0,r=Object.getOwnPropertySymbols(t);ie.indexOf(r[i])&&Object.prototype.propertyIsEnumerable.call(t,r[i])&&(n[r[i]]=t[r[i]]);return n}function l(t,e,n,r){var i,A=arguments.length,o=A<3?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(t,e,n,r);else for(var s=t.length-1;s>=0;s--)(i=t[s])&&(o=(A<3?i(o):A>3?i(e,n,o):i(e,n))||o);return A>3&&o&&Object.defineProperty(e,n,o),o}function c(t,e){return function(n,r){e(n,r,t)}}function u(t,e,n,r,i,A){function o(t){if(void 0!==t&&"function"!=typeof t)throw TypeError("Function expected");return t}for(var s,a=r.kind,l="getter"===a?"get":"setter"===a?"set":"value",c=!e&&t?r.static?t:t.prototype:null,u=e||(c?Object.getOwnPropertyDescriptor(c,r.name):{}),h=!1,d=n.length-1;d>=0;d--){var f={};for(var p in r)f[p]="access"===p?{}:r[p];for(var p in r.access)f.access[p]=r.access[p];f.addInitializer=function(t){if(h)throw TypeError("Cannot add initializers after decoration has completed");A.push(o(t||null))};var g=(0,n[d])("accessor"===a?{get:u.get,set:u.set}:u[l],f);if("accessor"===a){if(void 0===g)continue;if(null===g||"object"!=typeof g)throw TypeError("Object expected");(s=o(g.get))&&(u.get=s),(s=o(g.set))&&(u.set=s),(s=o(g.init))&&i.unshift(s)}else(s=o(g))&&("field"===a?i.unshift(s):u[l]=s)}c&&Object.defineProperty(c,r.name,u),h=!0}function h(t,e,n){for(var r=arguments.length>2,i=0;i0&&i[i.length-1])&&(6===s[0]||2===s[0])){o=0;continue}if(3===s[0]&&(!i||s[1]>i[0]&&s[1]=t.length&&(t=void 0),{value:t&&t[r++],done:!t}}};throw TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")}function b(t,e){var n="function"==typeof Symbol&&t[Symbol.iterator];if(!n)return t;var r,i,A=n.call(t),o=[];try{for(;(void 0===e||e-- >0)&&!(r=A.next()).done;)o.push(r.value)}catch(t){i={error:t}}finally{try{r&&!r.done&&(n=A.return)&&n.call(A)}finally{if(i)throw i.error}}return o}function B(){for(var t=[],e=0;e1||s(t,e)})})}function s(t,e){try{var n;(n=i[t](e)).value instanceof x?Promise.resolve(n.value.v).then(a,l):c(A[0][2],n)}catch(t){c(A[0][3],t)}}function a(t){s("next",t)}function l(t){s("throw",t)}function c(t,e){t(e),A.shift(),A.length&&s(A[0][0],A[0][1])}}function F(t){var e,n;return e={},r("next"),r("throw",function(t){throw t}),r("return"),e[Symbol.iterator]=function(){return this},e;function r(r,i){e[r]=t[r]?function(e){return(n=!n)?{value:x(t[r](e)),done:!1}:i?i(e):e}:i}}function Q(t){if(!Symbol.asyncIterator)throw TypeError("Symbol.asyncIterator is not defined.");var e,n=t[Symbol.asyncIterator];return n?n.call(t):(t=w(t),e={},r("next"),r("throw"),r("return"),e[Symbol.asyncIterator]=function(){return this},e);function r(n){e[n]=t[n]&&function(e){return new Promise(function(r,i){!function(t,e,n,r){Promise.resolve(r).then(function(e){t({value:e,done:n})},e)}(r,i,(e=t[n](e)).done,e.value)})}}}function E(t,e){return Object.defineProperty?Object.defineProperty(t,"raw",{value:e}):t.raw=e,t}var S=Object.create?function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}:function(t,e){t.default=e};function U(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var n in t)"default"!==n&&Object.prototype.hasOwnProperty.call(t,n)&&v(e,t,n);return S(e,t),e}function L(t){return t&&t.__esModule?t:{default:t}}function I(t,e,n,r){if("a"===n&&!r)throw TypeError("Private accessor was defined without a getter");if("function"==typeof e?t!==e||!r:!e.has(t))throw TypeError("Cannot read private member from an object whose class did not declare it");return"m"===n?r:"a"===n?r.call(t):r?r.value:e.get(t)}function j(t,e,n,r,i){if("m"===r)throw TypeError("Private method is not writable");if("a"===r&&!i)throw TypeError("Private accessor was defined without a setter");if("function"==typeof e?t!==e||!i:!e.has(t))throw TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?i.call(t,n):i?i.value=n:e.set(t,n),n}function M(t,e){if(null===e||"object"!=typeof e&&"function"!=typeof e)throw TypeError("Cannot use 'in' operator on non-object");return"function"==typeof t?e===t:t.has(e)}function D(t,e,n){if(null!=e){var r;if("object"!=typeof e&&"function"!=typeof e)throw TypeError("Object expected.");if(n){if(!Symbol.asyncDispose)throw TypeError("Symbol.asyncDispose is not defined.");r=e[Symbol.asyncDispose]}if(void 0===r){if(!Symbol.dispose)throw TypeError("Symbol.dispose is not defined.");r=e[Symbol.dispose]}if("function"!=typeof r)throw TypeError("Object not disposable.");t.stack.push({value:e,dispose:r,async:n})}else n&&t.stack.push({async:!0});return e}var N="function"==typeof SuppressedError?SuppressedError:function(t,e,n){var r=Error(n);return r.name="SuppressedError",r.error=t,r.suppressed=e,r};function P(t){function e(e){t.error=t.hasError?new N(e,t.error,"An error was suppressed during disposal."):e,t.hasError=!0}return function n(){for(;t.stack.length;){var r=t.stack.pop();try{var i=r.dispose&&r.dispose.call(r.value);if(r.async)return Promise.resolve(i).then(n,function(t){return e(t),n()})}catch(t){e(t)}}if(t.hasError)throw t.error}()}n.default={__extends:o,__assign:s,__rest:a,__decorate:l,__param:c,__metadata:p,__awaiter:g,__generator:m,__createBinding:v,__exportStar:y,__values:w,__read:b,__spread:B,__spreadArrays:_,__spreadArray:C,__await:x,__asyncGenerator:k,__asyncDelegator:F,__asyncValues:Q,__makeTemplateObject:E,__importStar:U,__importDefault:L,__classPrivateFieldGet:I,__classPrivateFieldSet:j,__classPrivateFieldIn:M,__addDisposableResource:D,__disposeResources:P}},{"@swc/helpers/_/_type_of":"2bRX5","@parcel/transformer-js/src/esmodule-helpers.js":"kPSB8"}],Tlrpp:[function(t,e,n){function r(t,e){for(var n=0;nt.length)&&(e=t.length);for(var n=0,r=Array(e);n0&&this.registerTriggers.apply(this,i(A)),this.onClick=this.onClick.bind(this),this.onKeydown=this.onKeydown.bind(this)}return t=[{key:"registerTriggers",value:function(){for(var t=this,e=arguments.length,n=Array(e),r=0;r0&&void 0!==arguments[0]?arguments[0]:null;(this.activeElement=document.activeElement,this.modal.setAttribute("aria-hidden","false"),this.modal.classList.add(this.config.openClass),this.scrollBehaviour("disable"),this.addEventListeners(),this.config.awaitOpenAnimation)?this.modal.addEventListener("animationend",function e(){t.modal.removeEventListener("animationend",e,!1),t.setFocusToFirstNode()},!1):this.setFocusToFirstNode(),this.config.onShow(this.modal,this.activeElement,e)}},{key:"closeModal",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,e=this.modal;if(this.modal.setAttribute("aria-hidden","true"),this.removeEventListeners(),this.scrollBehaviour("enable"),this.activeElement&&this.activeElement.focus&&this.activeElement.focus(),this.config.onClose(this.modal,this.activeElement,t),this.config.awaitCloseAnimation){var n=this.config.openClass;this.modal.addEventListener("animationend",function t(){e.classList.remove(n),e.removeEventListener("animationend",t,!1)},!1)}else e.classList.remove(this.config.openClass)}},{key:"closeModalById",value:function(t){this.modal=document.getElementById(t),this.modal&&this.closeModal()}},{key:"scrollBehaviour",value:function(t){if(this.config.disableScroll){var e=document.querySelector("body");switch(t){case"enable":Object.assign(e.style,{overflow:""});break;case"disable":Object.assign(e.style,{overflow:"hidden"})}}}},{key:"addEventListeners",value:function(){this.modal.addEventListener("touchstart",this.onClick),this.modal.addEventListener("click",this.onClick),document.addEventListener("keydown",this.onKeydown)}},{key:"removeEventListeners",value:function(){this.modal.removeEventListener("touchstart",this.onClick),this.modal.removeEventListener("click",this.onClick),document.removeEventListener("keydown",this.onKeydown)}},{key:"onClick",value:function(t){(t.target.hasAttribute(this.config.closeTrigger)||t.target.parentNode.hasAttribute(this.config.closeTrigger))&&(t.preventDefault(),t.stopPropagation(),this.closeModal(t))}},{key:"onKeydown",value:function(t){27===t.keyCode&&this.closeModal(t),9===t.keyCode&&this.retainFocus(t)}},{key:"getFocusableNodes",value:function(){return Array.apply(void 0,i(this.modal.querySelectorAll(o)))}},{key:"setFocusToFirstNode",value:function(){var t=this;if(!this.config.disableFocus){var e=this.getFocusableNodes();if(0!==e.length){var n=e.filter(function(e){return!e.hasAttribute(t.config.closeTrigger)});n.length>0&&n[0].focus(),0===n.length&&e[0].focus()}}}},{key:"retainFocus",value:function(t){var e=this.getFocusableNodes();if(0!==e.length){if(e=e.filter(function(t){return null!==t.offsetParent}),this.modal.contains(document.activeElement)){var n=e.indexOf(document.activeElement);t.shiftKey&&0===n&&(e[e.length-1].focus(),t.preventDefault()),!t.shiftKey&&e.length>0&&n===e.length-1&&(e[0].focus(),t.preventDefault())}else e[0].focus()}}}],r(n.prototype,t),e&&r(n,e),n}(),a=null,l=function(t){if(!document.getElementById(t))return console.warn("MicroModal: â—Seems like you have missed %c'".concat(t,"'"),"background-color: #f8f9fa;color: #50596c;font-weight: bold;","ID somewhere in your code. Refer example below to resolve it."),console.warn("%cExample:","background-color: #f8f9fa;color: #50596c;font-weight: bold;",'')),!1},c=function(t,e){if(t.length<=0&&(console.warn("MicroModal: â—Please specify at least one %c'micromodal-trigger'","background-color: #f8f9fa;color: #50596c;font-weight: bold;","data attribute."),console.warn("%cExample:","background-color: #f8f9fa;color: #50596c;font-weight: bold;",'')),!e)return!0;for(var n in e)l(n);return!0},{init:function(t){var e,n,r=Object.assign({},{openTrigger:"data-micromodal-trigger"},t),A=i(document.querySelectorAll("[".concat(r.openTrigger,"]"))),o=(e=r.openTrigger,n=[],A.forEach(function(t){var r=t.attributes[e].value;void 0===n[r]&&(n[r]=[]),n[r].push(t)}),n);if(!0!==r.debugMode||!1!==c(A,o))for(var l in o){var u=o[l];r.targetModal=l,r.triggers=i(u),a=new s(r)}},show:function(t,e){var n=e||{};n.targetModal=t,!0===n.debugMode&&!1===l(t)||(a&&a.removeEventListeners(),(a=new s(n)).showModal())},close:function(t){t?a.closeModalById(t):a.closeModal()}});"undefined"!=typeof window&&(window.MicroModal=u),n.default=u},{"@parcel/transformer-js/src/esmodule-helpers.js":"kPSB8"}],afw1Q:[function(t,e,n){var r=t("@parcel/transformer-js/src/esmodule-helpers.js");r.defineInteropFlag(n),r.export(n,"default",function(){return u});var i=t("@swc/helpers/_/_class_call_check"),A=t("@swc/helpers/_/_create_class"),o=t("@swc/helpers/_/_define_property"),s=t("@swc/helpers/_/_inherits"),a=t("@swc/helpers/_/_object_spread"),l=t("@swc/helpers/_/_object_spread_props"),c=t("@swc/helpers/_/_create_super"),u=function(t){(0,s._)(n,t);var e=(0,c._)(n);function n(){return(0,i._)(this,n),e.apply(this,arguments)}return(0,A._)(n,[{key:"submit",value:function(t){var e=this;t.preventDefault();var n=(0,l._)((0,a._)({},iawpActions.create_campaign),{path:this.formTarget.elements.path.value,utm_source:this.formTarget.elements.utm_source.value,utm_medium:this.formTarget.elements.utm_medium.value,utm_campaign:this.formTarget.elements.utm_campaign.value,utm_term:this.formTarget.elements.utm_term.value,utm_content:this.formTarget.elements.utm_content.value});this.submitButtonTarget.setAttribute("disabled","disabled"),this.submitButtonTarget.classList.add("sending"),jQuery.post(ajaxurl,n,function(t){e.submitButtonTarget.removeAttribute("disabled"),e.submitButtonTarget.classList.remove("sending"),e.element.outerHTML=t.data.html})}},{key:"reuse",value:function(t){var e=this;try{this.newCampaignTarget.remove()}catch(t){}var n=JSON.parse(t.target.dataset.result);Object.keys(this.formTarget.elements).forEach(function(t){e.formTarget.elements[t].classList.remove("error"),e.formTarget.elements[t].parentElement.querySelectorAll("p.error").forEach(function(t){t.remove()})}),Object.keys(n).forEach(function(t){e.formTarget.elements[t]&&(e.formTarget.elements[t].value=n[t])}),this.formTarget.parentElement.scrollIntoView({behavior:"smooth"})}},{key:"delete",value:function(t){t.preventDefault();var e=(0,l._)((0,a._)({},iawpActions.delete_campaign),{campaign_url_id:t.target.dataset.campaignUrlId});t.target.setAttribute("disabled","disabled"),t.target.classList.add("sending"),jQuery.post(ajaxurl,e,function(e){t.target.removeAttribute("disabled"),t.target.classList.add("sent"),t.target.classList.remove("sending"),setTimeout(function(){t.target.closest(".campaign").classList.add("removing")},500),setTimeout(function(){t.target.closest(".campaign").remove()},1e3)})}}]),n}(t("@hotwired/stimulus").Controller);(0,o._)(u,"targets",["form","submitButton","newCampaign"])},{"@swc/helpers/_/_class_call_check":"2HOGN","@swc/helpers/_/_create_class":"8oe8p","@swc/helpers/_/_define_property":"27c3O","@swc/helpers/_/_inherits":"7gHjg","@swc/helpers/_/_object_spread":"kexvf","@swc/helpers/_/_object_spread_props":"c7x3p","@swc/helpers/_/_create_super":"a37Ru","@hotwired/stimulus":"crDvk","@parcel/transformer-js/src/esmodule-helpers.js":"kPSB8"}],kexvf:[function(t,e,n){var r=t("@parcel/transformer-js/src/esmodule-helpers.js");r.defineInteropFlag(n),r.export(n,"_object_spread",function(){return A}),r.export(n,"_",function(){return A});var i=t("./_define_property.js");function A(t){for(var e=1;e1&&window.iawp_chart.data.datasets.pop(),this.hasSecondaryMetric()){var n=this.secondaryChartMetricIdValue,r=this.secondaryChartMetricNameValue,i=this.dataValue[n],A=this.hasSharedAxis(this.primaryChartMetricIdValue,n)?"y":"defaultRight";window.iawp_chart.data.datasets.push(this.makeDataset(n,r,i,A,"rgba(246,157,10)"));var o=i.every(function(t){return 0===t});window.iawp_chart.options.scales.defaultRight.suggestedMax=o?10:null,window.iawp_chart.options.scales.defaultRight.beginAtZero="bounce_rate"!==n}window.iawp_chart.update()}},{key:"makeDataset",value:function(t,e,n,r,i){var A=arguments.length>5&&void 0!==arguments[5]&&arguments[5],o=(0,m.default)(i);return{id:t,label:e,data:n,borderColor:o.string(),backgroundColor:o.alpha(.1).string(),pointBackgroundColor:o.string(),tension:.4,yAxisID:r,fill:!0,order:A?1:0}}},{key:"shouldUseDarkMode",value:function(){return document.body.classList.contains("iawp-dark-mode")&&!this.isPreviewValue}},{key:"createChart",value:function(){var t=this;p.Chart.defaults.font.family='-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"';var e=document.getElementById("independent-analytics-chart"),n={type:"line",data:{labels:this.labelsValue,datasets:[this.makeDataset(this.primaryChartMetricIdValue,this.primaryChartMetricNameValue,this.dataValue[this.primaryChartMetricIdValue],"y","rgba(108,70,174)",!0)].filter(function(t){return null!==t})},options:{locale:this.getLocale(),interaction:{intersect:!1,mode:"index"},scales:{y:{grid:{color:this.shouldUseDarkMode()?"#676173":"#DEDAE6",borderColor:"#DEDAE6",tickColor:"#DEDAE6",display:!0,drawOnChartArea:!0,borderDash:[2,4]},beginAtZero:!0,suggestedMax:null,ticks:{color:this.shouldUseDarkMode()?"#ffffff":"#6D6A73",font:{size:14,weight:400},precision:0,callback:function(e,n,r){return t.formatValueForMetric(t.primaryChartMetricIdValue,e)}}},defaultRight:{position:"right",display:"auto",grid:{color:this.shouldUseDarkMode()?"#9a95a6":"#DEDAE6",borderColor:"#DEDAE6",tickColor:"#DEDAE6",display:!0,drawOnChartArea:!1,borderDash:[2,4]},beginAtZero:!0,suggestedMax:null,ticks:{color:this.shouldUseDarkMode()?"#ffffff":"#6D6A73",font:{size:14,weight:400},precision:0,callback:function(e,n,r){return t.hasSecondaryMetric()?t.formatValueForMetric(t.secondaryChartMetricIdValue,e):e}}},x:{grid:{borderColor:"#DEDAE6",tickColor:"#DEDAE6",display:!0,drawOnChartArea:!1},ticks:{color:this.shouldUseDarkMode()?"#ffffff":"#6D6A73",autoSkip:!0,autoSkipPadding:16,maxRotation:0,font:{size:14,weight:400},callback:this.tickText}}},plugins:{mode:String,legend:{display:!1},corsair:{dash:[2,4],color:"#777",width:1},tooltip:{itemSort:function(t,e){return t.datasetIndexs||cA){t.corsair={x:l,y:c,draw:!1},t.draw();return}t.corsair={x:l,y:c,draw:!0},t.draw()}},afterDatasetsDraw:function(t,e,n){if(!n.disabled){var r=t.ctx,i=t.chartArea,A=i.top,o=i.bottom;i.left,i.right;var s=t.corsair,a=s.x;s.y,s.draw&&(a=t.tooltip.caretX,r.lineWidth=n.width||0,r.setLineDash(n.dash||[]),r.strokeStyle=n.color||"black",r.save(),r.beginPath(),r.moveTo(a,o),r.lineTo(a,A),r.stroke(),r.restore(),r.setLineDash([]))}}}},{}],"1stGI":[function(t,e,n){/*! * Chart.js v3.9.1 * https://www.chartjs.org * (c) 2022 Chart.js Contributors * Released under the MIT License */var r=t("@parcel/transformer-js/src/esmodule-helpers.js");r.defineInteropFlag(n),r.export(n,"defaults",function(){return v.d}),r.export(n,"Animation",function(){return B}),r.export(n,"Animations",function(){return C}),r.export(n,"ArcElement",function(){return er}),r.export(n,"BarController",function(){return T}),r.export(n,"BarElement",function(){return ey}),r.export(n,"BasePlatform",function(){return tx}),r.export(n,"BasicPlatform",function(){return tk}),r.export(n,"BubbleController",function(){return R}),r.export(n,"CategoryScale",function(){return e$}),r.export(n,"Chart",function(){return t7}),r.export(n,"DatasetController",function(){return M}),r.export(n,"Decimation",function(){return e_}),r.export(n,"DomPlatform",function(){return tH}),r.export(n,"DoughnutController",function(){return K}),r.export(n,"Element",function(){return W}),r.export(n,"Filler",function(){return ej}),r.export(n,"Interaction",function(){return tf}),r.export(n,"Legend",function(){return eN}),r.export(n,"LineController",function(){return V}),r.export(n,"LineElement",function(){return eu}),r.export(n,"LinearScale",function(){return e2}),r.export(n,"LogarithmicScale",function(){return e4}),r.export(n,"PieController",function(){return G}),r.export(n,"PointElement",function(){return ed}),r.export(n,"PolarAreaController",function(){return z}),r.export(n,"RadarController",function(){return q}),r.export(n,"RadialLinearScale",function(){return e7}),r.export(n,"Scale",function(){return tn}),r.export(n,"ScatterController",function(){return tA}),r.export(n,"SubTitle",function(){return eT}),r.export(n,"Ticks",function(){return X}),r.export(n,"TimeScale",function(){return no}),r.export(n,"TimeSeriesScale",function(){return na}),r.export(n,"Title",function(){return eO}),r.export(n,"Tooltip",function(){return eJ}),r.export(n,"_adapters",function(){return tl}),r.export(n,"_detectPlatform",function(){return tT}),r.export(n,"animator",function(){return y}),r.export(n,"controllers",function(){return to}),r.export(n,"elements",function(){return ew}),r.export(n,"layouts",function(){return tC}),r.export(n,"plugins",function(){return eZ}),r.export(n,"registerables",function(){return nc}),r.export(n,"registry",function(){return ti}),r.export(n,"scales",function(){return nl});var i=t("@swc/helpers/_/_assert_this_initialized"),A=t("@swc/helpers/_/_class_call_check"),o=t("@swc/helpers/_/_create_class"),s=t("@swc/helpers/_/_define_property"),a=t("@swc/helpers/_/_get"),l=t("@swc/helpers/_/_get_prototype_of"),c=t("@swc/helpers/_/_inherits"),u=t("@swc/helpers/_/_object_spread"),h=t("@swc/helpers/_/_object_spread_props"),d=t("@swc/helpers/_/_sliced_to_array"),f=t("@swc/helpers/_/_to_consumable_array"),p=t("@swc/helpers/_/_type_of"),g=t("@swc/helpers/_/_wrap_native_super"),m=t("@swc/helpers/_/_create_super"),v=t("./chunks/helpers.segment.mjs"),y=new(function(){function t(){(0,A._)(this,t),this._request=null,this._charts=new Map,this._running=!1,this._lastDate=void 0}return(0,o._)(t,[{key:"_notify",value:function(t,e,n,r){var i=e.listeners[r],A=e.duration;i.forEach(function(r){return r({chart:t,initial:e.initial,numSteps:A,currentStep:Math.min(n-e.start,A)})})}},{key:"_refresh",value:function(){var t=this;this._request||(this._running=!0,this._request=(0,v.r).call(window,function(){t._update(),t._request=null,t._running&&t._refresh()}))}},{key:"_update",value:function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:Date.now(),n=0;this._charts.forEach(function(r,i){if(r.running&&r.items.length){for(var A,o=r.items,s=o.length-1,a=!1;s>=0;--s)(A=o[s])._active?(A._total>r.duration&&(r.duration=A._total),A.tick(e),a=!0):(o[s]=o[o.length-1],o.pop());a&&(i.draw(),t._notify(i,r,e,"progress")),o.length||(r.running=!1,t._notify(i,r,e,"complete"),r.initial=!1),n+=o.length}}),this._lastDate=e,0===n&&(this._running=!1)}},{key:"_getAnims",value:function(t){var e=this._charts,n=e.get(t);return n||(n={running:!1,initial:!0,items:[],listeners:{complete:[],progress:[]}},e.set(t,n)),n}},{key:"listen",value:function(t,e,n){this._getAnims(t).listeners[e].push(n)}},{key:"add",value:function(t,e){var n;e&&e.length&&(n=this._getAnims(t).items).push.apply(n,(0,f._)(e))}},{key:"has",value:function(t){return this._getAnims(t).items.length>0}},{key:"start",value:function(t){var e=this._charts.get(t);e&&(e.running=!0,e.start=Date.now(),e.duration=e.items.reduce(function(t,e){return Math.max(t,e._duration)},0),this._refresh())}},{key:"running",value:function(t){if(!this._running)return!1;var e=this._charts.get(t);return!!e&&!!e.running&&!!e.items.length}},{key:"stop",value:function(t){var e=this._charts.get(t);if(e&&e.items.length){for(var n=e.items,r=n.length-1;r>=0;--r)n[r].cancel();e.items=[],this._notify(t,e,Date.now(),"complete")}}},{key:"remove",value:function(t){return this._charts.delete(t)}}]),t}()),w="transparent",b={boolean:function(t,e,n){return n>.5?e:t},color:function(t,e,n){var r=(0,v.c)(t||w),i=r.valid&&(0,v.c)(e||w);return i&&i.valid?i.mix(r,n).hexString():e},number:function(t,e,n){return t+(e-t)*n}},B=function(){function t(e,n,r,i){(0,A._)(this,t);var o=n[r];i=(0,v.a)([e.to,i,o,e.from]);var s=(0,v.a)([e.from,o,i]);this._active=!0,this._fn=e.fn||b[e.type||(void 0===s?"undefined":(0,p._)(s))],this._easing=v.e[e.easing]||v.e.linear,this._start=Math.floor(Date.now()+(e.delay||0)),this._duration=this._total=Math.floor(e.duration),this._loop=!!e.loop,this._target=n,this._prop=r,this._from=s,this._to=i,this._promises=void 0}return(0,o._)(t,[{key:"active",value:function(){return this._active}},{key:"update",value:function(t,e,n){if(this._active){this._notify(!1);var r=this._target[this._prop],i=n-this._start,A=this._duration-i;this._start=n,this._duration=Math.floor(Math.max(A,t.duration)),this._total+=i,this._loop=!!t.loop,this._to=(0,v.a)([t.to,e,r,t.from]),this._from=(0,v.a)([t.from,r,e])}}},{key:"cancel",value:function(){this._active&&(this.tick(Date.now()),this._active=!1,this._notify(!1))}},{key:"tick",value:function(t){var e,n=t-this._start,r=this._duration,i=this._prop,A=this._from,o=this._loop,s=this._to;if(this._active=A!==s&&(o||n1?2-e:e,e=this._easing(Math.min(1,Math.max(0,e))),this._target[i]=this._fn(A,s,e)}},{key:"wait",value:function(){var t=this._promises||(this._promises=[]);return new Promise(function(e,n){t.push({res:e,rej:n})})}},{key:"_notify",value:function(t){for(var e=t?"res":"rej",n=this._promises||[],r=0;r=0;--s){var s,a=A[s];if("$"!==a.charAt(0)){if("options"===a){r.push.apply(r,(0,f._)(this._animateOptions(t,e)));continue}var l=e[a],c=i[a],u=n.get(a);if(c){if(u&&c.active()){c.update(u,l,o);continue}c.cancel()}if(!u||!u.duration){t[a]=l;continue}i[a]=c=new B(u,t,a,l),r.push(c)}}return r}},{key:"update",value:function(t,e){if(0===this._properties.size){Object.assign(t,e);return}var n=this._createAnimations(t,e);if(n.length)return y.add(this._chart,n),!0}}]),t}();function x(t,e){var n=t&&t.options||{},r=n.reverse,i=void 0===n.min?e:0,A=void 0===n.max?e:0;return{start:r?A:i,end:r?i:A}}function k(t,e){var n,r,i=[],A=t._getSortedDatasetMetas(e);for(n=0,r=A.length;n3&&void 0!==arguments[3]?arguments[3]:{},a=t.keys,l="single"===s.mode;if(null!==e){for(r=0,i=a.length;r0||!n&&c<0)return l.index}}catch(t){A=!0,o=t}finally{try{i||null==a.return||a.return()}finally{if(A)throw o}}return null}function S(t,e){for(var n,r=t.chart,i=t._cachedMeta,A=r._stacks||(r._stacks={}),o=i.iScale,s=i.vScale,a=i.index,l=o.axis,c=s.axis,u="".concat(o.id,".").concat(s.id,".").concat(i.stack||i.type),h=e.length,d=0;d0&&A._parsed[t-1];if(!1===this._parsing)A._parsed=o,A._sorted=!0,i=o;else{for(n=0,i=(0,v.b)(o[t])?this.parseArrayData(A,o,t,e):(0,v.i)(o[t])?this.parseObjectData(A,o,t,e):this.parsePrimitiveData(A,o,t,e);ne||m=0;--o)if(!y()){this.updateRangeFromParsed(f,t,s,d);break}}return f}},{key:"getAllParsedValues",value:function(t){var e,n,r,i=this._cachedMeta._parsed,A=[];for(e=0,n=i.length;e=0&&t1&&void 0!==arguments[1]?arguments[1]:"default",r=arguments.length>2?arguments[2]:void 0,i="active"===n,A=this._cachedDataOpts,o=t+"-"+n,s=A[o],a=this.enableOptionSharing&&(0,v.j)(r);if(s)return j(s,a);var l=this.chart.config,c=l.datasetElementScopeKeys(this._type,t),u=l.getOptionScopes(this.getDataset(),c),h=Object.keys(v.d.elements[t]),d=l.resolveNamedOptions(u,h,function(){return e.getContext(r,i)},i?["".concat(t,"Hover"),"hover",t,""]:[t,""]);return d.$shared&&(d.$shared=a,A[o]=Object.freeze(j(d,a))),d}},{key:"_resolveAnimations",value:function(t,e,n){var r,i=this.chart,A=this._cachedDataOpts,o="animation-".concat(e),s=A[o];if(s)return s;if(!1!==i.options.animation){var a=this.chart.config,l=a.datasetAnimationScopeKeys(this._type,e),c=a.getOptionScopes(this.getDataset(),l);r=a.createResolver(c,this.getContext(t,n,e))}var u=new C(i,r&&r.animations);return r&&r._cacheable&&(A[o]=Object.freeze(u)),u}},{key:"getSharedOptions",value:function(t){if(t.$shared)return this._sharedOptions||(this._sharedOptions=Object.assign({},t))}},{key:"includeOptions",value:function(t,e){return!e||I(t)||this.chart._animationsDisabled}},{key:"_getSharedOptions",value:function(t,e){var n=this.resolveDataElementOptions(t,e),r=this._sharedOptions,i=this.getSharedOptions(n),A=this.includeOptions(e,i)||i!==r;return this.updateSharedOptions(i,e,n),{sharedOptions:i,includeOptions:A}}},{key:"updateElement",value:function(t,e,n,r){I(r)?Object.assign(t,n):this._resolveAnimations(e,r).update(t,n)}},{key:"updateSharedOptions",value:function(t,e,n){t&&!I(e)&&this._resolveAnimations(void 0,e).update(t,n)}},{key:"_setStyle",value:function(t,e,n,r){t.active=r;var i=this.getStyle(e,r);this._resolveAnimations(e,n,r).update(t,{options:!r&&this.getSharedOptions(i)||i})}},{key:"removeHoverStyle",value:function(t,e,n){this._setStyle(t,n,"active",!1)}},{key:"setHoverStyle",value:function(t,e,n){this._setStyle(t,n,"active",!0)}},{key:"_removeDatasetHoverStyle",value:function(){var t=this._cachedMeta.dataset;t&&this._setStyle(t,void 0,"active",!1)}},{key:"_setDatasetHoverStyle",value:function(){var t=this._cachedMeta.dataset;t&&this._setStyle(t,void 0,"active",!0)}},{key:"_resyncElements",value:function(t){var e=this._data,n=this._cachedMeta.data,r=!0,i=!1,A=void 0;try{for(var o,s=this._syncList[Symbol.iterator]();!(r=(o=s.next()).done);r=!0){var a=(0,d._)(o.value,3),l=a[0],c=a[1],u=a[2];this[l](c,u)}}catch(t){i=!0,A=t}finally{try{r||null==s.return||s.return()}finally{if(i)throw A}}this._syncList=[];var h=n.length,f=e.length,p=Math.min(f,h);p&&this.parse(0,p),f>h?this._insertElements(h,f-h,t):f2)||void 0===arguments[2]||arguments[2],i=this._cachedMeta,A=i.data,o=t+e,s=function(t){for(t.length+=e,n=t.length-1;n>=o;n--)t[n]=t[n-e]};for(s(A),n=t;nMath.abs(s)&&(a=s,l=o),e[n.axis]=l,e._custom={barStart:a,barEnd:l,start:i,end:A,min:o,max:s}}else e[n.axis]=n.parse(t,r);return e}function N(t,e,n,r){var i,A,o,s,a=t.iScale,l=t.vScale,c=a.getLabels(),u=a===l,h=[];for(i=n,A=n+r;it.x,A="left",o="right"):(i=t.base=l?1:-1))*a,d===l&&(m-=n/2);var y,w=i.getPixelForDecimal(0),b=i.getPixelForDecimal(1),B=Math.min(w,b);e=(m=Math.max(Math.min(m,Math.max(w,b)),B))+n}if(m===i.getPixelForValue(l)){var _=(0,v.s)(n)*i.getLineWidthForValue(l)/2;m+=_,n-=_}return{size:n,base:m,head:e,center:e+n/2}}},{key:"_calculateBarIndexPixels",value:function(t,e){var n,r,i=e.scale,A=this.options,o=A.skipNull,s=(0,v.v)(A.maxBarThickness,1/0);if(e.grouped){var a,l,c,u,h,d,f,p,g,m=o?this._getStackCount(t):e.stackCount,y="flex"===A.barThickness?(l=(a=e.pixels)[t],c=t>0?a[t-1]:null,u=t=0;--n)e=Math.max(e,t[n].size(this.resolveDataElementOptions(n))/2);return e>0&&e}},{key:"getLabelAndValue",value:function(t){var e=this._cachedMeta,n=e.xScale,r=e.yScale,i=this.getParsed(t),A=n.getLabelForValue(i.x),o=r.getLabelForValue(i.y),s=i._custom;return{label:e.label,value:"("+A+", "+o+(s?", "+s:"")+")"}}},{key:"update",value:function(t){var e=this._cachedMeta.data;this.updateElements(e,0,e.length,t)}},{key:"updateElements",value:function(t,e,n,r){for(var i="reset"===r,A=this._cachedMeta,o=A.iScale,s=A.vScale,a=this._getSharedOptions(e,r),l=a.sharedOptions,c=a.includeOptions,u=o.axis,h=s.axis,d=e;d0&&!isNaN(t)?v.T*(Math.abs(t)/e):0}},{key:"getLabelAndValue",value:function(t){var e=this._cachedMeta,n=this.chart,r=n.data.labels||[],i=(0,v.o)(e._parsed[t],n.options.locale);return{label:r[t]||"",value:i}}},{key:"getMaxBorderWidth",value:function(t){var e,n,r,i,A,o=0,s=this.chart;if(!t){for(e=0,n=s.data.datasets.length;e0&&this.getParsed(e-1),B=e;B0&&Math.abs(C[d]-b[d])>y,m&&(x.parsed=C,x.raw=l.data[B]),h&&(x.options=u||this.resolveDataElementOptions(B,_.active?"active":r)),w||this.updateElement(_,B,x,r),b=C}}},{key:"getMaxOverflow",value:function(){var t=this._cachedMeta,e=t.dataset,n=e.options&&e.options.borderWidth||0,r=t.data||[];return r.length?Math.max(n,r[0].size(this.resolveDataElementOptions(0)),r[r.length-1].size(this.resolveDataElementOptions(r.length-1)))/2:n}},{key:"draw",value:function(){var t=this._cachedMeta;t.dataset.updateControlPoints(this.chart.chartArea,t.iScale.axis),(0,a._)((0,l._)(n.prototype),"draw",this).call(this)}}]),n}(M);V.id="line",V.defaults={datasetElementType:"line",dataElementType:"point",showLine:!0,spanGaps:!1},V.overrides={scales:{_index_:{type:"category"},_value_:{type:"linear"}}};var z=function(t){(0,c._)(n,t);var e=(0,m._)(n);function n(t,r){var i;return(0,A._)(this,n),(i=e.call(this,t,r)).innerRadius=void 0,i.outerRadius=void 0,i}return(0,o._)(n,[{key:"getLabelAndValue",value:function(t){var e=this._cachedMeta,n=this.chart,r=n.data.labels||[],i=(0,v.o)(e._parsed[t].r,n.options.locale);return{label:r[t]||"",value:i}}},{key:"parseObjectData",value:function(t,e,n,r){return(0,v.y).bind(this)(t,e,n,r)}},{key:"update",value:function(t){var e=this._cachedMeta.data;this._updateRadius(),this.updateElements(e,0,e.length,t)}},{key:"getMinMax",value:function(){var t=this,e=this._cachedMeta,n={min:Number.POSITIVE_INFINITY,max:Number.NEGATIVE_INFINITY};return e.data.forEach(function(e,r){var i=t.getParsed(r).r;!isNaN(i)&&t.chart.getDataVisibility(r)&&(in.max&&(n.max=i))}),n}},{key:"_updateRadius",value:function(){var t=this.chart,e=t.chartArea,n=t.options,r=Math.max(Math.min(e.right-e.left,e.bottom-e.top)/2,0),i=Math.max(n.cutoutPercentage?r/100*n.cutoutPercentage:1,0),A=(r-i)/t.getVisibleDatasetCount();this.outerRadius=r-A*this.index,this.innerRadius=this.outerRadius-A}},{key:"updateElements",value:function(t,e,n,r){var i,A="reset"===r,o=this.chart,s=o.options.animation,a=this._cachedMeta.rScale,l=a.xCenter,c=a.yCenter,u=a.getIndexAngle(0)-.5*v.P,h=u,d=360/this.countVisibleElements();for(i=0;i1){var o,s=Math.max(Math.abs(n[0].value),Math.abs(n[n.length-1].value));(s<1e-4||s>1e15)&&(r="scientific"),Math.abs(o=n.length>3?n[2].value-n[1].value:n[1].value-n[0].value)>=1&&t!==Math.floor(t)&&(o=t-Math.floor(t)),A=o}var a=Math.max(Math.min(-1*Math.floor((0,v.z)(Math.abs(A))),20),0),l={notation:r,minimumFractionDigits:a,maximumFractionDigits:a};return Object.assign(l,this.options.ticks.format),(0,v.o)(t,i,l)},logarithmic:function(t,e,n){if(0===t)return"0";var r=t/Math.pow(10,Math.floor((0,v.z)(t)));return 1===r||2===r||5===r?Y.numeric.call(this,t,e,n):""}},X={formatters:Y};function J(t,e,n,r,i){var A,o,s,a=(0,v.v)(r,0),l=Math.min((0,v.v)(i,t.length),t.length),c=0;for(n=Math.ceil(n),i&&(n=(A=i-r)/Math.floor(A/n)),s=a;s<0;)s=Math.round(a+ ++c*n);for(o=Math.max(a,0);oi?i:r,i=A&&r>i?r:i,{min:(0,v.B)(r,(0,v.B)(i,r)),max:(0,v.B)(i,(0,v.B)(r,i))}}},{key:"getPadding",value:function(){return{left:this.paddingLeft||0,top:this.paddingTop||0,right:this.paddingRight||0,bottom:this.paddingBottom||0}}},{key:"getTicks",value:function(){return this.ticks}},{key:"getLabels",value:function(){var t=this.chart.data;return this.options.labels||(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels||[]}},{key:"beforeLayout",value:function(){this._cache={},this._dataLimitsCached=!1}},{key:"beforeUpdate",value:function(){(0,v.C)(this.options.beforeUpdate,[this])}},{key:"update",value:function(t,e,n){var r=this.options,i=r.beginAtZero,A=r.grace,o=r.ticks,s=o.sampleSize;this.beforeUpdate(),this.maxWidth=t,this.maxHeight=e,this._margins=n=Object.assign({left:0,right:0,top:0,bottom:0},n),this.ticks=null,this._labelSizes=null,this._gridLineItems=null,this._labelItems=null,this.beforeSetDimensions(),this.setDimensions(),this.afterSetDimensions(),this._maxLength=this.isHorizontal()?this.width+n.left+n.right:this.height+n.top+n.bottom,this._dataLimitsCached||(this.beforeDataLimits(),this.determineDataLimits(),this.afterDataLimits(),this._range=(0,v.D)(this,A,i),this._dataLimitsCached=!0),this.beforeBuildTicks(),this.ticks=this.buildTicks()||[],this.afterBuildTicks();var a=sr)return function(t,e,n,r){var i,A=0,o=n[0];for(i=0,r=Math.ceil(r);ii)return a}return Math.max(i,1)}(i,e,r);if(A>0){var c,u,h,d,f=A>1?Math.round((s-o)/(A-1)):null;for(J(e,a,l,(0,v.k)(f)?0:o-f,o),h=0,d=A-1;h=s||A<=1||!this.isHorizontal()){this.labelRotation=o;return}var l=this._getLabelSizes(),c=l.widest.width,u=l.highest.height,h=(0,v.E)(this.chart.width-c,0,this.maxWidth);c+6>(t=r.offset?this.maxWidth/A:h/(A-1))&&(t=h/(A-(r.offset?.5:1)),e=this.maxHeight-tt(r.grid)-i.padding-te(r.title,this.chart.options.font),n=Math.sqrt(c*c+u*u),a=Math.max(o,Math.min(s,a=(0,v.F)(Math.min(Math.asin((0,v.E)((l.highest.height+6)/t,-1,1)),Math.asin((0,v.E)(e/n,-1,1))-Math.asin((0,v.E)(u/n,-1,1))))))),this.labelRotation=a}},{key:"afterCalculateLabelRotation",value:function(){(0,v.C)(this.options.afterCalculateLabelRotation,[this])}},{key:"afterAutoSkip",value:function(){}},{key:"beforeFit",value:function(){(0,v.C)(this.options.beforeFit,[this])}},{key:"fit",value:function(){var t={width:0,height:0},e=this.chart,n=this.options,r=n.ticks,i=n.title,A=n.grid,o=this._isVisible(),s=this.isHorizontal();if(o){var a=te(i,e.options.font);if(s?(t.width=this.maxWidth,t.height=tt(A)+a):(t.height=this.maxHeight,t.width=tt(A)+a),r.display&&this.ticks.length){var l=this._getLabelSizes(),c=l.first,u=l.last,h=l.widest,d=l.highest,f=2*r.padding,p=(0,v.t)(this.labelRotation),g=Math.cos(p),m=Math.sin(p);if(s){var y=r.mirror?0:m*h.width+g*d.height;t.height=Math.min(this.maxHeight,t.height+y+f)}else{var w=r.mirror?0:g*h.width+m*d.height;t.width=Math.min(this.maxWidth,t.width+w+f)}this._calculatePadding(c,u,m,g)}}this._handleMargins(),s?(this.width=this._length=e.width-this._margins.left-this._margins.right,this.height=t.height):(this.width=t.width,this.height=this._length=e.height-this._margins.top-this._margins.bottom)}},{key:"_calculatePadding",value:function(t,e,n,r){var i=this.options,A=i.ticks,o=A.align,s=A.padding,a=i.position,l=0!==this.labelRotation,c="top"!==a&&"x"===this.axis;if(this.isHorizontal()){var u=this.getPixelForTick(0)-this.left,h=this.right-this.getPixelForTick(this.ticks.length-1),d=0,f=0;l?c?(d=r*t.width,f=n*e.height):(d=n*t.height,f=r*e.width):"start"===o?f=e.width:"end"===o?d=t.width:"inner"!==o&&(d=t.width/2,f=e.width/2),this.paddingLeft=Math.max((d-u+s)*this.width/(this.width-u),0),this.paddingRight=Math.max((f-h+s)*this.width/(this.width-h),0)}else{var p=e.height/2,g=t.height/2;"start"===o?(p=0,g=t.height):"end"===o&&(p=e.height,g=0),this.paddingTop=p+s,this.paddingBottom=g+s}}},{key:"_handleMargins",value:function(){this._margins&&(this._margins.left=Math.max(this.paddingLeft,this._margins.left),this._margins.top=Math.max(this.paddingTop,this._margins.top),this._margins.right=Math.max(this.paddingRight,this._margins.right),this._margins.bottom=Math.max(this.paddingBottom,this._margins.bottom))}},{key:"afterFit",value:function(){(0,v.C)(this.options.afterFit,[this])}},{key:"isHorizontal",value:function(){var t=this.options,e=t.axis,n=t.position;return"top"===n||"bottom"===n||"x"===e}},{key:"isFullSize",value:function(){return this.options.fullSize}},{key:"_convertTicksToLabels",value:function(t){var e,n;for(this.beforeTickToLabelConversion(),this.generateTickLabels(t),e=0,n=t.length;ee){for(n=0;ne.length-1?null:this.getPixelForValue(e[t].value)}},{key:"getPixelForDecimal",value:function(t){this._reversePixels&&(t=1-t);var e=this._startPixel+t*this._length;return(0,v.I)(this._alignToPixels?(0,v.J)(this.chart,e,0):e)}},{key:"getDecimalForPixel",value:function(t){var e=(t-this._startPixel)/this._length;return this._reversePixels?1-e:e}},{key:"getBasePixel",value:function(){return this.getPixelForValue(this.getBaseValue())}},{key:"getBaseValue",value:function(){var t=this.min,e=this.max;return t<0&&e<0?e:t>0&&e>0?t:0}},{key:"getContext",value:function(t){var e,n=this.ticks||[];if(t>=0&&to*r?o/n:s/r:s*r0}},{key:"_computeGridLineItems",value:function(t){var e,n,r,i,A,o,s,a,l,c,u,h,d=this.axis,f=this.chart,p=this.options,g=p.grid,m=p.position,y=g.offset,w=this.isHorizontal(),b=this.ticks.length+(y?1:0),B=tt(g),_=[],C=g.setContext(this.getContext()),x=C.drawBorder?C.borderWidth:0,k=x/2,F=function(t){return(0,v.J)(f,t,x)};if("top"===m)e=F(this.bottom),o=this.bottom-B,a=e-k,c=F(t.top)+k,h=t.bottom;else if("bottom"===m)e=F(this.top),c=t.top,h=F(t.bottom)-k,o=e+k,a=this.top+B;else if("left"===m)e=F(this.right),A=this.right-B,s=e-k,l=F(t.left)+k,u=t.right;else if("right"===m)e=F(this.left),l=t.left,u=F(t.right)-k,A=e+k,s=this.left+B;else if("x"===d){if("center"===m)e=F((t.top+t.bottom)/2+.5);else if((0,v.i)(m)){var Q=Object.keys(m)[0],E=m[Q];e=F(this.chart.scales[Q].getPixelForValue(E))}c=t.top,h=t.bottom,a=(o=e+k)+B}else if("y"===d){if("center"===m)e=F((t.left+t.right)/2);else if((0,v.i)(m)){var S=Object.keys(m)[0],U=m[S];e=F(this.chart.scales[S].getPixelForValue(U))}s=(A=e-k)-B,l=t.left,u=t.right}var L=(0,v.v)(p.ticks.maxTicksLimit,b),I=Math.max(1,Math.ceil(b/L));for(n=0;ns+1e-6)))return a}(this,n,y))&&(i=(0,v.J)(f,r,M),w?A=s=l=u=i:o=a=c=h=i,_.push({tx1:A,ty1:o,tx2:s,ty2:a,x1:l,y1:c,x2:u,y2:h,width:M,color:D,borderDash:N,borderDashOffset:P,tickWidth:O,tickColor:H,tickBorderDash:T,tickBorderDashOffset:R}))}return this._ticksLength=b,this._borderValue=e,_}},{key:"_computeLabelItems",value:function(t){var e,n,r,i,A,o,s,a,l,c,u,h=this.axis,d=this.options,f=d.position,p=d.ticks,g=this.isHorizontal(),m=this.ticks,y=p.align,w=p.crossAlign,b=p.padding,B=p.mirror,_=tt(d.grid),C=_+b,x=B?-b:C,k=-(0,v.t)(this.labelRotation),F=[],Q="middle";if("top"===f)A=this.bottom-x,o=this._getXAxisLabelAlignment();else if("bottom"===f)A=this.top+x,o=this._getXAxisLabelAlignment();else if("left"===f){var E=this._getYAxisLabelAlignment(_);o=E.textAlign,i=E.x}else if("right"===f){var S=this._getYAxisLabelAlignment(_);o=S.textAlign,i=S.x}else if("x"===h){if("center"===f)A=(t.top+t.bottom)/2+C;else if((0,v.i)(f)){var U=Object.keys(f)[0],L=f[U];A=this.chart.scales[U].getPixelForValue(L)+C}o=this._getXAxisLabelAlignment()}else if("y"===h){if("center"===f)i=(t.left+t.right)/2-C;else if((0,v.i)(f)){var I=Object.keys(f)[0],j=f[I];i=this.chart.scales[I].getPixelForValue(j)}o=this._getYAxisLabelAlignment(_).textAlign}"y"===h&&("start"===y?Q="top":"end"===y&&(Q="bottom"));var M=this._getLabelSizes();for(e=0,n=m.length;e=0?e.setContext(this.getContext(n)).lineWidth:0}},{key:"drawGrid",value:function(t){var e,n,r=this.options.grid,i=this.ctx,A=this._gridLineItems||(this._gridLineItems=this._computeGridLineItems(t)),o=function(t,e,n){n.width&&n.color&&(i.save(),i.lineWidth=n.width,i.strokeStyle=n.color,i.setLineDash(n.borderDash||[]),i.lineDashOffset=n.borderDashOffset,i.beginPath(),i.moveTo(t.x,t.y),i.lineTo(e.x,e.y),i.stroke(),i.restore())};if(r.display)for(e=0,n=A.length;e0&&this.getParsed(e-1),B=e;B0&&Math.abs(C[d]-b[d])>y,m&&(x.parsed=C,x.raw=l.data[B]),h&&(x.options=u||this.resolveDataElementOptions(B,_.active?"active":r)),w||this.updateElement(_,B,x,r),b=C}this.updateSharedOptions(u,r,c)}},{key:"getMaxOverflow",value:function(){var t=this._cachedMeta,e=t.data||[];if(!this.options.showLine){for(var n=0,r=e.length-1;r>=0;--r)n=Math.max(n,e[r].size(this.resolveDataElementOptions(r))/2);return n>0&&n}var i=t.dataset,A=i.options&&i.options.borderWidth||0;return e.length?Math.max(A,e[0].size(this.resolveDataElementOptions(0)),e[e.length-1].size(this.resolveDataElementOptions(e.length-1)))/2:A}}]),n}(M);tA.id="scatter",tA.defaults={datasetElementType:!1,dataElementType:"point",showLine:!1,fill:!1},tA.overrides={interaction:{mode:"point"},plugins:{tooltip:{callbacks:{title:function(){return""},label:function(t){return"("+t.label+", "+t.formattedValue+")"}}}},scales:{x:{type:"linear"},y:{type:"linear"}}};var to=Object.freeze({__proto__:null,BarController:T,BubbleController:R,DoughnutController:K,LineController:V,PolarAreaController:z,PieController:G,RadarController:q,ScatterController:tA});function ts(){throw Error("This method is not implemented: Check that a complete date adapter is provided.")}var ta=function(){function t(e){(0,A._)(this,t),this.options=e||{}}return(0,o._)(t,[{key:"init",value:function(t){}},{key:"formats",value:function(){return ts()}},{key:"parse",value:function(t,e){return ts()}},{key:"format",value:function(t,e){return ts()}},{key:"add",value:function(t,e,n){return ts()}},{key:"diff",value:function(t,e,n){return ts()}},{key:"startOf",value:function(t,e,n){return ts()}},{key:"endOf",value:function(t,e){return ts()}}]),t}();ta.override=function(t){Object.assign(ta.prototype,t)};var tl={_date:ta};function tc(t,e,n,r,i){for(var A=t.getSortedVisibleDatasetMetas(),o=n[e],s=0,a=A.length;s0){var a=s[0].datasetIndex,l=t.getDatasetMeta(a).data;s=[];for(var c=0;c3&&void 0!==arguments[3]?arguments[3]:[""],i={$shared:!0},A=tZ(this._resolverCache,t,r),o=A.resolver,s=A.subPrefixes,a=o;if(function(t,e){var n=(0,v.ab)(t),r=n.isScriptable,i=n.isIndexable,A=!0,o=!1,s=void 0;try{for(var a,l=e[Symbol.iterator]();!(A=(a=l.next()).done);A=!0){var c=a.value,u=r(c),h=i(c),d=(h||u)&&t[c];if(u&&((0,v.a8)(d)||t$(d))||h&&(0,v.b)(d))return!0}}catch(t){o=!0,s=t}finally{try{A||null==l.return||l.return()}finally{if(o)throw s}}return!1}(o,e)){i.$shared=!1,n=(0,v.a8)(n)?n():n;var l=this.createResolver(t,n,s);a=(0,v.a9)(o,n,l)}var c=!0,u=!1,h=void 0;try{for(var d,f=e[Symbol.iterator]();!(c=(d=f.next()).done);c=!0){var p=d.value;i[p]=a[p]}}catch(t){u=!0,h=t}finally{try{c||null==f.return||f.return()}finally{if(u)throw h}}return i}},{key:"createResolver",value:function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[""],r=arguments.length>3?arguments[3]:void 0,i=tZ(this._resolverCache,t,n).resolver;return(0,v.i)(e)?(0,v.a9)(i,e,void 0,r):i}}]),t}();function tZ(t,e,n){var r=t.get(e);r||(r=new Map,t.set(e,r));var i=n.join(),A=r.get(i);return A||(A={resolver:(0,v.aa)(e,n),subPrefixes:n.filter(function(t){return!t.toLowerCase().includes("hover")})},r.set(i,A)),A}var t$=function(t){return(0,v.i)(t)&&Object.getOwnPropertyNames(t).reduce(function(e,n){return e||(0,v.a8)(t[n])},!1)},t0=["top","bottom","left","right","chartArea"];function t1(t,e){return"top"===t||"bottom"===t||-1===t0.indexOf(t)&&"x"===e}function t2(t,e){return function(n,r){return n[t]===r[t]?n[e]-r[e]:n[t]-r[t]}}function t5(t){var e=t.chart,n=e.options.animation;e.notifyPlugins("afterRender"),(0,v.C)(n&&n.onComplete,[t],e)}function t4(t){var e=t.chart,n=e.options.animation;(0,v.C)(n&&n.onProgress,[t],e)}function t3(t){return(0,v.a6)()&&"string"==typeof t?t=document.getElementById(t):t&&t.length&&(t=t[0]),t&&t.canvas&&(t=t.canvas),t}var t6={},t8=function(t){var e=t3(t);return Object.values(t6).filter(function(t){return t.canvas===e}).pop()},t7=function(){function t(e,n){var r=this;(0,A._)(this,t);var i=this.config=new tJ(n),o=t3(e),s=t8(o);if(s)throw Error("Canvas is already in use. Chart with ID '"+s.id+"' must be destroyed before the canvas with ID '"+s.canvas.id+"' can be reused.");var a=i.createResolver(i.chartOptionScopes(),this.getContext());this.platform=new(i.platform||tT(o)),this.platform.updateConfig(i);var l=this.platform.acquireContext(o,a.aspectRatio),c=l&&l.canvas,u=c&&c.height,h=c&&c.width;if(this.id=(0,v.ad)(),this.ctx=l,this.canvas=c,this.width=h,this.height=u,this._options=a,this._aspectRatio=this.aspectRatio,this._layers=[],this._metasets=[],this._stacks=void 0,this.boxes=[],this.currentDevicePixelRatio=void 0,this.chartArea=void 0,this._active=[],this._lastEvent=void 0,this._listeners={},this._responsiveListeners=void 0,this._sortedMetasets=[],this.scales={},this._plugins=new tR,this.$proxies={},this._hiddenIndices={},this.attached=!1,this._animationsDisabled=void 0,this.$context=void 0,this._doResize=(0,v.ae)(function(t){return r.update(t)},a.resizeDelay||0),this._dataChanges=[],t6[this.id]=this,!l||!c){console.error("Failed to create chart: can't acquire context from the given item");return}y.listen(this,"complete",t5),y.listen(this,"progress",t4),this._initialize(),this.attached&&this.update()}return(0,o._)(t,[{key:"aspectRatio",get:function(){var t=this.options,e=t.aspectRatio,n=t.maintainAspectRatio,r=this.width,i=this.height,A=this._aspectRatio;return(0,v.k)(e)?n&&A?A:i?r/i:null:e}},{key:"data",get:function(){return this.config.data},set:function(t){this.config.data=t}},{key:"options",get:function(){return this._options},set:function(t){this.config.options=t}},{key:"_initialize",value:function(){return this.notifyPlugins("beforeInit"),this.options.responsive?this.resize():(0,v.af)(this,this.options.devicePixelRatio),this.bindEvents(),this.notifyPlugins("afterInit"),this}},{key:"clear",value:function(){return(0,v.ag)(this.canvas,this.ctx),this}},{key:"stop",value:function(){return y.stop(this),this}},{key:"resize",value:function(t,e){y.running(this)?this._resizeBeforeDraw={width:t,height:e}:this._resize(t,e)}},{key:"_resize",value:function(t,e){var n=this.options,r=this.canvas,i=n.maintainAspectRatio&&this.aspectRatio,A=this.platform.getMaximumSize(r,t,e,i),o=n.devicePixelRatio||this.platform.getDevicePixelRatio(),s=this.width?"resize":"attach";this.width=A.width,this.height=A.height,this._aspectRatio=this.aspectRatio,(0,v.af)(this,o,!0)&&(this.notifyPlugins("resize",{size:A}),(0,v.C)(n.onResize,[this,A],this),this.attached&&this._doResize(s)&&this.render())}},{key:"ensureScalesHaveIDs",value:function(){var t=this.options.scales||{};(0,v.Q)(t,function(t,e){t.id=e})}},{key:"buildOrUpdateScales",value:function(){var t=this,e=this.options,n=e.scales,r=this.scales,i=Object.keys(r).reduce(function(t,e){return t[e]=!1,t},{}),A=[];n&&(A=A.concat(Object.keys(n).map(function(t){var e=n[t],r=tV(t,e),i="r"===r,A="x"===r;return{options:e,dposition:i?"chartArea":A?"bottom":"left",dtype:i?"radialLinear":A?"category":"linear"}}))),(0,v.Q)(A,function(n){var A=n.options,o=A.id,s=tV(o,A),a=(0,v.v)(A.type,n.dtype);(void 0===A.position||t1(A.position,s)!==t1(n.dposition))&&(A.position=n.dposition),i[o]=!0;var l=null;o in r&&r[o].type===a?l=r[o]:r[(l=new(ti.getScale(a))({id:o,type:a,ctx:t.ctx,chart:t})).id]=l,l.init(A,e)}),(0,v.Q)(i,function(t,e){t||delete r[e]}),(0,v.Q)(r,function(e){tC.configure(t,e,e.options),tC.addBox(t,e)})}},{key:"_updateMetasets",value:function(){var t=this._metasets,e=this.data.datasets.length,n=t.length;if(t.sort(function(t,e){return t.index-e.index}),n>e){for(var r=e;rn.length&&delete this._stacks,e.forEach(function(e,r){0===n.filter(function(t){return t===e._dataset}).length&&t._destroyDatasetMeta(r)})}},{key:"buildOrUpdateControllers",value:function(){var t,e,n=[],r=this.data.datasets;for(this._removeUnreferencedMetasets(),t=0,e=r.length;t=e){var u=t[l];delete t[l],(n>0||c>e)&&(t[c+n]=u)}}}catch(t){A=!0,o=t}finally{try{i||null==a.return||a.return()}finally{if(A)throw o}}}(t,l,u)}}catch(t){r=!0,i=t}finally{try{n||null==o.return||o.return()}finally{if(r)throw i}}}},{key:"_getUniformDataChanges",value:function(){var t=this._dataChanges;if(t&&t.length){this._dataChanges=[];for(var e=this.data.datasets.length,n=function(e){return new Set(t.filter(function(t){return t[0]===e}).map(function(t,e){return e+","+t.splice(1).join(",")}))},r=n(0),i=1;i=0;--e)this._drawDataset(t[e]);this.notifyPlugins("afterDatasetsDraw")}}},{key:"_drawDataset",value:function(t){var e=this.ctx,n=t._clip,r=!n.disabled,i=this.chartArea,A={meta:t,index:t.index,cancelable:!0};!1!==this.notifyPlugins("beforeDatasetDraw",A)&&(r&&(0,v.L)(e,{left:!1===n.left?0:i.left-n.left,right:!1===n.right?this.width:i.right+n.right,top:!1===n.top?0:i.top-n.top,bottom:!1===n.bottom?this.height:i.bottom+n.bottom}),t.controller.draw(),r&&(0,v.N)(e),A.cancelable=!1,this.notifyPlugins("afterDatasetDraw",A))}},{key:"isPointInArea",value:function(t){return(0,v.$)(t,this.chartArea,this._minPadding)}},{key:"getElementsAtEventForMode",value:function(t,e,n,r){var i=tf.modes[e];return"function"==typeof i?i(this,t,n,r):[]}},{key:"getDatasetMeta",value:function(t){var e=this.data.datasets[t],n=this._metasets,r=n.filter(function(t){return t&&t._dataset===e}).pop();return r||(r={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null,order:e&&e.order||0,index:t,_dataset:e,_parsed:[],_sorted:!1},n.push(r)),r}},{key:"getContext",value:function(){return this.$context||(this.$context=(0,v.h)(null,{chart:this,type:"chart"}))}},{key:"getVisibleDatasetCount",value:function(){return this.getSortedVisibleDatasetMetas().length}},{key:"isDatasetVisible",value:function(t){var e=this.data.datasets[t];if(!e)return!1;var n=this.getDatasetMeta(t);return"boolean"==typeof n.hidden?!n.hidden:!e.hidden}},{key:"setDatasetVisibility",value:function(t,e){this.getDatasetMeta(t).hidden=!e}},{key:"toggleDataVisibility",value:function(t){this._hiddenIndices[t]=!this._hiddenIndices[t]}},{key:"getDataVisibility",value:function(t){return!this._hiddenIndices[t]}},{key:"_updateVisibility",value:function(t,e,n){var r=n?"show":"hide",i=this.getDatasetMeta(t),A=i.controller._resolveAnimations(void 0,r);(0,v.j)(e)?(i.data[e].hidden=!n,this.update()):(this.setDatasetVisibility(t,n),A.update(i,{visible:n}),this.update(function(e){return e.datasetIndex===t?r:void 0}))}},{key:"hide",value:function(t,e){this._updateVisibility(t,e,!1)}},{key:"show",value:function(t,e){this._updateVisibility(t,e,!0)}},{key:"_destroyDatasetMeta",value:function(t){var e=this._metasets[t];e&&e.controller&&e.controller._destroy(),delete this._metasets[t]}},{key:"_stop",value:function(){var t,e;for(this.stop(),y.remove(this),t=0,e=this.data.datasets.length;ti?(l=i/a,t.arc(A,o,a,n+l,r-l,!0)):t.arc(A,o,i,n+v.H,r-v.H),t.closePath(),t.clip()}function ee(t,e,n,r){return{x:n+t*Math.cos(e),y:r+t*Math.sin(e)}}function en(t,e,n,r,i,A){var o,s,a,l,c,u,h=e.x,d=e.y,f=e.startAngle,p=e.pixelMargin,g=e.innerRadius,m=Math.max(e.outerRadius+r+n-p,0),y=g>0?g+r+n+p:0,w=0,b=i-f;if(r){var B=m>0?m-r:0,_=((g>0?g-r:0)+B)/2;w=(b-(0!==_?b*_/(_+r):b))/2}var C=Math.max(.001,b*m-n/v.P)/m,x=(b-C)/2,k=f+x+w,F=i-x-w,Q=(o=F-k,s=e.options.borderRadius,a=(0,v.al)(s,["outerStart","outerEnd","innerStart","innerEnd"]),c=Math.min(l=(m-y)/2,o*y/2),{outerStart:(u=function(t){var e=(m-Math.min(l,t))*o/2;return(0,v.E)(t,0,Math.min(l,e))})(a.outerStart),outerEnd:u(a.outerEnd),innerStart:(0,v.E)(a.innerStart,0,c),innerEnd:(0,v.E)(a.innerEnd,0,c)}),E=Q.outerStart,S=Q.outerEnd,U=Q.innerStart,L=Q.innerEnd,I=m-E,j=m-S,M=k+E/I,D=F-S/j,N=y+U,P=y+L,O=k+U/N,H=F-L/P;if(t.beginPath(),A){if(t.arc(h,d,m,M,D),S>0){var T=ee(j,D,h,d);t.arc(T.x,T.y,S,D,F+v.H)}var R=ee(P,F,h,d);if(t.lineTo(R.x,R.y),L>0){var K=ee(P,H,h,d);t.arc(K.x,K.y,L,F+v.H,H+Math.PI)}if(t.arc(h,d,y,F-L/y,k+U/y,!0),U>0){var V=ee(N,O,h,d);t.arc(V.x,V.y,U,O+Math.PI,k-v.H)}var z=ee(I,k,h,d);if(t.lineTo(z.x,z.y),E>0){var G=ee(I,M,h,d);t.arc(G.x,G.y,E,k-v.H,M)}}else{t.moveTo(h,d);var q=Math.cos(M)*m+h,W=Math.sin(M)*m+d;t.lineTo(q,W);var Y=Math.cos(D)*m+h,X=Math.sin(D)*m+d;t.lineTo(Y,X)}t.closePath()}Object.defineProperties(t7,{defaults:{enumerable:!0,value:v.d},instances:{enumerable:!0,value:t6},overrides:{enumerable:!0,value:v.U},registry:{enumerable:!0,value:ti},version:{enumerable:!0,value:"3.9.1"},getChart:{enumerable:!0,value:t8},register:{enumerable:!0,value:function(){for(var t=arguments.length,e=Array(t),n=0;n=v.T||(0,v.p)(A,a,l),p=(0,v.ak)(o,c+d,u+d);return f&&p}},{key:"getCenterPoint",value:function(t){var e=this.getProps(["x","y","startAngle","endAngle","innerRadius","outerRadius","circumference"],t),n=e.x,r=e.y,i=e.startAngle,A=e.endAngle,o=e.innerRadius,s=e.outerRadius,a=this.options,l=a.offset,c=a.spacing,u=(i+A)/2,h=(o+s+c+l)/2;return{x:n+Math.cos(u)*h,y:r+Math.sin(u)*h}}},{key:"tooltipPosition",value:function(t){return this.getCenterPoint(t)}},{key:"draw",value:function(t){var e=this.options,n=this.circumference,r=(e.offset||0)/2,i=(e.spacing||0)/2,A=e.circular;if(this.pixelMargin="inner"===e.borderAlign?.33:0,this.fullCircles=n>v.T?Math.floor(n/v.T):0,0!==n&&!(this.innerRadius<0)&&!(this.outerRadius<0)){t.save();var o,s,a,l,c,u=0;if(r){u=r/2;var h=(this.startAngle+this.endAngle)/2;t.translate(Math.cos(h)*u,Math.sin(h)*u),this.circumference>=v.P&&(u=r)}t.fillStyle=e.backgroundColor,t.strokeStyle=e.borderColor;var d=function(t,e,n,r,i){var A=e.fullCircles,o=e.startAngle,s=e.circumference,a=e.endAngle;if(A){en(t,e,n,r,o+v.T,i);for(var l=0;l2&&void 0!==arguments[2]?arguments[2]:e;t.lineCap=(0,v.v)(n.borderCapStyle,e.borderCapStyle),t.setLineDash((0,v.v)(n.borderDash,e.borderDash)),t.lineDashOffset=(0,v.v)(n.borderDashOffset,e.borderDashOffset),t.lineJoin=(0,v.v)(n.borderJoinStyle,e.borderJoinStyle),t.lineWidth=(0,v.v)(n.borderWidth,e.borderWidth),t.strokeStyle=(0,v.v)(n.borderColor,e.borderColor)}function eA(t,e,n){t.lineTo(n.x,n.y)}function eo(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=t.length,i=n.start,A=void 0===i?0:i,o=n.end,s=void 0===o?r-1:o,a=e.start,l=e.end,c=Math.max(A,a),u=Math.min(s,l);return{count:r,start:c,loop:e.loop,ilen:ul&&s>l)?r+u-c:u-c}}function es(t,e,n,r){var i,A,o,s=e.points,a=e.options,l=eo(s,n,r),c=l.count,u=l.start,h=l.loop,d=l.ilen,f=a.stepped?v.as:a.tension||"monotone"===a.cubicInterpolationMode?v.at:eA,p=r||{},g=p.move,m=void 0===g||g,y=p.reverse;for(i=0;i<=d;++i)(A=s[(u+(y?d-i:i))%c]).skip||(m?(t.moveTo(A.x,A.y),m=!1):f(t,o,A,y,a.stepped),o=A);return h&&f(t,o,A=s[(u+(y?d:0))%c],y,a.stepped),!!h}function ea(t,e,n,r){var i,A,o,s,a,l,c=e.points,u=eo(c,n,r),h=u.count,d=u.start,f=u.ilen,p=r||{},g=p.move,m=p.reverse,v=0,y=0,w=function(t){return(d+(m?f-t:t))%h},b=function(){s!==a&&(t.lineTo(v,a),t.lineTo(v,s),t.lineTo(v,l))};for((void 0===g||g)&&(A=c[w(0)],t.moveTo(A.x,A.y)),i=0;i<=f;++i)if(!(A=c[w(i)]).skip){var B=A.x,_=A.y,C=0|B;C===o?(_a&&(a=_),v=(y*v+B)/++y):(b(),t.lineTo(B,_),o=C,y=0,s=a=_),l=_}b()}function el(t){var e=t.options,n=e.borderDash&&e.borderDash.length;return t._decimated||t._loop||e.tension||"monotone"===e.cubicInterpolationMode||e.stepped||n?es:ea}er.id="arc",er.defaults={borderAlign:"center",borderColor:"#fff",borderJoinStyle:void 0,borderRadius:0,borderWidth:2,offset:0,spacing:0,angle:void 0,circular:!0},er.defaultRoutes={backgroundColor:"backgroundColor"};var ec="function"==typeof Path2D,eu=function(t){(0,c._)(n,t);var e=(0,m._)(n);function n(t){var r;return(0,A._)(this,n),(r=e.call(this)).animated=!0,r.options=void 0,r._chart=void 0,r._loop=void 0,r._fullLoop=void 0,r._path=void 0,r._points=void 0,r._segments=void 0,r._decimated=!1,r._pointsUpdated=!1,r._datasetIndex=void 0,t&&Object.assign((0,i._)(r),t),r}return(0,o._)(n,[{key:"updateControlPoints",value:function(t,e){var n=this.options;if((n.tension||"monotone"===n.cubicInterpolationMode)&&!n.stepped&&!this._pointsUpdated){var r=n.spanGaps?this._loop:this._fullLoop;(0,v.am)(this._points,n,t,r,e),this._pointsUpdated=!0}}},{key:"points",get:function(){return this._points},set:function(t){this._points=t,delete this._segments,delete this._path,this._pointsUpdated=!1}},{key:"segments",get:function(){return this._segments||(this._segments=(0,v.an)(this,this.options.segment))}},{key:"first",value:function(){var t=this.segments,e=this.points;return t.length&&e[t[0].start]}},{key:"last",value:function(){var t=this.segments,e=this.points,n=t.length;return n&&e[t[n-1].end]}},{key:"interpolate",value:function(t,e){var n,r,i=this.options,A=t[e],o=this.points,s=(0,v.ao)(this,{property:e,start:A,end:A});if(s.length){var a=[],l=i.stepped?v.ap:i.tension||"monotone"===i.cubicInterpolationMode?v.aq:v.ar;for(n=0,r=s.length;n2&&void 0!==arguments[2]?arguments[2]:{},r=t.x!==n.x?-e:0,i=t.y!==n.y?-e:0,A=(t.x+t.w!==n.x+n.w?e:0)-r,o=(t.y+t.h!==n.y+n.h?e:0)-i;return{x:t.x+r,y:t.y+i,w:t.w+A,h:t.h+o,radius:t.radius}}ed.id="point",ed.defaults={borderWidth:1,hitRadius:1,hoverBorderWidth:1,hoverRadius:4,pointStyle:"circle",radius:3,rotation:0},ed.defaultRoutes={backgroundColor:"backgroundColor",borderColor:"borderColor"};var ey=function(t){(0,c._)(n,t);var e=(0,m._)(n);function n(t){var r;return(0,A._)(this,n),(r=e.call(this)).options=void 0,r.horizontal=void 0,r.base=void 0,r.width=void 0,r.height=void 0,r.inflateAmount=void 0,t&&Object.assign((0,i._)(r),t),r}return(0,o._)(n,[{key:"draw",value:function(t){var e,n,r,i,A,o,s,a,l,c,u,h,d,f,p,g,m,y,w,b=this.inflateAmount,B=this.options,_=B.borderColor,C=B.backgroundColor,x=(n=(e=ef(this)).right-e.left,r=e.bottom-e.top,i=n/2,A=r/2,o=this.options.borderWidth,s=this.borderSkipped,a=(0,v.aw)(o),l={t:ep(s.top,a.top,0,A),r:ep(s.right,a.right,0,i),b:ep(s.bottom,a.bottom,0,A),l:ep(s.left,a.left,0,i)},c=n/2,u=r/2,h=this.getProps(["enableBorderRadius"]).enableBorderRadius,d=this.options.borderRadius,f=(0,v.ax)(d),p=Math.min(c,u),g=this.borderSkipped,y={topLeft:ep(!(m=h||(0,v.i)(d))||g.top||g.left,f.topLeft,0,p),topRight:ep(!m||g.top||g.right,f.topRight,0,p),bottomLeft:ep(!m||g.bottom||g.left,f.bottomLeft,0,p),bottomRight:ep(!m||g.bottom||g.right,f.bottomRight,0,p)},{outer:{x:e.left,y:e.top,w:n,h:r,radius:y},inner:{x:e.left+l.l,y:e.top+l.t,w:n-l.l-l.r,h:r-l.t-l.b,radius:{topLeft:Math.max(0,y.topLeft-Math.max(l.t,l.l)),topRight:Math.max(0,y.topRight-Math.max(l.t,l.r)),bottomLeft:Math.max(0,y.bottomLeft-Math.max(l.b,l.l)),bottomRight:Math.max(0,y.bottomRight-Math.max(l.b,l.r))}}}),k=x.inner,F=x.outer,Q=(w=F.radius).topLeft||w.topRight||w.bottomLeft||w.bottomRight?v.av:em;t.save(),(F.w!==k.w||F.h!==k.h)&&(t.beginPath(),Q(t,ev(F,b,k)),t.clip(),Q(t,ev(k,-b,F)),t.fillStyle=_,t.fill("evenodd")),t.beginPath(),Q(t,ev(k,b)),t.fillStyle=C,t.fill(),t.restore()}},{key:"inRange",value:function(t,e,n){return eg(this,t,e,n)}},{key:"inXRange",value:function(t,e){return eg(this,t,null,e)}},{key:"inYRange",value:function(t,e){return eg(this,null,t,e)}},{key:"getCenterPoint",value:function(t){var e=this.getProps(["x","y","base","horizontal"],t),n=e.x,r=e.y,i=e.base,A=e.horizontal;return{x:A?(n+i)/2:n,y:A?r:(r+i)/2}}},{key:"getRange",value:function(t){return"x"===t?this.width/2:this.height/2}}]),n}((0,g._)(W));ey.id="bar",ey.defaults={borderSkipped:"start",borderWidth:0,borderRadius:0,inflateAmount:"auto",pointStyle:void 0},ey.defaultRoutes={backgroundColor:"backgroundColor",borderColor:"borderColor"};var ew=Object.freeze({__proto__:null,ArcElement:er,LineElement:eu,PointElement:ed,BarElement:ey});function eb(t){if(t._decimated){var e=t._data;delete t._decimated,delete t._data,Object.defineProperty(t,"data",{value:e})}}function eB(t){t.data.datasets.forEach(function(t){eb(t)})}var e_={id:"decimation",defaults:{algorithm:"min-max",enabled:!1},beforeElementsUpdate:function(t,e,n){if(!n.enabled){eB(t);return}var r=t.width;t.data.datasets.forEach(function(e,i){var A,o=e._data,s=e.indexAxis,a=t.getDatasetMeta(i),l=o||e.data;if("y"!==(0,v.a)([s,t.options.indexAxis])&&a.controller.supportsDecimation){var c=t.scales[a.xAxisID];if(("linear"===c.type||"time"===c.type)&&!t.options.parsing){var d,f,p,g,m,y,w,b,B,_=(f=l.length,p=0,y=(m=(g=a.iScale).getUserBounds()).min,w=m.max,b=m.minDefined,B=m.maxDefined,b&&(p=(0,v.E)((0,v.Z)(l,g.axis,y).lo,0,f-1)),d=B?(0,v.E)((0,v.Z)(l,g.axis,w).hi+1,p,f)-p:f-p,{start:p,count:d}),C=_.start,x=_.count;if(x<=(n.threshold||4*r)){eb(e);return}switch((0,v.k)(o)&&(e._data=l,delete e.data,Object.defineProperty(e,"data",{configurable:!0,enumerable:!0,get:function(){return this._decimated},set:function(t){this._data=t}})),n.algorithm){case"lttb":A=function(t,e,n,r,i){var A,o,s,a,l,c=i.samples||r;if(c>=n)return t.slice(e,e+n);var u=[],h=(n-2)/(c-2),d=0,f=e+n-1,p=e;for(A=0,u[d++]=t[p];As&&(s=a,o=t[v],l=v);u[d++]=o,p=l}return u[d++]=t[f],u}(l,C,x,r,n);break;case"min-max":A=function(t,e,n,r){var i,A,o,s,a,l,c,d,f,p,g=0,m=0,y=[],w=t[e].x,b=t[e+n-1].x-w;for(i=e;ip&&(p=s,c=i),g=(m*g+A.x)/++m;else{var _=i-1;if(!(0,v.k)(l)&&!(0,v.k)(c)){var C=Math.min(l,c),x=Math.max(l,c);C!==d&&C!==_&&y.push((0,h._)((0,u._)({},t[C]),{x:g})),x!==d&&x!==_&&y.push((0,h._)((0,u._)({},t[x]),{x:g}))}i>0&&_!==d&&y.push(t[_]),y.push(A),a=B,m=0,f=p=s,l=c=d=i}}return y}(l,C,x,r);break;default:throw Error("Unsupported decimation algorithm '".concat(n.algorithm,"'"))}e._decimated=A}}})},destroy:function(t){eB(t)}};function eC(t,e,n,r){if(!r){var i=e[t],A=n[t];return"angle"===t&&(i=(0,v.az)(i),A=(0,v.az)(A)),{property:t,start:i,end:A}}}function ex(t,e,n){for(;e>t;e--){var r=n[e];if(!isNaN(r.x)&&!isNaN(r.y))break}return e}function ek(t,e,n,r){return t&&e?r(t[n],e[n]):t?t[n]:e?e[n]:0}function eF(t,e){var n,r,i,A,o,s,a,l=[],c=!1;return(0,v.b)(t)?(c=!0,l=t):(i=void 0===(r=(n=t||{}).x)?null:r,o=void 0===(A=n.y)?null:A,s=e.points,a=[],e.segments.forEach(function(t){var e=t.start,n=t.end;n=ex(e,n,s);var r=s[e],A=s[n];null!==o?(a.push({x:r.x,y:o}),a.push({x:A.x,y:o})):null!==i&&(a.push({x:i,y:r.y}),a.push({x:i,y:A.y}))}),l=a),l.length?new eu({points:l,options:{tension:0},_loop:c,_fullLoop:c}):null}function eQ(t){return t&&!1!==t.fill}var eE=function(){function t(e){(0,A._)(this,t),this.x=e.x,this.y=e.y,this.radius=e.radius}return(0,o._)(t,[{key:"pathSegment",value:function(t,e,n){var r=this.x,i=this.y,A=this.radius;return e=e||{start:0,end:v.T},t.arc(r,i,A,e.end,e.start,!0),!n.bounds}},{key:"interpolate",value:function(t){var e=this.x,n=this.y,r=this.radius,i=t.angle;return{x:e+Math.cos(i)*r,y:n+Math.sin(i)*r,angle:i}}}]),t}();function eS(t,e,n){var r,i,A,o,s,a,l,c,u=function(t){var e,n=t.chart,r=t.fill,i=t.line;if((0,v.g)(r))return(e=n.getDatasetMeta(r))&&n.isDatasetVisible(r)?e.dataset:null;if("stack"===r)return function(t){var e=t.scale,n=t.index,r=t.line,i=[],A=r.segments,o=r.points,s=function(t,e){for(var n=[],r=t.getMatchingVisibleMetas("line"),i=0;i=n)&&i):["origin","start","end","stack","shape"].indexOf(A)>=0&&A}(A,i,s),chart:t,axis:r.controller.options.indexAxis,scale:r.vScale,line:A}),r.$filler=o,a.push(o);for(i=0;i=0;--o){var s=i[o].$filler;s&&(s.line.updateControlPoints(A,s.axis),r&&s.fill&&eS(t.ctx,s,A))}},beforeDatasetsDraw:function(t,e,n){if("beforeDatasetsDraw"===n.drawTime)for(var r=t.getSortedVisibleDatasetMetas(),i=r.length-1;i>=0;--i){var A=r[i].$filler;eQ(A)&&eS(t.ctx,A,t.chartArea)}},beforeDatasetDraw:function(t,e,n){var r=e.meta.$filler;eQ(r)&&"beforeDatasetDraw"===n.drawTime&&eS(t.ctx,r,t.chartArea)},defaults:{propagate:!0,drawTime:"beforeDatasetDraw"}},eM=function(t,e){var n=t.boxHeight,r=void 0===n?e:n,i=t.boxWidth,A=void 0===i?e:i;return t.usePointStyle&&(r=Math.min(r,e),A=t.pointStyleWidth||Math.min(A,e)),{boxWidth:A,boxHeight:r,itemHeight:Math.max(e,r)}},eD=function(t){(0,c._)(n,t);var e=(0,m._)(n);function n(t){var r;return(0,A._)(this,n),(r=e.call(this))._added=!1,r.legendHitBoxes=[],r._hoveredItem=null,r.doughnutMode=!1,r.chart=t.chart,r.options=t.options,r.ctx=t.ctx,r.legendItems=void 0,r.columnSizes=void 0,r.lineWidths=void 0,r.maxHeight=void 0,r.maxWidth=void 0,r.top=void 0,r.bottom=void 0,r.left=void 0,r.right=void 0,r.height=void 0,r.width=void 0,r._margins=void 0,r.position=void 0,r.weight=void 0,r.fullSize=void 0,r}return(0,o._)(n,[{key:"update",value:function(t,e,n){this.maxWidth=t,this.maxHeight=e,this._margins=n,this.setDimensions(),this.buildLabels(),this.fit()}},{key:"setDimensions",value:function(){this.isHorizontal()?(this.width=this.maxWidth,this.left=this._margins.left,this.right=this.width):(this.height=this.maxHeight,this.top=this._margins.top,this.bottom=this.height)}},{key:"buildLabels",value:function(){var t=this,e=this.options.labels||{},n=(0,v.C)(e.generateLabels,[this.chart],this)||[];e.filter&&(n=n.filter(function(n){return e.filter(n,t.chart.data)})),e.sort&&(n=n.sort(function(n,r){return e.sort(n,r,t.chart.data)})),this.options.reverse&&n.reverse(),this.legendItems=n}},{key:"fit",value:function(){var t,e,n=this.options,r=this.ctx;if(!n.display){this.width=this.height=0;return}var i=n.labels,A=(0,v.O)(i.font),o=A.size,s=this._computeTitleHeight(),a=eM(i,o),l=a.boxWidth,c=a.itemHeight;r.font=A.string,this.isHorizontal()?(t=this.maxWidth,e=this._fitRows(s,o,l,c)+10):(e=this.maxHeight,t=this._fitCols(s,o,l,c)+10),this.width=Math.min(t,n.maxWidth||this.maxWidth),this.height=Math.min(e,n.maxHeight||this.maxHeight)}},{key:"_fitRows",value:function(t,e,n,r){var i=this.ctx,A=this.maxWidth,o=this.options.labels.padding,s=this.legendHitBoxes=[],a=this.lineWidths=[0],l=r+o,c=t;i.textAlign="left",i.textBaseline="middle";var u=-1,h=-l;return this.legendItems.forEach(function(t,d){var f=n+e/2+i.measureText(t.text).width;(0===d||a[a.length-1]+f+2*o>A)&&(c+=l,a[a.length-(d>0?0:1)]=0,h+=l,u++),s[d]={left:0,top:h,row:u,width:f,height:r},a[a.length-1]+=f+o}),c}},{key:"_fitCols",value:function(t,e,n,r){var i=this.ctx,A=this.maxHeight,o=this.options.labels.padding,s=this.legendHitBoxes=[],a=this.columnSizes=[],l=A-t,c=o,u=0,h=0,d=0,f=0;return this.legendItems.forEach(function(t,A){var p=n+e/2+i.measureText(t.text).width;A>0&&h+r+2*o>l&&(c+=u+o,a.push({width:u,height:h}),d+=u+o,f++,u=h=0),s[A]={left:d,top:h,col:f,width:p,height:r},u=Math.max(u,p),h+=r+o}),c+=u,a.push({width:u,height:h}),c}},{key:"adjustHitBoxes",value:function(){if(this.options.display){var t=this._computeTitleHeight(),e=this.legendHitBoxes,n=this.options,r=n.align,i=n.labels.padding,A=n.rtl,o=(0,v.aA)(A,this.left,this.width);if(this.isHorizontal()){var s=0,a=(0,v.S)(r,this.left+i,this.right-this.lineWidths[s]),l=!0,c=!1,u=void 0;try{for(var h,d=e[Symbol.iterator]();!(l=(h=d.next()).done);l=!0){var f=h.value;s!==f.row&&(s=f.row,a=(0,v.S)(r,this.left+i,this.right-this.lineWidths[s])),f.top+=this.top+t+i,f.left=o.leftForLtr(o.x(a),f.width),a+=f.width+i}}catch(t){c=!0,u=t}finally{try{l||null==d.return||d.return()}finally{if(c)throw u}}}else{var p=0,g=(0,v.S)(r,this.top+t+i,this.bottom-this.columnSizes[p].height),m=!0,y=!1,w=void 0;try{for(var b,B=e[Symbol.iterator]();!(m=(b=B.next()).done);m=!0){var _=b.value;_.col!==p&&(p=_.col,g=(0,v.S)(r,this.top+t+i,this.bottom-this.columnSizes[p].height)),_.top=g,_.left+=this.left+i,_.left=o.leftForLtr(o.x(_.left),_.width),g+=_.height+i}}catch(t){y=!0,w=t}finally{try{m||null==B.return||B.return()}finally{if(y)throw w}}}}}},{key:"isHorizontal",value:function(){return"top"===this.options.position||"bottom"===this.options.position}},{key:"draw",value:function(){if(this.options.display){var t=this.ctx;(0,v.L)(t,this),this._draw(),(0,v.N)(t)}}},{key:"_draw",value:function(){var t,e=this,n=this.options,r=this.columnSizes,i=this.lineWidths,A=this.ctx,o=n.align,s=n.labels,a=v.d.color,l=(0,v.aA)(n.rtl,this.left,this.width),c=(0,v.O)(s.font),u=s.color,h=s.padding,d=c.size,f=d/2;this.drawTitle(),A.textAlign=l.textAlign("left"),A.textBaseline="middle",A.lineWidth=.5,A.font=c.string;var p=eM(s,d),g=p.boxWidth,m=p.boxHeight,y=p.itemHeight,w=function(t,e,n){if(!(isNaN(g)||g<=0||isNaN(m))&&!(m<0)){A.save();var r=(0,v.v)(n.lineWidth,1);if(A.fillStyle=(0,v.v)(n.fillStyle,a),A.lineCap=(0,v.v)(n.lineCap,"butt"),A.lineDashOffset=(0,v.v)(n.lineDashOffset,0),A.lineJoin=(0,v.v)(n.lineJoin,"miter"),A.lineWidth=r,A.strokeStyle=(0,v.v)(n.strokeStyle,a),A.setLineDash((0,v.v)(n.lineDash,[])),s.usePointStyle){var i={radius:m*Math.SQRT2/2,pointStyle:n.pointStyle,rotation:n.rotation,borderWidth:r},o=l.xPlus(t,g/2);(0,v.aE)(A,i,o,e+f,s.pointStyleWidth&&g)}else{var c=e+Math.max((d-m)/2,0),u=l.leftForLtr(t,g),h=(0,v.ax)(n.borderRadius);A.beginPath(),Object.values(h).some(function(t){return 0!==t})?(0,v.av)(A,{x:u,y:c,w:g,h:m,radius:h}):A.rect(u,c,g,m),A.fill(),0!==r&&A.stroke()}A.restore()}},b=function(t,e,n){(0,v.M)(A,n.text,t,e+y/2,c,{strikethrough:n.hidden,textAlign:l.textAlign(n.textAlign)})},B=this.isHorizontal(),_=this._computeTitleHeight();t=B?{x:(0,v.S)(o,this.left+h,this.right-i[0]),y:this.top+h+_,line:0}:{x:this.left+h,y:(0,v.S)(o,this.top+_+h,this.bottom-r[0].height),line:0},(0,v.aB)(this.ctx,n.textDirection);var C=y+h;this.legendItems.forEach(function(a,c){A.strokeStyle=a.fontColor||u,A.fillStyle=a.fontColor||u;var d=A.measureText(a.text).width,p=l.textAlign(a.textAlign||(a.textAlign=s.textAlign)),m=g+f+d,y=t.x,x=t.y;l.setWidth(e.width),B?c>0&&y+m+h>e.right&&(x=t.y+=C,t.line++,y=t.x=(0,v.S)(o,e.left+h,e.right-i[t.line])):c>0&&x+C>e.bottom&&(y=t.x=y+r[t.line].width+h,t.line++,x=t.y=(0,v.S)(o,e.top+_+h,e.bottom-r[t.line].height)),w(l.x(y),x,a),y=(0,v.aC)(p,y+g+f,B?y+m:e.right,n.rtl),b(l.x(y),x,a),B?t.x+=m+h:t.y+=C}),(0,v.aD)(this.ctx,n.textDirection)}},{key:"drawTitle",value:function(){var t,e,n=this.options,r=n.title,i=(0,v.O)(r.font),A=(0,v.K)(r.padding);if(r.display){var o=(0,v.aA)(n.rtl,this.left,this.width),s=this.ctx,a=r.position,l=i.size/2,c=A.top+l,u=this.left,h=this.width;if(this.isHorizontal())h=(e=Math).max.apply(e,(0,f._)(this.lineWidths)),t=this.top+c,u=(0,v.S)(n.align,u,this.right-h);else{var d=this.columnSizes.reduce(function(t,e){return Math.max(t,e.height)},0);t=c+(0,v.S)(n.align,this.top,this.bottom-d-n.labels.padding-this._computeTitleHeight())}var p=(0,v.S)(a,u,u+h);s.textAlign=o.textAlign((0,v.R)(a)),s.textBaseline="middle",s.strokeStyle=r.color,s.fillStyle=r.color,s.font=i.string,(0,v.M)(s,r.text,p,t,i)}}},{key:"_computeTitleHeight",value:function(){var t=this.options.title,e=(0,v.O)(t.font),n=(0,v.K)(t.padding);return t.display?e.lineHeight+n.height:0}},{key:"_getLegendItemAt",value:function(t,e){var n,r,i;if((0,v.ak)(t,this.left,this.right)&&(0,v.ak)(e,this.top,this.bottom)){for(n=0,i=this.legendHitBoxes;n-1?t.split("\n"):t}function ez(t,e){var n=t.chart.ctx,r=t.body,i=t.footer,A=t.title,o=e.boxWidth,s=e.boxHeight,a=(0,v.O)(e.bodyFont),l=(0,v.O)(e.titleFont),c=(0,v.O)(e.footerFont),u=A.length,h=i.length,d=r.length,f=(0,v.K)(e.padding),p=f.height,g=0,m=r.reduce(function(t,e){return t+e.before.length+e.lines.length+e.after.length},0);m+=t.beforeBody.length+t.afterBody.length,u&&(p+=u*l.lineHeight+(u-1)*e.titleSpacing+e.titleMarginBottom),m&&(p+=d*(e.displayColors?Math.max(s,a.lineHeight):a.lineHeight)+(m-d)*a.lineHeight+(m-1)*e.bodySpacing),h&&(p+=e.footerMarginTop+h*c.lineHeight+(h-1)*e.footerSpacing);var y=0,w=function(t){g=Math.max(g,n.measureText(t).width+y)};return n.save(),n.font=l.string,(0,v.Q)(t.title,w),n.font=a.string,(0,v.Q)(t.beforeBody.concat(t.afterBody),w),y=e.displayColors?o+2+e.boxPadding:0,(0,v.Q)(r,function(t){(0,v.Q)(t.before,w),(0,v.Q)(t.lines,w),(0,v.Q)(t.after,w)}),y=0,n.font=c.string,(0,v.Q)(t.footer,w),n.restore(),{width:g+=f.width,height:p}}function eG(t,e,n){var r,i,A,o,s,a,l,c,u,h=n.yAlign||e.yAlign||((r=n.y)<(i=n.height)/2?"top":r>t.height-i/2?"bottom":"center");return{xAlign:n.xAlign||e.xAlign||(A=n.x,o=n.width,s=t.width,l=(a=t.chartArea).left,c=a.right,u="center","center"===h?u=A<=(l+c)/2?"left":"right":A<=o/2?u="left":A>=s-o/2&&(u="right"),function(t,e,n,r){var i=r.x,A=r.width,o=n.caretSize+n.caretPadding;if("left"===t&&i+A+o>e.width||"right"===t&&i-A-o<0)return!0}(u,t,e,n)&&(u="center"),u),yAlign:h}}function eq(t,e,n,r){var i,A,o,s,a=t.caretSize,l=t.caretPadding,c=t.cornerRadius,u=n.xAlign,h=n.yAlign,d=a+l,f=(0,v.ax)(c),p=f.topLeft,g=f.topRight,m=f.bottomLeft,y=f.bottomRight,w=(i=e.x,A=e.width,"right"===u?i-=A:"center"===u&&(i-=A/2),i),b=(o=e.y,s=e.height,"top"===h?o+=d:"bottom"===h?o-=s+d:o-=s/2,o);return"center"===h?"left"===u?w+=d:"right"===u&&(w-=d):"left"===u?w-=Math.max(p,m)+a:"right"===u&&(w+=Math.max(g,y)+a),{x:(0,v.E)(w,0,r.width-e.width),y:(0,v.E)(b,0,r.height-e.height)}}function eW(t,e,n){var r=(0,v.K)(n.padding);return"center"===e?t.x+t.width/2:"right"===e?t.x+t.width-r.right:t.x+r.left}function eY(t,e){var n=e&&e.dataset&&e.dataset.tooltip&&e.dataset.tooltip.callbacks;return n?t.override(n):t}var eX=function(t){(0,c._)(n,t);var e=(0,m._)(n);function n(t){var r;return(0,A._)(this,n),(r=e.call(this)).opacity=0,r._active=[],r._eventPosition=void 0,r._size=void 0,r._cachedAnimations=void 0,r._tooltipItems=[],r.$animations=void 0,r.$context=void 0,r.chart=t.chart||t._chart,r._chart=r.chart,r.options=t.options,r.dataPoints=void 0,r.title=void 0,r.beforeBody=void 0,r.body=void 0,r.afterBody=void 0,r.footer=void 0,r.xAlign=void 0,r.yAlign=void 0,r.x=void 0,r.y=void 0,r.height=void 0,r.width=void 0,r.caretX=void 0,r.caretY=void 0,r.labelColors=void 0,r.labelPointStyles=void 0,r.labelTextColors=void 0,r}return(0,o._)(n,[{key:"initialize",value:function(t){this.options=t,this._cachedAnimations=void 0,this.$context=void 0}},{key:"_resolveAnimations",value:function(){var t=this._cachedAnimations;if(t)return t;var e=this.chart,n=this.options.setContext(this.getContext()),r=n.enabled&&e.options.animation&&n.animations,i=new C(this.chart,r);return r._cacheable&&(this._cachedAnimations=Object.freeze(i)),i}},{key:"getContext",value:function(){var t,e;return this.$context||(this.$context=(t=this.chart.getContext(),e=this._tooltipItems,(0,v.h)(t,{tooltip:this,tooltipItems:e,type:"tooltip"})))}},{key:"getTitle",value:function(t,e){var n=e.callbacks,r=n.beforeTitle.apply(this,[t]),i=n.title.apply(this,[t]),A=n.afterTitle.apply(this,[t]),o=[];return o=eK(o,eV(r)),o=eK(o,eV(i)),o=eK(o,eV(A))}},{key:"getBeforeBody",value:function(t,e){return eK([],eV(e.callbacks.beforeBody.apply(this,[t])))}},{key:"getBody",value:function(t,e){var n=this,r=e.callbacks,i=[];return(0,v.Q)(t,function(t){var e={before:[],lines:[],after:[]},A=eY(r,t);eK(e.before,eV(A.beforeLabel.call(n,t))),eK(e.lines,A.label.call(n,t)),eK(e.after,eV(A.afterLabel.call(n,t))),i.push(e)}),i}},{key:"getAfterBody",value:function(t,e){return eK([],eV(e.callbacks.afterBody.apply(this,[t])))}},{key:"getFooter",value:function(t,e){var n=e.callbacks,r=n.beforeFooter.apply(this,[t]),i=n.footer.apply(this,[t]),A=n.afterFooter.apply(this,[t]),o=[];return o=eK(o,eV(r)),o=eK(o,eV(i)),o=eK(o,eV(A))}},{key:"_createItems",value:function(t){var e,n,r=this,i=this._active,A=this.chart.data,o=[],s=[],a=[],l=[];for(e=0,n=i.length;e0&&e.stroke()}},{key:"_updateAnimationTarget",value:function(t){var e=this.chart,n=this.$animations,r=n&&n.x,i=n&&n.y;if(r||i){var A=eR[t.position].call(this,this._active,this._eventPosition);if(!A)return;var o=this._size=ez(this,t),s=Object.assign({},A,this._size),a=eG(e,t,s),l=eq(t,s,a,e);(r._to!==l.x||i._to!==l.y)&&(this.xAlign=a.xAlign,this.yAlign=a.yAlign,this.width=o.width,this.height=o.height,this.caretX=A.x,this.caretY=A.y,this._resolveAnimations().update(this,l))}}},{key:"_willRender",value:function(){return!!this.opacity}},{key:"draw",value:function(t){var e=this.options.setContext(this.getContext()),n=this.opacity;if(n){this._updateAnimationTarget(e);var r={width:this.width,height:this.height},i={x:this.x,y:this.y};n=.001>Math.abs(n)?0:n;var A=(0,v.K)(e.padding),o=this.title.length||this.beforeBody.length||this.body.length||this.afterBody.length||this.footer.length;e.enabled&&o&&(t.save(),t.globalAlpha=n,this.drawBackground(i,t,r,e),(0,v.aB)(t,e.textDirection),i.y+=A.top,this.drawTitle(i,t,e),this.drawBody(i,t,e),this.drawFooter(i,t,e),(0,v.aD)(t,e.textDirection),t.restore())}}},{key:"getActiveElements",value:function(){return this._active||[]}},{key:"setActiveElements",value:function(t,e){var n=this,r=this._active,i=t.map(function(t){var e=t.datasetIndex,r=t.index,i=n.chart.getDatasetMeta(e);if(!i)throw Error("Cannot find a dataset at index "+e);return{datasetIndex:e,element:i.data[r],index:r}}),A=!(0,v.ai)(r,i),o=this._positionChanged(i,e);(A||o)&&(this._active=i,this._eventPosition=e,this._ignoreReplayEvents=!0,this.update(!0))}},{key:"handleEvent",value:function(t,e){var n=!(arguments.length>2)||void 0===arguments[2]||arguments[2];if(e&&this._ignoreReplayEvents)return!1;this._ignoreReplayEvents=!1;var r=this.options,i=this._active||[],A=this._getActiveElements(t,i,e,n),o=this._positionChanged(A,t),s=e||!(0,v.ai)(A,i)||o;return s&&(this._active=A,(r.enabled||r.external)&&(this._eventPosition={x:t.x,y:t.y},this.update(!0,e))),s}},{key:"_getActiveElements",value:function(t,e,n,r){var i=this.options;if("mouseout"===t.type)return[];if(!r)return e;var A=this.chart.getElementsAtEventForMode(t,i.mode,i,n);return i.reverse&&A.reverse(),A}},{key:"_positionChanged",value:function(t,e){var n=this.caretX,r=this.caretY,i=eR[this.options.position].call(this,t,e);return!1!==i&&(n!==i.x||r!==i.y)}}]),n}((0,g._)(W));eX.positioners=eR;var eJ={id:"tooltip",_element:eX,positioners:eR,afterInit:function(t,e,n){n&&(t.tooltip=new eX({chart:t,options:n}))},beforeUpdate:function(t,e,n){t.tooltip&&t.tooltip.initialize(n)},reset:function(t,e,n){t.tooltip&&t.tooltip.initialize(n)},afterDraw:function(t){var e=t.tooltip;if(e&&e._willRender()){var n={tooltip:e};if(!1===t.notifyPlugins("beforeTooltipDraw",n))return;e.draw(t.ctx),t.notifyPlugins("afterTooltipDraw",n)}},afterEvent:function(t,e){if(t.tooltip){var n=e.replay;t.tooltip.handleEvent(e.event,n,e.inChartArea)&&(e.changed=!0)}},defaults:{enabled:!0,external:null,position:"average",backgroundColor:"rgba(0,0,0,0.8)",titleColor:"#fff",titleFont:{weight:"bold"},titleSpacing:2,titleMarginBottom:6,titleAlign:"left",bodyColor:"#fff",bodySpacing:2,bodyFont:{},bodyAlign:"left",footerColor:"#fff",footerSpacing:2,footerMarginTop:6,footerFont:{weight:"bold"},footerAlign:"left",padding:6,caretPadding:2,caretSize:5,cornerRadius:6,boxHeight:function(t,e){return e.bodyFont.size},boxWidth:function(t,e){return e.bodyFont.size},multiKeyBackground:"#fff",displayColors:!0,boxPadding:0,borderColor:"rgba(0,0,0,0)",borderWidth:0,animation:{duration:400,easing:"easeOutQuart"},animations:{numbers:{type:"number",properties:["x","y","width","height","caretX","caretY"]},opacity:{easing:"linear",duration:200}},callbacks:{beforeTitle:v.aF,title:function(t){if(t.length>0){var e=t[0],n=e.chart.data.labels,r=n?n.length:0;if(this&&this.options&&"dataset"===this.options.mode)return e.dataset.label||"";if(e.label)return e.label;if(r>0&&e.dataIndex=0&&te.length-1?null:this.getPixelForValue(e[t].value)}},{key:"getValueForPixel",value:function(t){return Math.round(this._startValue+this.getDecimalForPixel(t)*this._valueRange)}},{key:"getBasePixel",value:function(){return this.bottom}}]),n}(tn);function e0(t,e,n){var r=n.horizontal,i=n.minRotation,A=(0,v.t)(i),o=(r?Math.sin(A):Math.cos(A))||.001,s=.75*e*(""+t).length;return Math.min(e/o,s)}e$.id="category",e$.defaults={ticks:{callback:e$.prototype.getLabelForValue}};var e1=function(t){(0,c._)(n,t);var e=(0,m._)(n);function n(t){var r;return(0,A._)(this,n),(r=e.call(this,t)).start=void 0,r.end=void 0,r._startValue=void 0,r._endValue=void 0,r._valueRange=0,r}return(0,o._)(n,[{key:"parse",value:function(t,e){return(0,v.k)(t)||("number"==typeof t||t instanceof Number)&&!isFinite(+t)?null:+t}},{key:"handleTickRangeOptions",value:function(){var t=this.options.beginAtZero,e=this.getUserBounds(),n=e.minDefined,r=e.maxDefined,i=this.min,A=this.max,o=function(t){return i=n?i:t},s=function(t){return A=r?A:t};if(t){var a=(0,v.s)(i),l=(0,v.s)(A);a<0&&l<0?s(0):a>0&&l>0&&o(0)}if(i===A){var c=1;(A>=Number.MAX_SAFE_INTEGER||i<=Number.MIN_SAFE_INTEGER)&&(c=Math.abs(.05*A)),s(A+c),t||o(i-c)}this.min=i,this.max=A}},{key:"getTickLimit",value:function(){var t,e=this.options.ticks,n=e.maxTicksLimit,r=e.stepSize;return r?(t=Math.ceil(this.max/r)-Math.floor(this.min/r)+1)>1e3&&(console.warn("scales.".concat(this.id,".ticks.stepSize: ").concat(r," would result generating up to ").concat(t," ticks. Limiting to 1000.")),t=1e3):(t=this.computeTickLimit(),n=n||11),n&&(t=Math.min(n,t)),t}},{key:"computeTickLimit",value:function(){return Number.POSITIVE_INFINITY}},{key:"buildTicks",value:function(){var t=this.options,e=t.ticks,n=this.getTickLimit(),r=function(t,e){var n,r,i,A,o=[],s=t.bounds,a=t.step,l=t.min,c=t.max,u=t.precision,h=t.count,d=t.maxTicks,f=t.maxDigits,p=t.includeBounds,g=a||1,m=d-1,y=e.min,w=e.max,b=!(0,v.k)(l),B=!(0,v.k)(c),_=!(0,v.k)(h),C=(w-y)/(f+1),x=(0,v.aI)((w-y)/m/g)*g;if(x<1e-14&&!b&&!B)return[{value:y},{value:w}];(A=Math.ceil(w/x)-Math.floor(y/x))>m&&(x=(0,v.aI)(A*x/m/g)*g),(0,v.k)(u)||(x=Math.ceil(x*(n=Math.pow(10,u)))/n),"ticks"===s?(r=Math.floor(y/x)*x,i=Math.ceil(w/x)*x):(r=y,i=w),b&&B&&a&&(0,v.aJ)((c-l)/a,x/1e3)?(A=Math.round(Math.min((c-l)/x,d)),x=(c-l)/A,r=l,i=c):_?(r=b?l:r,x=((i=B?c:i)-r)/(A=h-1)):(A=(i-r)/x,A=(0,v.aK)(A,Math.round(A),x/1e3)?Math.round(A):Math.ceil(A));var k=Math.max((0,v.aL)(x),(0,v.aL)(r));r=Math.round(r*(n=Math.pow(10,(0,v.k)(u)?k:u)))/n,i=Math.round(i*n)/n;var F=0;for(b&&(p&&r!==l?(o.push({value:l}),r0?n:null}},{key:"determineDataLimits",value:function(){var t=this.getMinMax(!0),e=t.min,n=t.max;this.min=(0,v.g)(e)?Math.max(0,e):null,this.max=(0,v.g)(n)?Math.max(0,n):null,this.options.beginAtZero&&(this._zero=!0),this.handleTickRangeOptions()}},{key:"handleTickRangeOptions",value:function(){var t=this.getUserBounds(),e=t.minDefined,n=t.maxDefined,r=this.min,i=this.max,A=function(t){return r=e?r:t},o=function(t){return i=n?i:t},s=function(t,e){return Math.pow(10,Math.floor((0,v.z)(t))+e)};r===i&&(r<=0?(A(1),o(10)):(A(s(r,-1)),o(s(i,1)))),r<=0&&A(s(i,-1)),i<=0&&o(s(r,1)),this._zero&&this.min!==this._suggestedMin&&r===s(this.min,0)&&A(s(r,-1)),this.min=r,this.max=i}},{key:"buildTicks",value:function(){var t=this.options,e=function(t,e){var n=Math.floor((0,v.z)(e.max)),r=Math.ceil(e.max/Math.pow(10,n)),i=[],A=(0,v.B)(t.min,Math.pow(10,Math.floor((0,v.z)(e.min)))),o=Math.floor((0,v.z)(A)),s=Math.floor(A/Math.pow(10,o)),a=o<0?Math.pow(10,Math.abs(o)):1;do i.push({value:A,major:e5(A)}),10==++s&&(s=1,a=++o>=0?1:a),A=Math.round(s*Math.pow(10,o)*a)/a;while(oi?{start:e-n,end:e}:{start:e,end:e+n}}function e8(t,e,n,r){var i=t.ctx;if(n)i.arc(t.xCenter,t.yCenter,e,0,v.T);else{var A=t.getPointPosition(0,e);i.moveTo(A.x,A.y);for(var o=1;oe.r&&(s=(r.end-e.r)/A,t.r=Math.max(t.r,e.r+s)),i.starte.b&&(a=(i.end-e.b)/o,t.b=Math.max(t.b,e.b+a))})(n,e,p,e6(g,h.x,f.w,0,180),e6(g,h.y,f.h,90,270))}t.setCenterPoint(e.l-n.l,n.r-e.r,e.t-n.t,n.b-e.b),t._pointLabelItems=function(t,e,n){for(var r=[],i=t._pointLabels.length,A=t.options,o=e3(A)/2,s=t.drawingArea,a=A.pointLabels.centerPointLabels?v.P/i:0,l=0;l270||p<90)&&(c-=u),c),y=0===p||180===p?"center":p<180?"left":"right",w=(h=f.x,d=g.w,"right"===y?h-=d:"center"===y&&(h-=d/2),h);r.push({x:f.x,y:m,textAlign:y,left:w,top:m,right:w+g.w,bottom:m+g.h})}return r}(t,r,i)}(this):this.setCenterPoint(0,0,0,0)}},{key:"setCenterPoint",value:function(t,e,n,r){this.xCenter+=Math.floor((t-e)/2),this.yCenter+=Math.floor((n-r)/2),this.drawingArea-=Math.min(this.drawingArea/2,Math.max(t,e,n,r))}},{key:"getIndexAngle",value:function(t){var e=v.T/(this._pointLabels.length||1),n=this.options.startAngle||0;return(0,v.az)(t*e+(0,v.t)(n))}},{key:"getDistanceFromCenterForValue",value:function(t){if((0,v.k)(t))return NaN;var e=this.drawingArea/(this.max-this.min);return this.options.reverse?(this.max-t)*e:(t-this.min)*e}},{key:"getValueForDistanceFromCenter",value:function(t){if((0,v.k)(t))return NaN;var e=t/(this.drawingArea/(this.max-this.min));return this.options.reverse?this.max-e:this.min+e}},{key:"getPointLabelContext",value:function(t){var e=this._pointLabels||[];if(t>=0&&t2&&void 0!==arguments[2]?arguments[2]:0,r=this.getIndexAngle(t)-v.H+n;return{x:Math.cos(r)*e+this.xCenter,y:Math.sin(r)*e+this.yCenter,angle:r}}},{key:"getPointPositionForValue",value:function(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))}},{key:"getBasePosition",value:function(t){return this.getPointPositionForValue(t||0,this.getBaseValue())}},{key:"getPointLabelPosition",value:function(t){var e=this._pointLabelItems[t];return{left:e.left,top:e.top,right:e.right,bottom:e.bottom}}},{key:"drawBackground",value:function(){var t=this.options,e=t.backgroundColor,n=t.grid.circular;if(e){var r=this.ctx;r.save(),r.beginPath(),e8(this,this.getDistanceFromCenterForValue(this._endValue),n,this._pointLabels.length),r.closePath(),r.fillStyle=e,r.fill(),r.restore()}}},{key:"drawGrid",value:function(){var t,e,n,r=this,i=this.ctx,A=this.options,o=A.angleLines,s=A.grid,a=this._pointLabels.length;if(A.pointLabels.display&&function(t,e){for(var n=t.ctx,r=t.options.pointLabels,i=e-1;i>=0;i--){var A=r.setContext(t.getPointLabelContext(i)),o=(0,v.O)(A.font),s=t._pointLabelItems[i],a=s.x,l=s.y,c=s.textAlign,u=s.left,h=s.top,d=s.right,f=s.bottom,p=A.backdropColor;if(!(0,v.k)(p)){var g=(0,v.ax)(A.borderRadius),m=(0,v.K)(A.backdropPadding);n.fillStyle=p;var y=u-m.left,w=h-m.top,b=d-u+m.width,B=f-h+m.height;Object.values(g).some(function(t){return 0!==t})?(n.beginPath(),(0,v.av)(n,{x:y,y:w,w:b,h:B,radius:g}),n.fill()):n.fillRect(y,w,b,B)}(0,v.M)(n,t._pointLabels[i],a,l+o.lineHeight/2,o,{color:A.color,textAlign:c,textBaseline:"middle"})}}(this,a),s.display&&this.ticks.forEach(function(t,n){if(0!==n){e=r.getDistanceFromCenterForValue(t.value);var i,A,o,l,c,u=s.setContext(r.getContext(n-1));i=e,A=r.ctx,o=u.circular,l=u.color,c=u.lineWidth,(o||a)&&l&&c&&!(i<0)&&(A.save(),A.strokeStyle=l,A.lineWidth=c,A.setLineDash(u.borderDash),A.lineDashOffset=u.borderDashOffset,A.beginPath(),e8(r,i,o,a),A.closePath(),A.stroke(),A.restore())}}),o.display){for(i.save(),t=a-1;t>=0;t--){var l=o.setContext(this.getPointLabelContext(t)),c=l.color,u=l.lineWidth;u&&c&&(i.lineWidth=u,i.strokeStyle=c,i.setLineDash(l.borderDash),i.lineDashOffset=l.borderDashOffset,e=this.getDistanceFromCenterForValue(A.ticks.reverse?this.min:this.max),n=this.getPointPosition(t,e),i.beginPath(),i.moveTo(this.xCenter,this.yCenter),i.lineTo(n.x,n.y),i.stroke())}i.restore()}}},{key:"drawBorder",value:function(){}},{key:"drawLabels",value:function(){var t,e,n=this,r=this.ctx,i=this.options,A=i.ticks;if(A.display){var o=this.getIndexAngle(0);r.save(),r.translate(this.xCenter,this.yCenter),r.rotate(o),r.textAlign="center",r.textBaseline="middle",this.ticks.forEach(function(o,s){if(0!==s||i.reverse){var a=A.setContext(n.getContext(s)),l=(0,v.O)(a.font);if(t=n.getDistanceFromCenterForValue(n.ticks[s].value),a.showLabelBackdrop){r.font=l.string,e=r.measureText(o.label).width,r.fillStyle=a.backdropColor;var c=(0,v.K)(a.backdropPadding);r.fillRect(-e/2-c.left,-t-l.size/2-c.top,e+c.width,l.size+c.height)}(0,v.M)(r,o.label,0,-t,l,{color:a.color})}}),r.restore()}}},{key:"drawTitle",value:function(){}}]),n}(e1);e7.id="radialLinear",e7.defaults={display:!0,animate:!0,position:"chartArea",angleLines:{display:!0,lineWidth:1,borderDash:[],borderDashOffset:0},grid:{circular:!1},startAngle:0,ticks:{showLabelBackdrop:!0,callback:X.formatters.numeric},pointLabels:{backdropColor:void 0,backdropPadding:2,display:!0,font:{size:10},callback:function(t){return t},padding:5,centerPointLabels:!1}},e7.defaultRoutes={"angleLines.color":"borderColor","pointLabels.color":"color","ticks.color":"color"},e7.descriptors={angleLines:{_fallback:"grid"}};var e9={millisecond:{common:!0,size:1,steps:1e3},second:{common:!0,size:1e3,steps:60},minute:{common:!0,size:6e4,steps:60},hour:{common:!0,size:36e5,steps:24},day:{common:!0,size:864e5,steps:30},week:{common:!1,size:6048e5,steps:4},month:{common:!0,size:2628e6,steps:12},quarter:{common:!1,size:7884e6,steps:4},year:{common:!0,size:3154e7}},nt=Object.keys(e9);function ne(t,e){return t-e}function nn(t,e){if((0,v.k)(e))return null;var n=t._adapter,r=t._parseOpts,i=r.parser,A=r.round,o=r.isoWeekday,s=e;return("function"==typeof i&&(s=i(s)),(0,v.g)(s)||(s="string"==typeof i?n.parse(s,i):n.parse(s)),null===s)?null:(A&&(s="week"===A&&((0,v.x)(o)||!0===o)?n.startOf(s,"isoWeek",o):n.startOf(s,A)),+s)}function nr(t,e,n,r){for(var i=nt.length,A=nt.indexOf(t);A=e?n[i]:n[A]]=!0}}else t[e]=!0}function nA(t,e,n){var r,i,A=[],o={},s=e.length;for(r=0;r=0&&(e[A].major=!0);return e}(t,A,o,n):A}var no=function(t){(0,c._)(n,t);var e=(0,m._)(n);function n(t){var r;return(0,A._)(this,n),(r=e.call(this,t))._cache={data:[],labels:[],all:[]},r._unit="day",r._majorUnit=void 0,r._offsets={},r._normalized=!1,r._parseOpts=void 0,r}return(0,o._)(n,[{key:"init",value:function(t,e){var r=t.time||(t.time={}),i=this._adapter=new tl._date(t.adapters.date);i.init(e),(0,v.ac)(r.displayFormats,i.formats()),this._parseOpts={parser:r.parser,round:r.round,isoWeekday:r.isoWeekday},(0,a._)((0,l._)(n.prototype),"init",this).call(this,t),this._normalized=e.normalized}},{key:"parse",value:function(t,e){return void 0===t?null:nn(this,t)}},{key:"beforeLayout",value:function(){(0,a._)((0,l._)(n.prototype),"beforeLayout",this).call(this),this._cache={data:[],labels:[],all:[]}}},{key:"determineDataLimits",value:function(){var t=this.options,e=this._adapter,n=t.time.unit||"day",r=this.getUserBounds(),i=r.min,A=r.max,o=r.minDefined,s=r.maxDefined;function a(t){o||isNaN(t.min)||(i=Math.min(i,t.min)),s||isNaN(t.max)||(A=Math.max(A,t.max))}o&&s||(a(this._getLabelBounds()),("ticks"!==t.bounds||"labels"!==t.ticks.source)&&a(this.getMinMax(!1))),i=(0,v.g)(i)&&!isNaN(i)?i:+e.startOf(Date.now(),n),A=(0,v.g)(A)&&!isNaN(A)?A:+e.endOf(Date.now(),n)+1,this.min=Math.min(i,A-1),this.max=Math.max(i+1,A)}},{key:"_getLabelBounds",value:function(){var t=this.getLabelTimestamps(),e=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY;return t.length&&(e=t[0],n=t[t.length-1]),{min:e,max:n}}},{key:"buildTicks",value:function(){var t=this.options,e=t.time,n=t.ticks,r="labels"===n.source?this.getLabelTimestamps():this._generate();"ticks"===t.bounds&&r.length&&(this.min=this._userMin||r[0],this.max=this._userMax||r[r.length-1]);var i=this.min,A=this.max,o=(0,v.aN)(r,i,A);return this._unit=e.unit||(n.autoSkip?nr(e.minUnit,this.min,this.max,this._getLabelCapacity(i)):function(t,e,n,r,i){for(var A=nt.length-1;A>=nt.indexOf(n);A--){var o=nt[A];if(e9[o].common&&t._adapter.diff(i,r,o)>=e-1)return o}return nt[n?nt.indexOf(n):0]}(this,o.length,e.minUnit,this.min,this.max)),this._majorUnit=n.major.enabled&&"year"!==this._unit?function(t){for(var e=nt.indexOf(t)+1,n=nt.length;e1e5*a)throw Error(r+" and "+i+" are too far apart with stepSize of "+a+" "+s);var d="data"===A.ticks.source&&this.getDataTimestamps();for(t=h,e=0;t0?o:1}},{key:"getDataTimestamps",value:function(){var t,e,n=this._cache.data||[];if(n.length)return n;var r=this.getMatchingVisibleMetas();if(this._normalized&&r.length)return this._cache.data=r[0].controller.getAllParsedValues(this);for(t=0,e=r.length;t=t[d].pos&&e<=t[f].pos&&(d=(s=(0,v.Z)(t,"pos",e)).lo,f=s.hi),r=(a=t[d]).pos,A=a.time,i=(l=t[f]).pos,o=l.time):(e>=t[d].time&&e<=t[f].time&&(d=(c=(0,v.Z)(t,"time",e)).lo,f=c.hi),r=(u=t[d]).time,A=u.pos,i=(h=t[f]).time,o=h.pos);var p=i-r;return p?A+(o-A)*(e-r)/p:A}no.id="time",no.defaults={bounds:"data",adapters:{},time:{parser:!1,unit:!1,round:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{}},ticks:{source:"auto",major:{enabled:!1}}};var na=function(t){(0,c._)(n,t);var e=(0,m._)(n);function n(t){var r;return(0,A._)(this,n),(r=e.call(this,t))._table=[],r._minPos=void 0,r._tableRange=void 0,r}return(0,o._)(n,[{key:"initOffsets",value:function(){var t=this._getTimestampsForTable(),e=this._table=this.buildLookupTable(t);this._minPos=ns(e,this.min),this._tableRange=ns(e,this.max)-this._minPos,(0,a._)((0,l._)(n.prototype),"initOffsets",this).call(this,t)}},{key:"buildLookupTable",value:function(t){var e,n,r,i=this.min,A=this.max,o=[],s=[];for(e=0,n=t.length;e=i&&r<=A&&o.push(r);if(o.length<2)return[{time:i,pos:0},{time:A,pos:1}];for(e=0,n=o.length;e")+"->"+t);return s.add(t),e=e(A,o||r),s.delete(t),eU(t,e)&&(e=eI(i._scopes,i,t,e)),e}(n,a,e,r)),f(a)&&a.length&&(a=function(e,n,r,i){var A=r._proxy,o=r._context,s=r._subProxy,a=r._descriptors;if(M(o.index)&&i(e))n=n[o.index%n.length];else if(p(n[0])){var l=n,c=A._scopes.filter(function(t){return t!==l});n=[];var u=!0,h=!1,d=void 0;try{for(var f,g=l[Symbol.iterator]();!(u=(f=g.next()).done);u=!0){var m=f.value,v=eI(c,A,e,m);n.push(t(v,o,s&&s[e],a))}}catch(t){h=!0,d=t}finally{try{u||null==g.return||g.return()}finally{if(h)throw d}}}return n}(n,a,e,s.isIndexable)),eU(n,a)&&(a=t(a,A,o&&o[n],s)),a})},getOwnPropertyDescriptor:function(t,n){return t._descriptors.allKeys?Reflect.has(e,n)?{enumerable:!0,configurable:!0}:void 0:Reflect.getOwnPropertyDescriptor(e,n)},getPrototypeOf:function(){return Reflect.getPrototypeOf(e)},has:function(t,n){return Reflect.has(e,n)},ownKeys:function(){return Reflect.ownKeys(e)},set:function(t,n,r){return e[n]=r,delete t[n],!0}})}}),A.export(n,"aA",function(){return e9}),A.export(n,"aB",function(){return nt}),A.export(n,"aC",function(){return tk}),A.export(n,"aD",function(){return ne}),A.export(n,"aE",function(){return ec}),A.export(n,"aF",function(){return u}),A.export(n,"aG",function(){return tA}),A.export(n,"aH",function(){return tt}),A.export(n,"aI",function(){return Y}),A.export(n,"aJ",function(){return $}),A.export(n,"aK",function(){return Z}),A.export(n,"aL",function(){return tr}),A.export(n,"aM",function(){return eo}),A.export(n,"aN",function(){return tp}),A.export(n,"aO",function(){return th}),A.export(n,"aP",function(){return t6}),A.export(n,"aQ",function(){return t7}),A.export(n,"aR",function(){return C}),A.export(n,"aS",function(){return k}),A.export(n,"aT",function(){return E}),A.export(n,"aU",function(){return S}),A.export(n,"aV",function(){return I}),A.export(n,"aW",function(){return ei}),A.export(n,"aX",function(){return eT}),A.export(n,"aY",function(){return eR}),A.export(n,"aZ",function(){return eY}),A.export(n,"a_",function(){return tw}),A.export(n,"aa",function(){return eE}),A.export(n,"ab",function(){return eS}),A.export(n,"ac",function(){return Q}),A.export(n,"ad",function(){return h}),A.export(n,"ae",function(){return t_}),A.export(n,"af",function(){return e1}),A.export(n,"ag",function(){return ea}),A.export(n,"ah",function(){return N}),A.export(n,"ai",function(){return _}),A.export(n,"aj",function(){return P}),A.export(n,"ak",function(){return tu}),A.export(n,"al",function(){return eb}),A.export(n,"am",function(){return eV}),A.export(n,"an",function(){return no}),A.export(n,"ao",function(){return nA}),A.export(n,"ap",function(){return e3}),A.export(n,"aq",function(){return e6}),A.export(n,"ar",function(){return e4}),A.export(n,"as",function(){return ef}),A.export(n,"at",function(){return ep}),A.export(n,"au",function(){return el}),A.export(n,"av",function(){return em}),A.export(n,"aw",function(){return eB}),A.export(n,"ax",function(){return e_}),A.export(n,"ay",function(){return ni}),A.export(n,"az",function(){return ts}),A.export(n,"b",function(){return f}),A.export(n,"b0",function(){return T}),A.export(n,"b1",function(){return R}),A.export(n,"b2",function(){return K}),A.export(n,"b3",function(){return z}),A.export(n,"b4",function(){return G}),A.export(n,"b5",function(){return to}),A.export(n,"c",function(){return t8}),A.export(n,"d",function(){return er}),A.export(n,"e",function(){return tL}),A.export(n,"f",function(){return L}),A.export(n,"g",function(){return g}),A.export(n,"h",function(){return eQ}),A.export(n,"i",function(){return p}),A.export(n,"j",function(){return M}),A.export(n,"k",function(){return d}),A.export(n,"l",function(){return tm}),A.export(n,"m",function(){return y}),A.export(n,"n",function(){return w}),A.export(n,"o",function(){return e7}),A.export(n,"p",function(){return ta}),A.export(n,"q",function(){return tF}),A.export(n,"r",function(){return tb}),A.export(n,"s",function(){return W}),A.export(n,"t",function(){return te}),A.export(n,"u",function(){return tv}),A.export(n,"v",function(){return v}),A.export(n,"w",function(){return tQ}),A.export(n,"x",function(){return J}),A.export(n,"y",function(){return eN}),A.export(n,"z",function(){return q});var o=t("@swc/helpers/_/_class_call_check"),s=t("@swc/helpers/_/_create_class"),a=t("@swc/helpers/_/_define_property"),l=t("@swc/helpers/_/_to_consumable_array"),c=t("@swc/helpers/_/_type_of");function u(){}var h=(r=0,function(){return r++});function d(t){return null==t}function f(t){if(Array.isArray&&Array.isArray(t))return!0;var e=Object.prototype.toString.call(t);return"[object"===e.slice(0,7)&&"Array]"===e.slice(-6)}function p(t){return null!==t&&"[object Object]"===Object.prototype.toString.call(t)}var g=function(t){return("number"==typeof t||t instanceof Number)&&isFinite(+t)};function m(t,e){return g(t)?t:e}function v(t,e){return void 0===t?e:t}var y=function(t,e){return"string"==typeof t&&t.endsWith("%")?parseFloat(t)/100:t/e},w=function(t,e){return"string"==typeof t&&t.endsWith("%")?parseFloat(t)/100*e:+t};function b(t,e,n){if(t&&"function"==typeof t.call)return t.apply(n,e)}function B(t,e,n,r){var i,A,o;if(f(t)){if(A=t.length,r)for(i=A-1;i>=0;i--)e.call(n,t[i],i);else for(i=0;i=t}function tt(t,e,n){var r,i,A;for(r=0,i=t.length;ra&&l3&&void 0!==arguments[3]?arguments[3]:1e-6;return t>=Math.min(e,n)-r&&t<=Math.max(e,n)+r}function th(t,e,n){n=n||function(n){return t[n]1;)n(r=A+i>>1)?A=r:i=r;return{lo:A,hi:i}}var td=function(t,e,n,r){return th(t,n,r?function(r){return t[r][e]<=n}:function(r){return t[r][e]=n})};function tp(t,e,n){for(var r=0,i=t.length;rr&&t[i-1]>n;)i--;return r>0||i0||(tg.forEach(function(e){delete t[e]}),delete t._chartjs)}}function ty(t){var e,n,r=new Set;for(e=0,n=t.length;e=1?t:-(Math.sqrt(1-t*t)-1)},easeOutCirc:function(t){return Math.sqrt(1-(t-=1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){return tE(t)?t:tS(t,.075,.3)},easeOutElastic:function(t){return tE(t)?t:tU(t,.075,.3)},easeInOutElastic:function(t){return tE(t)?t:t<.5?.5*tS(2*t,.1125,.45):.5+.5*tU(2*t-1,.1125,.45)},easeInBack:function(t){return t*t*(2.70158*t-1.70158)},easeOutBack:function(t){return(t-=1)*t*(2.70158*t+1.70158)+1},easeInOutBack:function(t){var e=1.70158;return(t/=.5)<1?t*t*(((e*=1.525)+1)*t-e)*.5:.5*((t-=2)*t*(((e*=1.525)+1)*t+e)+2)},easeInBounce:function(t){return 1-tL.easeOutBounce(1-t)},easeOutBounce:function(t){return t<.36363636363636365?7.5625*t*t:t<.7272727272727273?7.5625*(t-=.5454545454545454)*t+.75:t<.9090909090909091?7.5625*(t-=.8181818181818182)*t+.9375:7.5625*(t-=.9545454545454546)*t+.984375},easeInOutBounce:function(t){return t<.5?.5*tL.easeInBounce(2*t):.5*tL.easeOutBounce(2*t-1)+.5}};/*! * @kurkle/color v0.2.1 * https://github.com/kurkle/color#readme * (c) 2022 Jukka Kurkela * Released under the MIT License */function tI(t){return t+.5|0}var tj=function(t,e,n){return Math.max(Math.min(t,n),e)};function tM(t){return tj(tI(2.55*t),0,255)}function tD(t){return tj(tI(255*t),0,255)}function tN(t){return tj(tI(t/2.55)/100,0,1)}function tP(t){return tj(tI(100*t),0,100)}var tO={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,A:10,B:11,C:12,D:13,E:14,F:15,a:10,b:11,c:12,d:13,e:14,f:15},tH=Array.from("0123456789ABCDEF"),tT=function(t){return tH[15&t]},tR=function(t){return tH[(240&t)>>4]+tH[15&t]},tK=function(t){return(240&t)>>4==(15&t)},tV=/^(hsla?|hwb|hsv)\(\s*([-+.e\d]+)(?:deg)?[\s,]+([-+.e\d]+)%[\s,]+([-+.e\d]+)%(?:[\s,]+([-+.e\d]+)(%)?)?\s*\)$/;function tz(t,e,n){var r=e*Math.min(n,1-n),i=function(e){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:(e+t/30)%12;return n-r*Math.max(Math.min(i-3,9-i,1),-1)};return[i(0),i(8),i(4)]}function tG(t,e,n){var r=function(r){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:(r+t/60)%6;return n-n*e*Math.max(Math.min(i,4-i,1),0)};return[r(5),r(3),r(1)]}function tq(t,e,n){var r,i=tz(t,1,.5);for(e+n>1&&(r=1/(e+n),e*=r,n*=r),r=0;r<3;r++)i[r]*=1-e-n,i[r]+=e;return i}function tW(t){var e,n,r,i=t.r/255,A=t.g/255,o=t.b/255,s=Math.max(i,A,o),a=Math.min(i,A,o),l=(s+a)/2;return s!==a&&(r=s-a,n=l>.5?r/(2-s-a):r/(s+a),e=60*(e=i===s?(A-o)/r+(A=3&&(e={r:t[0],g:t[1],b:t[2],a:255},t.length>3&&(e.a=tD(t[3]))):(e=t5(t,{r:0,g:0,b:0,a:1})).a=tD(e.a),e}var t3=function(){function t(e){if((0,o._)(this,t),e instanceof t)return e;var n,r,A,s,a=void 0===e?"undefined":(0,c._)(e);"object"===a?s=t4(e):"string"===a&&(r=e.length,"#"===e[0]&&(4===r||5===r?n={r:255&17*tO[e[1]],g:255&17*tO[e[2]],b:255&17*tO[e[3]],a:5===r?17*tO[e[4]]:255}:(7===r||9===r)&&(n={r:tO[e[1]]<<4|tO[e[2]],g:tO[e[3]]<<4|tO[e[4]],b:tO[e[5]]<<4|tO[e[6]],a:9===r?tO[e[7]]<<4|tO[e[8]]:255})),s=n||(i||((i=function(){var t,e,n,r,i,A={},o=Object.keys(tZ),s=Object.keys(tJ);for(t=0;t>16&255,n>>8&255,255&n]}return A}()).transparent=[0,0,0,0]),(A=i[e.toLowerCase()])&&{r:A[0],g:A[1],b:A[2],a:4===A.length?A[3]:255})||("r"===e.charAt(0)?function(t){var e,n,r,i=t$.exec(t),A=255;if(i){if(i[7]!==e){var o=+i[7];A=i[8]?tM(o):tj(255*o,0,255)}return e=+i[1],n=+i[3],r=+i[5],{r:e=255&(i[2]?tM(e):tj(e,0,255)),g:n=255&(i[4]?tM(n):tj(n,0,255)),b:r=255&(i[6]?tM(r):tj(r,0,255)),a:A}}}(e):function(t){var e,n=tV.exec(t),r=255;if(n){n[5]!==e&&(r=n[6]?tM(+n[5]):tD(+n[5]));var i=tX(+n[2]),A=+n[3]/100,o=+n[4]/100;return{r:(e="hwb"===n[1]?tY(tq,i,A,o):"hsv"===n[1]?tY(tG,i,A,o):tY(tz,i,A,o))[0],g:e[1],b:e[2],a:r}}}(e))),this._rgb=s,this._valid=!!s}return(0,s._)(t,[{key:"valid",get:function(){return this._valid}},{key:"rgb",get:function(){var t=t5(this._rgb);return t&&(t.a=tN(t.a)),t},set:function(t){this._rgb=t4(t)}},{key:"rgbString",value:function(){var t;return this._valid?(t=this._rgb)&&(t.a<255?"rgba(".concat(t.r,", ").concat(t.g,", ").concat(t.b,", ").concat(tN(t.a),")"):"rgb(".concat(t.r,", ").concat(t.g,", ").concat(t.b,")")):void 0}},{key:"hexString",value:function(){var t,e,n,r;return this._valid?(n=tK((e=t=this._rgb).r)&&tK(e.g)&&tK(e.b)&&tK(e.a)?tT:tR,t?"#"+n(t.r)+n(t.g)+n(t.b)+((r=t.a)<255?n(r):""):void 0):void 0}},{key:"hslString",value:function(){return this._valid?function(t){if(t){var e=tW(t),n=e[0],r=tP(e[1]),i=tP(e[2]);return t.a<255?"hsla(".concat(n,", ").concat(r,"%, ").concat(i,"%, ").concat(tN(t.a),")"):"hsl(".concat(n,", ").concat(r,"%, ").concat(i,"%)")}}(this._rgb):void 0}},{key:"mix",value:function(t,e){if(t){var n,r=this.rgb,i=t.rgb,A=e===n?.5:e,o=2*A-1,s=r.a-i.a,a=((o*s==-1?o:(o+s)/(1+o*s))+1)/2;n=1-a,r.r=255&a*r.r+n*i.r+.5,r.g=255&a*r.g+n*i.g+.5,r.b=255&a*r.b+n*i.b+.5,r.a=A*r.a+(1-A)*i.a,this.rgb=r}return this}},{key:"interpolate",value:function(t,e){if(t){var n,r,i,A,o;this._rgb=(n=this._rgb,r=t._rgb,i=t1(tN(n.r)),A=t1(tN(n.g)),o=t1(tN(n.b)),{r:tD(t0(i+e*(t1(tN(r.r))-i))),g:tD(t0(A+e*(t1(tN(r.g))-A))),b:tD(t0(o+e*(t1(tN(r.b))-o))),a:n.a+e*(r.a-n.a)})}return this}},{key:"clone",value:function(){return new t(this.rgb)}},{key:"alpha",value:function(t){return this._rgb.a=tD(t),this}},{key:"clearer",value:function(t){var e=this._rgb;return e.a*=1-t,this}},{key:"greyscale",value:function(){var t=this._rgb,e=tI(.3*t.r+.59*t.g+.11*t.b);return t.r=t.g=t.b=e,this}},{key:"opaquer",value:function(t){var e=this._rgb;return e.a*=1+t,this}},{key:"negate",value:function(){var t=this._rgb;return t.r=255-t.r,t.g=255-t.g,t.b=255-t.b,this}},{key:"lighten",value:function(t){return t2(this._rgb,2,t),this}},{key:"darken",value:function(t){return t2(this._rgb,2,-t),this}},{key:"saturate",value:function(t){return t2(this._rgb,1,t),this}},{key:"desaturate",value:function(t){return t2(this._rgb,1,-t),this}},{key:"rotate",value:function(t){var e,n;return(n=tW(e=this._rgb))[0]=tX(n[0]+t),n=tY(tz,n,void 0,void 0),e.r=n[0],e.g=n[1],e.b=n[2],this}}]),t}();function t6(t){if(t&&"object"==typeof t){var e=t.toString();return"[object CanvasPattern]"===e||"[object CanvasGradient]"===e}return!1}function t8(t){return t6(t)?t:new t3(t)}function t7(t){return t6(t)?t:new t3(t).saturate(.5).darken(.1).hexString()}var t9=Object.create(null),et=Object.create(null);function ee(t,e){if(!e)return t;for(var n=e.split("."),r=0,i=n.length;rr&&(r=A),r}function eo(t,e,n,r){var i,A,o,s,a,l=(r=r||{}).data=r.data||{},c=r.garbageCollect=r.garbageCollect||[];r.font!==e&&(l=r.data={},c=r.garbageCollect=[],r.font=e),t.save(),t.font=e;var u=0,h=n.length;for(i=0;in.length){for(i=0;i0&&t.stroke()}}function eu(t,e,n){return n=n||.5,!e||t&&t.x>e.left-n&&t.xe.top-n&&t.y5&&void 0!==arguments[5]?arguments[5]:{},a=f(e)?e:[e],l=s.strokeWidth>0&&""!==s.strokeColor;for(t.save(),t.font=i.string,s.translation&&t.translate(s.translation[0],s.translation[1]),d(s.rotation)||t.rotate(s.rotation),s.color&&(t.fillStyle=s.color),s.textAlign&&(t.textAlign=s.textAlign),s.textBaseline&&(t.textBaseline=s.textBaseline),A=0;A1&&void 0!==arguments[1]?arguments[1]:[""],r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:t,i=arguments.length>3?arguments[3]:void 0,A=arguments.length>4&&void 0!==arguments[4]?arguments[4]:function(){return t[0]};return M(i)||(i=eM("_fallback",t)),new Proxy((e={},(0,a._)(e,Symbol.toStringTag,"Object"),(0,a._)(e,"_cacheable",!0),(0,a._)(e,"_scopes",t),(0,a._)(e,"_rootScopes",r),(0,a._)(e,"_fallback",i),(0,a._)(e,"_getTarget",A),(0,a._)(e,"override",function(e){return eE([e].concat((0,l._)(t)),n,r,i)}),e),{deleteProperty:function(e,n){return delete e[n],delete e._keys,delete t[0][n],!0},get:function(e,r){return eL(e,r,function(){return function(t,e,n,r){var i=!0,A=!1,o=void 0;try{for(var s,a,l=e[Symbol.iterator]();!(i=(a=l.next()).done);i=!0){var c=a.value;if(s=eM(c?c+j(t):t,n),M(s))return eU(t,s)?eI(n,r,t,s):s}}catch(t){A=!0,o=t}finally{try{i||null==l.return||l.return()}finally{if(A)throw o}}}(r,n,t,e)})},getOwnPropertyDescriptor:function(t,e){return Reflect.getOwnPropertyDescriptor(t._scopes[0],e)},getPrototypeOf:function(){return Reflect.getPrototypeOf(t[0])},has:function(t,e){return eD(t).includes(e)},ownKeys:function(t){return eD(t)},set:function(t,e,n){var r=t._storage||(t._storage=A());return t[e]=r[e]=n,delete t._keys,!0}})}function eS(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{scriptable:!0,indexable:!0},n=t._scriptable,r=void 0===n?e.scriptable:n,i=t._indexable,A=void 0===i?e.indexable:i,o=t._allKeys;return{allKeys:void 0===o?e.allKeys:o,scriptable:r,indexable:A,isScriptable:D(r)?r:function(){return r},isIndexable:D(A)?A:function(){return A}}}var eU=function(t,e){return p(e)&&"adapters"!==t&&(null===Object.getPrototypeOf(e)||e.constructor===Object)};function eL(t,e,n){if(Object.prototype.hasOwnProperty.call(t,e))return t[e];var r=n();return t[e]=r,r}function eI(t,e,n,r){var i,A=e._rootScopes,o=D(i=e._fallback)?i(n,r):i,s=(0,l._)(t).concat((0,l._)(A)),a=new Set;a.add(r);var c=ej(a,s,n,o||n,r);return!(null===c||M(o)&&o!==n&&null===(c=ej(a,s,o,c,r)))&&eE(Array.from(a),[""],A,o,function(){var t,i;return n in(t=e._getTarget())||(t[n]={}),f(i=t[n])&&p(r)?r:i})}function ej(t,e,n,r,i){for(;n;)n=function(t,e,n,r,i){var A=!0,o=!1,s=void 0;try{for(var a,l=e[Symbol.iterator]();!(A=(a=l.next()).done);A=!0){var c=a.value,u=!0===n?c:"string"==typeof n?L(c,n):void 0;if(u){t.add(u);var h,d=(h=u._fallback,D(h)?h(n,i):h);if(M(d)&&d!==n&&d!==r)return d}else if(!1===u&&M(r)&&n!==r)return null}}catch(t){o=!0,s=t}finally{try{A||null==l.return||l.return()}finally{if(o)throw s}}return!1}(t,e,n,r,i);return n}function eM(t,e){var n=!0,r=!1,i=void 0;try{for(var A,o=e[Symbol.iterator]();!(n=(A=o.next()).done);n=!0){var s=A.value;if(s){var a=s[t];if(M(a))return a}}}catch(t){r=!0,i=t}finally{try{n||null==o.return||o.return()}finally{if(r)throw i}}}function eD(t){var e=t._keys;return e||(e=t._keys=function(t){var e=new Set,n=!0,r=!1,i=void 0,A=!0,o=!1,s=void 0;try{for(var a,l=t[Symbol.iterator]();!(A=(a=l.next()).done);A=!0){var c=a.value;try{for(var u,h=Object.keys(c).filter(function(t){return!t.startsWith("_")})[Symbol.iterator]();!(n=(u=h.next()).done);n=!0){var d=u.value;e.add(d)}}catch(t){r=!0,i=t}finally{try{n||null==h.return||h.return()}finally{if(r)throw i}}}}catch(t){o=!0,s=t}finally{try{A||null==l.return||l.return()}finally{if(o)throw s}}return Array.from(e)}(t._scopes)),e}function eN(t,e,n,r){var i,A,o,s=t.iScale,a=this._parsing.key,l=void 0===a?"r":a,c=Array(r);for(i=0;i1&&void 0!==arguments[1]?arguments[1]:"x",A=eH(i),o=t.length,s=Array(o).fill(0),a=Array(o),l=eO(t,0);for(e=0;e2&&void 0!==arguments[2]?arguments[2]:"x",o=eH(A),s=t.length,a=eO(t,0),l=0;l0||a>0)&&(!n||!n.shadowRoot))r=s,i=a;else{var c=e.getBoundingClientRect();r=o.clientX-c.left,i=o.clientY-c.top,l=!0}return{x:r,y:i,box:l}}(t,n),l=a.x,c=a.y,u=a.box,h=o.left+(u&&s.left),d=o.top+(u&&s.top),f=e.width,p=e.height;return A&&(f-=o.width+s.width,p-=o.height+s.height),{x:Math.round((l-h)/f*n.width/r),y:Math.round((c-d)/p*n.height/r)}}var e$=function(t){return Math.round(10*t)/10};function e0(t,e,n,r){var i=eW(t),A=eJ(i,"margin"),o=eq(i.maxWidth,t,"clientWidth")||R,s=eq(i.maxHeight,t,"clientHeight")||R,a=function(t,e,n){var r,i;if(void 0===e||void 0===n){var A=eG(t);if(A){var o=A.getBoundingClientRect(),s=eW(A),a=eJ(s,"border","width"),l=eJ(s,"padding");e=o.width-l.width-a.width,n=o.height-l.height-a.height,r=eq(s.maxWidth,A,"clientWidth"),i=eq(s.maxHeight,A,"clientHeight")}else e=t.clientWidth,n=t.clientHeight}return{width:e,height:n,maxWidth:r||R,maxHeight:i||R}}(t,e,n),l=a.width,c=a.height;if("content-box"===i.boxSizing){var u=eJ(i,"border","width"),h=eJ(i,"padding");l-=h.width+u.width,c-=h.height+u.height}return l=Math.max(0,l-A.width),c=Math.max(0,r?Math.floor(l/r):c-A.height),l=e$(Math.min(l,o,a.maxWidth)),c=e$(Math.min(c,s,a.maxHeight)),l&&!c&&(c=e$(l/2)),{width:l,height:c}}function e1(t,e,n){var r=e||1,i=Math.floor(t.height*r),A=Math.floor(t.width*r);t.height=i/r,t.width=A/r;var o=t.canvas;return o.style&&(n||!o.style.height&&!o.style.width)&&(o.style.height="".concat(t.height,"px"),o.style.width="".concat(t.width,"px")),(t.currentDevicePixelRatio!==r||o.height!==i||o.width!==A)&&(t.currentDevicePixelRatio=r,o.height=i,o.width=A,t.ctx.setTransform(r,0,0,r,0,0),!0)}var e2=function(){var t=!1;try{var e={get passive(){return t=!0,!1}};window.addEventListener("test",null,e),window.removeEventListener("test",null,e)}catch(t){}return t}();function e5(t,e){var n=eY(t,e),r=n&&n.match(/^(\d+)(\.\d+)?px$/);return r?+r[1]:void 0}function e4(t,e,n,r){return{x:t.x+n*(e.x-t.x),y:t.y+n*(e.y-t.y)}}function e3(t,e,n,r){return{x:t.x+n*(e.x-t.x),y:"middle"===r?n<.5?t.y:e.y:"after"===r?n<1?t.y:e.y:n>0?e.y:t.y}}function e6(t,e,n,r){var i={x:t.cp2x,y:t.cp2y},A={x:e.cp1x,y:e.cp1y},o=e4(t,i,n),s=e4(i,A,n),a=e4(A,e,n),l=e4(o,s,n),c=e4(s,a,n);return e4(l,c,n)}var e8=new Map;function e7(t,e,n){var r,i,A;return(i=e+JSON.stringify(r=(r=n)||{}),(A=e8.get(i))||(A=new Intl.NumberFormat(e,r),e8.set(i,A)),A).format(t)}function e9(t,e,n){var r;return t?(r=n,{x:function(t){return e+e+r-t},setWidth:function(t){r=t},textAlign:function(t){return"center"===t?t:"right"===t?"left":"right"},xPlus:function(t,e){return t-e},leftForLtr:function(t,e){return t-e}}):{x:function(t){return t},setWidth:function(t){},textAlign:function(t){return t},xPlus:function(t,e){return t+e},leftForLtr:function(t,e){return t}}}function nt(t,e){var n,r;("ltr"===e||"rtl"===e)&&(r=[(n=t.canvas.style).getPropertyValue("direction"),n.getPropertyPriority("direction")],n.setProperty("direction",e,"important"),t.prevTextDirection=r)}function ne(t,e){void 0!==e&&(delete t.prevTextDirection,t.canvas.style.setProperty("direction",e[0],e[1]))}function nn(t){return"angle"===t?{between:ta,compare:to,normalize:ts}:{between:tu,compare:function(t,e){return t-e},normalize:function(t){return t}}}function nr(t){var e=t.start,n=t.end,r=t.count;return{start:e%r,end:n%r,loop:t.loop&&(n-e+1)%r==0,style:t.style}}function ni(t,e,n){if(!n)return[t];for(var r,i,A,o=n.property,s=n.start,a=n.end,l=e.length,c=nn(o),u=c.compare,h=c.between,d=c.normalize,f=function(t,e,n){var r,i=n.property,A=n.start,o=n.end,s=nn(i),a=s.between,l=s.normalize,c=e.length,u=t.start,h=t.end,d=t.loop;if(d){for(u+=c,h+=c,r=0;ri&&t[A%e].skip;)A--;return{start:i,end:A%=e}}(n,i,A,r),s=o.start,a=o.end;if(!0===r)return ns(t,[{start:s,end:a,loop:A}],n,e);var l=a0){this.model=e||"rgb",r=s[this.model].channels;var c=Array.prototype.slice.call(t,0,r);this.color=x(c,r),this.valpha="number"==typeof t[r]?t[r]:1}else if("number"==typeof t)this.model="rgb",this.color=[t>>16&255,t>>8&255,255&t],this.valpha=1;else{this.valpha=1;var u=Object.keys(t);"alpha"in t&&(u.splice(u.indexOf("alpha"),1),this.valpha="number"==typeof t.alpha?t.alpha:0);var h=u.sort().join("");if(!(h in l))throw Error("Unable to parse color from object: "+JSON.stringify(t));this.model=l[h];var d=s[this.model].labels,f=[];for(n=0;nn?(e+.05)/(n+.05):(n+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return e>=7?"AAA":e>=4.5?"AA":""},isDark:function(){var t=this.rgb().color;return(2126*t[0]+7152*t[1]+722*t[2])/1e4<128},isLight:function(){return!this.isDark()},negate:function(){for(var t=this.rgb(),e=0;e<3;e++)t.color[e]=255-t.color[e];return t},lighten:function(t){var e=this.hsl();return e.color[2]+=e.color[2]*t,e},darken:function(t){var e=this.hsl();return e.color[2]-=e.color[2]*t,e},saturate:function(t){var e=this.hsl();return e.color[1]+=e.color[1]*t,e},desaturate:function(t){var e=this.hsl();return e.color[1]-=e.color[1]*t,e},whiten:function(t){var e=this.hwb();return e.color[1]+=e.color[1]*t,e},blacken:function(t){var e=this.hwb();return e.color[2]+=e.color[2]*t,e},grayscale:function(){var t=this.rgb().color,e=.3*t[0]+.59*t[1]+.11*t[2];return m.rgb(e,e,e)},fade:function(t){return this.alpha(this.valpha-this.valpha*t)},opaquer:function(t){return this.alpha(this.valpha+this.valpha*t)},rotate:function(t){var e=this.hsl(),n=e.color[0];return n=(n=(n+t)%360)<0?360+n:n,e.color[0]=n,e},mix:function(t,e){if(!t||!t.rgb)throw Error('Argument to "mix" was not a Color instance, but rather an instance of '+(void 0===t?"undefined":(0,A._)(t)));var n=t.rgb(),r=this.rgb(),i=void 0===e?.5:e,o=2*i-1,s=n.alpha()-r.alpha(),a=((o*s==-1?o:(o+s)/(1+o*s))+1)/2,l=1-a;return m.rgb(a*n.red()+l*r.red(),a*n.green()+l*r.green(),a*n.blue()+l*r.blue(),n.alpha()*i+r.alpha()*(1-i))}};var v=!0,y=!1,w=void 0;try{for(var b,B=Object.keys(s)[Symbol.iterator]();!(v=(b=B.next()).done);v=!0)!function(){var t=b.value;if(!a.includes(t)){var e=s[t].channels;m.prototype[t]=function(){for(var e,n=arguments.length,r=Array(n),A=0;A0?new m(r,t):new m((0,i._)((e=s[this.model][t].raw(this.color),Array.isArray(e)?e:[e])).concat([this.valpha]),t)},m[t]=function(){for(var n=arguments.length,r=Array(n),i=0;i=4&&1!==t[3]&&(e=", "+t[3]),"hwb("+t[0]+", "+t[1]+"%, "+t[2]+"%"+e+")"},a.to.keyword=function(t){return o[t.slice(0,3)]}},{d7a6eeb7388b4bb:"9CRqC","248ce9e419a8df53":"7SGVb"}],"9CRqC":[function(t,e,n){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]}},{}],"7SGVb":[function(t,e,n){var r=t("ce0bf6d0bc000d24"),i=Array.prototype.concat,A=Array.prototype.slice,o=e.exports=function(t){for(var e=[],n=0,o=t.length;n=0&&(t.splice instanceof Function||Object.getOwnPropertyDescriptor(t,t.length-1)&&"String"!==t.constructor.name))}},{}],b0bZu:[function(t,e,n){var r=t("739980f7990d3c32"),i=t("30ea0c7ee5f3dd94"),A={};Object.keys(r).forEach(function(t){A[t]={},Object.defineProperty(A[t],"channels",{value:r[t].channels}),Object.defineProperty(A[t],"labels",{value:r[t].labels});var e=i(t);Object.keys(e).forEach(function(n){var r,i,o=e[n];A[t][n]=(r=function(){for(var t=arguments.length,e=Array(t),n=0;n1&&(e=r);var i=o(e);if("object"==typeof i)for(var A=i.length,s=0;s1&&(e=r),o(e))},"conversion"in o&&(i.conversion=o.conversion),i)})}),e.exports=A},{"739980f7990d3c32":"bLCsr","30ea0c7ee5f3dd94":"B0afd"}],bLCsr:[function(t,e,n){var r=t("@swc/helpers/_/_sliced_to_array"),i=t("efc99055946c4df8"),A={},o=!0,s=!1,a=void 0;try{for(var l,c=Object.keys(i)[Symbol.iterator]();!(o=(l=c.next()).done);o=!0){var u=l.value;A[i[u]]=u}}catch(t){s=!0,a=t}finally{try{o||null==c.return||c.return()}finally{if(s)throw a}}var h={rgb:{channels:3,labels:"rgb"},hsl:{channels:3,labels:"hsl"},hsv:{channels:3,labels:"hsv"},hwb:{channels:3,labels:"hwb"},cmyk:{channels:4,labels:"cmyk"},xyz:{channels:3,labels:"xyz"},lab:{channels:3,labels:"lab"},lch:{channels:3,labels:"lch"},hex:{channels:1,labels:["hex"]},keyword:{channels:1,labels:["keyword"]},ansi16:{channels:1,labels:["ansi16"]},ansi256:{channels:1,labels:["ansi256"]},hcg:{channels:3,labels:["h","c","g"]},apple:{channels:3,labels:["r16","g16","b16"]},gray:{channels:1,labels:["gray"]}};e.exports=h;var d=!0,f=!1,p=void 0;try{for(var g,m=Object.keys(h)[Symbol.iterator]();!(d=(g=m.next()).done);d=!0){var v=g.value;if(!("channels"in h[v]))throw Error("missing channels property: "+v);if(!("labels"in h[v]))throw Error("missing channel labels property: "+v);if(h[v].labels.length!==h[v].channels)throw Error("channel and label counts mismatch: "+v);var y=h[v],w=y.channels,b=y.labels;delete h[v].channels,delete h[v].labels,Object.defineProperty(h[v],"channels",{value:w}),Object.defineProperty(h[v],"labels",{value:b})}}catch(t){f=!0,p=t}finally{try{d||null==m.return||m.return()}finally{if(f)throw p}}h.rgb.hsl=function(t){var e,n=t[0]/255,r=t[1]/255,i=t[2]/255,A=Math.min(n,r,i),o=Math.max(n,r,i),s=o-A;o===A?e=0:n===o?e=(r-i)/s:r===o?e=2+(i-n)/s:i===o&&(e=4+(n-r)/s),(e=Math.min(60*e,360))<0&&(e+=360);var a=(A+o)/2;return[e,100*(o===A?0:a<=.5?s/(o+A):s/(2-o-A)),100*a]},h.rgb.hsv=function(t){var e,n,r,i,A,o=t[0]/255,s=t[1]/255,a=t[2]/255,l=Math.max(o,s,a),c=l-Math.min(o,s,a),u=function(t){return(l-t)/6/c+.5};return 0===c?(i=0,A=0):(A=c/l,e=u(o),n=u(s),r=u(a),o===l?i=r-n:s===l?i=1/3+e-r:a===l&&(i=2/3+n-e),i<0?i+=1:i>1&&(i-=1)),[360*i,100*A,100*l]},h.rgb.hwb=function(t){var e=t[0],n=t[1],r=t[2];return[h.rgb.hsl(t)[0],1/255*Math.min(e,Math.min(n,r))*100,100*(r=1-1/255*Math.max(e,Math.max(n,r)))]},h.rgb.cmyk=function(t){var e=t[0]/255,n=t[1]/255,r=t[2]/255,i=Math.min(1-e,1-n,1-r);return[100*((1-e-i)/(1-i)||0),100*((1-n-i)/(1-i)||0),100*((1-r-i)/(1-i)||0),100*i]},h.rgb.keyword=function(t){var e=A[t];if(e)return e;var n=1/0,r=!0,o=!1,s=void 0;try{for(var a,l,c=Object.keys(i)[Symbol.iterator]();!(r=(l=c.next()).done);r=!0){var u=l.value,h=i[u],d=Math.pow(t[0]-h[0],2)+Math.pow(t[1]-h[1],2)+Math.pow(t[2]-h[2],2);d.04045?Math.pow((e+.055)/1.055,2.4):e/12.92)+.3576*(n=n>.04045?Math.pow((n+.055)/1.055,2.4):n/12.92)+.1805*(r=r>.04045?Math.pow((r+.055)/1.055,2.4):r/12.92)),100*(.2126*e+.7152*n+.0722*r),100*(.0193*e+.1192*n+.9505*r)]},h.rgb.lab=function(t){var e=h.rgb.xyz(t),n=e[0],r=e[1],i=e[2];return n/=95.047,r/=100,i/=108.883,n=n>.008856?Math.pow(n,1/3):7.787*n+16/116,[116*(r=r>.008856?Math.pow(r,1/3):7.787*r+16/116)-16,500*(n-r),200*(r-(i=i>.008856?Math.pow(i,1/3):7.787*i+16/116))]},h.hsl.rgb=function(t){var e,n,r,i=t[0]/360,A=t[1]/100,o=t[2]/100;if(0===A)return[r=255*o,r,r];e=o<.5?o*(1+A):o+A-o*A;for(var s=2*o-e,a=[0,0,0],l=0;l<3;l++)(n=i+-(1/3*(l-1)))<0&&n++,n>1&&n--,r=6*n<1?s+(e-s)*6*n:2*n<1?e:3*n<2?s+(e-s)*(2/3-n)*6:s,a[l]=255*r;return a},h.hsl.hsv=function(t){var e=t[0],n=t[1]/100,r=t[2]/100,i=n,A=Math.max(r,.01);r*=2,n*=r<=1?r:2-r,i*=A<=1?A:2-A;var o=(r+n)/2;return[e,100*(0===r?2*i/(A+i):2*n/(r+n)),100*o]},h.hsv.rgb=function(t){var e=t[0]/60,n=t[1]/100,r=t[2]/100,i=Math.floor(e)%6,A=e-Math.floor(e),o=255*r*(1-n),s=255*r*(1-n*A),a=255*r*(1-n*(1-A));switch(r*=255,i){case 0:return[r,a,o];case 1:return[s,r,o];case 2:return[o,r,a];case 3:return[o,s,r];case 4:return[a,o,r];case 5:return[r,o,s]}},h.hsv.hsl=function(t){var e,n,r=t[0],i=t[1]/100,A=t[2]/100,o=Math.max(A,.01);n=(2-i)*A;var s=(2-i)*o;return[r,100*(i*o/(s<=1?s:2-s)||0),100*(n/=2)]},h.hwb.rgb=function(t){var e,n,r,i,A=t[0]/360,o=t[1]/100,s=t[2]/100,a=o+s;a>1&&(o/=a,s/=a);var l=Math.floor(6*A),c=1-s;e=6*A-l,(1&l)!=0&&(e=1-e);var u=o+e*(c-o);switch(l){default:case 6:case 0:n=c,r=u,i=o;break;case 1:n=u,r=c,i=o;break;case 2:n=o,r=c,i=u;break;case 3:n=o,r=u,i=c;break;case 4:n=u,r=o,i=c;break;case 5:n=c,r=o,i=u}return[255*n,255*r,255*i]},h.cmyk.rgb=function(t){var e=t[0]/100,n=t[1]/100,r=t[2]/100,i=t[3]/100;return[255*(1-Math.min(1,e*(1-i)+i)),255*(1-Math.min(1,n*(1-i)+i)),255*(1-Math.min(1,r*(1-i)+i))]},h.xyz.rgb=function(t){var e,n,r,i=t[0]/100,A=t[1]/100,o=t[2]/100;return e=3.2406*i+-1.5372*A+-.4986*o,n=-.9689*i+1.8758*A+.0415*o,r=.0557*i+-.204*A+1.057*o,e=e>.0031308?1.055*Math.pow(e,1/2.4)-.055:12.92*e,n=n>.0031308?1.055*Math.pow(n,1/2.4)-.055:12.92*n,r=r>.0031308?1.055*Math.pow(r,1/2.4)-.055:12.92*r,[255*(e=Math.min(Math.max(0,e),1)),255*(n=Math.min(Math.max(0,n),1)),255*(r=Math.min(Math.max(0,r),1))]},h.xyz.lab=function(t){var e=t[0],n=t[1],r=t[2];return e/=95.047,n/=100,r/=108.883,e=e>.008856?Math.pow(e,1/3):7.787*e+16/116,[116*(n=n>.008856?Math.pow(n,1/3):7.787*n+16/116)-16,500*(e-n),200*(n-(r=r>.008856?Math.pow(r,1/3):7.787*r+16/116))]},h.lab.xyz=function(t){var e,n,r,i=t[0],A=t[1],o=t[2];e=A/500+(n=(i+16)/116),r=n-o/200;var s=Math.pow(n,3),a=Math.pow(e,3),l=Math.pow(r,3);return n=(s>.008856?s:(n-16/116)/7.787)*100,[e=(a>.008856?a:(e-16/116)/7.787)*95.047,n,r=(l>.008856?l:(r-16/116)/7.787)*108.883]},h.lab.lch=function(t){var e,n=t[0],r=t[1],i=t[2];return(e=360*Math.atan2(i,r)/2/Math.PI)<0&&(e+=360),[n,Math.sqrt(r*r+i*i),e]},h.lch.lab=function(t){var e=t[0],n=t[1],r=t[2]/360*2*Math.PI;return[e,n*Math.cos(r),n*Math.sin(r)]},h.rgb.ansi16=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,n=(0,r._)(t,3),i=n[0],A=n[1],o=n[2],s=null===e?h.rgb.hsv(t)[2]:e;if(0===(s=Math.round(s/50)))return 30;var a=30+(Math.round(o/255)<<2|Math.round(A/255)<<1|Math.round(i/255));return 2===s&&(a+=60),a},h.hsv.ansi16=function(t){return h.rgb.ansi16(h.hsv.rgb(t),t[2])},h.rgb.ansi256=function(t){var e=t[0],n=t[1],r=t[2];return e===n&&n===r?e<8?16:e>248?231:Math.round((e-8)/247*24)+232:16+36*Math.round(e/255*5)+6*Math.round(n/255*5)+Math.round(r/255*5)},h.ansi16.rgb=function(t){var e=t%10;if(0===e||7===e)return t>50&&(e+=3.5),[e=e/10.5*255,e,e];var n=(~~(t>50)+1)*.5;return[(1&e)*n*255,(e>>1&1)*n*255,(e>>2&1)*n*255]},h.ansi256.rgb=function(t){if(t>=232){var e,n=(t-232)*10+8;return[n,n,n]}return[Math.floor((t-=16)/36)/5*255,Math.floor((e=t%36)/6)/5*255,e%6/5*255]},h.rgb.hex=function(t){var e=(((255&Math.round(t[0]))<<16)+((255&Math.round(t[1]))<<8)+(255&Math.round(t[2]))).toString(16).toUpperCase();return"000000".substring(e.length)+e},h.hex.rgb=function(t){var e=t.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!e)return[0,0,0];var n=e[0];3===e[0].length&&(n=n.split("").map(function(t){return t+t}).join(""));var r=parseInt(n,16);return[r>>16&255,r>>8&255,255&r]},h.rgb.hcg=function(t){var e,n=t[0]/255,r=t[1]/255,i=t[2]/255,A=Math.max(Math.max(n,r),i),o=Math.min(Math.min(n,r),i),s=A-o;return e=s<1?o/(1-s):0,[(s<=0?0:A===n?(r-i)/s%6:A===r?2+(i-n)/s:4+(n-r)/s)/6%1*360,100*s,100*e]},h.hsl.hcg=function(t){var e=t[1]/100,n=t[2]/100,r=n<.5?2*e*n:2*e*(1-n),i=0;return r<1&&(i=(n-.5*r)/(1-r)),[t[0],100*r,100*i]},h.hsv.hcg=function(t){var e=t[1]/100,n=t[2]/100,r=e*n,i=0;return r<1&&(i=(n-r)/(1-r)),[t[0],100*r,100*i]},h.hcg.rgb=function(t){var e=t[0]/360,n=t[1]/100,r=t[2]/100;if(0===n)return[255*r,255*r,255*r];var i=[0,0,0],A=e%1*6,o=A%1,s=1-o,a=0;switch(Math.floor(A)){case 0:i[0]=1,i[1]=o,i[2]=0;break;case 1:i[0]=s,i[1]=1,i[2]=0;break;case 2:i[0]=0,i[1]=1,i[2]=o;break;case 3:i[0]=0,i[1]=s,i[2]=1;break;case 4:i[0]=o,i[1]=0,i[2]=1;break;default:i[0]=1,i[1]=0,i[2]=s}return a=(1-n)*r,[(n*i[0]+a)*255,(n*i[1]+a)*255,(n*i[2]+a)*255]},h.hcg.hsv=function(t){var e=t[1]/100,n=e+t[2]/100*(1-e),r=0;return n>0&&(r=e/n),[t[0],100*r,100*n]},h.hcg.hsl=function(t){var e=t[1]/100,n=t[2]/100*(1-e)+.5*e,r=0;return n>0&&n<.5?r=e/(2*n):n>=.5&&n<1&&(r=e/(2*(1-n))),[t[0],100*r,100*n]},h.hcg.hwb=function(t){var e=t[1]/100,n=e+t[2]/100*(1-e);return[t[0],(n-e)*100,(1-n)*100]},h.hwb.hcg=function(t){var e=t[1]/100,n=1-t[2]/100,r=n-e,i=0;return r<1&&(i=(n-r)/(1-r)),[t[0],100*r,100*i]},h.apple.rgb=function(t){return[t[0]/65535*255,t[1]/65535*255,t[2]/65535*255]},h.rgb.apple=function(t){return[t[0]/255*65535,t[1]/255*65535,t[2]/255*65535]},h.gray.rgb=function(t){return[t[0]/100*255,t[0]/100*255,t[0]/100*255]},h.gray.hsl=function(t){return[0,0,t[0]]},h.gray.hsv=h.gray.hsl,h.gray.hwb=function(t){return[0,100,t[0]]},h.gray.cmyk=function(t){return[0,0,0,t[0]]},h.gray.lab=function(t){return[t[0],0,0]},h.gray.hex=function(t){var e=255&Math.round(t[0]/100*255),n=((e<<16)+(e<<8)+e).toString(16).toUpperCase();return"000000".substring(n.length)+n},h.rgb.gray=function(t){return[(t[0]+t[1]+t[2])/3/255*100]}},{"@swc/helpers/_/_sliced_to_array":"hefcy",efc99055946c4df8:"9CRqC"}],B0afd:[function(t,e,n){var r=t("22442592002c5ac3");e.exports=function(t){for(var e=function(t){var e=function(){for(var t={},e=Object.keys(r),n=e.length,i=0;i0&&void 0!==arguments[0]?arguments[0]:null,o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"YYYY-MM-DD",a=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"en-US";return(0,A._)(this,n),t=e.call(this,n.parseDateTime(r,o,a)),(0,s._)((0,i._)(t),"lang",void 0),t.lang=a,(0,c._)(t)}return(0,o._)(n,[{key:"getWeek",value:function(t){var e=new Date(this.midnight_ts(this)),n=(this.getDay()+(7-t))%7;e.setDate(e.getDate()-n);var r=e.getTime();return e.setMonth(0,1),e.getDay()!==t&&e.setMonth(0,1+(4-e.getDay()+7)%7),1+Math.ceil((r-e.getTime())/6048e5)}},{key:"clone",value:function(){return new n(this)}},{key:"toJSDate",value:function(){return new Date(this)}},{key:"inArray",value:function(t){var e=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"[]";return t.some(function(t){return t instanceof Array?e.isBetween(t[0],t[1],n):e.isSame(t,"day")})}},{key:"isBetween",value:function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"()";switch(n){default:case"()":return this.midnight_ts(this)>this.midnight_ts(t)&&this.midnight_ts(this)=this.midnight_ts(t)&&this.midnight_ts(this)this.midnight_ts(t)&&this.midnight_ts(this)<=this.midnight_ts(e);case"[]":return this.midnight_ts()>=this.midnight_ts(t)&&this.midnight_ts()<=this.midnight_ts(e)}}},{key:"isBefore",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"days";switch(e){case"day":case"days":return new Date(t.getFullYear(),t.getMonth(),t.getDate()).getTime()>new Date(this.getFullYear(),this.getMonth(),this.getDate()).getTime();case"month":case"months":return new Date(t.getFullYear(),t.getMonth(),1).getTime()>new Date(this.getFullYear(),this.getMonth(),1).getTime();case"year":case"years":return t.getFullYear()>this.getFullYear()}throw Error("isBefore: Invalid unit!")}},{key:"isSameOrBefore",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"days";switch(e){case"day":case"days":return new Date(t.getFullYear(),t.getMonth(),t.getDate()).getTime()>=new Date(this.getFullYear(),this.getMonth(),this.getDate()).getTime();case"month":case"months":return new Date(t.getFullYear(),t.getMonth(),1).getTime()>=new Date(this.getFullYear(),this.getMonth(),1).getTime()}throw Error("isSameOrBefore: Invalid unit!")}},{key:"isAfter",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"days";switch(e){case"day":case"days":return new Date(this.getFullYear(),this.getMonth(),this.getDate()).getTime()>new Date(t.getFullYear(),t.getMonth(),t.getDate()).getTime();case"month":case"months":return new Date(this.getFullYear(),this.getMonth(),1).getTime()>new Date(t.getFullYear(),t.getMonth(),1).getTime();case"year":case"years":return this.getFullYear()>t.getFullYear()}throw Error("isAfter: Invalid unit!")}},{key:"isSameOrAfter",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"days";switch(e){case"day":case"days":return new Date(this.getFullYear(),this.getMonth(),this.getDate()).getTime()>=new Date(t.getFullYear(),t.getMonth(),t.getDate()).getTime();case"month":case"months":return new Date(this.getFullYear(),this.getMonth(),1).getTime()>=new Date(t.getFullYear(),t.getMonth(),1).getTime()}throw Error("isSameOrAfter: Invalid unit!")}},{key:"isSame",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"days";switch(e){case"day":case"days":return new Date(this.getFullYear(),this.getMonth(),this.getDate()).getTime()===new Date(t.getFullYear(),t.getMonth(),t.getDate()).getTime();case"month":case"months":return new Date(this.getFullYear(),this.getMonth(),1).getTime()===new Date(t.getFullYear(),t.getMonth(),1).getTime()}throw Error("isSame: Invalid unit!")}},{key:"add",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"days";switch(e){case"day":case"days":this.setDate(this.getDate()+t);break;case"month":case"months":this.setMonth(this.getMonth()+t)}return this}},{key:"subtract",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"days";switch(e){case"day":case"days":this.setDate(this.getDate()-t);break;case"month":case"months":this.setMonth(this.getMonth()-t)}return this}},{key:"diff",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"days";switch(e){default:case"day":case"days":return Math.round((this.midnight_ts()-this.midnight_ts(t))/864e5);case"month":case"months":var n=12*(t.getFullYear()-this.getFullYear());return n-=t.getMonth(),n+=this.getMonth()}}},{key:"format",value:function(t){for(var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"en-US",r="",i=[],A=null;null!=(A=n.regex.exec(t));)"\\"!==A[1]&&i.push(A);if(i.length){i[0].index>0&&(r+=t.substring(0,i[0].index));var o=!0,s=!1,a=void 0;try{for(var l,c=Object.entries(i)[Symbol.iterator]();!(o=(l=c.next()).done);o=!0){var h=(0,u._)(l.value,2),d=h[0],f=h[1],p=Number(d);r+=this.formatTokens(f[0],e),i[p+1]&&(r+=t.substring(f.index+f[0].length,i[p+1].index)),p===i.length-1&&(r+=t.substring(f.index+f[0].length))}}catch(t){s=!0,a=t}finally{try{o||null==c.return||c.return()}finally{if(s)throw a}}}return r.replace(/\\/g,"")}},{key:"midnight_ts",value:function(t){return t?new Date(t.getFullYear(),t.getMonth(),t.getDate(),0,0,0,0).getTime():new Date(this.getFullYear(),this.getMonth(),this.getDate(),0,0,0,0).getTime()}},{key:"formatTokens",value:function(t,e){switch(t){case"YY":return String(this.getFullYear()).slice(-2);case"YYYY":return String(this.getFullYear());case"M":return String(this.getMonth()+1);case"MM":return"0".concat(this.getMonth()+1).slice(-2);case"MMM":return n.shortMonths(e)[this.getMonth()];case"MMMM":return n.longMonths(e)[this.getMonth()];case"D":return String(this.getDate());case"DD":return"0".concat(this.getDate()).slice(-2);case"H":return String(this.getHours());case"HH":return"0".concat(this.getHours()).slice(-2);case"h":return String(this.getHours()%12||12);case"hh":return"0".concat(this.getHours()%12||12).slice(-2);case"m":return String(this.getMinutes());case"mm":return"0".concat(this.getMinutes()).slice(-2);case"s":return String(this.getSeconds());case"ss":return"0".concat(this.getSeconds()).slice(-2);case"a":return 12>this.getHours()||24===this.getHours()?"am":"pm";case"A":return 12>this.getHours()||24===this.getHours()?"AM":"PM";default:return""}}}],[{key:"parseDateTime",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"YYYY-MM-DD",r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"en-US";if(!t)return new Date((new Date).setHours(0,0,0,0));if(t instanceof n)return t.toJSDate();if(t instanceof Date)return t;if(/^-?\d{10,}$/.test(String(t)))return new Date(Number(t));if("string"==typeof t){for(var i=[],A=null;null!=(A=n.regex.exec(e));)"\\"!==A[1]&&i.push(A);if(i.length){var o={year:null,month:null,shortMonth:null,longMonth:null,day:null,hour:0,minute:0,second:0,ampm:null,value:""};i[0].index>0&&(o.value+=".*?");var s=!0,a=!1,l=void 0;try{for(var c,h=Object.entries(i)[Symbol.iterator]();!(s=(c=h.next()).done);s=!0){var d=(0,u._)(c.value,2),f=d[0],p=d[1],g=Number(f),m=n.formatPatterns(p[0],r),v=m.group,y=m.pattern;o[v]=g+1,o.value+=y,o.value+=".*?"}}catch(t){a=!0,l=t}finally{try{s||null==h.return||h.return()}finally{if(a)throw l}}var w=new RegExp("^".concat(o.value,"$"));if(w.test(t)){var b=w.exec(t),B=Number(b[o.year]),_=null;o.month?_=Number(b[o.month])-1:o.shortMonth?_=n.shortMonths(r).indexOf(b[o.shortMonth]):o.longMonth&&(_=n.longMonths(r).indexOf(b[o.longMonth]));var C=Number(b[o.day])||1,x=Number(b[o.hour]),k=Number.isNaN(x)?0:x,F=Number(b[o.minute]),Q=Number.isNaN(F)?0:F,E=Number(b[o.second]),S=Number.isNaN(E)?0:E,U=b[o.ampm];return U&&"PM"===U&&24===(k+=12)&&(k=0),new Date(B,_,C,k,Q,S,0)}}}return new Date((new Date).setHours(0,0,0,0))}},{key:"shortMonths",value:function(t){return n.MONTH_JS.map(function(e){return new Date(2019,e).toLocaleString(t,{month:"short"})})}},{key:"longMonths",value:function(t){return n.MONTH_JS.map(function(e){return new Date(2019,e).toLocaleString(t,{month:"long"})})}},{key:"formatPatterns",value:function(t,e){switch(t){case"YY":case"YYYY":return{group:"year",pattern:"(\\d{".concat(t.length,"})")};case"M":return{group:"month",pattern:"(\\d{1,2})"};case"MM":return{group:"month",pattern:"(\\d{2})"};case"MMM":return{group:"shortMonth",pattern:"(".concat(n.shortMonths(e).join("|"),")")};case"MMMM":return{group:"longMonth",pattern:"(".concat(n.longMonths(e).join("|"),")")};case"D":return{group:"day",pattern:"(\\d{1,2})"};case"DD":return{group:"day",pattern:"(\\d{2})"};case"h":case"H":return{group:"hour",pattern:"(\\d{1,2})"};case"hh":case"HH":return{group:"hour",pattern:"(\\d{2})"};case"m":return{group:"minute",pattern:"(\\d{1,2})"};case"mm":return{group:"minute",pattern:"(\\d{2})"};case"s":return{group:"second",pattern:"(\\d{1,2})"};case"ss":return{group:"second",pattern:"(\\d{2})"};case"a":case"A":return{group:"ampm",pattern:"(AM|PM|am|pm)"}}}}]),n}((0,d._)(Date));(0,s._)(p,"regex",/(\\)?(Y{2,4}|M{1,4}|D{1,2}|H{1,2}|h{1,2}|m{1,2}|s{1,2}|A|a)/g),(0,s._)(p,"MONTH_JS",[0,1,2,3,4,5,6,7,8,9,10,11]);var g=function(){function t(e){(0,A._)(this,t),(0,s._)(this,"picker",void 0),this.picker=e}return(0,o._)(t,[{key:"render",value:function(t,e){t||(t=new p),t.setDate(1),t.setHours(0,0,0,0),"function"==typeof this["get".concat(e,"View")]&&this["get".concat(e,"View")](t)}},{key:"getContainerView",value:function(t){this.picker.ui.container.innerHTML="",this.picker.options.header&&this.picker.trigger("render",{date:t.clone(),view:"Header"}),this.picker.trigger("render",{date:t.clone(),view:"Main"}),this.picker.options.autoApply||this.picker.trigger("render",{date:t.clone(),view:"Footer"})}},{key:"getHeaderView",value:function(t){var e=document.createElement("header");this.picker.options.header instanceof HTMLElement&&e.appendChild(this.picker.options.header),"string"==typeof this.picker.options.header&&(e.innerHTML=this.picker.options.header),this.picker.ui.container.appendChild(e),this.picker.trigger("view",{target:e,date:t.clone(),view:"Header"})}},{key:"getMainView",value:function(t){var e=document.createElement("main");this.picker.ui.container.appendChild(e);var n=document.createElement("div");n.className="calendars grid-".concat(this.picker.options.grid);for(var r=0;r".concat(t.toLocaleString(this.picker.options.lang,{month:"long"})," ").concat(t.format("YYYY")),e.appendChild(n);var r=document.createElement("button");r.className="previous-button unit",r.innerHTML=this.picker.options.locale.previousMonth,e.appendChild(r);var i=document.createElement("button");return i.className="next-button unit",i.innerHTML=this.picker.options.locale.nextMonth,e.appendChild(i),e}},{key:"getCalendarDayNamesView",value:function(){var t=document.createElement("div");t.className="daynames-row";for(var e=1;e<=7;e++){var n=3+this.picker.options.firstDay+e,r=document.createElement("div");r.className="dayname",r.innerHTML=new Date(1970,0,n,12,0,0,0).toLocaleString(this.picker.options.lang,{weekday:"short"}),r.title=new Date(1970,0,n,12,0,0,0).toLocaleString(this.picker.options.lang,{weekday:"long"}),t.appendChild(r),this.picker.trigger("view",{dayIdx:n,view:"CalendarDayName",target:r})}return t}},{key:"getCalendarDaysView",value:function(t){var e=document.createElement("div");e.className="days-grid";for(var n=this.calcOffsetDays(t,this.picker.options.firstDay),r=32-new Date(t.getFullYear(),t.getMonth(),32).getDate(),i=0;ie.priority?-1:t.prioritye.dependencies.length?1:t.dependencies.length',previousMonth:'',cancel:"Cancel",apply:"Apply"},documentClick:this.binds.hidePicker,plugins:[]}),(0,s._)(this,"ui",{container:null,shadowRoot:null,wrapper:null}),(0,s._)(this,"version","1.2.1");var n=(0,l._)({},this.options.locale,e.locale);this.options=(0,l._)({},this.options,e),this.options.locale=n,this.handleOptions(),this.ui.wrapper=document.createElement("span"),this.ui.wrapper.style.display="none",this.ui.wrapper.style.position="absolute",this.ui.wrapper.style.pointerEvents="none",this.ui.wrapper.className="easepick-wrapper",this.ui.wrapper.attachShadow({mode:"open"}),this.ui.shadowRoot=this.ui.wrapper.shadowRoot,this.ui.container=document.createElement("div"),this.ui.container.className="container",this.options.zIndex&&(this.ui.container.style.zIndex=String(this.options.zIndex)),this.options.inline&&(this.ui.wrapper.style.position="relative",this.ui.container.classList.add("inline")),this.ui.shadowRoot.appendChild(this.ui.container),this.options.element.after(this.ui.wrapper),this.handleCSS(),this.options.element.addEventListener("click",this.binds.show),this.on("view",this.onView.bind(this)),this.on("render",this.onRender.bind(this)),this.PluginManager.initialize(),this.parseValues(),"function"==typeof this.options.setup&&this.options.setup(this),this.on("click",this.onClick.bind(this));var r=this.options.scrollToDate?this.getDate():null;this.renderAll(r)}return(0,o._)(t,[{key:"on",value:function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};this.ui.container.addEventListener(t,e,n)}},{key:"off",value:function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};this.ui.container.removeEventListener(t,e,n)}},{key:"trigger",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return this.ui.container.dispatchEvent(new CustomEvent(t,{detail:e}))}},{key:"destroy",value:function(){var t=this;this.options.element.removeEventListener("click",this.binds.show),"function"==typeof this.options.documentClick&&document.removeEventListener("click",this.options.documentClick,!0),Object.keys(this.PluginManager.instances).forEach(function(e){t.PluginManager.removeInstance(e)}),this.ui.wrapper.remove()}},{key:"onRender",value:function(t){var e=t.detail,n=e.view,r=e.date;this.Calendar.render(r,n)}},{key:"onView",value:function(t){var e=t.detail,n=e.view,r=e.target;"Footer"===n&&this.datePicked.length&&(r.querySelector(".apply-button").disabled=!1)}},{key:"onClickHeaderButton",value:function(t){this.isCalendarHeaderButton(t)&&(t.classList.contains("next-button")?this.calendars[0].add(1,"month"):this.calendars[0].subtract(1,"month"),this.renderAll(this.calendars[0]))}},{key:"onClickCalendarDay",value:function(t){if(this.isCalendarDay(t)){var e=new p(t.dataset.time);this.options.autoApply?(this.setDate(e),this.trigger("select",{date:this.getDate()}),this.hide()):(this.datePicked[0]=e,this.trigger("preselect",{date:this.getDate()}),this.renderAll())}}},{key:"onClickApplyButton",value:function(t){if(this.isApplyButton(t)){if(this.datePicked[0]instanceof Date){var e=this.datePicked[0].clone();this.setDate(e)}this.hide(),this.trigger("select",{date:this.getDate()})}}},{key:"onClickCancelButton",value:function(t){this.isCancelButton(t)&&this.hide()}},{key:"onClick",value:function(t){var e=t.target;if(e instanceof HTMLElement){var n=e.closest(".unit");if(!(n instanceof HTMLElement))return;this.onClickHeaderButton(n),this.onClickCalendarDay(n),this.onClickApplyButton(n),this.onClickCancelButton(n)}}},{key:"isShown",value:function(){return this.ui.container.classList.contains("inline")||this.ui.container.classList.contains("show")}},{key:"show",value:function(t){if(!this.isShown()){var e=t&&"target"in t?t.target:this.options.element,n=this.adjustPosition(e),r=n.top,i=n.left;this.ui.container.style.top="".concat(r,"px"),this.ui.container.style.left="".concat(i,"px"),this.ui.container.classList.add("show"),this.trigger("show",{target:e})}}},{key:"hide",value:function(){this.ui.container.classList.remove("show"),this.datePicked.length=0,this.renderAll(),this.trigger("hide")}},{key:"setDate",value:function(t){var e=new p(t,this.options.format);this.options.date=e.clone(),this.updateValues(),this.calendars.length&&this.renderAll()}},{key:"getDate",value:function(){return this.options.date instanceof p?this.options.date.clone():null}},{key:"parseValues",value:function(){this.options.date?this.setDate(this.options.date):this.options.element instanceof HTMLInputElement&&this.options.element.value.length&&this.setDate(this.options.element.value),this.options.date instanceof Date||(this.options.date=null)}},{key:"updateValues",value:function(){var t=this.getDate(),e=t instanceof Date?t.format(this.options.format,this.options.lang):"",n=this.options.element;n instanceof HTMLInputElement?n.value=e:n instanceof HTMLElement&&(n.innerText=e)}},{key:"hidePicker",value:function(t){var e=t.target,n=null;e.shadowRoot&&(n=(e=t.composedPath()[0]).getRootNode().host),this.isShown()&&n!==this.ui.wrapper&&e!==this.options.element&&this.hide()}},{key:"renderAll",value:function(t){this.trigger("render",{view:"Container",date:(t||this.calendars[0]).clone()})}},{key:"isCalendarHeaderButton",value:function(t){return["previous-button","next-button"].some(function(e){return t.classList.contains(e)})}},{key:"isCalendarDay",value:function(t){return t.classList.contains("day")}},{key:"isApplyButton",value:function(t){return t.classList.contains("apply-button")}},{key:"isCancelButton",value:function(t){return t.classList.contains("cancel-button")}},{key:"gotoDate",value:function(t){var e=new p(t,this.options.format);e.setDate(1),this.calendars[0]=e.clone(),this.renderAll()}},{key:"clear",value:function(){this.options.date=null,this.datePicked.length=0,this.updateValues(),this.renderAll(),this.trigger("clear")}},{key:"handleOptions",value:function(){this.options.element instanceof HTMLElement||(this.options.element=this.options.doc.querySelector(this.options.element)),"function"==typeof this.options.documentClick&&document.addEventListener("click",this.options.documentClick,!0),this.options.element instanceof HTMLInputElement&&(this.options.element.readOnly=this.options.readonly),this.options.date?this.calendars[0]=new p(this.options.date,this.options.format):this.calendars[0]=new p}},{key:"handleCSS",value:function(){var t=this;if(Array.isArray(this.options.css))this.options.css.forEach(function(e){var n=document.createElement("link");n.href=e,n.rel="stylesheet";var r=function(){t.cssLoaded++,t.cssLoaded===t.options.css.length&&(t.ui.wrapper.style.display="")};n.addEventListener("load",r),n.addEventListener("error",r),t.ui.shadowRoot.append(n)});else if("string"==typeof this.options.css){var e=document.createElement("style"),n=document.createTextNode(this.options.css);e.appendChild(n),this.ui.shadowRoot.append(e),this.ui.wrapper.style.display=""}else"function"==typeof this.options.css&&(this.options.css.call(this,this),this.ui.wrapper.style.display="")}},{key:"adjustPosition",value:function(t){var e=t.getBoundingClientRect(),n=this.ui.wrapper.getBoundingClientRect();this.ui.container.classList.add("calc");var r=this.ui.container.getBoundingClientRect();this.ui.container.classList.remove("calc");var i=e.bottom-n.bottom,A=e.left-n.left;return"undefined"!=typeof window&&(window.innerHeight=0&&(i=e.top-n.top-r.height),window.innerWidth=0&&(A=e.right-n.right-r.width)),{left:A,top:i}}}]),t}(),y=Object.freeze({__proto__:null,Core:v,create:v}),w=function(){function t(){(0,A._)(this,t),(0,s._)(this,"picker",void 0),(0,s._)(this,"options",void 0),(0,s._)(this,"priority",0),(0,s._)(this,"dependencies",[])}return(0,o._)(t,[{key:"attach",value:function(t){var e=this,n=this.getName(),r=(0,l._)({},this.options);this.options=(0,l._)({},this.options,t.options[n]||{});var i=!0,A=!1,o=void 0;try{for(var s,a=this,c=Object.keys(r)[Symbol.iterator]();!(i=(s=c.next()).done);i=!0)!function(){var e=s.value;if(null!==r[e]&&"object"==typeof r[e]&&Object.keys(r[e]).length&&n in t.options&&e in t.options[n]){var i=(0,l._)({},t.options[n][e]);null!==i&&"object"==typeof i&&Object.keys(i).length&&Object.keys(i).every(function(t){return Object.keys(r[e]).includes(t)})&&(a.options[e]=(0,l._)({},r[e],i))}}()}catch(t){A=!0,o=t}finally{try{i||null==c.return||c.return()}finally{if(A)throw o}}if(this.picker=t,this.dependenciesNotFound()){var u=this.dependencies.filter(function(t){return!e.pluginsAsStringArray().includes(t)});return void console.warn("".concat(this.getName(),": required dependencies (").concat(u.join(", "),")."))}var h=this.camelCaseToKebab(this.getName());this.picker.ui.container.classList.add(h),this.onAttach()}},{key:"detach",value:function(){var t=this.camelCaseToKebab(this.getName());this.picker.ui.container.classList.remove(t),"function"==typeof this.onDetach&&this.onDetach()}},{key:"dependenciesNotFound",value:function(){var t=this;return this.dependencies.length&&!this.dependencies.every(function(e){return t.pluginsAsStringArray().includes(e)})}},{key:"pluginsAsStringArray",value:function(){return this.picker.options.plugins.map(function(t){return"function"==typeof t?(new t).getName():t})}},{key:"camelCaseToKebab",value:function(t){return t.replace(/([a-zA-Z])(?=[A-Z])/g,"$1-").toLowerCase()}}]),t}(),b=function(t){(0,a._)(n,t);var e=(0,f._)(n);function n(){var t;return(0,A._)(this,n),t=e.apply(this,arguments),(0,s._)((0,i._)(t),"priority",1),(0,s._)((0,i._)(t),"binds",{onView:t.onView.bind((0,i._)(t))}),(0,s._)((0,i._)(t),"options",{minDate:null,maxDate:null,minDays:null,maxDays:null,selectForward:null,selectBackward:null,presets:!0,inseparable:!1,filter:null}),t}return(0,o._)(n,[{key:"getName",value:function(){return"LockPlugin"}},{key:"onAttach",value:function(){if(this.options.minDate&&(this.options.minDate=new p(this.options.minDate,this.picker.options.format,this.picker.options.lang)),this.options.maxDate&&(this.options.maxDate=new p(this.options.maxDate,this.picker.options.format,this.picker.options.lang),this.options.maxDate instanceof p&&this.picker.options.calendars>1&&this.picker.calendars[0].isSame(this.options.maxDate,"month"))){var t=this.picker.calendars[0].clone().subtract(1,"month");this.picker.gotoDate(t)}(this.options.minDays||this.options.maxDays||this.options.selectForward||this.options.selectBackward)&&!this.picker.options.plugins.includes("RangePlugin")&&console.warn("".concat(this.getName(),": options ").concat("minDays, maxDays, selectForward, selectBackward"," required RangePlugin.")),this.picker.on("view",this.binds.onView)}},{key:"onDetach",value:function(){this.picker.off("view",this.binds.onView)}},{key:"onView",value:function(t){var e=t.detail,n=e.view,r=e.target,i=e.date;if("CalendarHeader"===n&&(this.options.minDate instanceof p&&i.isSameOrBefore(this.options.minDate,"month")&&r.classList.add("no-previous-month"),this.options.maxDate instanceof p&&i.isSameOrAfter(this.options.maxDate,"month")&&r.classList.add("no-next-month")),"CalendarDay"===n){var A=this.picker.datePicked.length?this.picker.datePicked[0]:null;if(this.testFilter(i))return void r.classList.add("locked");if(this.options.inseparable){if(this.options.minDays){for(var o=i.clone().subtract(this.options.minDays-1,"day"),s=i.clone().add(this.options.minDays-1,"day"),a=!1,l=!1;o.isBefore(i,"day");){if(this.testFilter(o)){a=!0;break}o.add(1,"day")}for(;s.isAfter(i,"day");){if(this.testFilter(s)){l=!0;break}s.subtract(1,"day")}a&&l&&r.classList.add("not-available")}this.rangeIsNotAvailable(i,A)&&r.classList.add("not-available")}this.dateIsNotAvailable(i,A)&&r.classList.add("not-available")}if(this.options.presets&&"PresetPluginButton"===n){var c=new p(Number(r.dataset.start)),u=new p(Number(r.dataset.end)),h=u.diff(c,"day"),d=this.options.minDays&&hthis.options.maxDays;(d||f||this.lockMinDate(c)||this.lockMaxDate(c)||this.lockMinDate(u)||this.lockMaxDate(u)||this.rangeIsNotAvailable(c,u))&&r.setAttribute("disabled","disabled")}}},{key:"dateIsNotAvailable",value:function(t,e){return this.lockMinDate(t)||this.lockMaxDate(t)||this.lockMinDays(t,e)||this.lockMaxDays(t,e)||this.lockSelectForward(t)||this.lockSelectBackward(t)}},{key:"rangeIsNotAvailable",value:function(t,e){if(!t||!e)return!1;for(var n=(t.isSameOrBefore(e,"day")?t:e).clone(),r=(e.isSameOrAfter(t,"day")?e:t).clone();n.isSameOrBefore(r,"day");){if(this.testFilter(n))return!0;n.add(1,"day")}return!1}},{key:"lockMinDate",value:function(t){return this.options.minDate instanceof p&&t.isBefore(this.options.minDate,"day")}},{key:"lockMaxDate",value:function(t){return this.options.maxDate instanceof p&&t.isAfter(this.options.maxDate,"day")}},{key:"lockMinDays",value:function(t,e){if(this.options.minDays&&e){var n=e.clone().subtract(this.options.minDays-1,"day"),r=e.clone().add(this.options.minDays-1,"day");return t.isBetween(n,r)}return!1}},{key:"lockMaxDays",value:function(t,e){if(this.options.maxDays&&e){var n=e.clone().subtract(this.options.maxDays,"day"),r=e.clone().add(this.options.maxDays,"day");return!t.isBetween(n,r)}return!1}},{key:"lockSelectForward",value:function(t){if(1===this.picker.datePicked.length&&this.options.selectForward){var e=this.picker.datePicked[0].clone();return t.isBefore(e,"day")}return!1}},{key:"lockSelectBackward",value:function(t){if(1===this.picker.datePicked.length&&this.options.selectBackward){var e=this.picker.datePicked[0].clone();return t.isAfter(e,"day")}return!1}},{key:"testFilter",value:function(t){return"function"==typeof this.options.filter&&this.options.filter(t,this.picker.datePicked)}}]),n}(w),B=function(t){(0,a._)(n,t);var e=(0,f._)(n);function n(){var t;return(0,A._)(this,n),t=e.apply(this,arguments),(0,s._)((0,i._)(t),"dependencies",["RangePlugin"]),(0,s._)((0,i._)(t),"binds",{onView:t.onView.bind((0,i._)(t)),onClick:t.onClick.bind((0,i._)(t))}),(0,s._)((0,i._)(t),"options",{customLabels:["Today","Yesterday","Last 7 Days","Last 30 Days","This Month","Last Month"],customPreset:{},position:"left"}),t}return(0,o._)(n,[{key:"getName",value:function(){return"PresetPlugin"}},{key:"onAttach",value:function(){var t=this;if(!Object.keys(this.options.customPreset).length){var e,n,r,i,A=new p,o=[[A.clone(),A.clone()],[A.clone().subtract(1,"day"),A.clone().subtract(1,"day")],[A.clone().subtract(6,"day"),A.clone()],[A.clone().subtract(29,"day"),A.clone()],((e=A.clone()).setDate(1),n=new Date(A.getFullYear(),A.getMonth()+1,0),[new p(e),new p(n)]),((r=A.clone()).setMonth(r.getMonth()-1),r.setDate(1),i=new Date(A.getFullYear(),A.getMonth(),0),[new p(r),new p(i)])];Object.values(this.options.customLabels).forEach(function(e,n){t.options.customPreset[e]=o[n]})}this.picker.on("view",this.binds.onView),this.picker.on("click",this.binds.onClick)}},{key:"onDetach",value:function(){this.picker.off("view",this.binds.onView),this.picker.off("click",this.binds.onClick)}},{key:"onView",value:function(t){var e=this,n=t.detail,r=n.view,i=n.target;if("Main"===r){var A=document.createElement("div");A.className="preset-plugin-container",Object.keys(this.options.customPreset).forEach(function(t){if(Object.prototype.hasOwnProperty.call(e.options.customPreset,t)){var n=e.options.customPreset[t],r=document.createElement("button");r.className="preset-button unit",r.innerHTML=t,r.dataset.start=n[0].getTime(),r.dataset.end=n[1].getTime(),A.appendChild(r),e.picker.trigger("view",{view:"PresetPluginButton",target:r})}}),i.appendChild(A),i.classList.add("preset-".concat(this.options.position)),this.picker.trigger("view",{view:"PresetPluginContainer",target:A})}}},{key:"onClick",value:function(t){var e=t.target;if(e instanceof HTMLElement){var n=e.closest(".unit");if(!(n instanceof HTMLElement))return;if(this.isPresetButton(n)){var r=new p(Number(n.dataset.start)),i=new p(Number(n.dataset.end));this.picker.options.autoApply?(this.picker.setDateRange(r,i),this.picker.trigger("select",{start:this.picker.getStartDate(),end:this.picker.getEndDate()}),this.picker.hide()):(this.picker.datePicked=[r,i],this.picker.renderAll())}}}},{key:"isPresetButton",value:function(t){return t.classList.contains("preset-button")}}]),n}(w),_=function(t){(0,a._)(n,t);var e=(0,f._)(n);function n(){var t;return(0,A._)(this,n),t=e.apply(this,arguments),(0,s._)((0,i._)(t),"tooltipElement",void 0),(0,s._)((0,i._)(t),"triggerElement",void 0),(0,s._)((0,i._)(t),"binds",{setStartDate:t.setStartDate.bind((0,i._)(t)),setEndDate:t.setEndDate.bind((0,i._)(t)),setDateRange:t.setDateRange.bind((0,i._)(t)),getStartDate:t.getStartDate.bind((0,i._)(t)),getEndDate:t.getEndDate.bind((0,i._)(t)),onView:t.onView.bind((0,i._)(t)),onShow:t.onShow.bind((0,i._)(t)),onMouseEnter:t.onMouseEnter.bind((0,i._)(t)),onMouseLeave:t.onMouseLeave.bind((0,i._)(t)),onClickCalendarDay:t.onClickCalendarDay.bind((0,i._)(t)),onClickApplyButton:t.onClickApplyButton.bind((0,i._)(t)),parseValues:t.parseValues.bind((0,i._)(t)),updateValues:t.updateValues.bind((0,i._)(t)),clear:t.clear.bind((0,i._)(t))}),(0,s._)((0,i._)(t),"options",{elementEnd:null,startDate:null,endDate:null,repick:!1,strict:!0,delimiter:" - ",tooltip:!0,tooltipNumber:function(t){return t},locale:{zero:"",one:"day",two:"",few:"",many:"",other:"days"},documentClick:t.hidePicker.bind((0,i._)(t))}),t}return(0,o._)(n,[{key:"getName",value:function(){return"RangePlugin"}},{key:"onAttach",value:function(){this.binds._setStartDate=this.picker.setStartDate,this.binds._setEndDate=this.picker.setEndDate,this.binds._setDateRange=this.picker.setDateRange,this.binds._getStartDate=this.picker.getStartDate,this.binds._getEndDate=this.picker.getEndDate,this.binds._parseValues=this.picker.parseValues,this.binds._updateValues=this.picker.updateValues,this.binds._clear=this.picker.clear,this.binds._onClickCalendarDay=this.picker.onClickCalendarDay,this.binds._onClickApplyButton=this.picker.onClickApplyButton,Object.defineProperties(this.picker,{setStartDate:{configurable:!0,value:this.binds.setStartDate},setEndDate:{configurable:!0,value:this.binds.setEndDate},setDateRange:{configurable:!0,value:this.binds.setDateRange},getStartDate:{configurable:!0,value:this.binds.getStartDate},getEndDate:{configurable:!0,value:this.binds.getEndDate},parseValues:{configurable:!0,value:this.binds.parseValues},updateValues:{configurable:!0,value:this.binds.updateValues},clear:{configurable:!0,value:this.binds.clear},onClickCalendarDay:{configurable:!0,value:this.binds.onClickCalendarDay},onClickApplyButton:{configurable:!0,value:this.binds.onClickApplyButton}}),this.options.elementEnd&&(this.options.elementEnd instanceof HTMLElement||(this.options.elementEnd=this.picker.options.doc.querySelector(this.options.elementEnd)),this.options.elementEnd instanceof HTMLInputElement&&(this.options.elementEnd.readOnly=this.picker.options.readonly),"function"==typeof this.picker.options.documentClick&&(document.removeEventListener("click",this.picker.options.documentClick,!0),"function"==typeof this.options.documentClick&&document.addEventListener("click",this.options.documentClick,!0)),this.options.elementEnd.addEventListener("click",this.picker.show.bind(this.picker))),this.options.repick=this.options.repick&&this.options.elementEnd instanceof HTMLElement,this.picker.options.date=null,this.picker.on("view",this.binds.onView),this.picker.on("show",this.binds.onShow),this.picker.on("mouseenter",this.binds.onMouseEnter,!0),this.picker.on("mouseleave",this.binds.onMouseLeave,!0),this.checkIntlPluralLocales()}},{key:"onDetach",value:function(){Object.defineProperties(this.picker,{setStartDate:{configurable:!0,value:this.binds._setStartDate},setEndDate:{configurable:!0,value:this.binds._setEndDate},setDateRange:{configurable:!0,value:this.binds._setDateRange},getStartDate:{configurable:!0,value:this.binds._getStartDate},getEndDate:{configurable:!0,value:this.binds._getEndDate},parseValues:{configurable:!0,value:this.binds._parseValues},updateValues:{configurable:!0,value:this.binds._updateValues},clear:{configurable:!0,value:this.binds._clear},onClickCalendarDay:{configurable:!0,value:this.binds._onClickCalendarDay},onClickApplyButton:{configurable:!0,value:this.binds._onClickApplyButton}}),this.picker.off("view",this.binds.onView),this.picker.off("show",this.binds.onShow),this.picker.off("mouseenter",this.binds.onMouseEnter,!0),this.picker.off("mouseleave",this.binds.onMouseLeave,!0)}},{key:"parseValues",value:function(){if(this.options.startDate||this.options.endDate)this.options.strict?this.options.startDate&&this.options.endDate?this.setDateRange(this.options.startDate,this.options.endDate):(this.options.startDate=null,this.options.endDate=null):(this.options.startDate&&this.setStartDate(this.options.startDate),this.options.endDate&&this.setEndDate(this.options.endDate));else if(this.options.elementEnd)this.options.strict?this.picker.options.element instanceof HTMLInputElement&&this.picker.options.element.value.length&&this.options.elementEnd instanceof HTMLInputElement&&this.options.elementEnd.value.length&&this.setDateRange(this.picker.options.element.value,this.options.elementEnd.value):(this.picker.options.element instanceof HTMLInputElement&&this.picker.options.element.value.length&&this.setStartDate(this.picker.options.element.value),this.options.elementEnd instanceof HTMLInputElement&&this.options.elementEnd.value.length&&this.setEndDate(this.options.elementEnd.value));else if(this.picker.options.element instanceof HTMLInputElement&&this.picker.options.element.value.length){var t=(0,u._)(this.picker.options.element.value.split(this.options.delimiter),2),e=t[0],n=t[1];this.options.strict?e&&n&&this.setDateRange(e,n):(e&&this.setStartDate(e),n&&this.setEndDate(n))}}},{key:"updateValues",value:function(){var t=this.picker.options.element,e=this.options.elementEnd,n=this.picker.getStartDate(),r=this.picker.getEndDate(),i=n instanceof Date?n.format(this.picker.options.format,this.picker.options.lang):"",A=r instanceof Date?r.format(this.picker.options.format,this.picker.options.lang):"";if(e)t instanceof HTMLInputElement?t.value=i:t instanceof HTMLElement&&(t.innerText=i),e instanceof HTMLInputElement?e.value=A:e instanceof HTMLElement&&(e.innerText=A);else{var o="".concat(i).concat(i||A?this.options.delimiter:"").concat(A);t instanceof HTMLInputElement?t.value=o:t instanceof HTMLElement&&(t.innerText=o)}}},{key:"clear",value:function(){this.options.startDate=null,this.options.endDate=null,this.picker.datePicked.length=0,this.updateValues(),this.picker.renderAll(),this.picker.trigger("clear")}},{key:"onShow",value:function(t){var e=t.detail.target;this.triggerElement=e,this.picker.options.scrollToDate&&this.getStartDate() instanceof Date&&this.picker.gotoDate(this.getStartDate()),this.initializeRepick()}},{key:"onView",value:function(t){var e=t.detail,n=e.view,r=e.target;if("Main"===n&&(this.tooltipElement=document.createElement("span"),this.tooltipElement.className="range-plugin-tooltip",r.appendChild(this.tooltipElement)),"CalendarDay"===n){var i=new p(r.dataset.time),A=this.picker.datePicked,o=A.length?this.picker.datePicked[0]:this.getStartDate(),s=A.length?this.picker.datePicked[1]:this.getEndDate();o&&o.isSame(i,"day")&&r.classList.add("start"),o&&s&&(s.isSame(i,"day")&&r.classList.add("end"),i.isBetween(o,s)&&r.classList.add("in-range"))}if("Footer"===n){var a=1===this.picker.datePicked.length&&!this.options.strict||2===this.picker.datePicked.length;r.querySelector(".apply-button").disabled=!a}}},{key:"hidePicker",value:function(t){var e=t.target,n=null;e.shadowRoot&&(n=(e=t.composedPath()[0]).getRootNode().host),this.picker.isShown()&&n!==this.picker.ui.wrapper&&e!==this.picker.options.element&&e!==this.options.elementEnd&&this.picker.hide()}},{key:"setStartDate",value:function(t){var e=new p(t,this.picker.options.format);this.options.startDate=e?e.clone():null,this.updateValues(),this.picker.renderAll()}},{key:"setEndDate",value:function(t){var e=new p(t,this.picker.options.format);this.options.endDate=e?e.clone():null,this.updateValues(),this.picker.renderAll()}},{key:"setDateRange",value:function(t,e){var n=new p(t,this.picker.options.format),r=new p(e,this.picker.options.format);this.options.startDate=n?n.clone():null,this.options.endDate=r?r.clone():null,this.updateValues(),this.picker.renderAll()}},{key:"getStartDate",value:function(){return this.options.startDate instanceof Date?this.options.startDate.clone():null}},{key:"getEndDate",value:function(){return this.options.endDate instanceof Date?this.options.endDate.clone():null}},{key:"onMouseEnter",value:function(t){var e=this,n=t.target;if(n instanceof HTMLElement){this.isContainer(n)&&this.initializeRepick();var r=n.closest(".unit");if(!(r instanceof HTMLElement))return;if(this.picker.isCalendarDay(r)){if(1!==this.picker.datePicked.length)return;var i=this.picker.datePicked[0].clone(),A=new p(r.dataset.time),o=!1;if(i.isAfter(A,"day")){var s=i.clone();i=A.clone(),A=s.clone(),o=!0}if((0,h._)(this.picker.ui.container.querySelectorAll(".day")).forEach(function(t){var n=new p(t.dataset.time),s=e.picker.Calendar.getCalendarDayView(n);n.isBetween(i,A)&&s.classList.add("in-range"),n.isSame(e.picker.datePicked[0],"day")&&(s.classList.add("start"),s.classList.toggle("flipped",o)),t===r&&(s.classList.add("end"),s.classList.toggle("flipped",o)),t.className=s.className}),this.options.tooltip){var a=this.options.tooltipNumber(A.diff(i,"day")+1);if(a>0){var l=new Intl.PluralRules(this.picker.options.lang).select(a),c="".concat(a," ").concat(this.options.locale[l]);this.showTooltip(r,c)}else this.hideTooltip()}}}}},{key:"onMouseLeave",value:function(t){if(this.isContainer(t.target)&&this.options.repick){var e=this.getStartDate(),n=this.getEndDate();e&&n&&(this.picker.datePicked.length=0,this.picker.renderAll())}}},{key:"onClickCalendarDay",value:function(t){if(this.picker.isCalendarDay(t)){2===this.picker.datePicked.length&&(this.picker.datePicked.length=0);var e=new p(t.dataset.time);if(this.picker.datePicked[this.picker.datePicked.length]=e,2===this.picker.datePicked.length&&this.picker.datePicked[0].isAfter(this.picker.datePicked[1])){var n=this.picker.datePicked[1].clone();this.picker.datePicked[1]=this.picker.datePicked[0].clone(),this.picker.datePicked[0]=n.clone()}1!==this.picker.datePicked.length&&this.picker.options.autoApply||this.picker.trigger("preselect",{start:this.picker.datePicked[0]instanceof Date?this.picker.datePicked[0].clone():null,end:this.picker.datePicked[1]instanceof Date?this.picker.datePicked[1].clone():null}),1===this.picker.datePicked.length&&(!this.options.strict&&this.picker.options.autoApply&&(this.picker.options.element===this.triggerElement&&this.setStartDate(this.picker.datePicked[0]),this.options.elementEnd===this.triggerElement&&this.setEndDate(this.picker.datePicked[0]),this.picker.trigger("select",{start:this.picker.getStartDate(),end:this.picker.getEndDate()})),this.picker.renderAll()),2===this.picker.datePicked.length&&(this.picker.options.autoApply?(this.setDateRange(this.picker.datePicked[0],this.picker.datePicked[1]),this.picker.trigger("select",{start:this.picker.getStartDate(),end:this.picker.getEndDate()}),this.picker.hide()):(this.hideTooltip(),this.picker.renderAll()))}}},{key:"onClickApplyButton",value:function(t){this.picker.isApplyButton(t)&&(1!==this.picker.datePicked.length||this.options.strict||(this.picker.options.element===this.triggerElement&&(this.options.endDate=null,this.setStartDate(this.picker.datePicked[0])),this.options.elementEnd===this.triggerElement&&(this.options.startDate=null,this.setEndDate(this.picker.datePicked[0]))),2===this.picker.datePicked.length&&this.setDateRange(this.picker.datePicked[0],this.picker.datePicked[1]),this.picker.trigger("select",{start:this.picker.getStartDate(),end:this.picker.getEndDate()}),this.picker.hide())}},{key:"showTooltip",value:function(t,e){this.tooltipElement.style.visibility="visible",this.tooltipElement.innerHTML=e;var n=this.picker.ui.container.getBoundingClientRect(),r=this.tooltipElement.getBoundingClientRect(),i=t.getBoundingClientRect(),A=i.top,o=i.left;A-=n.top,o-=n.left,A-=r.height,o-=r.width/2,o+=i.width/2,this.tooltipElement.style.top="".concat(A,"px"),this.tooltipElement.style.left="".concat(o,"px")}},{key:"hideTooltip",value:function(){this.tooltipElement.style.visibility="hidden"}},{key:"checkIntlPluralLocales",value:function(){if(this.options.tooltip){var t=(0,h._)(new Set([new Intl.PluralRules(this.picker.options.lang).select(0),new Intl.PluralRules(this.picker.options.lang).select(1),new Intl.PluralRules(this.picker.options.lang).select(2),new Intl.PluralRules(this.picker.options.lang).select(6),new Intl.PluralRules(this.picker.options.lang).select(18)])),e=Object.keys(this.options.locale);t.every(function(t){return e.includes(t)})||console.warn("".concat(this.getName(),": provide locales (").concat(t.join(", "),") for correct tooltip text."))}}},{key:"initializeRepick",value:function(){if(this.options.repick){var t=this.getStartDate(),e=this.getEndDate();e&&this.triggerElement===this.picker.options.element&&(this.picker.datePicked[0]=e),t&&this.triggerElement===this.options.elementEnd&&(this.picker.datePicked[0]=t)}}},{key:"isContainer",value:function(t){return t===this.picker.ui.container}}]),n}(w),C=function(t){(0,a._)(n,t);var e=(0,f._)(n);function n(){var t;return(0,A._)(this,n),t=e.apply(this,arguments),(0,s._)((0,i._)(t),"options",{native:!1,seconds:!1,stepHours:1,stepMinutes:5,stepSeconds:5,format12:!1}),(0,s._)((0,i._)(t),"rangePlugin",void 0),(0,s._)((0,i._)(t),"timePicked",{input:null,start:null,end:null}),(0,s._)((0,i._)(t),"timePrePicked",{input:null,start:null,end:null}),(0,s._)((0,i._)(t),"binds",{getDate:t.getDate.bind((0,i._)(t)),getStartDate:t.getStartDate.bind((0,i._)(t)),getEndDate:t.getEndDate.bind((0,i._)(t)),onView:t.onView.bind((0,i._)(t)),onInput:t.onInput.bind((0,i._)(t)),onChange:t.onChange.bind((0,i._)(t)),onClick:t.onClick.bind((0,i._)(t)),setTime:t.setTime.bind((0,i._)(t)),setStartTime:t.setStartTime.bind((0,i._)(t)),setEndTime:t.setEndTime.bind((0,i._)(t))}),t}return(0,o._)(n,[{key:"getName",value:function(){return"TimePlugin"}},{key:"onAttach",value:function(){this.binds._getDate=this.picker.getDate,this.binds._getStartDate=this.picker.getStartDate,this.binds._getEndDate=this.picker.getEndDate,Object.defineProperties(this.picker,{getDate:{configurable:!0,value:this.binds.getDate},getStartDate:{configurable:!0,value:this.binds.getStartDate},getEndDate:{configurable:!0,value:this.binds.getEndDate},setTime:{configurable:!0,value:this.binds.setTime},setStartTime:{configurable:!0,value:this.binds.setStartTime},setEndTime:{configurable:!0,value:this.binds.setEndTime}}),this.rangePlugin=this.picker.PluginManager.getInstance("RangePlugin"),this.parseValues(),this.picker.on("view",this.binds.onView),this.picker.on("input",this.binds.onInput),this.picker.on("change",this.binds.onChange),this.picker.on("click",this.binds.onClick)}},{key:"onDetach",value:function(){delete this.picker.setTime,delete this.picker.setStartTime,delete this.picker.setEndTime,Object.defineProperties(this.picker,{getDate:{configurable:!0,value:this.binds._getDate},getStartDate:{configurable:!0,value:this.binds._getStartDate},getEndDate:{configurable:!0,value:this.binds._getEndDate}}),this.picker.off("view",this.binds.onView),this.picker.off("input",this.binds.onInput),this.picker.off("change",this.binds.onChange),this.picker.off("click",this.binds.onClick)}},{key:"onView",value:function(t){var e=t.detail,n=e.view,r=e.target;if("Main"===n){this.rangePlugin=this.picker.PluginManager.getInstance("RangePlugin");var i=document.createElement("div");if(i.className="time-plugin-container",this.rangePlugin){var A=this.getStartInput();i.appendChild(A),this.picker.trigger("view",{view:"TimePluginInput",target:A});var o=this.getEndInput();i.appendChild(o),this.picker.trigger("view",{view:"TimePluginInput",target:o})}else{var s=this.getSingleInput();i.appendChild(s),this.picker.trigger("view",{view:"TimePluginInput",target:s})}r.appendChild(i),this.picker.trigger("view",{view:"TimePluginContainer",target:i})}}},{key:"onInput",value:function(t){var e=t.target;if(e instanceof HTMLInputElement&&e.classList.contains("time-plugin-input")){var n=this.timePicked[e.name]||new p,r=(0,u._)(e.value.split(":"),2),i=r[0],A=r[1];n.setHours(Number(i)||0,Number(A)||0,0,0),this.picker.options.autoApply?(this.timePicked[e.name]=n,this.picker.updateValues()):this.timePrePicked[e.name]=n}}},{key:"onChange",value:function(t){var e=t.target;if(e instanceof HTMLSelectElement&&e.classList.contains("time-plugin-custom-input")){var n=(0,u._)(e.name.match(/(\w+)\[(\w+)\]/),3),r=n[1],i=n[2],A=Number(e.value),o=new p;switch(!this.picker.options.autoApply&&this.timePrePicked[r]instanceof Date?o=this.timePrePicked[r].clone():this.timePicked[r]instanceof Date&&(o=this.timePicked[r].clone()),i){case"HH":if(this.options.format12){var s=e.closest(".time-plugin-custom-block").querySelector('select[name="'.concat(r,'[period]"]')).value,a=this.handleFormat12(s,o,A);o.setHours(a.getHours(),a.getMinutes(),a.getSeconds(),0)}else o.setHours(A,o.getMinutes(),o.getSeconds(),0);break;case"mm":o.setHours(o.getHours(),A,o.getSeconds(),0);break;case"ss":o.setHours(o.getHours(),o.getMinutes(),A,0);break;case"period":if(this.options.format12){var l=e.closest(".time-plugin-custom-block").querySelector('select[name="'.concat(r,'[HH]"]')).value,c=this.handleFormat12(e.value,o,Number(l));o.setHours(c.getHours(),c.getMinutes(),c.getSeconds(),0)}}if(this.picker.options.autoApply)this.timePicked[r]=o,this.picker.updateValues();else{this.timePrePicked[r]=o;var h=this.picker.ui.container.querySelector(".apply-button");if(this.rangePlugin){var d=this.rangePlugin.options,f=this.picker.datePicked,g=d.strict&&2===f.length||!d.strict&&f.length>0||!f.length&&d.strict&&d.startDate instanceof Date&&d.endDate instanceof Date||!f.length&&!d.strict&&(d.startDate instanceof Date||d.endDate instanceof Date);h.disabled=!g}else this.picker.datePicked.length&&(h.disabled=!1)}}}},{key:"onClick",value:function(t){var e=this,n=t.target;if(n instanceof HTMLElement){var r=n.closest(".unit");if(!(r instanceof HTMLElement))return;this.picker.isApplyButton(r)&&(Object.keys(this.timePicked).forEach(function(t){e.timePrePicked[t]instanceof Date&&(e.timePicked[t]=e.timePrePicked[t].clone())}),this.picker.updateValues(),this.timePrePicked={input:null,start:null,end:null}),this.picker.isCancelButton(r)&&(this.timePrePicked={input:null,start:null,end:null},this.picker.renderAll())}}},{key:"setTime",value:function(t){var e=this.handleTimeString(t);this.timePicked.input=e.clone(),this.picker.renderAll(),this.picker.updateValues()}},{key:"setStartTime",value:function(t){var e=this.handleTimeString(t);this.timePicked.start=e.clone(),this.picker.renderAll(),this.picker.updateValues()}},{key:"setEndTime",value:function(t){var e=this.handleTimeString(t);this.timePicked.end=e.clone(),this.picker.renderAll(),this.picker.updateValues()}},{key:"handleTimeString",value:function(t){var e=new p,n=(0,u._)(t.split(":").map(function(t){return Number(t)}),3),r=n[0],i=n[1],A=n[2],o=r&&!Number.isNaN(r)?r:0,s=i&&!Number.isNaN(i)?i:0,a=A&&!Number.isNaN(A)?A:0;return e.setHours(o,s,a,0),e}},{key:"getDate",value:function(){if(this.picker.options.date instanceof Date){var t=new p(this.picker.options.date,this.picker.options.format);if(this.timePicked.input instanceof Date){var e=this.timePicked.input;t.setHours(e.getHours(),e.getMinutes(),e.getSeconds(),0)}return t}return null}},{key:"getStartDate",value:function(){if(this.rangePlugin.options.startDate instanceof Date){var t=new p(this.rangePlugin.options.startDate,this.picker.options.format);if(this.timePicked.start instanceof Date){var e=this.timePicked.start;t.setHours(e.getHours(),e.getMinutes(),e.getSeconds(),0)}return t}return null}},{key:"getEndDate",value:function(){if(this.rangePlugin.options.endDate instanceof Date){var t=new p(this.rangePlugin.options.endDate,this.picker.options.format);if(this.timePicked.end instanceof Date){var e=this.timePicked.end;t.setHours(e.getHours(),e.getMinutes(),e.getSeconds(),0)}return t}return null}},{key:"getSingleInput",value:function(){return this.options.native?this.getNativeInput("input"):this.getCustomInput("input")}},{key:"getStartInput",value:function(){return this.options.native?this.getNativeInput("start"):this.getCustomInput("start")}},{key:"getEndInput",value:function(){return this.options.native?this.getNativeInput("end"):this.getCustomInput("end")}},{key:"getNativeInput",value:function(t){var e=document.createElement("input");e.type="time",e.name=t,e.className="time-plugin-input unit";var n=this.timePicked[t];if(n){var r="0".concat(n.getHours()).slice(-2),i="0".concat(n.getMinutes()).slice(-2);e.value="".concat(r,":").concat(i)}return e}},{key:"getCustomInput",value:function(t){var e=document.createElement("div");e.className="time-plugin-custom-block";var n=document.createElement("select");n.className="time-plugin-custom-input unit",n.name="".concat(t,"[HH]");var r=this.options.format12?1:0,i=this.options.format12?13:24,A=null;!this.picker.options.autoApply&&this.timePrePicked[t]instanceof Date?A=this.timePrePicked[t].clone():this.timePicked[t]instanceof Date&&(A=this.timePicked[t].clone());for(var o=r;o=12&&(e.selected=!0),f.appendChild(e)}),e.appendChild(f)}return e}},{key:"handleFormat12",value:function(t,e,n){var r=e.clone();switch(t){case"AM":12===n?r.setHours(0,r.getMinutes(),r.getSeconds(),0):r.setHours(n,r.getMinutes(),r.getSeconds(),0);break;case"PM":12!==n?r.setHours(n+12,r.getMinutes(),r.getSeconds(),0):r.setHours(n,r.getMinutes(),r.getSeconds(),0)}return r}},{key:"parseValues",value:function(){if(this.rangePlugin){if(this.rangePlugin.options.strict){if(this.rangePlugin.options.startDate&&this.rangePlugin.options.endDate){var t=new p(this.rangePlugin.options.startDate,this.picker.options.format),e=new p(this.rangePlugin.options.endDate,this.picker.options.format);this.timePicked.start=t.clone(),this.timePicked.end=e.clone()}}else{if(this.rangePlugin.options.startDate){var n=new p(this.rangePlugin.options.startDate,this.picker.options.format);this.timePicked.start=n.clone()}if(this.rangePlugin.options.endDate){var r=new p(this.rangePlugin.options.endDate,this.picker.options.format);this.timePicked.end=r.clone()}}if(this.rangePlugin.options.elementEnd){if(this.rangePlugin.options.strict){if(this.picker.options.element instanceof HTMLInputElement&&this.picker.options.element.value.length&&this.rangePlugin.options.elementEnd instanceof HTMLInputElement&&this.rangePlugin.options.elementEnd.value.length){var i=new p(this.picker.options.element.value,this.picker.options.format),A=new p(this.rangePlugin.options.elementEnd.value,this.picker.options.format);this.timePicked.start=i.clone(),this.timePicked.end=A.clone()}}else{if(this.picker.options.element instanceof HTMLInputElement&&this.picker.options.element.value.length){var o=new p(this.picker.options.element.value,this.picker.options.format);this.timePicked.start=o.clone()}if(this.rangePlugin.options.elementEnd instanceof HTMLInputElement&&this.rangePlugin.options.elementEnd.value.length){var s=new p(this.rangePlugin.options.elementEnd.value,this.picker.options.format);this.timePicked.start=s.clone()}}}else if(this.picker.options.element instanceof HTMLInputElement&&this.picker.options.element.value.length){var a=(0,u._)(this.picker.options.element.value.split(this.rangePlugin.options.delimiter),2),l=a[0],c=a[1];if(this.rangePlugin.options.strict){if(l&&c){var h=new p(l,this.picker.options.format),d=new p(c,this.picker.options.format);this.timePicked.start=h.clone(),this.timePicked.end=d.clone()}}else{if(l){var f=new p(l,this.picker.options.format);this.timePicked.start=f.clone()}if(c){var g=new p(c,this.picker.options.format);this.timePicked.start=g.clone()}}}}else{if(this.picker.options.date){var m=new p(this.picker.options.date,this.picker.options.format);this.timePicked.input=m.clone()}if(this.picker.options.element instanceof HTMLInputElement&&this.picker.options.element.value.length){var v=new p(this.picker.options.element.value,this.picker.options.format);this.timePicked.input=v.clone()}}}}]),n}(w),x=function(t){(0,a._)(n,t);var e=(0,f._)(n);function n(){var t;return(0,A._)(this,n),t=e.apply(this,arguments),(0,s._)((0,i._)(t),"docElement",null),(0,s._)((0,i._)(t),"rangePlugin",void 0),(0,s._)((0,i._)(t),"binds",{onView:t.onView.bind((0,i._)(t)),onKeydown:t.onKeydown.bind((0,i._)(t))}),(0,s._)((0,i._)(t),"options",{unitIndex:1,dayIndex:2}),t}return(0,o._)(n,[{key:"getName",value:function(){return"KbdPlugin"}},{key:"onAttach",value:function(){var t=this,e=this.picker.options.element,n=e.getBoundingClientRect();if(this.docElement=document.createElement("span"),this.docElement.style.position="absolute",this.docElement.style.top="".concat(e.offsetTop,"px"),this.docElement.style.left=e.offsetLeft+n.width-25+"px",this.docElement.attachShadow({mode:"open"}),this.options.html)this.docElement.shadowRoot.innerHTML=this.options.html;else{var r="\n \n\n \n ");this.docElement.shadowRoot.innerHTML=r}var i=this.docElement.shadowRoot.querySelector("button");i&&(i.addEventListener("click",function(e){e.preventDefault(),t.picker.show({target:t.picker.options.element})},{capture:!0}),i.addEventListener("keydown",function(e){"Escape"===e.code&&t.picker.hide()},{capture:!0})),this.picker.options.element.after(this.docElement),this.picker.on("view",this.binds.onView),this.picker.on("keydown",this.binds.onKeydown)}},{key:"onDetach",value:function(){this.docElement&&this.docElement.isConnected&&this.docElement.remove(),this.picker.off("view",this.binds.onView),this.picker.off("keydown",this.binds.onKeydown)}},{key:"onView",value:function(t){var e=this,n=t.detail,r=n.view,i=n.target;i&&"querySelector"in i&&("CalendarDay"!==r||["locked","not-available"].some(function(t){return i.classList.contains(t)})?(0,h._)(i.querySelectorAll(".unit:not(.day)")).forEach(function(t){return t.tabIndex=e.options.unitIndex}):i.tabIndex=this.options.dayIndex)}},{key:"onKeydown",value:function(t){switch(this.onMouseEnter(t),t.code){case"ArrowUp":case"ArrowDown":this.verticalMove(t);break;case"ArrowLeft":case"ArrowRight":this.horizontalMove(t);break;case"Enter":case"Space":this.handleEnter(t);break;case"Escape":this.picker.hide()}}},{key:"findAllowableDaySibling",value:function(t,e,n){var r=this,i=Array.from(t.querySelectorAll('.day[tabindex="'.concat(this.options.dayIndex,'"]'))),A=i.indexOf(e);return i.filter(function(t,e){return n(e,A)&&t.tabIndex===r.options.dayIndex})[0]}},{key:"changeMonth",value:function(t){var e=this,n={ArrowLeft:"previous",ArrowRight:"next"},r=this.picker.ui.container.querySelector(".".concat(n[t.code],'-button[tabindex="').concat(this.options.unitIndex,'"]'));r&&!r.parentElement.classList.contains("no-".concat(n[t.code],"-month"))&&(r.dispatchEvent(new Event("click",{bubbles:!0})),setTimeout(function(){var n=null;switch(t.code){case"ArrowLeft":var r=e.picker.ui.container.querySelectorAll('.day[tabindex="'.concat(e.options.dayIndex,'"]'));n=r[r.length-1];break;case"ArrowRight":n=e.picker.ui.container.querySelector('.day[tabindex="'.concat(e.options.dayIndex,'"]'))}n&&n.focus()}))}},{key:"verticalMove",value:function(t){var e=t.target;if(e.classList.contains("day")){t.preventDefault();var n=this.findAllowableDaySibling(this.picker.ui.container,e,function(e,n){return e===("ArrowUp"===t.code?n-7:n+7)});n&&n.focus()}}},{key:"horizontalMove",value:function(t){var e=t.target;if(e.classList.contains("day")){t.preventDefault();var n=this.findAllowableDaySibling(this.picker.ui.container,e,function(e,n){return e===("ArrowLeft"===t.code?n-1:n+1)});n?n.focus():this.changeMonth(t)}}},{key:"handleEnter",value:function(t){var e=this,n=t.target;n.classList.contains("day")&&(t.preventDefault(),n.dispatchEvent(new Event("click",{bubbles:!0})),setTimeout(function(){if(e.rangePlugin=e.picker.PluginManager.getInstance("RangePlugin"),e.rangePlugin||!e.picker.options.autoApply){var t=e.picker.ui.container.querySelector(".day.selected");t&&setTimeout(function(){t.focus()})}}))}},{key:"onMouseEnter",value:function(t){var e=this;t.target.classList.contains("day")&&setTimeout(function(){var t=e.picker.ui.shadowRoot.activeElement;t&&t.dispatchEvent(new Event("mouseenter",{bubbles:!0}))})}}]),n}(w),k=function(t){(0,a._)(n,t);var e=(0,f._)(n);function n(){var t;return(0,A._)(this,n),t=e.apply(this,arguments),(0,s._)((0,i._)(t),"rangePlugin",void 0),(0,s._)((0,i._)(t),"lockPlugin",void 0),(0,s._)((0,i._)(t),"priority",10),(0,s._)((0,i._)(t),"binds",{onView:t.onView.bind((0,i._)(t)),onColorScheme:t.onColorScheme.bind((0,i._)(t))}),(0,s._)((0,i._)(t),"options",{dropdown:{months:!1,years:!1,minYear:1950,maxYear:null},darkMode:!0,locale:{resetButton:''}}),(0,s._)((0,i._)(t),"matchMedia",void 0),t}return(0,o._)(n,[{key:"getName",value:function(){return"AmpPlugin"}},{key:"onAttach",value:function(){this.options.darkMode&&window&&"matchMedia"in window&&(this.matchMedia=window.matchMedia("(prefers-color-scheme: dark)"),this.matchMedia.matches&&(this.picker.ui.container.dataset.theme="dark"),this.matchMedia.addEventListener("change",this.binds.onColorScheme)),this.options.weekNumbers&&this.picker.ui.container.classList.add("week-numbers"),this.picker.on("view",this.binds.onView)}},{key:"onDetach",value:function(){this.options.darkMode&&window&&"matchMedia"in window&&this.matchMedia.removeEventListener("change",this.binds.onColorScheme),this.picker.ui.container.removeAttribute("data-theme"),this.picker.ui.container.classList.remove("week-numbers"),this.picker.off("view",this.binds.onView)}},{key:"onView",value:function(t){this.lockPlugin=this.picker.PluginManager.getInstance("LockPlugin"),this.rangePlugin=this.picker.PluginManager.getInstance("RangePlugin"),this.handleDropdown(t),this.handleResetButton(t),this.handleWeekNumbers(t)}},{key:"onColorScheme",value:function(t){var e=t.matches?"dark":"light";this.picker.ui.container.dataset.theme=e}},{key:"handleDropdown",value:function(t){var e=this,n=t.detail,r=n.view,i=n.target,A=n.date;if(n.index,"CalendarHeader"===r){var o=i.querySelector(".month-name");if(this.options.dropdown.months){o.childNodes[0].remove();var s=document.createElement("select");s.className="month-name--select month-name--dropdown";for(var a=0;a<12;a+=1){var l=document.createElement("option"),c=new p(new Date(A.getFullYear(),a,2,0,0,0)),u=new p(new Date(A.getFullYear(),a,1,0,0,0));l.value=String(a),l.text=c.toLocaleString(this.picker.options.lang,{month:"long"}),this.lockPlugin&&(l.disabled=this.lockPlugin.options.minDate&&u.isBefore(new p(this.lockPlugin.options.minDate),"month")||this.lockPlugin.options.maxDate&&u.isAfter(new p(this.lockPlugin.options.maxDate),"month")),l.selected=u.getMonth()===A.getMonth(),s.appendChild(l)}s.addEventListener("change",function(t){var n=t.target;e.picker.calendars[0].setDate(1),e.picker.calendars[0].setMonth(Number(n.value)),e.picker.renderAll()}),o.prepend(s)}if(this.options.dropdown.years){o.childNodes[1].remove();var h=document.createElement("select");h.className="month-name--select";var d=this.options.dropdown.minYear,f=this.options.dropdown.maxYear?this.options.dropdown.maxYear:(new Date).getFullYear();if(A.getFullYear()>f){var g=document.createElement("option");g.value=String(A.getFullYear()),g.text=String(A.getFullYear()),g.selected=!0,g.disabled=!0,h.appendChild(g)}for(var m=f;m>=d;m-=1){var v=document.createElement("option"),y=new p(new Date(m,0,1,0,0,0));v.value=String(m),v.text=String(m),this.lockPlugin&&(v.disabled=this.lockPlugin.options.minDate&&y.isBefore(new p(this.lockPlugin.options.minDate),"year")||this.lockPlugin.options.maxDate&&y.isAfter(new p(this.lockPlugin.options.maxDate),"year")),v.selected=A.getFullYear()===m,h.appendChild(v)}if(A.getFullYear()0?t.createInitialFilters():t.addCondition()}),(0,s._)((0,i._)(t),"maybeClose",function(e){var n=t.modalTarget.classList.contains("show"),r=t.element.contains(e.target);n&&!r&&t.closeModal()}),t}return(0,o._)(n,[{key:"connect",value:function(){document.addEventListener("click",this.maybeClose),document.addEventListener("iawp:filtersChanged",this.updateFilters),document.addEventListener("iawp:fetchingReport",this.onFetchingReport),this.filtersValue.length>0?(this.createInitialFilters(),this.setResetEnabled(!0)):this.addCondition()}},{key:"disconnect",value:function(){document.removeEventListener("click",this.maybeClose),document.removeEventListener("iawp:filtersChanged",this.updateFilters),document.removeEventListener("iawp:fetchingReport",this.onFetchingReport)}},{key:"createInitialFilters",value:function(){var t=this;this.filtersValue.forEach(function(e){var n=t.blueprintTarget.content.cloneNode(!0);t.filtersTarget.appendChild(n);var r=t.filtersTarget.lastElementChild,i=t.inclusionTargets.find(function(t){return r.contains(t)}),A=t.columnTargets.find(function(t){return r.contains(t)});i.value=e.inclusion,A.value=e.column;var o=A.options[A.selectedIndex].dataset.type;t.operatorTargets.filter(function(t){return r.contains(t)}).forEach(function(t){var n=t.dataset.type===o;t.classList.toggle("show",n),n&&(t.value=e.operator)}),t.operandTargets.filter(function(t){return r.contains(t)}).forEach(function(n){var r=n.dataset.column===A.value;n.classList.toggle("show",r),r&&(n.value=e.operand,setTimeout(function(){var r=t.application.getControllerForElementAndIdentifier(n,"easepick");if(r){var i=new u.DateTime(1e3*e.operand);n.easepick.setDate(i),n.easepick.gotoDate(i),r.unixTimestampValue=e.operand}},0))})})}},{key:"toggleModal",value:function(t){t.preventDefault(),this.modalTarget.classList.contains("show")?this.closeModal():this.openModal()}},{key:"openModal",value:function(){this.modalTarget.classList.add("show"),this.modalButtonTarget.classList.add("open"),document.getElementById("iawp-layout").classList.add("modal-open")}},{key:"closeModal",value:function(){this.modalTarget.classList.remove("show"),this.modalButtonTarget.classList.remove("open"),document.getElementById("iawp-layout").classList.remove("modal-open")}},{key:"addCondition",value:function(){this.filtersTarget.append(this.blueprintTarget.content.cloneNode(!0)),this.setResetEnabled(!0)}},{key:"removeCondition",value:function(t){t.stopPropagation(),this.conditionTargets.forEach(function(e){e.contains(t.target)&&e.remove()}),0===this.conditionTargets.length&&(this.addCondition(),document.dispatchEvent(new CustomEvent("iawp:changeFilters",{detail:{filters:[]}})),this.setResetEnabled(!1)),1===this.conditionTargets.length&&(this.setResetEnabled(!1),this.setCount(0)),0===this.conditionTargets.length&&this.addCondition(),this.appliedConditions>1&&this.apply()}},{key:"apply",value:function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.showLoadingOverlay,r=!1;if(this.conditionTargets.forEach(function(e){var n=t.columnTargets.find(function(t){return e.contains(t)}),i=t.operandTargets.find(function(t){return e.contains(t)&&t.classList.contains("show")});""===n.value&&(n.classList.add("error"),r=!0),i&&""===i.value&&(i.classList.add("error"),r=!0)}),!r){var i=this.conditionTargets.map(function(e){var n=t.inclusionTargets.find(function(t){return e.contains(t)}),r=t.columnTargets.find(function(t){return e.contains(t)}),i=t.operatorTargets.find(function(t){return e.contains(t)&&t.classList.contains("show")}),A=t.operandTargets.find(function(t){return e.contains(t)&&t.classList.contains("show")}),o={inclusion:n.value,column:r.value,operator:i.value,operand:A.value},s=t.application.getControllerForElementAndIdentifier(A,"easepick");return s&&(o.operand=s.unixTimestampValue.toString()),o});this.appliedConditions=i.length,this.setResetEnabled(!0),this.setCount(i.length),this.closeModal(),document.dispatchEvent(new CustomEvent("iawp:changeFilters",{detail:{filters:i,showLoadingOverlay:void 0===n||n}}))}}},{key:"reset",value:function(){this.conditionTargets.forEach(function(t){t.remove()}),this.addCondition(),this.setResetEnabled(!1),this.appliedConditions=0,this.setCount(0),this.closeModal(),document.dispatchEvent(new CustomEvent("iawp:changeFilters",{detail:{filters:[]}}))}},{key:"setCount",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;document.getElementById("toolbar").setAttribute("data-filter-count",t)}},{key:"setResetEnabled",value:function(){var t=!(arguments.length>0)||void 0===arguments[0]||arguments[0];t?this.resetTarget.removeAttribute("disabled"):this.resetTarget.setAttribute("disabled","disabled")}},{key:"columnSelect",value:function(t){var e=this.conditionTargets.find(function(e){return e.contains(t.target)}),n=t.target.value,r=t.target.options[t.target.selectedIndex].dataset.type;t.target.classList.remove("error"),this.operatorTargets.filter(function(t){return e.contains(t)}).forEach(function(t){var e=t.dataset.type===r;t.classList.toggle("show",e)}),this.operandTargets.filter(function(t){return e.contains(t)}).forEach(function(t){var e=t.dataset.column===n;t.classList.toggle("show",e)})}},{key:"operandChange",value:function(t){t.target.classList.remove("error")}},{key:"operandKeyDown",value:function(t){13===t.keyCode&&this.apply()}}]),n}(c.Controller);(0,s._)(h,"values",{filters:Array}),(0,s._)(h,"targets",["modal","modalButton","blueprint","filters","condition","reset","inclusion","column","operator","operand","conditionButtons","spinner"])},{"@swc/helpers/_/_assert_this_initialized":"atUI0","@swc/helpers/_/_class_call_check":"2HOGN","@swc/helpers/_/_create_class":"8oe8p","@swc/helpers/_/_define_property":"27c3O","@swc/helpers/_/_inherits":"7gHjg","@swc/helpers/_/_create_super":"a37Ru","@hotwired/stimulus":"crDvk","@easepick/bundle":"2FFGt","@parcel/transformer-js/src/esmodule-helpers.js":"kPSB8"}],eG4Fk:[function(t,e,n){var r=t("@parcel/transformer-js/src/esmodule-helpers.js");r.defineInteropFlag(n),r.export(n,"default",function(){return a});var i=t("@swc/helpers/_/_class_call_check"),A=t("@swc/helpers/_/_create_class"),o=t("@swc/helpers/_/_inherits"),s=t("@swc/helpers/_/_create_super"),a=function(t){(0,o._)(n,t);var e=(0,s._)(n);function n(){return(0,i._)(this,n),e.apply(this,arguments)}return(0,A._)(n,[{key:"changeGroup",value:function(t){var e=t.target.value;document.dispatchEvent(new CustomEvent("iawp:changeGroup",{detail:{group:e}}))}}]),n}(t("@hotwired/stimulus").Controller)},{"@swc/helpers/_/_class_call_check":"2HOGN","@swc/helpers/_/_create_class":"8oe8p","@swc/helpers/_/_inherits":"7gHjg","@swc/helpers/_/_create_super":"a37Ru","@hotwired/stimulus":"crDvk","@parcel/transformer-js/src/esmodule-helpers.js":"kPSB8"}],eFMyx:[function(t,e,n){var r=t("@parcel/transformer-js/src/esmodule-helpers.js");r.defineInteropFlag(n),r.export(n,"default",function(){return p});var i=t("@swc/helpers/_/_assert_this_initialized"),A=t("@swc/helpers/_/_async_to_generator"),o=t("@swc/helpers/_/_class_call_check"),s=t("@swc/helpers/_/_create_class"),a=t("@swc/helpers/_/_define_property"),l=t("@swc/helpers/_/_inherits"),c=t("@swc/helpers/_/_object_spread"),u=t("@swc/helpers/_/_object_spread_props"),h=t("@swc/helpers/_/_create_super"),d=t("@swc/helpers/_/_ts_generator"),f=t("@hotwired/stimulus");t("../download");var p=function(t){(0,l._)(n,t);var e=(0,h._)(n);function n(){var t;return(0,o._)(this,n),t=e.apply(this,arguments),(0,a._)((0,i._)(t),"fileData",null),t}return(0,s._)(n,[{key:"import",value:function(){var t=this;this.disableSubmissions(),this.submitButtonTarget.classList.add("sending");var e=(0,u._)((0,c._)({},iawpActions.import_reports),{json:JSON.stringify(this.fileData)});jQuery.post(ajaxurl,e,function(e){t.clearFileInput(),t.submitButtonTarget.classList.remove("sending"),t.submitButtonTarget.classList.add("sent"),setTimeout(function(){t.submitButtonTarget.classList.remove("sent"),window.location.reload()},1e3)}).fail(function(){})}},{key:"handleFileSelected",value:function(t){var e=this;return(0,A._)(function(){var n;return(0,d._)(this,function(r){switch(r.label){case 0:return[4,t.target.files[0].text()];case 1:if(n=JSON.parse(r.sent()),e.fileData=null,e.hideWarning(),e.disableSubmissions(),!n.database_version||!Array.isArray(n.reports))return e.showWarning(iawpText.invalidReportArchive),[2];return e.enableSubmissions(),e.fileData=n,[2]}})})()}},{key:"clearFileInput",value:function(){this.fileData=null,this.fileInputTarget.value=null,this.hideWarning(),this.disableSubmissions()}},{key:"showWarning",value:function(t){this.warningMessageTarget.innerText=t,this.warningMessageTarget.style.display="block"}},{key:"hideWarning",value:function(){this.warningMessageTarget.style.display="none"}},{key:"enableSubmissions",value:function(){this.submitButtonTarget.removeAttribute("disabled")}},{key:"disableSubmissions",value:function(){this.submitButtonTarget.setAttribute("disabled","disabled")}}]),n}(f.Controller);(0,a._)(p,"targets",["submitButton","warningMessage","fileInput"]),(0,a._)(p,"values",{databaseVersion:String})},{"@swc/helpers/_/_assert_this_initialized":"atUI0","@swc/helpers/_/_async_to_generator":"6Tpxj","@swc/helpers/_/_class_call_check":"2HOGN","@swc/helpers/_/_create_class":"8oe8p","@swc/helpers/_/_define_property":"27c3O","@swc/helpers/_/_inherits":"7gHjg","@swc/helpers/_/_object_spread":"kexvf","@swc/helpers/_/_object_spread_props":"c7x3p","@swc/helpers/_/_create_super":"a37Ru","@swc/helpers/_/_ts_generator":"lwj56","@hotwired/stimulus":"crDvk","../download":"ce5U5","@parcel/transformer-js/src/esmodule-helpers.js":"kPSB8"}],"8sFSN":[function(t,e,n){var r=t("@parcel/transformer-js/src/esmodule-helpers.js");r.defineInteropFlag(n),r.export(n,"default",function(){return u});var i=t("@swc/helpers/_/_assert_this_initialized"),A=t("@swc/helpers/_/_class_call_check"),o=t("@swc/helpers/_/_create_class"),s=t("@swc/helpers/_/_define_property"),a=t("@swc/helpers/_/_inherits"),l=t("@swc/helpers/_/_object_spread"),c=t("@swc/helpers/_/_create_super"),u=function(t){(0,a._)(n,t);var e=(0,c._)(n);function n(){var t;return(0,A._)(this,n),t=e.apply(this,arguments),(0,s._)((0,i._)(t),"hasSetError",!1),t}return(0,o._)(n,[{key:"connect",value:function(){var t=this;this.interval=setInterval(function(){t.check()},5e3),this.check()}},{key:"check",value:function(){var t=this,e=(0,l._)({},iawpActions.migration_status);jQuery.post(ajaxurl,e,function(e){e.data&&!1===e.data.isMigrating?(clearInterval(t.interval),document.location.reload()):e.data&&e.data.errorHtml&&!t.hasSetError&&(document.getElementById("iawp-migration-error").innerHTML=e.data.errorHtml,document.getElementById("iawp-update-running").innerHTML="",t.hasSetError=!0)})}}]),n}(t("@hotwired/stimulus").Controller)},{"@swc/helpers/_/_assert_this_initialized":"atUI0","@swc/helpers/_/_class_call_check":"2HOGN","@swc/helpers/_/_create_class":"8oe8p","@swc/helpers/_/_define_property":"27c3O","@swc/helpers/_/_inherits":"7gHjg","@swc/helpers/_/_object_spread":"kexvf","@swc/helpers/_/_create_super":"a37Ru","@hotwired/stimulus":"crDvk","@parcel/transformer-js/src/esmodule-helpers.js":"kPSB8"}],eKSV5:[function(t,e,n){var r=t("@parcel/transformer-js/src/esmodule-helpers.js");r.defineInteropFlag(n),r.export(n,"default",function(){return c});var i=t("@swc/helpers/_/_assert_this_initialized"),A=t("@swc/helpers/_/_class_call_check"),o=t("@swc/helpers/_/_create_class"),s=t("@swc/helpers/_/_define_property"),a=t("@swc/helpers/_/_inherits"),l=t("@swc/helpers/_/_create_super"),c=function(t){(0,a._)(n,t);var e=(0,l._)(n);function n(){var t;return(0,A._)(this,n),t=e.apply(this,arguments),(0,s._)((0,i._)(t),"maybeClose",function(e){var n=t.modalTarget.classList.contains("show"),r=t.element.contains(e.target);e.isTrusted&&n&&!r&&t.closeModal()}),t}return(0,o._)(n,[{key:"connect",value:function(){document.addEventListener("click",this.maybeClose)}},{key:"disconnect",value:function(){document.removeEventListener("click",this.maybeClose)}},{key:"toggleModal",value:function(t){t.preventDefault(),this.modalTarget.classList.contains("show")?this.closeModal():this.openModal()}},{key:"openModal",value:function(){this.modalTarget.classList.add("show"),this.modalButtonTarget.classList.add("open"),document.getElementById("iawp-layout").classList.add("modal-open")}},{key:"closeModal",value:function(){this.modalTarget.classList.remove("show"),this.modalButtonTarget.classList.remove("open"),document.getElementById("iawp-layout").classList.remove("modal-open")}}]),n}(t("@hotwired/stimulus").Controller);(0,s._)(c,"targets",["modal","modalButton"])},{"@swc/helpers/_/_assert_this_initialized":"atUI0","@swc/helpers/_/_class_call_check":"2HOGN","@swc/helpers/_/_create_class":"8oe8p","@swc/helpers/_/_define_property":"27c3O","@swc/helpers/_/_inherits":"7gHjg","@swc/helpers/_/_create_super":"a37Ru","@hotwired/stimulus":"crDvk","@parcel/transformer-js/src/esmodule-helpers.js":"kPSB8"}],"3da1p":[function(t,e,n){var r=t("@parcel/transformer-js/src/esmodule-helpers.js");r.defineInteropFlag(n),r.export(n,"default",function(){return c});var i=t("@swc/helpers/_/_assert_this_initialized"),A=t("@swc/helpers/_/_class_call_check"),o=t("@swc/helpers/_/_create_class"),s=t("@swc/helpers/_/_define_property"),a=t("@swc/helpers/_/_inherits"),l=t("@swc/helpers/_/_create_super"),c=function(t){(0,a._)(n,t);var e=(0,l._)(n);function n(){var t;return(0,A._)(this,n),t=e.apply(this,arguments),(0,s._)((0,i._)(t),"onFetchingReport",function(){if("columns"===t.optionTypeValue){var e=t.element.querySelectorAll("input:not([disabled])");e.forEach(function(t){return t.disabled=!0}),t.spinnerTarget.classList.remove("hidden"),document.addEventListener("iawp:fetchedReport",function(){e.forEach(function(t){return t.disabled=!1}),t.spinnerTarget.classList.add("hidden")},{once:!0})}}),(0,s._)((0,i._)(t),"maybeClose",function(e){var n=t.modalTarget.classList.contains("show"),r=t.element.contains(e.target);n&&!r&&t.closeModal()}),t}return(0,o._)(n,[{key:"connect",value:function(){document.addEventListener("click",this.maybeClose),document.addEventListener("iawp:fetchingReport",this.onFetchingReport)}},{key:"disconnect",value:function(){document.removeEventListener("click",this.maybeClose),document.removeEventListener("iawp:fetchingReport",this.onFetchingReport),this.modalTarget.classList.contains("show")&&this.closeModal()}},{key:"toggleModal",value:function(t){t.preventDefault(),this.modalTarget.classList.contains("show")?this.closeModal():this.openModal()}},{key:"openModal",value:function(){this.modalTarget.classList.add("show"),this.modalButtonTarget.classList.add("open"),document.getElementById("iawp-layout").classList.add("modal-open")}},{key:"closeModal",value:function(){this.modalTarget.classList.remove("show"),this.modalButtonTarget.classList.remove("open"),document.getElementById("iawp-layout").classList.remove("modal-open")}},{key:"requestGroupChange",value:function(t){t.preventDefault(),this.changeGroup(t.currentTarget.dataset.optionId)}},{key:"changeGroup",value:function(t){this.tabTargets.forEach(function(e,n){e.classList.toggle("current",e.dataset.optionId===t)}),this.checkboxContainerTargets.forEach(function(e,n){e.classList.toggle("current",e.dataset.optionId===t)})}},{key:"toggleOption",value:function(){var t=this.checkboxTargets.filter(function(t){return t.checked});this.checkboxTargets.forEach(function(t){t.setAttribute("data-test-visibility",t.checked?"visible":"hidden"),t.removeAttribute("disabled")}),1===t.length&&t.at(0).setAttribute("disabled","disabled"),document.dispatchEvent(new CustomEvent(this.getEventName(),{detail:{optionIds:t.map(function(t){return t.name})}}))}},{key:"getEventName",value:function(){switch(this.optionTypeValue){case"columns":return"iawp:changeColumns";case"quick_stats":return"iawp:changeQuickStats"}}}]),n}(t("@hotwired/stimulus").Controller);(0,s._)(c,"targets",["modal","modalButton","checkbox","checkboxContainer","tab","spinner"]),(0,s._)(c,"values",{optionType:String})},{"@swc/helpers/_/_assert_this_initialized":"atUI0","@swc/helpers/_/_class_call_check":"2HOGN","@swc/helpers/_/_create_class":"8oe8p","@swc/helpers/_/_define_property":"27c3O","@swc/helpers/_/_inherits":"7gHjg","@swc/helpers/_/_create_super":"a37Ru","@hotwired/stimulus":"crDvk","@parcel/transformer-js/src/esmodule-helpers.js":"kPSB8"}],gruj2:[function(t,e,n){var r=t("@parcel/transformer-js/src/esmodule-helpers.js");r.defineInteropFlag(n),r.export(n,"default",function(){return m});var i=t("@swc/helpers/_/_assert_this_initialized"),A=t("@swc/helpers/_/_async_to_generator"),o=t("@swc/helpers/_/_class_call_check"),s=t("@swc/helpers/_/_create_class"),a=t("@swc/helpers/_/_define_property"),l=t("@swc/helpers/_/_inherits"),c=t("@swc/helpers/_/_object_spread"),u=t("@swc/helpers/_/_object_spread_props"),h=t("@swc/helpers/_/_create_super"),d=t("@swc/helpers/_/_ts_generator"),f=t("@hotwired/stimulus"),p=t("micromodal"),g=r.interopDefault(p),m=function(t){(0,l._)(n,t);var e=(0,h._)(n);function n(){var t;return(0,o._)(this,n),t=e.apply(this,arguments),(0,a._)((0,i._)(t),"isModalActuallyOpen",!1),(0,a._)((0,i._)(t),"showConfirmationModal",function(e){t.confirmationTextTarget.innerText=e,t.isModalActuallyOpen=!0,(0,g.default).show("prune-modal",{onClose:function(){t.cancelConfirmation()}})}),(0,a._)((0,i._)(t),"hideConfirmationModal",function(e){t.isModalActuallyOpen&&(t.isModalActuallyOpen=!1,(0,g.default).close("prune-modal"))}),t}return(0,s._)(n,[{key:"saveClick",value:function(){this.actuallySave(!1)}},{key:"confirmClick",value:function(){var t=this;return(0,A._)(function(){return(0,d._)(this,function(e){switch(e.label){case 0:return t.confirmButtonTarget.setAttribute("disabled","disabled"),t.confirmButtonTarget.innerText=t.confirmButtonTarget.dataset.loadingText,[4,t.actuallySave(!0)];case 1:return e.sent(),t.confirmButtonTarget.removeAttribute("disabled"),t.confirmButtonTarget.innerText=t.confirmButtonTarget.dataset.originalText,t.hideConfirmationModal(),[2]}})})()}},{key:"selectChanged",value:function(){this.saveButtonTarget.removeAttribute("disabled")}},{key:"cancelConfirmation",value:function(t){t&&t.target!==t.currentTarget||(this.hideConfirmationModal(),this.saveButtonTarget.removeAttribute("disabled"),this.saveButtonTarget.innerText=this.saveButtonTarget.dataset.originalText)}},{key:"actuallySave",value:function(){var t=arguments.length>0&&void 0!==arguments[0]&&arguments[0],e=this;return(0,A._)(function(){var n;return(0,d._)(this,function(r){switch(r.label){case 0:return e.saveButtonTarget.setAttribute("disabled","disabled"),e.saveButtonTarget.innerText=e.saveButtonTarget.dataset.loadingText,[4,e.sendRequest({pruningCutoff:e.cutoffsTarget.value,isConfirmed:t})];case 1:return!(n=r.sent()).wasSuccessful&&n.confirmationText?e.showConfirmationModal(n.confirmationText):(e.statusMessageTarget.classList.toggle("is-scheduled",n.isEnabled),e.statusMessageTarget.querySelector("p").innerHTML=n.statusMessage,e.saveButtonTarget.removeAttribute("disabled"),e.saveButtonTarget.innerText=e.saveButtonTarget.dataset.originalText,e.saveButtonTarget.setAttribute("disabled","disabled"),e.hideConfirmationModal()),[2]}})})()}},{key:"sendRequest",value:function(t){var e=t.pruningCutoff,n=t.isConfirmed;return(0,A._)(function(){var t,r;return(0,d._)(this,function(i){switch(i.label){case 0:return t=(0,u._)((0,c._)({},iawpActions.configure_pruner),{pruningCutoff:e,isConfirmed:n}),[4,jQuery.post(ajaxurl,t)];case 1:return[2,{wasSuccessful:(r=i.sent()).success,confirmationText:r.data.confirmationText,isEnabled:r.data.isEnabled,statusMessage:r.data.statusMessage}]}})})()}}]),n}(f.Controller);(0,a._)(m,"targets",["cutoffs","saveButton","confirmButton","statusMessage","confirmationText"])},{"@swc/helpers/_/_assert_this_initialized":"atUI0","@swc/helpers/_/_async_to_generator":"6Tpxj","@swc/helpers/_/_class_call_check":"2HOGN","@swc/helpers/_/_create_class":"8oe8p","@swc/helpers/_/_define_property":"27c3O","@swc/helpers/_/_inherits":"7gHjg","@swc/helpers/_/_object_spread":"kexvf","@swc/helpers/_/_object_spread_props":"c7x3p","@swc/helpers/_/_create_super":"a37Ru","@swc/helpers/_/_ts_generator":"lwj56","@hotwired/stimulus":"crDvk",micromodal:"Tlrpp","@parcel/transformer-js/src/esmodule-helpers.js":"kPSB8"}],i0Fis:[function(t,e,n){var r=t("@parcel/transformer-js/src/esmodule-helpers.js");r.defineInteropFlag(n),r.export(n,"default",function(){return c});var i=t("@swc/helpers/_/_assert_this_initialized"),A=t("@swc/helpers/_/_class_call_check"),o=t("@swc/helpers/_/_create_class"),s=t("@swc/helpers/_/_define_property"),a=t("@swc/helpers/_/_inherits"),l=t("@swc/helpers/_/_create_super"),c=function(t){(0,a._)(n,t);var e=(0,l._)(n);function n(){var t;return(0,A._)(this,n),t=e.apply(this,arguments),(0,s._)((0,i._)(t),"updateTableUI",function(e){var n=e.detail.optionIds,r=n.length;t.element.classList.forEach(function(e){e.startsWith("total-of-")&&t.element.classList.remove(e)}),t.element.classList.add("total-of-"+r.toString()),t.quickStatTargets.forEach(function(t){var e=n.includes(t.dataset.id);t.classList.toggle("visible",e)})}),t}return(0,o._)(n,[{key:"connect",value:function(){document.addEventListener("iawp:changeQuickStats",this.updateTableUI)}},{key:"disconnect",value:function(){document.removeEventListener("iawp:changeQuickStats",this.updateTableUI)}}]),n}(t("@hotwired/stimulus").Controller);(0,s._)(c,"targets",["quickStat"])},{"@swc/helpers/_/_assert_this_initialized":"atUI0","@swc/helpers/_/_class_call_check":"2HOGN","@swc/helpers/_/_create_class":"8oe8p","@swc/helpers/_/_define_property":"27c3O","@swc/helpers/_/_inherits":"7gHjg","@swc/helpers/_/_create_super":"a37Ru","@hotwired/stimulus":"crDvk","@parcel/transformer-js/src/esmodule-helpers.js":"kPSB8"}],goGxO:[function(t,e,n){var r,i=t("@parcel/transformer-js/src/esmodule-helpers.js");i.defineInteropFlag(n),i.export(n,"default",function(){return b});var A=t("@swc/helpers/_/_assert_this_initialized"),o=t("@swc/helpers/_/_class_call_check"),s=t("@swc/helpers/_/_create_class"),a=t("@swc/helpers/_/_define_property"),l=t("@swc/helpers/_/_inherits"),c=t("@swc/helpers/_/_object_spread"),u=t("@swc/helpers/_/_to_consumable_array"),h=t("@swc/helpers/_/_create_super"),d=t("@hotwired/stimulus"),f=t("chart.js"),p=t("isotope-layout"),g=i.interopDefault(p),m=t("../chart_plugins/html_legend_plugin"),v=i.interopDefault(m),y=t("../chart_plugins/corsair_plugin"),w=i.interopDefault(y);(r=f.Chart).register.apply(r,(0,u._)(f.registerables)),f.Chart.defaults.font.family='-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"';var b=function(t){(0,l._)(n,t);var e=(0,h._)(n);function n(){var t;return(0,o._)(this,n),t=e.apply(this,arguments),(0,a._)((0,A._)(t),"tabVisibilityChanged",function(){t.visibleValue=!document.hidden,t.visibleValue&&(t.refresh(),t.startServerPolling())}),t}return(0,s._)(n,[{key:"connect",value:function(){document.addEventListener("visibilitychange",this.tabVisibilityChanged),this.initializeChart({element:this.minuteChartTarget,visitors:this.chartDataValue.minute_interval_visitors,views:this.chartDataValue.minute_interval_views,labelsShort:this.chartDataValue.minute_interval_labels_short,labelsFull:this.chartDataValue.minute_interval_labels_full}),this.initializeChart({element:this.secondChartTarget,visitors:this.chartDataValue.second_interval_visitors,views:this.chartDataValue.second_interval_views,labelsShort:this.chartDataValue.second_interval_labels_short,labelsFull:this.chartDataValue.second_interval_labels_full}),this.startServerPolling()}},{key:"disconnect",value:function(){document.removeEventListener("visibilitychange",this.tabVisibilityChanged)}},{key:"startServerPolling",value:function(){var t=this;clearInterval(this.interval),this.interval=setInterval(function(){t.visibleValue?t.refresh():clearInterval(t.interval)},1e4)}},{key:"refresh",value:function(){var t=this,e=(0,c._)({},iawpActions.real_time_data);jQuery.post(ajaxurl,e,function(e,n,r){document.getElementById("real-time-dashboard").classList.remove("refreshed"),document.getElementById("real-time-dashboard").offsetWidth,document.getElementById("real-time-dashboard").classList.add("refreshed"),e.success&&t.rerender(e.data)})}},{key:"rerender",value:function(t){this.visitorMessageTarget.textContent=t.visitor_message,this.pageMessageTarget.textContent=t.page_message,this.referrerMessageTarget.textContent=t.referrer_message,this.countryMessageTarget.textContent=t.country_message,this.updateChart({element:this.minuteChartTarget,visitors:t.chart_data.minute_interval_visitors,views:t.chart_data.minute_interval_views}),this.updateChart({element:this.secondChartTarget,visitors:t.chart_data.second_interval_visitors,views:t.chart_data.second_interval_views}),this.updateList({element:this.pagesListTarget,entries:t.lists.pages.entries}),this.updateList({element:this.referrersListTarget,entries:t.lists.referrers.entries}),this.updateList({element:this.countriesListTarget,entries:t.lists.countries.entries}),this.updateList({element:this.campaignsListTarget,entries:t.lists.campaigns.entries}),this.updateList({element:this.device_typesListTarget,entries:t.lists.device_types.entries})}},{key:"existingElements",value:function(){return Array.from(this.element.querySelectorAll("li:not(.exiting)"))}},{key:"existingIds",value:function(){return this.existingElements().map(function(t){return t.dataset.id})}},{key:"updateList",value:function(t){var e=this,n=t.element,r=t.entries,i=n.iso;i||(i=n.iso=new g.default(n,{itemSelector:"li",layoutMode:"vertical",sortColumn:"position",getSortData:{position:function(t){return parseInt(t.dataset.position)}}})),this.existingElements().forEach(function(t){var e=t.dataset.id,n=r.find(function(t){return t.id===e});n?(t.dataset.position=n.position,t.querySelector(".real-time-position").textContent=n.position+".",t.querySelector(".real-time-stat").textContent=n.views):i.remove(t)}),r.forEach(function(t,n){if(!e.existingIds().includes(t.id)){var r=e.elementFromEntry(t);i.insert(r)}}),i.updateSortData(),i.arrange();var A=i.items.length,o=n.parentNode.querySelector(".most-popular-empty-message");A>0?o.classList.add("hide"):o.classList.remove("hide")}},{key:"elementFromEntry",value:function(t){var e=t.id,n=t.position,r=t.title,i=t.subtitle,A=t.views,o=t.flag?t.flag:"",s='\n
  • \n ').concat(n,".\n ").concat(o,'\n ').concat(r," ").concat(i?''.concat(i,""):"",'\n ').concat(A,"\n
  • \n "),a=document.createElement("div");return a.innerHTML=s,a.firstElementChild}},{key:"initializeChart",value:function(t){var e=t.element,n=(t.visitors,t.views),r=t.labelsShort,i={type:"bar",data:{labels:t.labelsFull,datasets:[{id:"views",label:iawpText.views,data:n,backgroundColor:"rgba(108,70,174,0.2)",borderColor:"rgba(108,70,174,1)",borderWidth:{bottom:0,top:3,left:0,right:0}}]},options:{interaction:{intersect:!1,mode:"index"},responsive:!0,scales:{y:{grid:{borderColor:"#DEDAE6",tickColor:"#DEDAE6",display:!0,drawOnChartArea:!0,borderDash:[2,4]},beginAtZero:!0,suggestedMax:5,ticks:{color:document.body.classList.contains("iawp-dark-mode")?"#ffffff":"#6D6A73",precision:0}},x:{stacked:!0,grid:{borderColor:"#DEDAE6",tickColor:"#DEDAE6",display:!0,drawOnChartArea:!1},ticks:{color:document.body.classList.contains("iawp-dark-mode")?"#ffffff":"#6D6A73",beginAtZero:!0,callback:function(t,e,n){return r[e]}}}},plugins:{mode:String,htmlLegend:{container:e.parentNode.querySelector(".legend")},legend:{display:!1},corsair:{dash:[2,4],color:"#777",width:1}}},plugins:[w.default,v.default]};new f.Chart(e,i)}},{key:"updateChart",value:function(t){var e=t.element,n=t.views,r=(0,f.Chart).getChart(e);r.data.datasets.forEach(function(t,e){var r;(r=t.data).splice.apply(r,[0,t.data.length].concat((0,u._)(n)))}),r.update("none")}}]),n}(d.Controller);(0,a._)(b,"targets",["minuteChart","secondChart","visitorMessage","pageMessage","referrerMessage","countryMessage","pagesList","referrersList","countriesList","campaignsList","device_typesList"]),(0,a._)(b,"values",{chartData:Object,nonce:String,visible:{type:Boolean,default:!0}})},{"@swc/helpers/_/_assert_this_initialized":"atUI0","@swc/helpers/_/_class_call_check":"2HOGN","@swc/helpers/_/_create_class":"8oe8p","@swc/helpers/_/_define_property":"27c3O","@swc/helpers/_/_inherits":"7gHjg","@swc/helpers/_/_object_spread":"kexvf","@swc/helpers/_/_to_consumable_array":"4oNkS","@swc/helpers/_/_create_super":"a37Ru","@hotwired/stimulus":"crDvk","chart.js":"1stGI","isotope-layout":"7FZhc","../chart_plugins/html_legend_plugin":"bGHGY","../chart_plugins/corsair_plugin":"aPJHp","@parcel/transformer-js/src/esmodule-helpers.js":"kPSB8"}],"7FZhc":[function(t,e,n){var r,i;r=window,i=function(t,e,n,r,i,A,o){var s=t.jQuery,a=String.prototype.trim?function(t){return t.trim()}:function(t){return t.replace(/^\s+|\s+$/g,"")},l=e.create("isotope",{layoutMode:"masonry",isJQueryFiltering:!0,sortAscending:!0});l.Item=A,l.LayoutMode=o;var c=l.prototype;c._create=function(){for(var t in this.itemGUID=0,this._sorters={},this._getSorters(),e.prototype._create.call(this),this.modes={},this.filteredItems=this.items,this.sortHistory=["original-order"],o.modes)this._initLayoutMode(t)},c.reloadItems=function(){this.itemGUID=0,e.prototype.reloadItems.call(this)},c._itemize=function(){for(var t=e.prototype._itemize.apply(this,arguments),n=0;ns||os?1:-1)*((void 0!==e[A]?e[A]:e)?1:-1)}return 0});this.filteredItems.sort(r)}},c._getIsSameSortBy=function(t){for(var e=0;e