#!/usr/bin/env perl
#------------------------------------------------------------------------------
#
# PgCluu - PostgreSQL monitoring tool with statistics collector and grapher
#
# This program is open source, licensed under the PostgreSQL license.
# For license terms, see the LICENSE file.
#
# Author: Gilles Darold
# Copyright: (C) 2012-2026 Gilles Darold - All rights reserved.
#------------------------------------------------------------------------------
use vars qw($VERSION $PROGRAM);

use strict qw(vars);
use warnings;

use constant UMASK      => 0027;

use IO::File;
use Getopt::Long qw(:config bundling no_ignore_case_always);
use File::Basename;
use Time::Local 'timegm_nocheck';
use POSIX qw(locale_h sys_wait_h ceil strftime);
setlocale(LC_ALL, 'C');
use Storable qw(store_fd fd_retrieve);
use Fcntl qw(:flock);

$VERSION = '5.0';
$PROGRAM = 'pgCluu';

# Global variables
my $CONFIG_FILE     = "/etc/pgcluu.conf";
my $OUTPUT_DIR      = '';
my $SADF_PROG       = '/usr/bin/sadf';
my $DISABLE_SAR     = 0;
my $HTML            = '';
my $NO_TB_STAT      = 0;
my @INCLUDE_DB      = ();
my @INCLUDE_TB      = ();
my @INCLUDE_DEV     = ();
my @INCLUDE_IFACE   = ();
my $IMG_FORMAT      = 'png';
my $FH              = undef;
my $IDX             = 1;
my $HELP            = 0;
my $SHOW_VER        = 0;
my $DEBUG           = 0;
my $BEGIN           = '';  # for PG data
my $END             = '';
my $BEGIN_STAT      = '';  # for sar
my $END_STAT        = '';
my $NUMBER_CPU      = 0;
my $TIMEZONE        = substr(strftime('%z', localtime()), 0, 3);
my $STATS_TIMEZONE  = '00'; # Timezone is auto detected from data files
my $REVERT_DATE     = 0;
my $FROM_SA_FILE    = 0;
my $SADC_INPUT_FILE = '';
my $SAR_INPUT_FILE  = '';
my $PIDSTAT_INPUT_FILE  = '';
our @DEVICE_LIST    = ();
our @IFACE_LIST     = ();
our @DEVICE_SPACE_LIST = ();
my $ZCAT_PROG       = '/bin/zcat';
my $CACHE           = 0;
my $CLEAN           = 0;
my $MAX_INDEXES     = 5;
my $RETENTION       = 0;
my $EXTERNAL_MENU   = 0;

my $OVERRIDE        = 1; # Force overriding of resources files (css and js) at each pgcluu run

my $SAR_UPPER_11_5_6 = 0;
my $SAR_UPPER_12_1_1 = 0;
my $SAR_UPPER_12_3_9 = 0;

my %RELKIND = (
	'r' => 'tables',
	'i' => 'indexes',
	'S' => 'sequences',
	'v' => 'views',
	'c' => 'composite types',
	't' => 'toast tables'
);
my $TOP_STAT       = 10;

# Global variables that need to be saved in incremental mode
our %OVERALL_STATS   = ();
our %global_infos = ();
our @global_databases = ();
our @global_tbspnames = ();
our %all_stat_database = ();
our %all_stat_database_conflicts = ();
our %all_database_size = ();
our %all_tablespace_size = ();
our %all_stat_user_tables = ();
our %all_stat_user_indexes = ();
our %all_stat_invalid_indexes = ();
our %all_stat_hash_indexes = ();
our %all_statio_user_tables = ();
our %all_relation_buffercache = ();
our %all_statio_user_indexes = ();
our %all_xlog_stat = ();
our %all_stat_bgwriter = ();
our %all_stat_connections = ();
our %all_stat_user_functions = ();
our %all_stat_replication = ();
our %all_pgbouncer_stats = ();
our %all_pgbouncer_ini = ();
our %all_pgbouncer_req_stats = ();
our %all_class_size = ();
our %all_stat_locks = ();
our %all_stat_unused_indexes = ();
our %all_stat_redundant_indexes = ();
our %all_stat_extended_statistics = ();
our %all_stat_count_indexes = ();
our %all_stat_missing_fkindexes = ();
our %all_postgresql_conf = ();
our %all_recovery_conf = ();
our %all_postgresql_auto_conf = ();
our %all_pg_hba_conf = ();
our %all_pg_ident_conf = ();
our %all_settings = ();
our %all_hba_rules = ();
our %all_nondefault_settings = ();
our %all_db_role_setting = ();
our %all_database_buffercache = ();
our %all_database_usagecount = ();
our %all_database_isdirty = ();
our %all_stat_archiver = ();
our @all_stat_slots = ();
our %all_stat_statements = ();
our %all_stat_unlogged = ();
our %all_postgresql_conf_diff = ();
our %all_recovery_conf_diff = ();
our %all_postgresql_auto_conf_diff = ();
our %all_pg_hba_conf_diff = ();
our %all_pg_ident_conf_diff = ();
our %all_settings_diff = ();
our %all_db_role_setting_diff = ();
our %all_pgbouncer_ini_diff = ();
our %all_prepared_xact = ();
our %all_subxact_counters = ();
our %all_wait_events = ();
our %all_stat_io = ();
our %all_stat_io_prev = ();
our %all_stat_aio = ();
our %kernel_stats = ();
our %kernel_stats_prev = ();
# Cumulative columns collected from pg_stat_io (see pg_stat_io())
our @STAT_IO_COLUMNS = qw(
	reads read_bytes read_time writes write_bytes write_time writebacks
	writeback_time extends extend_bytes extend_time hits evictions reuses
	fsyncs fsync_time
);
# Dispatch table between pg_stat_io graph names and the functions building them
our %STAT_IO_GRAPHS = (
	'cluster-io_read_throughput'   => sub { &stat_io_rate_graph(@_, 'read_bytes', 0, 'relation|temp relation', undef); },
	'cluster-io_write_throughput'  => sub { &stat_io_rate_graph(@_, 'write_bytes', 0, 'relation|temp relation', undef); },
	'cluster-io_extend_throughput' => sub { &stat_io_rate_graph(@_, 'extend_bytes', 0, 'relation|temp relation', undef); },
	'cluster-io_buffer_writes'     => sub { &stat_io_rate_graph(@_, 'write_bytes', 0, 'relation', 'normal'); },
	'cluster-io_evictions'         => sub { &stat_io_rate_graph(@_, 'evictions', 0, 'relation', 'normal'); },
	'cluster-io_backend_fsyncs'    => sub { &stat_io_rate_graph(@_, 'fsyncs', 0, 'relation', undef, 'checkpointer'); },
	'cluster-io_hit_ratio'         => \&stat_io_hit_ratio_graph,
	'cluster-io_ring_buffers'      => \&stat_io_ring_graph,
	'cluster-io_read_latency'      => sub { &stat_io_latency_graph(@_, 'read_time', 'reads', 0, 'relation|temp relation', undef); },
	'cluster-io_write_latency'     => sub { &stat_io_latency_graph(@_, 'write_time', 'writes', 0, 'relation|temp relation', undef); },
	'cluster-io_extend_latency'    => sub { &stat_io_latency_graph(@_, 'extend_time', 'extends', 0, 'relation|temp relation', undef); },
	'cluster-io_fsync_latency'     => sub { &stat_io_latency_graph(@_, 'fsync_time', 'fsyncs', 0, 'relation', undef); },
	'cluster-io_size'              => \&stat_io_size_graph,
	'cluster-io_wal_write'         => sub { &stat_io_rate_graph(@_, 'write_bytes', 0, 'wal', 'normal'); },
	'cluster-io_wal_fsync'         => sub { &stat_io_rate_graph(@_, 'fsyncs', 0, 'wal', 'normal'); },
	'cluster-io_wal_write_latency' => sub { &stat_io_latency_graph(@_, 'write_time', 'writes', 0, 'wal', 'normal'); },
	'cluster-io_wal_fsync_latency' => sub { &stat_io_latency_graph(@_, 'fsync_time', 'fsyncs', 0, 'wal', 'normal'); },
	'cluster-io_wal_init'          => sub { &stat_io_rate_graph(@_, 'write_bytes', 0, 'wal', 'init'); },
	'cluster-io_wal_read'          => sub { &stat_io_rate_graph(@_, 'read_bytes', 0, 'wal', undef); },
	'cluster-io_temp_throughput'   => sub { &stat_io_ops_rate_graph(@_, 'temp relation', undef, 'read' => 'read_bytes', 'write' => 'write_bytes', 'extend' => 'extend_bytes'); },
	'cluster-io_temp_hit_ratio'    => \&stat_io_temp_hit_ratio_graph,
	'cluster-io_temp_evictions'    => sub { &stat_io_rate_graph(@_, 'evictions', 0, 'temp relation', undef); },
);
# Pages of the pg_stat_io reports and their label in the menu
our @STAT_IO_PAGES = (
	[ 'cluster-io_throughput', 'I/O throughput per backend type' ],
	[ 'cluster-io_writers', 'Shared buffers writers and evictions' ],
	[ 'cluster-io_cache', 'Buffer hit ratio and ring buffers' ],
	[ 'cluster-io_latency', 'I/O latency and size' ],
	[ 'cluster-io_wal', 'WAL I/O' ],
	[ 'cluster-io_temp', 'Temporary relations I/O' ],
	[ 'cluster-io_aio', 'Asynchronous I/O' ],
);

# Names of the variables that need to be saved as binary file
our @pg_to_be_stored = (
	'global_infos',
	'global_databases',
	'global_tbspnames',
	'all_stat_database',
	'all_stat_database_conflicts',
	'all_database_size',
	'all_tablespace_size',
	'all_stat_user_tables',
	'all_stat_user_indexes',
	'all_stat_invalid_indexes',
	'all_stat_hash_indexes',
	'all_statio_user_tables',
	'all_relation_buffercache',
	'all_statio_user_indexes',
	'all_xlog_stat',
	'all_stat_bgwriter',
	'all_stat_connections',
	'all_stat_user_functions',
	'all_stat_replication',
	'all_pgbouncer_stats',
	'all_pgbouncer_ini',
	'all_pgbouncer_req_stats',
	'all_class_size',
	'all_stat_locks',
	'all_stat_unused_indexes',
	'all_stat_redundant_indexes',
	'all_stat_extended_statistics',
	'all_stat_count_indexes',
	'all_stat_missing_fkindexes',
	'all_postgresql_conf',
	'all_recovery_conf',
	'all_postgresql_auto_conf',
	'all_pg_hba_conf',
	'all_pg_ident_conf',
	'all_settings',
	'all_hba_rules',
	'all_nondefault_settings',
	'all_db_role_setting',
	'all_pgbouncer_ini_diff',
	'all_db_role_setting_diff',
	'all_postgresql_conf_diff',
	'all_recovery_conf_diff',
	'all_postgresql_auto_conf_diff',
	'all_pg_hba_conf_diff',
	'all_pg_ident_conf_diff',
	'all_settings_diff',
	'all_database_buffercache',
	'all_database_usagecount',
	'all_database_isdirty',
	'all_stat_archiver',
	'all_stat_statements',
	'all_stat_unlogged',
	'all_prepared_xact',
	'all_subxact_counters',
	'all_wait_events',
	'all_stat_slots',
	'all_stat_io',
	'all_stat_io_prev',
	'all_stat_aio',
	'kernel_stats',
	'kernel_stats_prev',
);

# Names of sar variables that need to be saved as binary file
our %sar_cpu_stat = ();
our %sar_load_stat = ();
our %sar_process_stat = ();
our %sar_context_stat = ();
our %sar_memory_stat = ();
our %sar_dirty_stat = ();
our %sar_swap_stat = ();
our %sar_pageswap_stat = ();
our %sar_block_stat = ();
our %sar_srvtime_stat = ();
our %sar_rw_devices_stat = ();
our %sar_space_devices_stat = ();
our %sar_util_devices_stat = ();
our %sar_networks_stat = ();
our %sar_neterror_stat = ();
our %sar_tcputil_stat = ();
our %sar_tcperror_stat = ();
our %sar_commit_memory_stat = ();

our @sar_to_be_stored = (
	'global_infos',
	'sar_cpu_stat',
	'sar_load_stat',
	'sar_process_stat',
	'sar_context_stat',
	'sar_memory_stat',
	'sar_dirty_stat',
	'sar_swap_stat',
	'sar_pageswap_stat',
	'sar_block_stat',
	'sar_srvtime_stat',
	'sar_rw_devices_stat',
	'sar_space_devices_stat',
	'sar_util_devices_stat',
	'sar_networks_stat',
	'sar_neterror_stat',
	'sar_tcputil_stat',
	'sar_tcperror_stat',
	'sar_commit_memory_stat'
);

# Names of pidstat variables that need to be saved as binary file
our %pidstat_cpu_stat = ();
our %pidstat_context_stat = ();
our %pidstat_memory_stat = ();
our %pidstat_io_stat = ();
# Samples of the pidstat file already counted, see pidstat_sample_stats()
our %pidstat_samples = ();
# Columns of the pidstat reports used, the values are read by column name.
# The names separated by | are the names used by the different versions of
# sysstat for the same column.
our %PIDSTAT_COLUMNS = (
	'pcpu'   => [ '%usr|%user', '%system', '%guest', '%wait', '%CPU' ],
	'pcswch' => [ 'cswch/s', 'nvcswch/s' ],
	'pmem'   => [ 'minflt/s', 'majflt/s', 'VSZ', 'RSS', '%MEM' ],
	'pio'    => [ 'kB_rd/s', 'kB_wr/s', 'kB_ccwr/s', 'iodelay' ],
);


# Cache files locking, see lock_cache_dir() and commit_cache_files()
our $CACHE_RUN_LOCK_FILE = '.pgcluu_cache_run.lock';
our $CACHE_DIR_LOCK_FILE = '.pgcluu_cache.lock';
our $CACHE_RUN_LOCK = undef;
our %PENDING_CACHE_FILES = ();

our @pidstat_to_be_stored = (
	'pidstat_cpu_stat',
	'pidstat_context_stat',
	'pidstat_memory_stat',
	'pidstat_io_stat',
	'pidstat_samples'
);

our %sysinfo   = (); # Hash used to store system information
our %fulldata  = (); # Hash to store full content of sar file per type
our %fullpidstatdata  = (); # Hash to store full content of pidstat file per type

# Store default timestamp
my ($o_sec, $o_min, $o_hour, $o_day, $o_month, $o_year) = localtime(time);
$o_year += 1900;
$o_month++;

# Variable use to construct the date part of the sar output
# it is set with de date found in sar file kernel header.
my $sar_year  = '';
my $sar_month = '';
my $sar_day   = '';
my $pidstat_year  = '';
my $pidstat_month = '';
my $pidstat_day   = '';

# Set the default mask for file and directory creation
umask(UMASK);

# Charset used in the html output
my $charset = 'utf-8';

my $week_start_monday = 1;
my $have_incremental_dir = 0;
my $have_hourly_dir = 0;
my $pgcluu_ico = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAjCAYAAAD17ghaAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB98GCwcGIvGIhhwAAAOBSURBVFjDvZdZiI1hGMd/55gFM/Ylss4YGsuQLDP2C3uWGyVzI1mypOxSCAmFO2WJUJaoKReDIhcmSbYaaphGmsgWMXZmmPnc/L96ejvfd86ZOeOp03e+733e9/m/z/5EaBxFgWFAgd6fAg+BBv4D9QBuAj8BT79fwG2gT3MK7gSs0y09PSt1+z8GzBagY6qFFwNvjZCfwEygNdAKmAJ8NOvvgOWpEFwAXDEH1wAngPQAvzjsALlu/CQp6gKcBr6bwy4A+Qns7QucNPt+AGeBrokIjgArgM/mgCpgcpx9LbTX0ljgsTnnG7AayAhTd7XZ8BfYKtW6NA7oad63yB9iAVsD1JpzXwDDXcZlhqEWOAfkhdx4krM+QsKCqJd8x4buGn+xP/BVH8uBIQG3bipFBPqeMclwhMQDKgK82/fwZMIqO05SqpDM9VEgRx/vyO5B6N843yaHAM4HRoUAKNczN2psVx+yoR4oNe9zgRvAfr2XKgf49AAoCTnP8520sbZeoudAmXA2sFL5I+mqlij1BLYBWUCdSTo9DE8bIA2Yn0oAUfnAUWA3sA+4q7VvwC3DWyNfuggcSAWAlsBi3Wy0bFcInAEuSyOl8odF8qfB4lsBdIgHIC3Oegbw0omGzsobc8z3qXrmGAfLVP6vaYoGvqqi/XDU/gvoJjDdgXZae69MGgFeOeAb7QPZ0tRSYK1ufkz9QTXwGngO7BXQkbL/GAGNS4ektmMxKlqGOp4nxlyzTEfkOb+DCTr/WfEfiaeBPKCfwi1fTnXcJC3PPD2F34BU5oHnakrSJLxMNo8ap/TM/17A/URDMBEAtcAl4JNKboEERozwiDGdJ5/ZCCxIFoAXwLNR9b/I4fUMCM/RBMCEBGqBl6YOFpXPaIyiVCPvznHUHolhBktVIZf2a8YHgIkqw3VqwVoEbLrmeP8LYDOwU+HmrzXIZO0DAGwAfmuWmOYe7insxscIyaEaRL6oNyg0azNMI9ugAcalIuCRkVNm+4kosMss1mv8cm+RrvTaOiBki6VRV3tXnelpR1AZGKUhs84wrwLaNqJnyFaB8s+pUydUGG9jujqeCrO5MsmecKGj7ipgngpUUrTTaaXLgUEh/Lmaku1UtKep7XRv4Lwzip9yzJIJHJFAn69EgFJG04FnRsAnYDuwyRlIq9UjNgu1Uof0OkYlfKMuKCuZA/8B+QsSxkN8YYwAAAAASUVORK5CYII=';
my $pgcluu_logo = 'data:image/png;base64,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';

# Statistics files to use with report
my %DB_GRAPH_INFOS = (
	'pg_stat_database.csv' => {
		'1' => {
			'name' =>  'database-backends',
			'title' => 'Connections on %s database',
			'all_title' => 'Global connections',
			'description' => 'Number of clients connected to a database.',
			'all_description' => 'Global number of clients connected.',
			'ylabel' => 'Connections',
			'legends' => ['backends'],
		},
		'2' => {
			'name' =>  'database-read_write_query',
			'title' => 'Affected tuples per operation on %s database',
			'all_title' => 'Global affected tuples per operation',
			'ylabel' => 'Tuples',
			'description' => 'Affected rows on databases grouped by statement family.',
			'all_description' => 'Global affected rows grouped by statement family.',
		},
		'3' => {
			'name' =>  'database-cache_ratio',
			'title' => 'Cache hit/miss ratio on %s database',
			'all_title' => 'Global cache hit/miss ratio',
			'description' => 'Per database cache hit/miss ratio.',
			'all_description' => 'Global cache hit/miss ratio.',
			'ylabel' => 'Blocks per second',
			'legends' => ['Cache hit','Cache miss','hit/miss ratio'],
			'y2label' => 'Percentage',
		},
		'4' => {
			'name' =>  'database-commits_rollbacks',
			'title' => 'Commits/Rollbacks per second on %s database',
			'all_title' => 'Global Commits/Rollbacks per second',
			'description' => 'Number of commits / rollbacks per second and number of backends per database.',
			'all_description' => 'Global number of commits / rollbacks per second and number of backends.',
			'ylabel' => 'Transaction/sec',
			'legends' => ['commit','rollback','backends'],
			'y2label' => 'Number of backend',
		},
		'5' => {
			'name' =>  'database-write_ratio',
			'title' => 'Write ratio on %s database',
			'all_title' => 'Global Write ratio',
			'description' => 'Write ratio on databases excluding templates and postgres.',
			'all_description' => 'Global write ratio, excluding templates and postgres databases.',
			'ylabel' => 'Write queries per second',
			'legends' => ['Insert','Update','Delete'],
		},
		'6' => {
			'name' =>  'database-read_ratio',
			'title' => 'Read tuples on %s database',
			'all_title' => 'Global read tuples',
			'description' => 'Show entries returned from the index and live rows fetched from the tables. The latter will be less if any dead or not-yet-committed rows are fetched using the index.',
			'all_description' => 'Show entries returned from the index and live rows fetched from the tables. The latter will be less if any dead or not-yet-committed rows are fetched using the index.',
			'ylabel' => 'Tuples per second',
			'legends' => ['Table (returned)','Index (fetched)'],
		},
		'7' => {
			'name' =>  'database-deadlocks',
			'title' => 'Number of deadlocks on %s database',
			'all_title' => 'Global number of deadlocks',
			'description' => 'Number of deadlocks detected in this database.',
			'all_description' => 'Global number of deadlocks detected.',
			'ylabel' => 'Number of deadlocks',
			'legends' => ['deadlocks'],
		},
		'8' => {
			'name' =>  'database-canceled_queries',
			'title' => 'Number of canceled queries on %s database',
			'all_title' => 'Global number of canceled queries',
			'description' => 'Number of queries canceled due to conflicts with recovery in this database. [Conflicts occur only on standby servers]',
			'all_description' => 'Global number of queries canceled due to conflicts with recovery. [Conflicts occur only on standby servers]',
			'ylabel' => 'Number of queries canceled',
			'legends' => ['conflicts'],
		},
		'9' => {
			'name' =>  'database-temporary_files',
			'title' => 'Number of temporary files on %s database',
			'all_title' => 'Global number of temporary files',
			'description' => 'Number of temporary files created by queries per database.',
			'all_description' => 'Global number of temporary files created by queries.',
			'ylabel' => 'Number of files',
			'legends' => ['temporary files'],
		},
		'10' => {
			'name' =>  'database-temporary_bytes',
			'title' => 'Size of temporary data on %s database',
			'all_title' => 'Global size of temporary data',
			'description' => 'Amount of data per seconde written to temporary files created by queries per database.',
			'all_description' => 'Global amount of data per second written to temporary files created by queries.',
			'ylabel' => 'Size per seconde',
			'legends' => ['temporary data'],
		},
		'11' => {
			'name' =>  'database-transactions',
			'title' => 'Transactions per second on %s database',
			'all_title' => 'Transaction throughput per second',
			'description' => 'Number of transaction (commit+rollback) issued per second.',
			'all_description' => 'Number of transaction (commit+rollback) issued per second.',
			'ylabel' => 'Transaction/sec',
			'legends' => ['tps'],
		},
	},
	'pg_stat_database_conflicts.csv' =>  {
		'1' => {
			'name' =>  'database-conflicts',
			'title' => 'Conflicts per type on %s database',
			'all_title' => 'Conflicts per type on all database',
			'description' => 'Per database statistics about query cancels occurring due to conflicts with recovery on standby servers.',
			'all_description' => 'Statistics about query cancels occurring due to conflicts with recovery on standby servers.',
                        'ylabel' => 'Number of conflict',
			'legends' => [ 'tablespace', 'lock', 'snapshot', 'bufferpin', 'deadlock' ],
		},
	},
	'pg_database_size.csv' => {
		'1' => {
			'name' =>  'database-size',
			'title' => 'Size of %s database',
			'description' => 'Database sizes.',
			'ylabel' => 'Size',
			'legends' => ['size'],
			'active' => 1,
		},
	},
	'pg_prepared_xact.csv' => {
		'1' => {
			'name' =>  'database-prepared',
			'title' => 'Prepared xact in %s database',
			'all_title' => 'Prepared transactions',
			'description' => 'Database prepared xact count and oldest prepared transaction in seconds.',
			'all_description' => 'Prepared transaction in the PostgreSQL cluster and oldest prepared transaction in seconds..',
			'ylabel' => 'Number of xact',
			'legends' => ['prepared xact','max prepared duration'],
			'active' => 1,
			'y2label' => 'Xact duration',
		},
	},
	'pg_tablespace_size.csv' => {
		'1' => {
			'name' =>  'tablespace-size',
			'title' => 'Size of %s tablespace',
			'description' => 'Tablespace size and location.',
			'ylabel' => 'Size',
			'legends' => ['size'],
		},
	},
	'pg_stat_bgwriter.csv' => {
		'1' => {
			'name' => 'cluster-checkpoints',
			'title' => 'checkpoints counter stats',
			'description' => 'Background writer statistics on checkpoints. Checkpoints timed is checkpoints issued because of checkpoint_timeout and checkpoints request is checkpoint issued by request. Comparing checkpoints timed and requested shows whether you’ve set checkpoint segments usefully.',
			'ylabel' => 'Number of checkpoints',
			'legends' => ['checkpoints timed','checkpoints requests'],
		},
		'2' => {
			'name' =>  'cluster-bgwriter_write',
			'title' => 'background writer clean stats',
			'description' => 'Background writer cache cleaning statistics by checkpoints, lru and backends. Buffers checkpoint are written during checkpoint calls, buffers backend represent client backend that had to write to satisfy an allocation and buffers clean represent background writer cleaning a dirty buffer expected by an allocation.',
			'ylabel' => 'Size per second',
			'legends' => ['checkpoint buffers','clean buffers','backend buffers'],
		},
		'3' => {
			'name' =>  'cluster-bgwriter_read',
			'title' => 'background writer allocated buffers',
			'description' => 'Background total allocated bytes per second. Buffers allocated is the total number of allocated new buffers whether or not it was already cached.',
			'ylabel' => 'Size per second',
			'legends' => ['allocated'],
		},
		'4' => {
			'name' =>  'cluster-bgwriter_count',
			'title' => 'background writer count stats',
			'description' => 'Background writer counter stats. Max written clean reports the number of times the background writer stopped a cleaning scan because it had written too many buffers. Buffers backend fsync reports the number of times a backend had to execute its own fsync call (normally the background writer handles those even when the backend does its own write).',
			'ylabel' => 'Times per second',
			'legends' => ['maxwritten clean','buffers backend fsync'],
		},
		'5' => {
			'name' => 'cluster-checkpoints_time',
			'title' => 'checkpoints write stats',
			'description' => 'Background writer statistics on checkpoints. Checkpoint write time reports the total amount of time that has been spent in the portion of checkpoint processing where files are written to disk. Checkpoint sync time reports the total amount of time that has been spent in the portion of checkpoint processing where files are synchronized to disk.',
			'ylabel' => 'Duration',
			'legends' => ['checkpoint write time','checkpoint sync time'],
		},
	},
	'pg_stat_connections.csv' => {
		'1' => {
			'name' =>  'database-connections',
			'title' => 'Connections by type on %s database',
			'all_title' => 'Global connections by type',
			'description' => 'Connections by type including idle ones.',
			'all_description' => 'Global connections by type including idle ones.',
			'ylabel' => 'Number of connections',
			'legends' => ['Active','Idle','Idle in xact', 'Waiting for a lock'],
		},
	},
	'pg_stat_user_functions.csv' => {
		'1' => {
			'name' =>  'database-functions',
			'title' => 'Functions statistics on database %s',
			'description' => 'Statistics about executions times and duration of user functions.',
			'ylabel' => 'Duration',
			'active' => 1,
			'legends' => ['total time','self time'],
			'menu' => 'Functions statistics',
		},
	},
	'pg_stat_user_tables.csv' => {
		'1' => {
			'name' =>  'table-indexes',
			'title' => 'Sequencial vs Index scan on %s',
			'description' => 'Number of sequential scan versus index scan per table during the audit period.',
			'ylabel' => 'Number per second',
			'legends' => ['sequential scan','index scan','% index scan ratio'],
			'y2label' => 'Percent',
			'active' => 1,
			'menu' => 'Index scan ratio',
		},
		'2' => {
			'name' =>  'table-vacuums-analyzes',
			'title' => 'Analyze/vacuums count on %s',
			'description' => 'Number of analyze, autoanalyze, vacuum and autovacuum count per table during the audit period.',
			'ylabel' => 'Number',
			'legends' => ['Analyze','Autoanalyze','Vacuum','Autovacuum'],
			'active' => 1,
			'menu' => 'Vacuums/analyzes',
		},
		'3' => {
			'name' =>  'table-query-tuples',
			'title' => 'Insert/update/delete and hot update tuples on %s',
			'description' => 'Number of insert/update/delete and hot update tuples count per table during the audit period.',
			'ylabel' => 'Number per second',
			'legends' => ['Insert','Update','Delete','Hot Update'],
			'active' => 1,
			'menu' => 'insert/update/delete',
		},
		'4' => {
			'name' =>  'table-kind-tuples',
			'title' => 'Live vs dead tuples on %s',
			'description' => 'Number of live and dead tuples per table at end of the audit period.',
			'ylabel' => 'Number',
			'legends' => ['Live','Dead','% Bloat ratio'],
			'y2label' => 'Percent',
			'active' => 1,
			'menu' => 'Live vs dead tuples',
		},
	},
	'pg_statio_user_tables.csv' => {
		'1' => {
			'name' =>  'statio-table',
			'title' => 'Statistics about I/O on %s',
			'description' => 'Number of disk blocks read from table or all indexes on this table versus number of buffer hits at end of the audit period.',
			'ylabel' => 'Number per second',
			'legends' => ['heap_blks_read','heap_blks_hit','idx_blks_read','idx_blks_hit'],
			'active' => 1,
			'menu' => 'Tables I/O stats',
		},
	},
	'pg_stat_user_indexes.csv' => {
		'1' => {
			'name' =>  'index-scan',
			'title' => 'Statistics about accesses to index %s',
			'description' => 'Number of index entries returned by index scans, and number of live table rows fetched by simple index scans using that index during the audit period.',
			'ylabel' => 'Number per second',
			'legends' => ['index scans initiated','index entries read','live table rows fetched'],
			'y2label' => 'Percent',
			'active' => 1,
			'menu' => 'Index read/fetch',
		},
	},
	'pg_statio_user_indexes.csv' => {
		'1' => {
			'name' =>  'statio-index',
			'title' => 'Statistics about I/O on %s',
			'description' => 'Number of disk blocks read from this index versus number of buffer hits in this index at end of the audit period.',
			'ylabel' => 'Number per second',
			'legends' => ['idx_blks_read','idx_blks_hit'],
			'active' => 1,
			'menu' => 'Indexes I/O stats',
		},
	},
	'pg_stat_invalid_indexes.csv' => {
		'1' => {
			'name' =>  'index-invalid',
			'title' => 'Invalid indexes on %s',
			'description' => 'List of invalid indexes during concurrency build.',
			'ylabel' => 'Number',
			'legends' => ['Invalid index'],
			'active' => 1,
			'menu' => 'Invalid Indexes',
		},
	},
	'pg_stat_hash_indexes.csv' => {
		'1' => {
			'name' =>  'index-hash',
			'title' => 'Hash indexes on %s',
			'description' => 'List of hash indexes during concurrency build.',
			'ylabel' => 'Number',
			'legends' => ['Hash index'],
			'active' => 1,
			'menu' => 'Hash Indexes',
		},
	},
	'pg_stat_unused_indexes.csv' => {
		'1' => {
			'name' =>  'unused-index',
			'title' => 'Unused indexes on %s',
			'description' => 'List of indexes never used (idx_scan = 0).',
			'ylabel' => 'Number',
			'legends' => ['Unused index'],
			'active' => 1,
			'menu' => 'Unused Indexes',
		},
	},
	'pg_stat_redundant_indexes.csv' => {
		'1' => {
			'name' =>  'redundant-index',
			'title' => 'Redundant indexes on %s',
			'description' => 'List of useless indexes because they are redundant. Before removing them, check that the redundant index is not a primary key or an index on a column referencing a foreign key.',
			'ylabel' => 'Number',
			'legends' => ['Redundant index'],
			'active' => 1,
			'menu' => 'Redundant indexes',
		},
	},
	'pg_stat_count_indexes.csv' => {
		'1' => {
			'name' =>  'zero-index',
			'title' => 'Tables without indexes on %s',
			'description' => 'List of tables without indexes.',
			'ylabel' => 'Number',
			'legends' => ['No indexes'],
			'active' => 1,
			'menu' => 'Tables without index',
		},
		'2' => {
			'name' =>  'count-index',
			'title' => 'Tables with lot of indexes on %s',
			'description' => 'List of tables with lot of indexes.',
			'ylabel' => 'Number',
			'legends' => ['Indexes count'],
			'active' => 1,
			'menu' => "Table with more than $MAX_INDEXES Indexes",
		},
	},
	'pg_stat_missing_fkindexes.csv' => {
		'1' => {
			'name' =>  'missing-index',
			'title' => 'Missing FK indexes on %s',
			'description' => 'List of DDL to create missing indexes on foreign keys.',
			'ylabel' => 'Number',
			'legends' => ['Missing index'],
			'active' => 1,
			'menu' => 'Missing indexes',
		},
	},
	'pg_xlog_stat.csv' => {
		'1' => {
			'name' =>  'cluster-xlog_files',
			'title' => 'WAL files',
			'description' => 'Number of WAL file in the xlog directory.',
			'ylabel' => 'Number of files',
			'legends' => ['total xlog'],
		},
	},
	'pg_stat_replication.csv' => {
		'1' => {
			'name' =>  'cluster-xlog',
			'title' => 'Xlog written',
			'description' => 'Number of xlog data written per second.',
			'ylabel' => 'Size per second',
			'legends' => ['written'],
		},
		'2' => {
			'name' =>  'cluster-replication',
			'title' => 'Replication lag with %s',
			'description' => 'Lag of replication between primary and secondary servers.',
			'ylabel' => 'Lag size',
			'legends' => ['Sent','Write','Replay'],
		},
	},
	'pgbouncer_stats.csv' => {
		'1' => {
			'name' =>  'pgbouncer-connections',
			'title' => 'pgbouncer connections statistics on pool %s',
			'description' => 'Number of active/waiting clients, active/idle/used server connections and maximum wait duration for client connections in each pgbouncer pool.',
			'ylabel' => 'Number of connections',
			'legends' => ['Client active','Client waiting','Server active','Server idle','Server used','Clients wait time'],
			'y2label' => 'Duration',
			'active' => 1,
		},
	},
	'pgbouncer_req_stats.csv' => {
		'1' => {
			'name' =>  'pgbouncer-duration',
			'title' => 'pgbouncer average queries duration on %s',
			'description' => 'Average queries duration in each pgbouncer pool.',
			'ylabel' => 'Duration',
			'legends' => ['avg_query'],
		},
		'2' => {
			'name' =>  'pgbouncer-number',
			'title' => 'pgbouncer queries per second on %s',
			'description' => 'Number of queries per second in each pgbouncer pool.',
			'ylabel' => 'Number',
			'legends' => ['avg_req'],
		},
		'3' => {
			'name' =>  'pgbouncer-wait-total',
			'title' => 'pgbouncer wait time on %s',
			'description' => 'Time spent by clients waiting for a server in microseconds.',
			'ylabel' => 'Microseconds',
			'legends' => ['total_wait_time'],
		},
		'4' => {
			'name' =>  'pgbouncer-wait-average',
			'title' => 'Average of wait time spent on %s',
			'description' => 'Average of time spent by clients waiting for a server in microseconds (average per second).',
			'ylabel' => 'Microseconds',
			'legends' => ['avg_wait_time'],
		},
	},
	'pg_class_size.csv' => {
		'1' => {
			'name' =>  'table-size',
			'title' => 'Size of table %s',
			'description' => 'Disk space used by the table with number of rows at end of the audit.',
			'ylabel' => 'Size',
			'legends' => ['Object size', 'Number of tuples' ],
			'y2label' => 'Number',
			'active' => 1,
			'menu' => 'Size and tuples',
		},
		'2' => {
			'name' =>  'index-size',
			'title' => 'Size of index %s',
			'description' => 'Disk space used by the index with number of rows at end of the audit.',
			'ylabel' => 'Size',
			'legends' => ['Object size', 'Number of tuples' ],
			'y2label' => 'Number',
			'active' => 1,
			'menu' => 'Size and tuples',
		},
	},
	'pg_stat_locks.csv' => {
		'1' => {
			'name' =>  'database-lock-types',
			'title' => 'Types of locks on %s database',
			'description' => 'Number of locks per type in a database. Type of the lockable object: relation, extend, page, tuple, transactionid, virtualxid, object, userlock, or advisory.',
			'ylabel' => 'Number',
			'legends' => [],
			'active' => 1,
		},
		'2' => {
			'name' =>  'database-lock-modes',
			'title' => 'Modes of locks on %s database',
			'description' => 'Number of locks per lock mode held or desired by all process.',
			'ylabel' => 'Number',
			'legends' => [],
			'active' => 1,
		},
		'3' => {
			'name' =>  'database-lock-granted',
			'title' => 'Granted locks on %s database',
			'description' => 'Number of locks held (granted) or awaited (waiting).',
			'ylabel' => 'Number',
			'legends' => [],
			'active' => 1,
		},
	},
	'postgresql.conf' => {
		'1' => {
			'name' =>  'cluster-pgconf',
			'title' => 'PostgreSQL configuration',
			'description' => 'Configuration directives and values defined in file postgresql.conf.',
			'ylabel' => 'Number',
			'legends' => ['Settings'],
			'active' => 1,
			'menu' => 'PostgreSQL configuration',
		},
	},
	'postgresql.auto.conf' => {
		'1' => {
			'name' =>  'cluster-alterconf',
			'title' => 'PostgreSQL system altered configuration',
			'description' => 'Configuration directives and values defined using ALTER SYSTEM.',
			'ylabel' => 'Number',
			'legends' => ['Settings'],
			'active' => 1,
			'menu' => 'PostgreSQL system altered configuration',
		},
	},
	'recovery.conf' => {
		'1' => {
			'name' =>  'cluster-recoveryconf',
			'title' => 'PostgreSQL recovery configuration',
			'description' => 'Configuration directives and values defined in file recovery.conf.',
			'ylabel' => 'Number',
			'legends' => ['Settings'],
			'active' => 1,
			'menu' => 'PostgreSQL recovery configuration',
		},
	},
	'pg_hba.conf' => {
		'1' => {
			'name' =>  'cluster-pghba',
			'title' => 'PostgreSQL authorization',
			'description' => 'Client authentication controlled by pg_hba.conf configuration file.',
			'ylabel' => 'Number',
			'legends' => ['Setting','Value'],
			'active' => 1,
			'menu' => 'PostgreSQL authorization',
		},
	},
	'pg_ident.conf' => {
		'1' => {
			'name' =>  'cluster-pgident',
			'title' => 'PostgreSQL User Name Maps',
			'description' => 'Different operating system user / database user mappings might be needed for different connections. They are defined in file pg_ident.conf.',
			'ylabel' => 'Number',
			'legends' => ['Setting','Value'],
			'active' => 1,
			'menu' => 'User Name Maps',
		},
	},
	'pg_settings.csv' => {
		'1' => {
			'name' =>  'cluster-settings',
			'title' => 'PostgreSQL Settings',
			'description' => 'All configuration directives and values defined in pg_settings.',
			'ylabel' => 'Number',
			'legends' => ['Settings'],
			'active' => 1,
			'menu' => 'PostgreSQL settings',
		},
	},
	'pg_nondefault_settings.csv' => {
		'1' => {
			'name' =>  'cluster-nondefault-settings',
			'title' => 'PostgreSQL Non Default Settings',
			'description' => 'Non default configuration directives and values defined in pg_settings.',
			'ylabel' => 'Number',
			'legends' => ['Settings'],
			'active' => 1,
			'menu' => 'PostgreSQL non default settings',
		},
	},
	'pg_db_role_setting.csv' => {
		'1' => {
			'name' =>  'cluster-dbrolesetting',
			'title' => 'PostgreSQL Database/Roles Settings',
			'description' => 'Configuration directives and values defined with ALTER DATABASE and ALTER ROLE.',
			'ylabel' => 'Number',
			'legends' => ['Settings'],
			'active' => 1,
			'menu' => 'Database/Roles settings',
		},
	},
	'pg_hba_rules.csv' => {
		'1' => {
			'name' =>  'cluster-hba',
			'title' => 'PostgreSQL HBA rules',
			'description' => 'All pg_hba.conf rules defined.',
			'ylabel' => 'Number',
			'legends' => ['Rules'],
			'active' => 1,
			'menu' => 'PostgreSQL HBA rules',
		},
	},
	'pgbouncer.ini' => {
		'1' => {
			'name' =>  'cluster-pgbouncer',
			'title' => 'Pgbouncer configuration',
			'description' => 'Configuration directives and values defined in file pgbouncer.ini.',
			'ylabel' => 'Number',
			'legends' => ['Setting','Value'],
			'active' => 1,
			'menu' => 'Pgbouncer settings',
		},
	},
	'pg_database_buffercache.csv' => {
		'1' => {
			'name' =>  'cluster-buffersused',
			'title' => 'Shared buffers utilization per database',
			'description' => 'Show statistics about percentage of shared buffers used per database.',
			'ylabel' => 'Percent',
			'legends' => [],
			'active' => 1,
			'menu' => 'Shared buffers utilization',
		},
		'2' => {
			'name' =>  'cluster-databaseloaded',
			'title' => 'Percentage of each databases loaded in shared buffers',
			'description' => 'Show statistics about percentage of each database loaded in shared buffers.',
			'ylabel' => 'Percent',
			'legends' => [],
			'menu' => 'Databases in shared buffers',
		},
	},
	'pg_database_usagecount.csv' => {
		'1' => {
			'name' =>  'cluster-usagecount',
			'title' => 'Shared buffers usagecount distribution',
			'description' => 'Show statistics about usagecount distribution in shared buffers.',
			'ylabel' => 'Percent',
			'legends' => [],
			'menu' => 'Usagecount utilization',
			'active' => 1,
		},
	},
	'pg_database_isdirty.csv' => {
		'1' => {
			'name' =>  'cluster-isdirty',
			'title' => 'Dirty shared buffers usagecount distribution',
			'description' => 'Show statistics about usagecount distribution in dirty shared buffers.',
			'ylabel' => 'Percent',
			'legends' => [],
			'menu' => 'Dirty Usagecount',
			'active' => 1,
		},
	},
	'pg_relation_buffercache.csv' => {
		'1' => {
			'name' =>  'buffercache-relation',
			'title' => 'Statistics about cache utilization for %s database',
			'description' => 'Number of shared buffers/pages used by a relation.',
			'ylabel' => 'Number',
			'legends' => ['buffers'],
			'active' => 1,
			'menu' => 'Buffercache per relation',
		},
		'2' => {
			'name' =>  'statio-buffercache',
			'title' => 'Statistics about cache utilization %s relation',
			'description' => 'Number of buffers loaded in cache for a relation and the percentage of the relation loaded.',
			'ylabel' => 'Number',
			'y2label' => 'percent',
			'legends' => ['buffered','relation %'],
			'menu' => 'Buffer I/O per relation',
		},
	},
	'pg_stat_archiver.csv' => {
		'1' => {
			'name' =>  'cluster-archive',
			'title' => 'Statistics about archiver',
			'description' => 'Number of WAL files archived with number of failure.',
			'ylabel' => 'Number',
			'legends' => ['archived count', 'failed count'],
			'active' => 1,
			'menu' => 'Archiving',
		}
	},
	'pg_stat_statements.csv' => {
		'1' => {
			'name' =>  'database-queries',
			'title' => 'Statistics about statements',
			'description' => 'Top N statistics about slowest or most used queries.',
			'ylabel' => 'Number',
			'legends' => ['queries'],
			'active' => 1,
			'menu' => 'Statements statistics',
		}
	},
	'pg_stat_unlogged.csv' => {
		'1' => {
			'name' =>  'table-unlogged',
			'title' => 'Unlogged tables on %s',
			'description' => 'List of unlogged tables in the database.',
			'ylabel' => 'Number',
			'legends' => ['Unlogged tables'],
			'active' => 1,
			'menu' => 'Unlogged tables',
		},
	},
	'pg_stat_ext.csv' => {
		'1' => {
			'name' =>  'table-extended',
			'title' => 'Extended statistics defined on %s',
			'description' => 'List of extended planner statistics created in the database.',
			'ylabel' => 'Number',
			'legends' => ['Extended stats'],
			'active' => 1,
			'menu' => 'Extended statistics',
		},
	},
	'pg_subxact_counters.csv' => {
		'1' => {
			'name' =>  'cluster-subxact_counters',
			'title' => 'Global subtransactions counters',
			'description' => 'Subtransactions can lead to performance issue. Counters to monitor the subtransactions (generation rate, overflow, state).',
			'ylabel' => 'Number of subxact',
			'legends' => ['Start','Commit','Abort', 'Overflow'],
			'y2label' => 'Number of overflow',
		},
	},
	'kernel_stats.csv' => {
		'1' => {
			'name' =>  'kernel-psi_host_some',
			'page' =>  'kernel-pressure',
			'title' => 'Host pressure stall: some tasks stalled',
			'description' => 'Percentage of time during which at least one task was stalled waiting for CPU, memory or I/O (pressure stall information, /proc/pressure, kernel 4.20+). This is the best indicator of a resource saturation: a sustained memory pressure means reclaim or swap activity, an I/O pressure means that the storage is the bottleneck.',
			'ylabel' => 'Percent',
			'legends' => [],
			'source' => 'host',
			'metrics' => ['psi_cpu_some', 'psi_memory_some', 'psi_io_some'],
			'mode' => 'psi',
		},
		'2' => {
			'name' =>  'kernel-psi_host_full',
			'page' =>  'kernel-pressure',
			'title' => 'Host pressure stall: all tasks stalled',
			'description' => 'Percentage of time during which all non-idle tasks were stalled at the same time waiting for memory or I/O (CPU full pressure since kernel 5.13). Time lost for any work on the host.',
			'ylabel' => 'Percent',
			'legends' => [],
			'source' => 'host',
			'metrics' => ['psi_cpu_full', 'psi_memory_full', 'psi_io_full'],
			'mode' => 'psi',
		},
		'3' => {
			'name' =>  'kernel-psi_cgroup_some',
			'page' =>  'kernel-pressure',
			'title' => 'PostgreSQL cgroup pressure stall: some tasks stalled',
			'description' => 'Percentage of time during which at least one task of the cgroup of the postmaster was stalled waiting for CPU, memory or I/O (cgroup v2 cpu.pressure, memory.pressure and io.pressure). Shows the effect of the cgroup limits on PostgreSQL.',
			'ylabel' => 'Percent',
			'legends' => [],
			'source' => 'cgroup',
			'metrics' => ['psi_cpu_some', 'psi_memory_some', 'psi_io_some'],
			'mode' => 'psi',
		},
		'4' => {
			'name' =>  'kernel-psi_cgroup_full',
			'page' =>  'kernel-pressure',
			'title' => 'PostgreSQL cgroup pressure stall: all tasks stalled',
			'description' => 'Percentage of time during which all non-idle tasks of the cgroup of the postmaster were stalled at the same time (cgroup v2).',
			'ylabel' => 'Percent',
			'legends' => [],
			'source' => 'cgroup',
			'metrics' => ['psi_cpu_full', 'psi_memory_full', 'psi_io_full'],
			'mode' => 'psi',
		},
		'5' => {
			'name' =>  'kernel-alloc_stalls',
			'page' =>  'kernel-events',
			'title' => 'Memory allocation stalls and compaction',
			'description' => 'Number of direct reclaims (allocstall) and memory compactions (compact_stall, compact_fail) per second (/proc/vmstat). A process doing a direct reclaim is blocked until memory is freed, see vm.min_free_kbytes and vm.watermark_scale_factor.',
			'ylabel' => 'Events per second',
			'legends' => [],
			'source' => 'host',
			'metrics' => ['allocstall', 'compact_stall', 'compact_fail'],
			'mode' => 'rate',
		},
		'6' => {
			'name' =>  'kernel-thp',
			'page' =>  'kernel-events',
			'title' => 'Transparent huge pages allocations',
			'description' => 'Transparent huge pages allocated on page fault, failures falling back to normal pages and failed collapses by khugepaged per second (/proc/vmstat). Fallbacks and compaction stalls are the usual cost of transparent huge pages.',
			'ylabel' => 'Events per second',
			'legends' => [],
			'source' => 'host',
			'metrics' => ['thp_fault_alloc', 'thp_fault_fallback', 'thp_collapse_alloc_failed'],
			'mode' => 'rate',
		},
		'7' => {
			'name' =>  'kernel-oom',
			'page' =>  'kernel-events',
			'title' => 'Out of memory kills',
			'description' => 'Number of processes killed by the OOM killer on the host per interval (/proc/vmstat oom_kill). The OOM events of the cgroup of the postmaster are in the cgroup memory events graph.',
			'ylabel' => 'Number of events',
			'legends' => [],
			'source' => 'host',
			'metrics' => ['oom_kill'],
			'mode' => 'count',
		},
		'8' => {
			'name' =>  'kernel-cgroup_memory_events',
			'page' =>  'kernel-events',
			'title' => 'PostgreSQL cgroup memory events',
			'description' => 'Number of times the cgroup of the postmaster was throttled because its memory usage was above memory.high (high), reached memory.max (max), had an OOM event (oom) or a process killed (oom_kill) per interval (cgroup v2 memory.events).',
			'ylabel' => 'Number of events',
			'legends' => [],
			'source' => 'cgroup',
			'metrics' => ['memory_events_high', 'memory_events_max', 'memory_events_oom', 'memory_events_oom_kill'],
			'mode' => 'count',
		},
		'9' => {
			'name' =>  'kernel-refaults',
			'page' =>  'kernel-events',
			'title' => 'Page cache refaults',
			'description' => 'Number of pages read again shortly after being evicted from memory per second (/proc/vmstat workingset_refault). A high value means that the working set does not fit in memory: the page cache is thrashing.',
			'ylabel' => 'Pages per second',
			'legends' => [],
			'source' => 'host',
			'metrics' => ['workingset_refault'],
			'mode' => 'rate',
		},
		'10' => {
			'name' =>  'kernel-numa',
			'page' =>  'kernel-events',
			'title' => 'NUMA allocations',
			'description' => 'Number of pages allocated on their preferred NUMA node (numa_hit) or on an other node (numa_miss, numa_foreign) per second (/proc/vmstat). Misses mean remote memory accesses, see kernel.numa_balancing and vm.zone_reclaim_mode.',
			'ylabel' => 'Pages per second',
			'legends' => [],
			'source' => 'host',
			'metrics' => ['numa_hit', 'numa_miss', 'numa_foreign'],
			'mode' => 'rate',
		},
	},
	'pg_stat_aio.csv' => {
		'1' => {
			'name' =>  'cluster-io_workers',
			'page' =>  'cluster-io_aio',
			'title' => 'I/O workers',
			'description' => 'Number of I/O worker processes running when io_method is set to worker (PostgreSQL 18+), compared to the io_workers setting (PostgreSQL 18) or to the io_min_workers and io_max_workers limits of the automatically sized pool (PostgreSQL 19+).',
			'ylabel' => 'Number of workers',
			'legends' => [],
		},
		'2' => {
			'name' =>  'cluster-io_aio_inflight',
			'page' =>  'cluster-io_aio',
			'title' => 'Asynchronous I/O in progress (sampled)',
			'description' => 'Number of asynchronous I/O in progress at the time of each snapshot, total and by operation (pg_aios, PostgreSQL 18+). This is a sample taken at each collect, not a cumulative counter: short peaks between two snapshots are not visible.',
			'ylabel' => 'Number of I/O',
			'legends' => [],
		},
	},
	'pg_stat_io.csv' => {
		'1' => {
			'name' =>  'cluster-io_read_throughput',
			'page' =>  'cluster-io_throughput',
			'title' => 'I/O read throughput per backend type',
			'description' => 'Bytes read per second from disk (or the OS page cache) on relations and temporary relations, by backend type (pg_stat_io). The percentage is the share of each backend type over the whole period. Since PostgreSQL 18 several blocks can be read with a single I/O operation.',
			'ylabel' => 'Size per second',
			'legends' => [],
		},
		'2' => {
			'name' =>  'cluster-io_write_throughput',
			'page' =>  'cluster-io_throughput',
			'title' => 'I/O write throughput per backend type',
			'description' => 'Bytes written per second on relations and temporary relations, by backend type (pg_stat_io). Writes are expected to be done by the checkpointer and the background writer, a high share of client backends or autovacuum workers means that they have to write dirty buffers by themselves.',
			'ylabel' => 'Size per second',
			'legends' => [],
		},
		'3' => {
			'name' =>  'cluster-io_extend_throughput',
			'page' =>  'cluster-io_throughput',
			'title' => 'Relation extension throughput per backend type',
			'description' => 'Bytes per second used to extend relations and temporary relations (new blocks added to the files), by backend type (pg_stat_io). This shows which processes are growing the data files.',
			'ylabel' => 'Size per second',
			'legends' => [],
		},
		'4' => {
			'name' =>  'cluster-io_buffer_writes',
			'page' =>  'cluster-io_writers',
			'title' => 'Shared buffers writes per backend type',
			'description' => 'Bytes written per second from shared buffers in the normal context (no buffer access strategy) by backend type (pg_stat_io). Dirty buffers should mostly be written by the checkpointer and the background writer. When client backends have a high share, they have to write dirty buffers themselves before reusing them: look at shared_buffers, bgwriter_lru_maxpages, bgwriter_lru_multiplier and bgwriter_delay.',
			'ylabel' => 'Size per second',
			'legends' => [],
		},
		'5' => {
			'name' =>  'cluster-io_evictions',
			'page' =>  'cluster-io_writers',
			'title' => 'Shared buffers evictions per backend type',
			'description' => 'Number of buffers evicted per second from shared buffers in the normal context to make room for another block, by backend type (pg_stat_io). A sustained eviction rate means that the working set does not fit in shared buffers.',
			'ylabel' => 'Buffers per second',
			'legends' => [],
		},
		'6' => {
			'name' =>  'cluster-io_backend_fsyncs',
			'page' =>  'cluster-io_writers',
			'title' => 'fsync calls done by backends',
			'description' => 'Number of fsync calls per second on relations done by processes other than the checkpointer (pg_stat_io). This should be zero: a backend has to execute its own fsync only when the checkpointer fsync request queue is full.',
			'ylabel' => 'Fsync per second',
			'legends' => [],
		},
		'7' => {
			'name' =>  'cluster-io_hit_ratio',
			'page' =>  'cluster-io_cache',
			'title' => 'Buffer hit ratio per I/O context',
			'description' => 'Percentage of blocks found in shared buffers on relations, per I/O context (pg_stat_io). Unlike the database cache ratio this distinguishes the normal context from the bulkread (large sequential scans), bulkwrite (COPY, CREATE TABLE AS) and vacuum contexts that use a small ring of buffers and are expected to have a low hit ratio.',
			'ylabel' => 'Percent',
			'legends' => [],
		},
		'8' => {
			'name' =>  'cluster-io_ring_buffers',
			'page' =>  'cluster-io_cache',
			'title' => 'Ring buffers reuses and evictions',
			'description' => 'Buffers reused from the ring and buffers evicted from shared buffers per second in the bulkread, bulkwrite and vacuum contexts (pg_stat_io). Reuses are expected, a high number of evictions compared to reuses means that the ring had to take new buffers from shared buffers, see vacuum_buffer_usage_limit for the vacuum context.',
			'ylabel' => 'Buffers per second',
			'legends' => [],
		},
		'9' => {
			'name' =>  'cluster-io_read_latency',
			'page' =>  'cluster-io_latency',
			'title' => 'Average read latency per backend type',
			'description' => 'Average time in milliseconds of a read operation on relations and temporary relations, by backend type (pg_stat_io). Requires track_io_timing. Since PostgreSQL 18 a read operation can read several blocks, see the average I/O size graph.',
			'ylabel' => 'Duration',
			'legends' => [],
			'timing' => 'track_io_timing',
		},
		'10' => {
			'name' =>  'cluster-io_write_latency',
			'page' =>  'cluster-io_latency',
			'title' => 'Average write latency per backend type',
			'description' => 'Average time in milliseconds of a write operation on relations and temporary relations, by backend type (pg_stat_io). Requires track_io_timing.',
			'ylabel' => 'Duration',
			'legends' => [],
			'timing' => 'track_io_timing',
		},
		'11' => {
			'name' =>  'cluster-io_extend_latency',
			'page' =>  'cluster-io_latency',
			'title' => 'Average relation extension latency per backend type',
			'description' => 'Average time in milliseconds of a relation extension operation on relations and temporary relations, by backend type (pg_stat_io). Requires track_io_timing.',
			'ylabel' => 'Duration',
			'legends' => [],
			'timing' => 'track_io_timing',
		},
		'12' => {
			'name' =>  'cluster-io_fsync_latency',
			'page' =>  'cluster-io_latency',
			'title' => 'Average fsync latency per backend type',
			'description' => 'Average time in milliseconds of a fsync call on relations, by backend type (pg_stat_io). Requires track_io_timing.',
			'ylabel' => 'Duration',
			'legends' => [],
			'timing' => 'track_io_timing',
		},
		'13' => {
			'name' =>  'cluster-io_size',
			'page' =>  'cluster-io_latency',
			'title' => 'Average I/O size on relations',
			'description' => 'Average number of bytes per read, write and extend operation on relations (pg_stat_io, PostgreSQL 18+). Values higher than the block size show that consecutive blocks are combined into a single I/O operation, see io_combine_limit.',
			'ylabel' => 'Size',
			'legends' => [],
		},
		'14' => {
			'name' =>  'cluster-io_wal_write',
			'page' =>  'cluster-io_wal',
			'title' => 'WAL write throughput per backend type',
			'description' => 'Bytes of WAL written per second by backend type (pg_stat_io, PostgreSQL 18+). WAL should mostly be written by the WAL writer, a high share of client backends means that wal_buffers was full or that synchronous commits had to write their own WAL.',
			'ylabel' => 'Size per second',
			'legends' => [],
		},
		'15' => {
			'name' =>  'cluster-io_wal_fsync',
			'page' =>  'cluster-io_wal',
			'title' => 'WAL fsync calls per backend type',
			'description' => 'Number of fsync calls per second on WAL files by backend type (pg_stat_io, PostgreSQL 18+). With synchronous_commit on, each commit not covered by a previous flush leads to a fsync by the committing backend.',
			'ylabel' => 'Fsync per second',
			'legends' => [],
		},
		'16' => {
			'name' =>  'cluster-io_wal_write_latency',
			'page' =>  'cluster-io_wal',
			'title' => 'Average WAL write latency per backend type',
			'description' => 'Average time in milliseconds of a WAL write operation by backend type (pg_stat_io, PostgreSQL 18+). Requires track_wal_io_timing.',
			'ylabel' => 'Duration',
			'legends' => [],
			'timing' => 'track_wal_io_timing',
		},
		'17' => {
			'name' =>  'cluster-io_wal_fsync_latency',
			'page' =>  'cluster-io_wal',
			'title' => 'Average WAL fsync latency per backend type',
			'description' => 'Average time in milliseconds of a fsync call on WAL files by backend type (pg_stat_io, PostgreSQL 18+). This is the latency added to each commit that has to flush WAL. Requires track_wal_io_timing.',
			'ylabel' => 'Duration',
			'legends' => [],
			'timing' => 'track_wal_io_timing',
		},
		'18' => {
			'name' =>  'cluster-io_wal_init',
			'page' =>  'cluster-io_wal',
			'title' => 'WAL segments initialization',
			'description' => 'Bytes written per second to initialize new WAL segment files, by backend type (pg_stat_io init context, PostgreSQL 18+). This activity happens when no recycled segment is available, see wal_init_zero, wal_recycle, min_wal_size and max_wal_size.',
			'ylabel' => 'Size per second',
			'legends' => [],
		},
		'19' => {
			'name' =>  'cluster-io_wal_read',
			'page' =>  'cluster-io_wal',
			'title' => 'WAL read throughput per backend type',
			'description' => 'Bytes of WAL read per second by backend type (pg_stat_io, PostgreSQL 18+), for example by the startup process during recovery or by WAL senders for replication and logical decoding.',
			'ylabel' => 'Size per second',
			'legends' => [],
		},
		'20' => {
			'name' =>  'cluster-io_temp_throughput',
			'page' =>  'cluster-io_temp',
			'title' => 'Temporary relations I/O throughput',
			'description' => 'Bytes read, written and used to extend temporary tables per second (pg_stat_io object temp relation). Temporary tables use local buffers private to each session (temp_buffers), writes and reads mean that the temporary data do not fit in temp_buffers.',
			'ylabel' => 'Size per second',
			'legends' => [],
		},
		'21' => {
			'name' =>  'cluster-io_temp_hit_ratio',
			'page' =>  'cluster-io_temp',
			'title' => 'Local buffers hit ratio',
			'description' => 'Percentage of temporary relations blocks found in local buffers (pg_stat_io object temp relation). A low ratio with a lot of reads may justify a higher temp_buffers for the sessions using large temporary tables.',
			'ylabel' => 'Percent',
			'legends' => [],
		},
		'22' => {
			'name' =>  'cluster-io_temp_evictions',
			'page' =>  'cluster-io_temp',
			'title' => 'Local buffers evictions per backend type',
			'description' => 'Number of local buffers evicted per second to make room for another block of a temporary relation, by backend type (pg_stat_io object temp relation).',
			'ylabel' => 'Buffers per second',
			'legends' => [],
		},
	},
	'pg_stat_waitevent.csv' => {
		'1' => {
			'name' =>  'cluster-waitevent_types',
			'title' => 'Wait Events types',
			'description' => 'Wait event by type. <b>Activity</b>: The server process is idle. This event type indicates a process waiting for activity in its main processing loop. <b>BufferPin</b>: The server process is waiting for exclusive access to a data buffer. Buffer pin waits can be protracted if another process holds an open cursor that last read data from the buffer in question. <b>Client</b>: The server process is waiting for activity on a socket connected to a user application. Thus, the server expects something to happen that is independent of its internal processes. <b>Extension</b>: The server process is waiting for some condition defined by an extension module. <b>IO</b>: The server process is waiting for an I/O operation to complete. <b>IPC</b>: The server process is waiting for some interaction with another server process. <b>Lock</b>: The server process is waiting for a heavyweight lock. Heavyweight locks, also known as lock manager locks or simply locks, primarily protect SQL-visible objects such as tables. However, they are also used to ensure mutual exclusion for certain internal operations such as relation extension. <b>LWLock</b>: The server process is waiting for a lightweight lock. Most such locks protect a particular data structure in shared memory. <b>Timeout</b>: The server process is waiting for a timeout to expire.',
			'ylabel' => 'Number of events types',
			'legends' => [],
		},
		'2' => {
			'name' =>  'cluster-waitevent_events',
			'title' => 'Wait Events',
			'description' => 'Use of Wait events. See <a href="https://www.postgresql.org/docs/current/monitoring-stats.html#WAIT-EVENT-TABLE" target="new">Wait Event table</a> for more information.',
			'ylabel' => 'Number of events types',
			'legends' => [],
		},
	},
);

my %SAR_GRAPH_INFOS = (
	'1' => {
		'name' =>  'system-cpu',
		'title' => 'CPU %s utilization',
		'all_title' => 'Global CPU utilization',
		'description' => 'Percentage of CPU utilization that occurred while executing at the system level (kernel), the user level (application) and the percentage of time that the CPU or CPUs were idle during which the system had an outstanding disk I/O request. The Idle stat shows the percentage of time that the CPUs were idle and the system did not have an outstanding disk I/O request.',
		'all_description' => 'Percentage of CPU utilization that occurred while executing at the system level (kernel), the user level (application) and the percentage of time that the CPU or CPUs were idle during which the system had an outstanding disk I/O request. The Idle stat shows the percentage of time that the CPUs were idle and the system did not have an outstanding disk I/O request.',
		'ylabel' => 'Percentage',
		'legends' => ['Total','System','User','Idle','Iowait'],
		'active' => 1,
	},
	'2' => {
		'name' =>  'system-load',
		'title' => 'System load',
		'description' => 'System  load average for the last minute, the past 5 and 15 minutes. The load average is calculated as the average number of runnable or running tasks (R state), and the number of tasks in uninterruptible sleep (D state) over the specified interval.',
		'ylabel' => 'Process load',
		'legends' => ['ldavg-1','ldavg-5','ldavg-15'],
	},
	'3' => {
		'name' =>  'system-process',
		'title' => 'Number of process',
		'description' => 'Number of tasks in the task list.',
		'ylabel' => 'Number of process',
		'legends' => ['plist-sz'],
	},
	'4' => {
		'name' =>  'system-memory',
		'title' => 'System memory utilization',
		'description' => 'Amount of memory used to cache data or as buffers by the kernel and free memory available.',
		'ylabel' => 'Memory size',
		'legends' => ['cached','buffers','memfree'],
	},
	'5' => {
		'name' =>  'system-swap',
		'title' => 'Swap In/Out (pages/seconds)',
		'description' => 'Total number of swap pages the system brought in/out per second. The page size usually is 4096 bytes.',
		'ylabel' => 'Pages/second',
		'legends' => ['pswpin/s','pswpout/s'],
	},
	'6' => {
		'name' =>  'system-block',
		'title' => 'Block In/Out (blocks/seconds)',
		'description' => 'Total amount of data read/write from the devices in blocks per second. Blocks are equivalent to sectors and therefore have a size of 512 bytes.',
		'ylabel' => 'Block per second',
		'legends' => ['bread/s','bwrtn/s'],
	},
	'7' => {
		'name' =>  'system-device',
		'title' => 'Data read/write on device %s',
		'description' => 'Number of bytes read/write from/to the device..',
		'ylabel' => 'Size Read/Written per second',
		'legends' => ['Read', 'Write'],
	},
	'8' => {
		'name' =>  'system-cpudevice',
		'title' => 'CPU utilization on device %s',
		'description' => 'Percentage of CPU time during which I/O requests were issued to the device (bandwidth utilization for the device). Device saturation occurs when this value is close to 100%.',
		'ylabel' => 'Percentage of CPU',
		'legends' => ['cpu used'],
	},
	'9' => {
		'name' =>  'system-srvtime',
		'title' => 'Average wait/service time for I/O requests on device %s',
		'description' => 'Await is the average time (in milliseconds) for I/O requests issued to the device to be served. This includes the time spent by the requests in queue and the time spent servicing them. Srvtime is the average service time (in milliseconds) for I/O requests that were issued to the device. Service time have been removed since sar verion 12.1.2',
		'ylabel' => 'Milliseconds',
		'y2label' => 'Milliseconds',
		'legends' => ['await','svctm'],
	},
	'10' => {
		'name' =>  'system-runqueue',
		'title' => 'Run queue length',
		'description' => 'Number of tasks waiting for run time and number of tasks currently blocked, waiting for I/O to complete (sysstat >= 9.1.7).',
		'ylabel' => 'Run queue length',
		'legends' => ['runq-sz','blocked'],
	},
	'11' => {
		'name' => 'system-page',
		'title' => 'System cache statistics',
		'description' => 'Total number of kilobytes the system paged in/out from/to disk per second.',
		'ylabel' => 'Size paged',
		'legends' => [ 'pgpgin/s', 'pgpgout/s' ],
	},
	'12' => {
		'name' => 'network-utilization',
		'title' => 'Network utilization on interface %s',
		'description' => 'Report statistics from the network devices utilization.',
		'ylabel' => 'Size per second',
		'legends' => ['received (rx)', 'transmitted (tx)' ],
	},
	'13' => {
		'name' => 'network-error',
		'title' => 'Network errors on interface %s',
		'description' => 'Report statistics on failures from the network device. Number of bad packets received,  number of errors that happened while transmitting packets, and number of collisions that happened per second while transmitting packets.',
		'ylabel' => 'Number per second',
		'legends' => ['rx errors', 'tx errors', 'collisions' ],
	},
	'14' => {
		'name' =>  'system-cswch',
		'title' => 'Context switches',
		'description' => 'Total number of context switches per second.',
		'ylabel' => 'Context switches',
		'legends' => ['cswch/s'],
	},
	'15' => {
		'name' =>  'system-pcrea',
		'title' => 'Tasks created',
		'description' => 'Total number of tasks created per second.',
		'ylabel' => 'Tasks',
		'legends' => ['proc/s'],
	},
	'16' => {
		'name' =>  'system-tps',
		'title' => 'Total number of transfers per second',
		'description' => 'Total number of transfers per second that were issued to physical devices. A transfer is an I/O request to a physical device. Multiple logical requests can be combined into a single I/O request to the device. A transfer is of indeterminate size.',
		'ylabel' => 'Transfers per second',
		'legends' => ['tps','rtps','wtps'],
	},
	'17' => {
		'name' =>  'system-tpsdevice',
		'title' => 'Transfert per second on device %s',
		'description' => 'Number of transfers per second that were issued to the device, multiple logical requests can be combined into a single I/O request to the device (a transfer is of indeterminate size).',
		'ylabel' => 'Number of transfers per second',
		'legends' => ['Tps'],
	},
	'18' => {
		'name' =>  'system-dirty',
		'title' => 'Dirty memory to be written',
		'description' => 'Amount of memory in kilobytes waiting to get written back to the disk with amount of active and inactive memory (sysstat >= 10.1.2).',
		'ylabel' => 'Memory size',
		'legends' => ['active','inactive','dirty'],
	},
	'19' => {
		'name' =>  'system-space',
		'title' => 'Disk space utilization on device %s',
		'description' => 'Percentage of disk space and inode used on the device. Close to 100% mean no more space or inode left.',
		'ylabel' => 'Percentage used',
		'legends' => ['Space', 'Inode'],
	},
	'20' => {
		'name' => 'system-fault',
		'title' => 'System page fault statistics',
		'description' => 'Total number of major and minor faults the system has made per second. Major are those which have required loading a memory page from disk and minor from cache. Dataset "minflt/s" is calculated as result of "fault/s - majflt/s".',
		'ylabel' => 'Number of faults',
		'legends' => [ 'majflt/s', 'minflt/s' ],
	},
	'21' => {
		'name' => 'system-scanpage',
		'title' => 'System page scanned statistics',
		'description' => 'Total number of pages scanned by the kswapd daemon and number of pages scanned directly per second. Number of pages the system has reclaimed from cache (pagecache and swapcache) per second to satisfy its memory demands. "%vmeff" is the efficiency of page reclaim. If it is near 100% then almost every page coming off the tail of the inactive list is being reaped. If it gets too low (e.g. less than 30%) then the virtual memory is having some difficulty.',
		'ylabel' => 'Number of pages',
		'y2label' => 'Percents',
		'legends' => [ 'pgscank/s', 'pgscand/s', 'pgsteal/s', '%vmeff' ],
	},
	'22' => {
		'name' =>  'system-commit_memory',
		'title' => 'Estimated memory to complete the workload',
		'description' => 'CommitLimit is the total amount of memory currently available to be allocated on the system based on the overcommit ratio (vm.overcommit_ratio). This limit is only adhered to if strict overcommit accounting is enabled (vm.overcommit_memory = 2). CommitLimit is calculated with the following formula: (MemTotal - Hugetlb) * overcommit_ratio / 100. Committed_AS is the total amount of memory estimated to complete the workload. This value represents the worst case scenario value, and also includes swap memory.',
		'ylabel' => 'Size',
		'legends' => ['CommitLimit', 'Committed_AS'],
	},
	'23' => {
		'name' =>  'system-await',
		'title' => 'Average wait time for I/O requests on device %s',
		'description' => 'Await is the average time (in milliseconds) for I/O requests issued to the device to be served. This includes the time spent by the requests in queue and the time spent servicing them.',
		'ylabel' => 'Milliseconds',
		'y2label' => 'Milliseconds',
		'legends' => ['await'],
	},
	'24' => {
		'name' => 'network-utilization-tcp',
		'title' => 'TCPv4 utilization',
		'description' => 'TCPv4 network trafic (all interfaces)',
		'ylabel' => 'Events/s',
		'legends' => [ 'Initiated opens', 'Passive opens', 'Received segments', 'Sent segments' ],
	},
	'25' => {
		'name' => 'network-error-tcp',
		'title' => 'TCPv4 errors',
		'description' => 'TCPv4 network errors (all interfaces)',
		'ylabel' => 'Errors/s',
		'legends' => [ 'Failed attempts', 'Established & reset', 'Retransmitted segments', 'Received in error', 'Reset flags' ],
	},
);

my %PIDSTAT_GRAPH_INFOS = (
	'1' => {
		'name' =>  'postgres-cpu',
		'title' => 'PostgreSQL CPU %s utilization',
		'all_title' => 'Global CPU utilization',
		'description' => 'Percentage of CPU used by PostgreSQL while executing at the user level (application), with or without nice priority. Note that this field does NOT include time spent running a virtual processor.',
		'all_description' => 'Percentage of CPU used by PostgreSQL while executing at the user level (application), with or without nice priority. Note that this field does NOT include time spent running a virtual processor.',
		'ylabel' => 'Percentage',
		'legends' => ['Total','System','User','Wait'],
		'active' => 1,
	},
	'2' => {
		'name' =>  'postgres-memory',
		'title' => 'PostgreSQL memory utilization',
		'description' => 'Report memory utilization. Virtual Size (VSZ): The virtual memory usage of entire task in kilobytes. Resident Set Size (RSS): The non-swapped physical memory used by the task in kilobytes. Values are the sum of all PostgreSQL processes, the shared memory is counted for each process using it.',
		'ylabel' => 'Memory size',
		'legends' => ['VSZ','RSS'],
	},
	'3' => {
		'name' =>  'postgres-mempercent',
		'title' => 'PostgreSQL percentage memory use',
		'description' => 'Report percentage of  memory use. The tasks\'s currently used share of available physical memory.',
		'ylabel' => 'Percent of Memory',
		'legends' => ['%MEM'],
	},
	'4' => {
		'name' =>  'postgres-io',
		'title' => 'PostgreSQL I/O statistics',
		'description' => 'Number of kilobytes PostgreSQL has caused to be read/written from/to disk per second. Number of kilobytes whose writing to disk has been cancelled by the task. This may occur when the task truncates some dirty pagecache. In this case, some IO which another task has been accounted for will not be happening.',
		'ylabel' => 'Kb per second',
		'legends' => ['kB_rd/s','kB_wr/s','kB_ccwr/s'],
	},
	'5' => {
		'name' =>  'postgres-iodelay',
		'title' => 'PostgreSQL I/O delay',
		'description' => 'Block I/O delay of the task being monitored, measured in clock ticks. This metric includes the delays spent waiting for sync block I/O completion and for swapin block I/O completion.',
		'ylabel' => 'Block I/O delay',
		'legends' => ['iodelay'],
	},
	'6' => {
		'name' => 'postgres-fault',
		'title' => 'Page faults statistics',
		'description' => 'Total number of minor/major faults the task has made per second, those which have not required loading a memory page from disk..',
		'ylabel' => 'Number of faults',
		'legends' => [ 'minflt/s', 'majflt/s' ],
	},
	'7' => {
		'name' =>  'postgres-cswch',
		'title' => 'PostgreSQL switching activity',
		'description' => 'Total number of voluntary/non voluntary context switches the task made per second. A voluntary context switch occurs when a task blocks because it requires a resource that is unavailable. A involuntary context switch takes place when a task executes for the duration of its time slice and then is forced to relinquish the processor.',
		'ylabel' => 'Context switches',
		'legends' => ['cswch/s', 'nvcswch/s'],
	},
);


my $COPYRIGHT = qq{
      <hr>
      <footer>
	<p>Report generated by <a href="http://pgcluu.darold.net/">$PROGRAM</a> $VERSION.</p>
      </footer>
};

# read configuration file before reading command line parameters
&read_conf();

# Process command line options and look for an action keyword. There
# are no mandatory options.
my @dbs_opts = ();
my @dev_opts = ();
my @tbs_opts = ();
my @net_opts = ();
GetOptions(
	"b|begin=s"          => \$BEGIN,
	"d|db-only=s"        => \@dbs_opts,
	"c|clean!"           => \$CLEAN,
	"C|cache!"           => \$CACHE,
	"D|device-only=s"    => \@dev_opts,
	"e|end=s"            => \$END,
	"h|help!"            => \$HELP,
	"i|sar-file=s"       => \$SAR_INPUT_FILE,
	"I|sadc-file=s"      => \$SADC_INPUT_FILE,
	"n|top-number=i"     => \$TOP_STAT,
	"N|network-only=s"   => \@net_opts,
	"o|output=s"         => \$OUTPUT_DIR,
	"p|pidstat-file=s"   => \$PIDSTAT_INPUT_FILE,
	"s|sadf=s"           => \$SADF_PROG,
	"r|reverse-date"     => \$REVERT_DATE,
	"S|disable-sar!"     => \$DISABLE_SAR,
	"t|with-table=s"     => \@tbs_opts,
	"T|no-table!"        => \$NO_TB_STAT,
	"v|verbose!"         => \$DEBUG,
	"V|version!"         => \$SHOW_VER,
	"z|timezone=s"       => \$TIMEZONE,
	"Z|stats-timezone=s" => \$STATS_TIMEZONE,
	"x|external-menu!"   => \$EXTERNAL_MENU,
	"from-sa-file!"      => \$FROM_SA_FILE,
	"charset=s"          => \$charset,
	"retention=i"        => \$RETENTION,
) or die usage();

&usage if ($HELP);


# Print version number to stdout
if ($SHOW_VER) {
	print "Version: $VERSION\n";
	exit 0;
}

# Clean retention value
if ($RETENTION) {
	$RETENTION =~ s/[+\-]//g;
}

my $INPUT_DIR   = $ARGV[0] || '';
# The input directory is part of the keys of the offsets stored in the cache,
# it must be written the same way by pgcluu and pgcluu.cgi.
$INPUT_DIR =~ s#/{2,}#/#g;
$INPUT_DIR =~ s#(.)/$#$1#;
$OUTPUT_DIR =~ s/\/$//;

# Set list of objects to monitor from command line options
# options. It can be used multiple time but also as a comma
# separated list of object name.
foreach (@dbs_opts) {
	push(@INCLUDE_DB, split(/[,]+/, $_));
}
foreach (@dev_opts) {
	push(@INCLUDE_DEV, split(/[,]+/, $_));
}
foreach (@tbs_opts) {
	push(@INCLUDE_TB, split(/[,]+/, $_));
}
foreach (@net_opts) {
	push(@INCLUDE_IFACE, split(/[,]+/, $_));
}

# Check start/end date time
if ($BEGIN) {
	print "DEBUG: Found BEGIN parameter: $BEGIN \n" if ($DEBUG);
	if ($BEGIN =~ /^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/) {
		$BEGIN = &timegm_nocheck($6, $5, $4, $3, $2 - 1, $1 - 1900) * 1000;
		$o_day = $3;
		$o_month = $2;
		$o_year = $1;
	} elsif ($BEGIN =~ /^(\d{4})-(\d{2})-(\d{2})$/) {
		$BEGIN = &timegm_nocheck(0, 0, 0, $3, $2 - 1, $1 - 1900) * 1000;
		$o_day = $3;
		$o_month = $2;
		$o_year = $1;
	} else {
		die "FATAL: bad format for begin datetime, should be yyyy-mm-dd hh:mm:ss\n";
	}
	print "DEBUG: Final BEGIN value: $BEGIN \n" if ($DEBUG);
}
if ($END) {
        print "DEBUG: Found END parameter: $END \n" if ($DEBUG);
	if ($END =~ /^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/) {
		$END = &timegm_nocheck($6, $5, $4, $3, $2 - 1, $1 - 1900) * 1000;
	} elsif ($END =~ /^(\d{4})-(\d{2})-(\d{2})$/) {
		$END = &timegm_nocheck(0, 0, 0, $3, $2 - 1, $1 - 1900) * 1000;
	} else {
		die "FATAL: bad format for ending datetime, should be yyyy-mm-dd hh:mm:ss\n";
	}
	print "DEBUG: Final END value: $BEGIN \n" if ($DEBUG);
}

# Force the user to give an output directory
if (!$CACHE && !$OUTPUT_DIR)
{
	die "FATAL: you must give an output directory $OUTPUT_DIR.\n";
}

if (!$CACHE)
{

	# Look for incremental directories (presence of years directories)
	if (not opendir(DIR, "$OUTPUT_DIR")) {
		die "FATAL: Can't open directory $OUTPUT_DIR: $!\n";
	}
	my @years = grep { /^\d+$/ && -d "$OUTPUT_DIR/$_" } readdir(DIR);
	closedir(DIR);
	$have_incremental_dir = 1 if ($#years >= 0);
	####
	# With retention limit we first start to remove obsolete tree
	####
	if ($RETENTION > 0 && $OUTPUT_DIR)
	{
		foreach my $y (sort { $a <=> $b } @years)
		{
			print "DEBUG: looking for obsolete directories under $OUTPUT_DIR/$y/\n" if ($DEBUG);
			`find '$OUTPUT_DIR/$y/' -name '*' -mtime +$RETENTION -delete`;
		}
	}

	# Check if the directory is empty if we are not in cache or incremental modes
	if (!$have_incremental_dir)
	{
		opendir(IDIR, "$OUTPUT_DIR") || die "FATAL: can not open directory $OUTPUT_DIR: $!";
		my @files = grep { /\.html$/ } readdir(IDIR);
		closedir(IDIR);
		if ($#files >= 0)
		{
			die "FATAL: output directory $OUTPUT_DIR is not empty";
		}
	}
}

# Check that sar input file is set when no input directory is provided
# otherwise that mean that this is a miss use and the input directory
# is missing.
if (!$INPUT_DIR || !-d $INPUT_DIR) {
	if (!$SAR_INPUT_FILE && !$SADC_INPUT_FILE) {
		print STDERR "ERROR: you must specify a valid input directory: $INPUT_DIR.\n";
		&usage();
	} elsif ($CACHE) {
		$INPUT_DIR = dirname($SAR_INPUT_FILE || $SADC_INPUT_FILE);
	}
}

# As cache mode can be run in cron job, absolute path for input directory is mandatory
if ($CACHE) {
	# Ensure this is not a relative path
	if (dirname($INPUT_DIR) eq '.') {
		die "FATAL: input directory ($INPUT_DIR) must be an absolute path in caching mode.\n";
	}

	# Warn that in cache mode the output directory in the same as input one
	if ($OUTPUT_DIR) {
		warn "WARNING: output directory will not be used, cache files will be generated in $INPUT_DIR\n" if ($DEBUG);
	}

	# Only one pgcluu process can build the cache of an input directory at
	# a time: a run started by cron while the previous one is still running
	# would read the cache files while they are rewritten. The lock is kept
	# until the end of the process.
	if (!open($CACHE_RUN_LOCK, '>>', "$INPUT_DIR/$CACHE_RUN_LOCK_FILE")) {
		die "FATAL: can't open lock file $INPUT_DIR/$CACHE_RUN_LOCK_FILE, $!\n";
	}
	if (!flock($CACHE_RUN_LOCK, LOCK_EX|LOCK_NB)) {
		print STDERR "WARNING: an other pgcluu process is building the cache of $INPUT_DIR, nothing to do.\n";
		exit 0;
	}

} else {

	# Write resources files (js and css) from __DATA__ section if they have not
	# been copied yet.
	&write_resources();

}

####
# In cache mode we have to look into subdirectories to find daily or hourly data files.
# In normal mode we will just compute statistics from the input directory.
# All working directories will be added to the @WORK_DIRS array
####
my @WORK_DIRS = ();
# Set working dir to - to mark that it is not used, by this way we will only parse sar file
if (!$INPUT_DIR && ($SAR_INPUT_FILE || $SADC_INPUT_FILE)) {
	push(@WORK_DIRS, '-');
} else {
	@WORK_DIRS = &get_data_directories();
}

####
# Now we will look over each statistics directories to compute stats
####
my $ORIG_OUTPUT_DIR = $OUTPUT_DIR;
foreach (my $dx = 0; $dx <= $#WORK_DIRS; $dx++)
{
	# Reset global variables before processing a new work dir
	&clear_stats();

	my $in_dir = "$INPUT_DIR/$WORK_DIRS[$dx]";
	if ($WORK_DIRS[$dx] ne '-') {
		$OUTPUT_DIR = "$ORIG_OUTPUT_DIR/$WORK_DIRS[$dx]";
	} else {
		$OUTPUT_DIR = "$ORIG_OUTPUT_DIR";
	}

	# Check if this directory have already been processed
	if (-e "$OUTPUT_DIR/done")
	{
		print "DEBUG: skipping directory $in_dir, it has already been processed.\n" if ($DEBUG);
		next;
	}

	# Check if we have binary file in the directory
	my @binfiles = ();
	if (-d "$in_dir")
	{
		opendir(IDIR, "$in_dir") || die "FATAL: can't opendir $in_dir: $!";
		@binfiles = grep { /^all_.*\.bin$/ } readdir(IDIR);
		closedir(IDIR);
	}

	# Look at system information
	&read_sysinfo($in_dir);

	# Set default sysstat file to read (binary or text format)
	# an extract the disk devices and network interfaces list
	# if there's no binary files
	my $sar_file = '';
	my $sadc_file = '';
	my $pidstat_file = '';
	if (!$DISABLE_SAR)
	{
		($sar_file, $sadc_file) = &set_sysstat_file($in_dir);
		$pidstat_file = &set_pidstat_file($in_dir);
	}

	# In cache mode create the system information binary file each time
	if ($CACHE && (scalar keys %sysinfo > 0) ) {
		print "DEBUG: Dumping system information into cache file $in_dir/sys_cache.bin\n" if ($DEBUG);
		&dump_sys_binary($in_dir, "sys_cache.bin");
		&commit_cache_files($in_dir);
	}

	# Defined the backward level where ressources files are stored
	my $src_base = $WORK_DIRS[$dx];
	$src_base =~ s/\d+/../g;
	$src_base = '' if ($WORK_DIRS[$dx] eq '-');

	# parse SQL stats files
	if (-d "$in_dir")
	{
		# Create output subdirectories if not exists yet
		if (!$CACHE && !-e "$OUTPUT_DIR")
		{
			my $ret = `mkdir -p '$OUTPUT_DIR' 2>&1`;
			if ($ret) {
				die "FATAL: $ret\n";
			}
		}

		my @statistics_build = ();

		# Check if there is csv file in the input directory
		print "DEBUG: looking for CSV file into directory $in_dir/\n" if ($DEBUG);
		opendir(IDIR, "$in_dir") || die "FATAL: can't opendir $in_dir: $!";
		my @files = grep { /\.csv(\.gz)?$/ } readdir(IDIR);
		closedir(IDIR);
		if ($#files < 0)
		{
			print "DEBUG: no csv file found in $in_dir" if ($DEBUG);
		}
		elsif ($#binfiles == -1)
		{
			# Detect timezone from csv file
			if ($STATS_TIMEZONE eq '00')
			{
				if (-e "$in_dir/pg_stat_database.csv" && !-z "$in_dir/pg_stat_database.csv") {
					$STATS_TIMEZONE = &detect_timezone("$in_dir/pg_stat_database.csv");
				} elsif (-e "$in_dir/pg_stat_database.csv.gz" ) {
					$STATS_TIMEZONE = &detect_timezone("$in_dir/pg_stat_database.csv.gz");
				}
				# Force use of same the same timezone for postgresql and system metrics
				if ($TIMEZONE ne $STATS_TIMEZONE) {
					$TIMEZONE = $STATS_TIMEZONE;
				}

				print "DEBUG: autodetected timezone value database : $STATS_TIMEZONE, system: $TIMEZONE\n" if ($DEBUG);
			}

			# Look for disk device and network interface from the sar file
			if (!$DISABLE_SAR)
			{
				@DEVICE_LIST = ();
				@IFACE_LIST = ();
				@DEVICE_SPACE_LIST = ();
				&set_device_list($sar_file, $sadc_file);
			}

			# Enable capture mode if all data file are not present
			if ($sysinfo{CONFIGURATION}{'capture'})
			{
				print "DEBUG: data directory was created in capture mode.\n" if ($DEBUG);
				if ($CACHE) {
					die "FATAL: caching mode can not be used on a capture repository.\n";
				}
			}
		}

		if ($#binfiles > 0)
		{
			# Load statistics from cache files
			print "DEBUG: Loading PostgreSQL statistics from cache files $in_dir/*.bin\n" if ($DEBUG);
			&load_pg_binary($in_dir);

			if (($TIMEZONE eq '00') && $global_infos{timezone}) {
				$TIMEZONE = $global_infos{timezone};
			}
			if (($STATS_TIMEZONE eq '00') && $global_infos{stats_timezone}) {
				$STATS_TIMEZONE = $global_infos{stats_timezone};
			}

		}

		if ($BEGIN or $END)
		{
			print "DEBUG: Adjusting END/BEGIN dates for stats: ( $BEGIN - $END ) with timezone $STATS_TIMEZONE /\n" if ($DEBUG);
			if ($BEGIN) { $BEGIN_STAT = $BEGIN - ($STATS_TIMEZONE*3600*1000) }
			if ($END)   { $END_STAT   = $END   - ($STATS_TIMEZONE*3600*1000) }
			print "DEBUG: BEGIN/END dates for stats: $BEGIN_STAT - $END_STAT /\n" if ($DEBUG);
		}

		# Loop over CSV files and graphics definition to generate reports
		print "DEBUG: Building PostgreSQL statistics from CSV files\n" if ($DEBUG);
		foreach my $k (sort {$a cmp $b} keys %DB_GRAPH_INFOS)
		{
			# Read statistics from csv file starting at begining of
			# the file or last offset when binary files are present
			if ((-e "$in_dir/$k" && !-z "$in_dir/$k") ||
				(-e "$in_dir/end-$k" && !-z "$in_dir/end-$k"))
			{
				&compute_postgresql_stat($in_dir, $k, $src_base, %{$DB_GRAPH_INFOS{$k}});
				push(@statistics_build, $k) if (!grep(/^$k$/, @statistics_build));
			}
			# Gzip data files are only available when they can't be appended anymore so
			# if we have binary files and gzipped files, binary files contains all stats
			elsif (($#binfiles == -1) && -e "$in_dir/$k.gz" && !-z "$in_dir/$k.gz")
			{
				&compute_postgresql_stat($in_dir, "$k.gz", $src_base, %{$DB_GRAPH_INFOS{$k}});
				push(@statistics_build, $k) if (!grep(/^$k$/, @statistics_build));
			}
			# Files use 'all' instead of 'user' with pgcluu_collectd --stat-type option
			elsif ($k =~ /_user_/)
			{
				my $f = $k;
				$f =~ s/_user_/_all_/;
				# Read statistics from csv file starting at at begining of the
				# file or last offset when binary files are present
				if ((-e "$in_dir/$f" && !-z "$in_dir/$f") ||
					(-e "$in_dir/end-$f" && !-z "$in_dir/end-$f"))
				{
					&compute_postgresql_stat($in_dir, $f, $src_base, %{$DB_GRAPH_INFOS{$k}});
					push(@statistics_build, $k) if (!grep(/^$k$/, @statistics_build));
				}
				# Gzip data files are only available when they can't be appended anymore so
				# if we have binary files and gzipped files, binary files contains all stats
				elsif (($#binfiles == -1) && -e "$in_dir/$f.gz" && !-z "$in_dir/$f.gz")
				{
					&compute_postgresql_stat($in_dir, "$f.gz", $src_base, %{$DB_GRAPH_INFOS{$k}});
					push(@statistics_build, $k) if (!grep(/^$k$/, @statistics_build));
				}
			}
		}

		if ($CACHE)
		{
			print "DEBUG: Generating PostgreSQL statistics files cache into $in_dir/\n" if ($DEBUG);
			$global_infos{'in_dir'} = $in_dir;
			$global_infos{'timezone'} = $TIMEZONE;
			$global_infos{'stats_timezone'} = $STATS_TIMEZONE;
			&dump_pg_binary($in_dir);
			&commit_cache_files($in_dir);
		}
		else
		{
			# Loop over statistic in memory to generate reports
			print "DEBUG: Building PostgreSQL statistics reports\n" if ($DEBUG);
			if ($#statistics_build > 0)
			{
				foreach my $k (@statistics_build) {
					&compute_postgresql_report($k, $src_base, %{$DB_GRAPH_INFOS{$k}});
				}
			}
			else
			{
				# Try to limit report generation to stats that exists in memory.
				# The storage variable names are the same than the keys in DB_GRAPH_INFOS
				# minus some transformation.
				foreach my $k (sort {$a cmp $b} keys %DB_GRAPH_INFOS)
				{
					my $inmem = $k;
					$inmem =~ s/\.csv//;
					$inmem =~ s/\./_/g;
					$inmem =~ s/^pg_/all_/;
					if ($inmem eq 'pgbouncer_stats') {
						$inmem = 'all_pgbouncer_stats';
					}
					if (($inmem =~ /_conf/) && ($inmem !~ /^all/)) {
						$inmem = 'all_' . $inmem;
					}
					$inmem =~ s/_all_/_user_/;
					# Skip this report if there's no statistics loaded in memory
					next if (scalar keys %{$inmem} == 0);
					print "DEBUG: Building report for $k (from memory \%$inmem)\n" if ($DEBUG);
					if ($k =~ /_all_/)
					{
						my $f = $k;
						$f =~ s/_all_/_user_/;
						&compute_postgresql_report($f, $src_base, %{$DB_GRAPH_INFOS{$k}});
					} else {
						&compute_postgresql_report($k, $src_base, %{$DB_GRAPH_INFOS{$k}});
					}
				}
			}

			# Add database general information
			foreach my $db (keys %{$OVERALL_STATS{'database'}}) {
				&write_database_info($db);
			}

			# Terminate each database and pgbouncer html file with the footer
			opendir(ODIR, "$OUTPUT_DIR") || die "FATAL: can't opendir $OUTPUT_DIR: $!";
			my @files = grep { /\.html$/ } readdir(ODIR);
			closedir(ODIR);
			foreach my $f (@files) {
				&end_html_file("$OUTPUT_DIR/$f");
			}
		}
	}
	elsif (!$sar_file && !$DISABLE_SAR)
	{
		print "FATAL: $in_dir is not a valid data directory\n";
		exit 1;
	}

	# Clear memory from PostgreSQL statistics storage
	&clear_db_stats() if ($dx > 0);

	# parse SAR stats file
	if (!$DISABLE_SAR) {

		@DEVICE_LIST = ();
		@IFACE_LIST = ();
		@DEVICE_SPACE_LIST = ();

		#Load statistics from cache files
		if ($#binfiles >= 0) {
			print "DEBUG: Loading Sar statistics from cache files $in_dir/*.bin\n" if ($DEBUG);
			# sar and pidstat files are written together, see lock_cache_dir()
			my $lock = &lock_cache_dir($in_dir, LOCK_SH);
			&load_sar_binary($in_dir);
			# Look for disk device and network interface from global info
			push(@DEVICE_LIST, @{$global_infos{DEVICE_LIST}}) if (exists $global_infos{DEVICE_LIST});
			push(@IFACE_LIST, @{$global_infos{IFACE_LIST}}) if (exists $global_infos{IFACE_LIST});
			push(@DEVICE_SPACE_LIST, @{$global_infos{DEVICE_SPACE_LIST}}) if (exists $global_infos{DEVICE_SPACE_LIST});
			&load_pidstat_binary($in_dir);
			close($lock) if ($lock);
		}
		# In cache/binary mode we can not process sadc binary data file
		if (($#binfiles == -1) && -f "$sadc_file")
		{
			print "DEBUG: looking for sadc binary data file $sadc_file\n" if ($DEBUG);
			foreach my $id (sort keys %SAR_GRAPH_INFOS) {
				&compute_sarstat_stats($sadc_file, %{$SAR_GRAPH_INFOS{$id}});
			}
		}
		# Read sar file from the start of the file or from the offset stored a previous
		# run of the cache. Gzipped files do not need to be read again with binary files
		elsif (-f "$sar_file" && (($#binfiles == -1) || ($sar_file !~ /\.gz$/)) )
		{
			print "DEBUG: looking for sar text data file $sar_file\n" if ($DEBUG);
			foreach my $id (sort keys %SAR_GRAPH_INFOS) {
				&compute_sarfile_stats($sar_file, $in_dir, %{$SAR_GRAPH_INFOS{$id}});
			}
			%fulldata = ();
			if ( defined $pidstat_file && -e $pidstat_file  && (($#binfiles == -1) || ($pidstat_file !~ /\.gz$/)) )
			{
				print "DEBUG: looking for pidstat data file $pidstat_file\n" if ($DEBUG);
				foreach my $id (sort keys %PIDSTAT_GRAPH_INFOS) {
					&compute_pidstatfile_stats($pidstat_file, $in_dir, %{$PIDSTAT_GRAPH_INFOS{$id}});
				}
				%fullpidstatdata = ();
			}
		}

		if ($CACHE) {
			print "DEBUG: Generating sar statistics files cache into $in_dir.\n" if ($DEBUG);
			$global_infos{'in_dir'} = $in_dir;
			$global_infos{'timezone'} = $TIMEZONE;
			$global_infos{'stats_timezone'} = $STATS_TIMEZONE;
			foreach my $d (@DEVICE_LIST) {
				push(@{$global_infos{DEVICE_LIST}}, $d) if (!grep(/^$d$/, @{$global_infos{DEVICE_LIST}}));
			}
			foreach my $d (@IFACE_LIST) {
				push(@{$global_infos{IFACE_LIST}}, $d) if (!grep(/^$d$/, @{$global_infos{IFACE_LIST}}));
			}
			foreach my $d (@DEVICE_SPACE_LIST) {
				push(@{$global_infos{DEVICE_SPACE_LIST}}, $d) if (!grep(/^$d$/, @{$global_infos{DEVICE_SPACE_LIST}}));
			}
			# The offsets in the pidstat file are stored with the sar ones
			&dump_sar_binary($in_dir);
			&dump_pidstat_binary($in_dir);
			&commit_cache_files($in_dir);

		} else {

			# Build sar statistics graphs
			print "DEBUG: Building sar statistics reports\n" if ($DEBUG);
			foreach my $id (sort keys %SAR_GRAPH_INFOS) {
				&compute_sar_graph($src_base, %{$SAR_GRAPH_INFOS{$id}});
			}
			# Build pidstat statistics graphs
			print "DEBUG: Building pidstat statistics reports\n" if ($DEBUG);
			foreach my $id (sort keys %PIDSTAT_GRAPH_INFOS) {
				&compute_pidstat_graph($src_base, %{$PIDSTAT_GRAPH_INFOS{$id}});
			}
		}
	}

	if (!$CACHE) {

		if ($OUTPUT_DIR) {

			# Generate main index
			&generate_html_index($in_dir, $src_base);
			my $menu = &generate_html_menu($in_dir, $OUTPUT_DIR);
			print "DEBUG: Inserting menu into all html files.\n" if ($DEBUG);
			opendir(ODIR, "$OUTPUT_DIR") || die "FATAL: can't opendir $OUTPUT_DIR: $!";
			my @files = grep { /\.html$/ } readdir(ODIR);
			closedir(ODIR);
			foreach my $f (@files) {
				my $tmp_content = '';
				my $fh = IO::File->new("$OUTPUT_DIR/$f", "r");
				die "FATAL: can't read file $OUTPUT_DIR/$f, $!" if (not defined $fh);
				while (my $l = <$fh>) {
					chomp($l);
					$l =~ s/\r//;
					if ($l =~ /<div id="navigation"><\/div>/) {
						$l = qq{
<div id="navigation">
$menu
</div>
};
					}
					$tmp_content .= "$l\n";
				}
				close($fh);
				# override file
				$fh = IO::File->new("$OUTPUT_DIR/$f", "w");
				die "FATAL: can't write file $OUTPUT_DIR/$f, $!" if (not defined $fh);
				print $fh $tmp_content;
				close($fh);
			}
		}

	# In cache mode if the --clean	option is enable we need to remove data file
	} elsif ($CLEAN && $CACHE) {

		print "DEBUG: removing all csv and data files from $in_dir.\n" if ($DEBUG);
		opendir(DIR, "$in_dir") || die "FATAL: can't opendir $in_dir: $!";
		my @file_list = grep { !/^.*\.bin$/ && -f "$in_dir/$_"; } readdir(DIR);
		closedir(DIR);
		foreach my $f (@file_list) {
			warn "ERROR: can not remove file $in_dir/$f: $!\n" unless(unlink("$in_dir/$f"));
		}
	}
}

if (!$CACHE && $have_incremental_dir) {
	build_incremental_index($ORIG_OUTPUT_DIR);
}

if ($CACHE && $have_hourly_dir) {
	print "DEBUG: building binary file per day from hourly binary files...\n" if ($DEBUG);
	build_daily_binary($ORIG_OUTPUT_DIR);
}

exit 0;

#----------------------------------------------------------------------------------

sub usage
{
    print qq{
usage: $0 [options] [-i sar_file | -I sadc_file] [input_dir]

	input_dir: directory where pgcluu_collectd or pgstats and sar data
		   files are stored.

options:
  -b, --begin  datetime      start date/time for the data to be parsed (time of current timezone).
  -C, --cache                generate cache files only (.bin), no html output.
  -d, --db-only dbname       only report for the whole cluster and the given
                             database name. You can use it multiple time or
                             give a comma separated list of database name.
  -D, --device-only dev      only report I/O stats for a particular device
                             You can use it multiple time or give a comma
                             separated list of device name, ex: sda,sdc.
  -e, --end    datetime      end date/time for the data to be parsed (time of current timezone).
  -i, --sar-file=FILE        path to the sar text data file to read to generate
                             system reports. Default to input_dir/sar_stats.dat.
  -I, --sadc-file=FILE       sadc binary data file to read to generate system
                             reports. Default to input_dir/sadc_stats.dat.
  -n, --top-number           Top number of tables or indexes I/O stats to show.
                             Default is set to top 10. Set it to 0 to show all.
  -N, --network-only iface   only report stats for a particular network interface.
                             You can use it multiple times or give a comma separated
                             list of network interfaces, ex: eth0,eth1.
  -o, --output=DIR           output directory
  -r, --reverse-date         By default pgcluu look at mm/dd/yy format in sar file.
                             When enabled pgcluu will look at dd/mm/yy format.
  -s, --sadf=BIN             path to the sadf sysstat command used to read the
                             sadc binary data file. Default: $SADF_PROG.
  -S, --disable-sar          disable collect of system statistics with sar.
  -t, --with-table table     Only report for the whole tables and the given
                             table name. You can use it multiple time or
                             give a comma separated list of database name.
  -T, --no-table             Do not report statistics related to tables.
  -v, --verbose              Print out debug informations.
  -V, --version              Show pgcluu version and exit.
  -x, --external-menu        Save menu in menu.html and load it into each report
                             using w3-include-html attribut from w3.js. This will
			     only work if acces to HTML reports is through a Web
			     server, not using the file:// protocol.
  -z, --timezone +/-XX       Set the number of hour(s) from GMT of the timezone,
                             Eg: -z +02
                             Usually autodetected.
                             Use this to adjust date/time from the sar output,
                             pgcluu use GMT time to draw charts.
  -Z, --stats-timezone +/-XX Set the number of hour(s) from GMT of the timezone.
                             Eg: -Z +02
                             Usually autodetected.
                             Use this to adjust date/time from the cluster and
                             system stats output, pgcluu use GMT time.
  --from-sa-file             instruct pgcluu that file specified by the -i option
                             uses the standard system activity daily data file.
  --charset                  used to set the HTML charset to be used.
                             Default: utf-8.
  --retention NDAYS          number of rolling days to keep in report directory.
                             Default is to store indefinitely.
  --help                     print usage

For example, you can generate all HTML reports from data files stored into
/tmp/stat_db1/ with the following commands:

        mkdir /tmp/report_db1/
        pgcluu -o /tmp/report_db1/ /tmp/stat_db1/

If you just want reports of some databases, use the following:

        pgcluu -o /tmp/report_db1/ /tmp/stat_db1/ --db-only "db1,db2,db3"

If you just want to create a report from a sar output file:

	sar -p -A 10 60 > /root/my_sar_file.txt
        pgcluu -o /tmp/report_sar/ -i /root/my_sar_file.txt

or from a daily sa file:

        sar -p -A -f /var/log/sa/sa18 > /root/my_sar_file.txt
        pgcluu -o /tmp/report_sar/ -i /root/my_sar_file.txt --from-sa-file

and from a sa binary file:

        pgcluu -o /tmp/report_sar/ -i /var/log/sysstat/sa22

or the sa text file if you don't have the same version of sysstat:

        pgcluu -o /tmp/report_sar/ -i /var/log/sysstat/sar23 --from-sa-file

If pgcluu_collectd have been run in incremental mode you can limit the number
of retention days used for the reports:

	pgcluu -o /tmp/report_sar/ /tmp/stat_db1/ --retention 30

A static report will be built for each day or hour following the rotation
used with pgcluu_collectd.
};
    exit 0;
}

sub is_interactive_mode
{
	return -t STDIN && -t STDOUT;
}

sub set_sysstat_file
{
	my $input_dir = shift;

	$input_dir ||= $INPUT_DIR;

	print "DEBUG: detecting sar/sadc file in $input_dir/\n" if ($DEBUG);
	my $sar_file = '';
	my $sadc_file = '';
	if (!$SADC_INPUT_FILE && !$SAR_INPUT_FILE) {
		if (-f "$input_dir/sadc_stats.dat") {
			$sadc_file = "$input_dir/" . 'sadc_stats.dat';
		} elsif (-f "$input_dir/sar_stats.dat") {
			$sar_file = "$input_dir/" . 'sar_stats.dat';
		} elsif (-f "$input_dir/sar_stats.dat.gz") {
			$sar_file = "$input_dir/" . 'sar_stats.dat.gz';
		}
		if (!$sadc_file && !$sar_file) {
			print STDERR "WARNING: No sar data file found. Consider using -S or --disable-sar command\nline option or use -i / -I option to set the path to the data file.\nContinuing normally without reporting sar statistics.\n";
			$DISABLE_SAR = 1;
			return;
		}
	} else {
		$sadc_file = $SADC_INPUT_FILE;
		$sar_file = $SAR_INPUT_FILE;
	}

	# Verify that the sar data file exists.
	if ($sadc_file && !-f "$sadc_file") {
		print STDERR "ERROR: sar binary data file $sadc_file can't be found.\n";
		exit 1;
	}
	if ($sar_file && !-f "$sar_file") {
		print STDERR "ERROR: sar text data file $sar_file can't be found.\n";
		exit 1;
	}

	my $pfile = $sadc_file;
	$pfile = $sar_file if ($sar_file);

	print "DEBUG: sar/sadc file detected $pfile\n" if ($DEBUG);

	return ($sar_file, $sadc_file);
}

sub set_pidstat_file
{
	my $input_dir = shift;

	$input_dir ||= $INPUT_DIR;

	print "DEBUG: detecting pidstat file in $input_dir/\n" if ($DEBUG);
	my $pidstat_file = '';
	if (!$PIDSTAT_INPUT_FILE) {
		if (-f "$input_dir/pidstat_stats.dat") {
			$pidstat_file = "$input_dir/" . 'pidstat_stats.dat';
		} elsif (-f "$input_dir/pidstat_stats.dat.gz") {
			$pidstat_file = "$input_dir/" . 'pidstat_stats.dat.gz';
		}
		if (!$pidstat_file) {
			print STDERR "WARNING: No pidstat data file found.\nContinuing normally without reporting pidstat statistics.\n";
			return;
		}
	} else {
		$pidstat_file = $PIDSTAT_INPUT_FILE;
	}

	# Verify that the sar data file exists.
	if ($pidstat_file && !-f "$pidstat_file") {
		print STDERR "ERROR: pidstat text data file $pidstat_file can not be found.\n";
		exit 1;
	}

	print "DEBUG: pidstat file detected $pidstat_file\n" if ($DEBUG);

	return $pidstat_file;
}

sub init_html_file
{
	my $ofile = shift;
	my $src_base = shift;

	$ofile =~ s/cluster-cluster-/cluster-/;
	# Open a filehandle for each database
	my $fhdb = IO::File->new($ofile, "w");
	die "FATAL: can't write file $ofile, $!" if (not defined $fhdb);
	&html_header($fhdb, $src_base);
	$fhdb->print("<ul id=\"slides\">\n");
	$fhdb->close();
}

sub append_to_html_file
{
	my $ofile = shift;
	my $src_base = shift;

	$ofile =~ s/cluster-cluster-/cluster-/;
	# If file doesn't exist create it
	if (! -e $ofile) {
		&init_html_file($ofile, $src_base);
	}

	# Open a filehandle for each database
	my $fhdb = IO::File->new($ofile, "a");
	die "FATAL: can't write file $ofile, $!" if (not defined $fhdb);
	return $fhdb;
}

sub end_html_file
{
	my $ofile = shift;

	$ofile =~ s/cluster-cluster-/cluster-/;
	my $fhdb = IO::File->new($ofile, "a");
	die "FATAL: can't write file $ofile, $!" if (not defined $fhdb);
	$fhdb->print("</ul>\n");
	&html_footer($fhdb);
	$fhdb->close;
}


sub progress_bar
{
	my ( $got, $total, $width, $char ) = @_;
	$width ||= 25; $char ||= '=';
	my $num_width = length $total;
	sprintf("[%-${width}s] Parsed %${num_width}s bytes of %s (%0.2f%%)\r",
		$char x (($width-1)*$got/$total). '>',
		$got, $total, 100*$got/+$total);
}

sub is_compressed
{
	my $file = shift;

	return 1 if ($file =~ /\.gz/);

	return 0;
}

sub open_filehdl
{
	my $file = shift;

	my $curfh = new IO::File;
	if (!is_compressed("$file")) {
		$curfh->open($file, 'r') or die "FATAL: can't read file $file: $!\n";
	} else {
		open($curfh, "-|", "$ZCAT_PROG $file");
		die "FATAL: can't read pipe from command: $ZCAT_PROG $file, $!\n" if (not defined $curfh);
	}
	return $curfh;
}

sub detect_timezone
{
	my $file = shift;

	my $tz = '+00';

	my $fh = open_filehdl($file);
	my $i = 1;
	while (<$fh>) {
		my @data = split(/;/);
		if ($data[0] =~ /^\d+-\d+-\d+ \d+:\d+:\d+([+\-]\d\d)/) {
			$tz = $1;
			last;
		}
		$i++;
		last if ($i > 10);
	}
	close($fh);

	return $tz;
}


sub get_data_id
{
	my ($str, %data_info) = @_;

	foreach my $i (sort {$a <=> $b} keys %data_info) {
		if ($data_info{$i}->{name} eq $str) {
			return $i;
		}
	}
	return -1;
}

sub set_device_list
{
	my ($sar_file, $sadc_file) = @_;

	if ($sadc_file && -f "$sadc_file") {

		my $command = "$SADF_PROG -t -P ALL -d $sadc_file -- -d -p";
		print STDERR "DEBUG: looking for device list using command $command'\n" if ($DEBUG);
		# Load data from file
		my $fh = IO::File->new($command, '-|');
		if (not defined $fh) {
			die "FATAL: can't read output from command ($command): $!\n";
		}
		while (my $l = <$fh>) {
			chomp($l);
			# hostname;interval;timestamp;DEV;tps;rd_sec/s;wr_sec/s;avgrq-sz;avgqu-sz;await;[svctm;]%util
			my @data = split(/;/, $l);
			next if ($data[2] !~ /^\d+/);
			next if ( $data[3] =~ /^loop\d+/);
			if (!grep(m#^$data[3]$#, @DEVICE_LIST)) {
				push(@DEVICE_LIST, $data[3]);
			} else {
				last;
			}
		}
		close($fh);

		$command = "$SADF_PROG -t -P ALL -d $sadc_file -- -n DEV";
		print STDERR "DEBUG: looking for network device list using command $command'\n" if ($DEBUG);
		# Load data from file
		$fh = IO::File->new($command, '-|');
		if (not defined $fh) {
			die "FATAL: can't read output from command ($command): $!\n";
		}
		while (my $l = <$fh>) {
			chomp($l);
			#hostname;interval;timestamp;IFACE;rxpck/s;txpck/s;...
			my @data = split(/;/, $l);
			next if ($data[2] !~ /^\d+/);
			if (!grep(m#^$data[3]$#, @IFACE_LIST)) {
				push(@IFACE_LIST, $data[3]);
			} else {
				last;
			}
		}
		close($fh);

		# There is no information about disk space device in sadc file
		#@DEVICE_SPACE_LIST = ...;

	} elsif ($sar_file && -f "$sar_file") {

		print STDERR "DEBUG: looking for devices in sar file $sar_file\n" if ($DEBUG);
		# Load data from file
		my $fh = open_filehdl($sar_file);
		my $type = '';
		while (my $l = <$fh>)
		{
			chomp($l);
			$l =~ s/\r//;

			# We only read the first sar report to extract device name
			last if ($l !~ /^Average/);

			# Skip non relevant part
			if ($l !~ /^\d+:\d+:\d+/ || !$l) {
				next;
			}

			# Get device type from reports headers
			if ($l =~ m#(DEV|IFACE|FILESYSTEM)\s+#) {
				$type = $1;
				next;
			}

			# Extract values from the current line
			my @values = ();
			push(@values, split(m#\s+#, $l));
			next if ( $values[1] =~ /^loop\d+/); # skip loop device

			# Set device list following the type
			if ($type eq 'DEV') {
				push(@DEVICE_LIST, $values[1]) if (!grep(/^$values[1]$/, @DEVICE_LIST));
			} elsif ($type eq 'IFACE') {
				push(@IFACE_LIST, $values[1]) if (!grep(/^$values[1]$/, @IFACE_LIST));
			} elsif ($type eq 'FILESYSTEM') {
				push(@DEVICE_SPACE_LIST, $values[8]) if (!grep(/^$values[8]$/, @DEVICE_SPACE_LIST));
			}
		}
		close($fh);
	}
}

sub write_database_info
{
	my $db = shift;
	my $src_base = shift;

	return if (($#INCLUDE_DB >= 0) && (!grep($db =~ /^$_$/, @INCLUDE_DB)));

	my $next = $#{$sysinfo{EXTENSION}{$db}} + 1;
	my $extlist = join(', ', @{$sysinfo{EXTENSION}{$db}});
	$extlist = ' (' . $extlist . ')' if ($extlist);
	my $nparts = 0;
	$nparts = scalar keys %{$sysinfo{PARTITIONNED_TABLE}{$db}} if (exists $sysinfo{PARTITIONNED_TABLE}{$db});
	my $partlist = '';
	$partlist = '(' . join(', ', keys %{$sysinfo{PARTITIONNED_TABLE}{$db}}) . ')' if ($nparts > 0);
	my $nsch = $#{$sysinfo{SCHEMA}{$db}} + 1;
	my $schlist = join(', ', @{$sysinfo{SCHEMA}{$db}});
	$schlist = ' (' . $schlist . ')' if ($schlist);
	my $njson = $#{$sysinfo{JSON}{$db}} + 1;
	my $jsonlist = join(', ', @{$sysinfo{JSON}{$db}});
	$jsonlist = ' (' . $jsonlist . ')' if ($jsonlist);
	my $procount = $sysinfo{PROCEDURE}{$db} || 0;
	my $trigcount = $sysinfo{TRIGGER}{$db} || 0;
	my $last_vacuum = $OVERALL_STATS{'database'}{$db}{last_vacuum} || '-';
	my $last_analyze = $OVERALL_STATS{'database'}{$db}{last_analyze} || '-';
	my $last_autovacuum = $OVERALL_STATS{'database'}{$db}{last_autovacuum} || '-';
	my $last_autoanalyze = $OVERALL_STATS{'database'}{$db}{last_autoanalyze} || '-';
	my $last_reset = $OVERALL_STATS{'database'}{$db}{'stat_reset'} || '';

	my $objects_count = '';
	foreach my $k (sort keys %RELKIND) {
	        $objects_count .= qq{<li><span class="figure">$OVERALL_STATS{'class'}{$db}{$k}</span> <span class="figure-label">} . lcfirst($RELKIND{$k}) . qq{</span></li>} if (exists $OVERALL_STATS{'class'}{$db}{$k});
	}
	$OVERALL_STATS{database}{$db}{invalid_indexes} ||= 0;
	$OVERALL_STATS{database}{$db}{hash_indexes} ||= 0;
	$OVERALL_STATS{database}{$db}{unlogged} ||= 0;
	my $dbsize = &pretty_print_size($OVERALL_STATS{'database'}{$db}{'size'});
	my $dbfh = &append_to_html_file("$OUTPUT_DIR/database-$db.html", $src_base);
	$dbfh->print( qq{
<li class="slide" id="database-info-slide">

	<div id="database-info"><br/><br/><br/></div>

	<div class="row">
            <div class="col-md-12">
              <div class="panel panel-default">
              <div class="panel-heading">
              <i class="glyphicon icon-desktop icon-2x pull-left"></i><h2>Database $db</h2>
              </div>
              <div class="panel-body">
		<div class="key-figures">
		<ul>
		<li></li>
	        <li><span class="figure">$dbsize</span> <span class="figure-label">Total size</span></li>
	        <li><span class="figure">$next</span> <span class="figure-label">Installed extensions$extlist</span></li>
	        <li><span class="figure">$nparts</span> <span class="figure-label">Partitionned tables$partlist</span></li>
	        <li><span class="figure">$OVERALL_STATS{database}{$db}{unlogged}</span> <span class="figure-label">Unlogged tables</span></li>
	        <li><span class="figure">$OVERALL_STATS{database}{$db}{invalid_indexes}</span> <span class="figure-label">Invalid indexes</span></li>
	        <li><span class="figure">$OVERALL_STATS{database}{$db}{hash_indexes}</span> <span class="figure-label">Hash indexes</span></li>
		<li><span class="figure">$nsch</span> <span class="figure-label">Schemas$schlist</span></li>
});
	$dbfh->print( qq{<li><span class="figure">$njson</span> <span class="figure-label">json vs jsonb columns$jsonlist</span></li>} ) if ($jsonlist);
	$dbfh->print( qq{
	        <li><span class="figure">$last_vacuum</span> <span class="figure-label">Last manual vacuum</span></li>
	        <li><span class="figure">$last_analyze</span> <span class="figure-label">Last manual analyze</span></li>
	        <li><span class="figure">$last_autovacuum</span> <span class="figure-label">Last auto vacuum</span></li>
	        <li><span class="figure">$last_autoanalyze</span> <span class="figure-label">Last auto analyze</span></li>
	        <li><span class="figure">$last_reset</span> <span class="figure-label">Last database stats reset</span></li>
	        <li><span class="figure">$procount</span> <span class="figure-label">Stored procedures</span></li>
	        <li><span class="figure">$trigcount</span> <span class="figure-label">Triggers</span></li>
		$objects_count
		</ul>
		</div>
              </div>
              </div>
            </div><!--/span-->
	</div>

</li>
}
	);

	if ($nparts > 0) {
		$dbfh->print( qq{
<li class="slide" id="partitionned-table-slide">
  <div id="partitionned-tbl"><br/><br/><br/></div>
  <div class="row">
    <div class="col-md-12">
      <div class="panel panel-default">
        <div class="panel-heading">
          <i class="glyphicon icon-desktop icon-2x pull-left"></i><h2>Partitionned tables in database $db</h2>
        </div>
        <div class="panel-body">
}
		);
		foreach my $oid (sort keys %{$sysinfo{PARTITIONNED_TABLE}{$db}}) {
			$sysinfo{PARTITIONNED_TABLE}{$db}{$oid}{implementation} ||= '';
			$dbfh->print( qq{
          <div class="analysis-item row-fluid" id="part-tbl-$oid">
            <div class="span11">
              <h3>$sysinfo{PARTITIONNED_TABLE}{$db}{$oid}{name}</h3>
              <div class="key-figures">
                <ul>
                  <li>Partitioning kind: <span class="figure">$sysinfo{PARTITIONNED_TABLE}{$db}{$oid}{kind}</span></li>
                  <li>Number of partitions: <span class="figure">$sysinfo{PARTITIONNED_TABLE}{$db}{$oid}{nparts}</span></li>
                  <li>$sysinfo{PARTITIONNED_TABLE}{$db}{$oid}{kind} detail: <pre>$sysinfo{PARTITIONNED_TABLE}{$db}{$oid}{implementation}</pre></li>
                </ul>
              </div>
              <table class="table table-striped sortable" id="part-tbl-$oid-table">
                <thead>
                  <tr>
                    <th>Partition name</th>
                    <th>Constraint</th>
                  </tr>
                </thead>
                <tbody>
}
			);

			foreach my $part (sort(keys %{$sysinfo{PARTITIONNED_TABLE}{$db}{$oid}{child}})) {
				$dbfh->print( qq{
                  <tr>
                    <td>$part</td>
                    <td>$sysinfo{PARTITIONNED_TABLE}{$db}{$oid}{child}{$part}</td>
                  </tr>
}
				);
			}
			$dbfh->print( qq{
              </table>
            </div>
          </div>
}
			);
        }
		$dbfh->print( qq{
        </div>
      </div>
    </div>
  </div>
</li>
}
		);

	}
}

sub compute_postgresql_stat
{
	my ($in_dir, $file, $src_base, %data_info) = @_;

	print "DEBUG: reading statistics in file $in_dir/$file\n" if ($DEBUG);

	# Compute graphs following the data file
	my $fctname = $file;
	$fctname =~ s/\.csv(\.gz)?//;
	$fctname =~ s/\.gz//;
	$fctname =~ s/\./_/g;
	my $offset = 0;
	$offset = $global_infos{"$in_dir/$file"} if (exists $global_infos{"$in_dir/$file"});
	# Call the function associated to the action and get back the new offset
	# offset is used in incremental mode to avoir parsing the entire file.
	$global_infos{"$in_dir/$file"} = $fctname->($in_dir, $file, $offset);
}

sub compute_postgresql_report
{
	my ($file, $src_base, %data_info) = @_;

	# Compute graphs following the data file
	my $fctname = $file;
	$fctname =~ s/\.csv(\.gz)?//;
	$fctname =~ s/\.gz//;
	$fctname =~ s/_all_/_user_/;
	$fctname =~ s/\./_/g;

	print "DEBUG: creating reports from statistics $fctname\n" if ($DEBUG);
	$fctname .= '_report';
	$fctname->($src_base, %data_info);
}


# Compute statistics of database statistics
sub pg_stat_database
{
	my ($in_dir, $file, $offset) = @_;

	my %start_vals = ();
	my %db_list = ();
	my $tmp_val = 0;
	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	$curfh->seek($offset,0);
	while (my $l = <$curfh>)
	{
		$offset += length($l);
		my @data = split(/;/, $l);
		next if (!&normalize_line(\@data));

		# Do not process shared relation
		next if ($data[1] == 0);

		# timestamp | datid | datname | numbackends | xact_commit | xact_rollback | blks_read | blks_hit | tup_returned | tup_fetched | tup_inserted | tup_updated | tup_deleted | conflicts | stats_reset | temp_files | temp_bytes | deadlocks | blk_read_time | blk_write_time

		# Store list of database
		$db_list{$data[2]} = 1;
		# Store previous data from the first line
		push(@{$start_vals{$data[2]}}, @data) if ($#{$start_vals{$data[2]}} < 0);

		# Store interval between previous run
		$all_stat_database{$data[0]}{$data[2]}{interval} = ($data[0] - $start_vals{$data[2]}[0])/1000;
		$all_stat_database{$data[0]}{all}{interval} = ($data[0] - $start_vals{$data[2]}[0])/1000;

		if ($#data >= 8)
		{
			if (($data[8] - $start_vals{$data[2]}[8]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[8] - $start_vals{$data[2]}[8]) };
			$all_stat_database{$data[0]}{$data[2]}{returned} = $tmp_val;
			$all_stat_database{$data[0]}{all}{returned} += $tmp_val;

			if (($data[9] - $start_vals{$data[2]}[9]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[9] - $start_vals{$data[2]}[9]) };
			$all_stat_database{$data[0]}{$data[2]}{fetched} = $tmp_val;
			$all_stat_database{$data[0]}{all}{fetched} += $tmp_val;

			# Gather insert statement
			if (($data[10] - $start_vals{$data[2]}[10]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[10] - $start_vals{$data[2]}[10]) };
			$all_stat_database{$data[0]}{$data[2]}{insert} = $tmp_val;
			$all_stat_database{$data[0]}{all}{insert} += $tmp_val;

			# Gather update statement
			if (($data[11] - $start_vals{$data[2]}[11]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[11] - $start_vals{$data[2]}[11]) };
			$all_stat_database{$data[0]}{$data[2]}{update} = $tmp_val;
			$all_stat_database{$data[0]}{all}{update} += $tmp_val;

			# Gather delete statement
			if (($data[12] - $start_vals{$data[2]}[12]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[12] - $start_vals{$data[2]}[12]) };
			$all_stat_database{$data[0]}{$data[2]}{delete} = $tmp_val;
			$all_stat_database{$data[0]}{all}{delete} += $tmp_val;
		}

		# Gather blks_read
		if (($data[6] - $start_vals{$data[2]}[6]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[6] - $start_vals{$data[2]}[6]) };
		$all_stat_database{$data[0]}{$data[2]}{blks_read} = $tmp_val;
		$all_stat_database{$data[0]}{all}{blks_read} += $tmp_val;

		# Gather blks_hit
		if (($data[7] - $start_vals{$data[2]}[7]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[7] - $start_vals{$data[2]}[7]) };
		$all_stat_database{$data[0]}{$data[2]}{blks_hit} = $tmp_val;
		$all_stat_database{$data[0]}{all}{blks_hit} += $tmp_val;

		# Gather number of running backend
		if ($data[3])
		{
			$all_stat_database{$data[0]}{$data[2]}{nbackend} = $data[3];
			$all_stat_database{$data[0]}{all}{nbackend} += $data[3];
		}

		# Gather number of committed transaction
		if (($data[4] - $start_vals{$data[2]}[4]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[4] - $start_vals{$data[2]}[4]) };
		$all_stat_database{$data[0]}{$data[2]}{xact_commit} = $tmp_val;
		$all_stat_database{$data[0]}{all}{xact_commit} += $tmp_val;
		$all_stat_database{$data[0]}{$data[2]}{xact_throughput} = $tmp_val;
		$all_stat_database{$data[0]}{all}{xact_throughput} += $tmp_val;

		# Gather number of rollbacked transaction
		if (($data[5] - $start_vals{$data[2]}[5]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[5] - $start_vals{$data[2]}[5]) };
		$all_stat_database{$data[0]}{$data[2]}{xact_rollback} = $tmp_val;
		$all_stat_database{$data[0]}{all}{xact_rollback} += $tmp_val;
		$all_stat_database{$data[0]}{$data[2]}{xact_throughput} += $tmp_val;
		$all_stat_database{$data[0]}{all}{xact_throughput} += $tmp_val;

		# Gather number of canceled queries and stat reset
		if ($#data >= 13)
		{
			if (($data[13] - $start_vals{$data[2]}[13]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[13] - $start_vals{$data[2]}[13]) };
			$all_stat_database{$data[0]}{$data[2]}{canceled_queries} = $tmp_val;
			$all_stat_database{$data[0]}{all}{canceled_queries} += $tmp_val;
			$OVERALL_STATS{'database'}{$data[2]}{'stat_reset'} = $data[14] if (!exists $OVERALL_STATS{'database'}{$data[2]}{'stat_reset'} || ($OVERALL_STATS{'database'}{$data[2]}{'stat_reset'} lt $data[14]));
		}

		# Gather number of temporary data and deadlock
		if ($#data > 15)
		{
			if (($data[15] - $start_vals{$data[2]}[15]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[15] - $start_vals{$data[2]}[15]) };
			$all_stat_database{$data[0]}{$data[2]}{temp_files} = $tmp_val;
			$all_stat_database{$data[0]}{all}{temp_files} += $tmp_val;

			if (($data[16] - $start_vals{$data[2]}[16]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[16] - $start_vals{$data[2]}[16]) };
			$all_stat_database{$data[0]}{$data[2]}{temp_bytes} = $tmp_val;
			$all_stat_database{$data[0]}{all}{temp_bytes} += $tmp_val;

			if (($data[17] - $start_vals{$data[2]}[17]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[17] - $start_vals{$data[2]}[17]) };
			$all_stat_database{$data[0]}{$data[2]}{deadlocks} = $tmp_val;
			$all_stat_database{$data[0]}{all}{deadlocks} += $tmp_val;
		}

		@{$start_vals{$data[2]}} = ();
		push(@{$start_vals{$data[2]}}, @data);
	}
	$curfh->close();

	# Store the full list of database
	foreach my $d (keys %db_list)
	{
		push(@global_databases, $d) if (!grep(/^$d$/, @global_databases));
	}
	push(@global_databases, 'all') if (($#global_databases >= 0) && !grep(/^all$/, @global_databases));

	return $offset || 0;

}

# Compute graphs of database statistics
sub pg_stat_database_report
{
	my ($src_base, %data_info) = @_;

	my %database_stat = ();
	my %total_query_type = ();
	my %has_conn = ();
	my $has_tuples = 0;
	my $has_temp = 0;
	my $has_conflict = 0;

	foreach my $t (sort {$a <=> $b} keys %all_stat_database)
	{
		foreach my $db (@global_databases)
		{
			$all_stat_database{$t}{$db}{interval} = 1 if ($sysinfo{CONFIGURATION}{'capture'});
			next if (!$all_stat_database{$t}{$db}{interval});
			next if (($db ne 'all') && ($#INCLUDE_DB >= 0) && (!grep($db =~ /^$_$/, @INCLUDE_DB)));
			foreach my $k (qw(insert returned fetched update delete blks_read blks_hit nbackend xact_commit xact_rollback canceled_queries deadlocks temp_files temp_bytes xact_throughput))
			{
				next if ($db eq 'all');
				$all_stat_database{$t}{$db}{$k} ||= 0;
				$OVERALL_STATS{'cluster'}{$k} += $all_stat_database{$t}{$db}{$k};
				$OVERALL_STATS{'database'}{$db}{$k} += $all_stat_database{$t}{$db}{$k};
			}

			$OVERALL_STATS{'start_date'} = $t if (!$OVERALL_STATS{'start_date'} || ($OVERALL_STATS{'start_date'} gt $t));
			$OVERALL_STATS{'end_date'} = $t if (!$OVERALL_STATS{'end_date'} || ($OVERALL_STATS{'end_date'} lt $t));
			# It depends on the postgresql version
			if (!$has_tuples)
			{
				foreach my $k (keys %{$all_stat_database{$t}{$db}})
				{
					if (grep(/^$k$/, 'insert','returned','fetched','update','delete'))
					{
						$has_tuples = 1;
						last;
					}
				}
			}
			if ($has_tuples)
			{
				$database_stat{$db}{insert} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . sprintf("%0.2f", ($all_stat_database{$t}{$db}{insert}/$all_stat_database{$t}{$db}{interval})) . '],';
				$database_stat{$db}{returned} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . sprintf("%0.2f", ($all_stat_database{$t}{$db}{returned}/$all_stat_database{$t}{$db}{interval})) . '],';
				$database_stat{$db}{fetched} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . sprintf("%0.2f", ($all_stat_database{$t}{$db}{fetched}/$all_stat_database{$t}{$db}{interval})) . '],';
				$database_stat{$db}{update} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . sprintf("%0.2f", ($all_stat_database{$t}{$db}{update}/$all_stat_database{$t}{$db}{interval})) . '],';
				$database_stat{$db}{delete} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . sprintf("%0.2f", ($all_stat_database{$t}{$db}{delete}/$all_stat_database{$t}{$db}{interval})) . '],';
				$total_query_type{$db}{'all'} +=  $all_stat_database{$t}{$db}{insert} + $all_stat_database{$t}{$db}{returned} + $all_stat_database{$t}{$db}{update} + $all_stat_database{$t}{$db}{delete};

				$total_query_type{$db}{'insert'} += $all_stat_database{$t}{$db}{insert};
				$total_query_type{$db}{'delete'} += $all_stat_database{$t}{$db}{delete};
				$total_query_type{$db}{'update'} += $all_stat_database{$t}{$db}{update};
				$total_query_type{$db}{'select'} += $all_stat_database{$t}{$db}{returned};
			}
			$all_stat_database{$t}{$db}{blks_read} ||= 0;
			$all_stat_database{$t}{$db}{blks_hit} ||= 0;
			$database_stat{$db}{blks_read} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . sprintf("%0.2f", ($all_stat_database{$t}{$db}{blks_read}/$all_stat_database{$t}{$db}{interval})) . '],';
			$database_stat{$db}{blks_hit} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . sprintf("%0.2f", ($all_stat_database{$t}{$db}{blks_hit}/$all_stat_database{$t}{$db}{interval})) . '],';

			if (($all_stat_database{$t}{$db}{blks_read} + $all_stat_database{$t}{$db}{blks_hit}) > 0) {
				$database_stat{$db}{ratio_hit_miss} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . sprintf("%0.2f", ($all_stat_database{$t}{$db}{blks_hit}*100)/($all_stat_database{$t}{$db}{blks_read} + $all_stat_database{$t}{$db}{blks_hit})) . '],';
			} else {
				$database_stat{$db}{ratio_hit_miss} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',0],';
			}
			$database_stat{$db}{nbackend} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_stat_database{$t}{$db}{nbackend}||0) . '],';
			$has_conn{$db} = 1 if ($all_stat_database{$t}{$db}{nbackend});
			$database_stat{$db}{xact_commit} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . sprintf("%0.2f", ($all_stat_database{$t}{$db}{xact_commit}||0)/$all_stat_database{$t}{$db}{interval}) . '],';
			$database_stat{$db}{xact_rollback} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . sprintf("%0.2f", ($all_stat_database{$t}{$db}{xact_rollback}||0)/$all_stat_database{$t}{$db}{interval}) . '],';
			$database_stat{$db}{xact_throughput} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . sprintf("%0.2f", ($all_stat_database{$t}{$db}{xact_throughput}||0)/$all_stat_database{$t}{$db}{interval}) . '],';
			# It depends on the postgresql version
			if (!$has_conflict)
			{
				foreach my $k (keys %{$all_stat_database{$t}{$db}})
				{
					if ($k eq 'canceled_queries')
					{
						$has_conflict = 1;
						last;
					}
				}
			}
			if ($has_conflict) {
				$database_stat{$db}{canceled_queries} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_stat_database{$t}{$db}{canceled_queries}||0) . '],';
			}
			# It depends on the postgresql version
			if (!$has_temp)
			{
				foreach my $k (keys %{$all_stat_database{$t}{$db}})
				{
					if (grep(/^$k$/, 'deadlocks','temp_files','temp_bytes'))
					{
						$has_temp = 1;
						last;
					}
				}
			}
			if ($has_temp)
			{
				$database_stat{$db}{deadlocks} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_stat_database{$t}{$db}{deadlocks}||0) . '],';
				$database_stat{$db}{temp_files} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_stat_database{$t}{$db}{temp_files}||0) . '],';
				$database_stat{$db}{temp_bytes} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . sprintf("%0.2f", ($all_stat_database{$t}{$db}{temp_bytes}||0)/$all_stat_database{$t}{$db}{interval}) . '],';
			}
		}
	}
	%all_stat_database = ();

	foreach my $id (sort {$a <=> $b} keys %data_info)
	{
		foreach my $db (sort keys %database_stat)
		{
			next if (($db ne 'all') && ($#INCLUDE_DB >= 0) && (!grep($db =~ /^$_$/, @INCLUDE_DB)));

			my $dbfh = undef;
			my $fhcluster = &append_to_html_file("$OUTPUT_DIR/cluster-$data_info{$id}{name}.html", $src_base);
			if ($data_info{$id}{name} eq 'database-write_ratio')
			{
				$dbfh = &append_to_html_file("$OUTPUT_DIR/database-io-$db.html", $src_base);
				if ($has_tuples)
				{
					$database_stat{$db}{insert} =~ s/,$//;
					$database_stat{$db}{update} =~ s/,$//;
					$database_stat{$db}{delete} =~ s/,$//;
				}
				if ($db ne 'all') {
					$dbfh->print( &jqplot_linegraph_array($IDX++, 'database-write_ratio', \%{$data_info{$id}}, $db, $database_stat{$db}{insert}, $database_stat{$db}{update}, $database_stat{$db}{delete}) );
				} else {
					print $fhcluster &jqplot_linegraph_array($IDX++, 'cluster-write_ratio', \%{$data_info{$id}}, $db, $database_stat{$db}{insert}, $database_stat{$db}{update}, $database_stat{$db}{delete});
				}
			}
			elsif ($data_info{$id}{name} eq 'database-read_ratio')
			{
				$dbfh = &append_to_html_file("$OUTPUT_DIR/database-io-$db.html", $src_base);
				if ($has_tuples)
				{
					$database_stat{$db}{returned} =~ s/,$//;
					$database_stat{$db}{fetched} =~ s/,$//;
				}
				if ($db ne 'all') {
					$dbfh->print( &jqplot_linegraph_array($IDX++, 'database-read_ratio', \%{$data_info{$id}}, $db, $database_stat{$db}{returned}, $database_stat{$db}{fetched}) );
				} else {
					print $fhcluster &jqplot_linegraph_array($IDX++, 'cluster-read_ratio', \%{$data_info{$id}}, $db, $database_stat{$db}{returned}, $database_stat{$db}{fetched});
				}

			}
			elsif ($data_info{$id}{name} eq 'database-read_write_query')
			{
				$dbfh = &append_to_html_file("$OUTPUT_DIR/database-io-$db.html", $src_base);
				if (exists $total_query_type{$db}{'all'} && ($total_query_type{$db}{'all'} > 0))
				{
					my %data = ();
					foreach my $t (keys %{$total_query_type{$db}})
					{
						next if ($t eq 'all');
						$data{$t} = sprintf("%0.2f", $total_query_type{$db}{$t}*100/$total_query_type{$db}{'all'});
					}
					if ($db ne 'all') {
						$dbfh->print( &jqplot_piegraph($IDX++, 'database-read_write_query', \%{$data_info{$id}}, $db, %data) );
					} else {
						print $fhcluster &jqplot_piegraph($IDX++, 'cluster-read_write_query', \%{$data_info{$id}}, $db, %data);
					}
				}
			}
			elsif ($data_info{$id}{name} eq 'database-cache_ratio')
			{
				$dbfh = &append_to_html_file("$OUTPUT_DIR/database-$db.html", $src_base);
				$database_stat{$db}{blks_read} =~ s/,$//;
				$database_stat{$db}{blks_hit} =~ s/,$//;
				if ($db ne 'all') {
					$dbfh->print( &jqplot_linegraph_array($IDX++, 'database-cache_ratio', \%{$data_info{$id}}, $db, $database_stat{$db}{blks_hit}, $database_stat{$db}{blks_read}, $database_stat{$db}{ratio_hit_miss}) );
				} else {
					print $fhcluster &jqplot_linegraph_array($IDX++, 'cluster-cache_ratio', \%{$data_info{$id}}, $db, $database_stat{$db}{blks_hit}, $database_stat{$db}{blks_read}, $database_stat{$db}{ratio_hit_miss});
				}
				delete $database_stat{$db}{blks_hit};
				delete $database_stat{$db}{blks_read};
				delete $database_stat{$db}{ratio_hit_miss};
			}
			elsif ($data_info{$id}{name} eq 'database-commits_rollbacks')
			{
				$dbfh = &append_to_html_file("$OUTPUT_DIR/database-tx-$db.html", $src_base);
				$database_stat{$db}{xact_commit} =~ s/,$//;
				$database_stat{$db}{xact_rollback} =~ s/,$//;
				$database_stat{$db}{nbackend} =~ s/,$//;
				if ($db ne 'all') {
					$dbfh->print( &jqplot_linegraph_array($IDX++, 'database-commits_rollbacks', \%{$data_info{$id}}, $db, $database_stat{$db}{xact_commit}, $database_stat{$db}{xact_rollback}, $database_stat{$db}{nbackend}) );
				} else {
					print $fhcluster &jqplot_linegraph_array($IDX++, 'cluster-commits_rollbacks', \%{$data_info{$id}}, $db, $database_stat{$db}{xact_commit}, $database_stat{$db}{xact_rollback}, $database_stat{$db}{nbackend});
				}
				delete $database_stat{$db}{xact_commit};
				delete $database_stat{$db}{xact_rollback};
			}
			elsif ($data_info{$id}{name} eq 'database-transactions')
			{
				$dbfh = &append_to_html_file("$OUTPUT_DIR/database-tx-$db.html", $src_base);
				$database_stat{$db}{xact_throughput} =~ s/,$//;
				if ($db ne 'all') {
					$dbfh->print( &jqplot_linegraph_array($IDX++, 'database-transactions', \%{$data_info{$id}}, $db, $database_stat{$db}{xact_throughput}) );
				} else {
					print $fhcluster &jqplot_linegraph_array($IDX++, 'cluster-transactions', \%{$data_info{$id}}, $db, $database_stat{$db}{xact_throughput});
				}
			}
			$dbfh->close() if (defined $dbfh);
			$fhcluster->close();
		}
	}

	foreach my $id (sort {$a <=> $b} keys %data_info)
	{
		my %data = ();
		my $found = 0;
		foreach my $db (sort keys %database_stat)
		{
			next if (($db ne 'all') && ($#INCLUDE_DB >= 0) && (!grep($db =~ /^$_$/, @INCLUDE_DB)));

			my $dbfh = undef;
			if ($data_info{$id}{name} eq 'database-backends')
			{
				$dbfh = &append_to_html_file("$OUTPUT_DIR/database-conn-$db.html", $src_base);
				$database_stat{$db}{nbackend} =~ s/,$//;
				$data{$db} = $database_stat{$db}{nbackend};
				if (($db ne 'all') && exists $has_conn{$db}) {
					$dbfh->print( &jqplot_linegraph_array($IDX++, $data_info{$id}{name}, \%{$data_info{$id}}, $db, $database_stat{$db}{nbackend}) );
				}
				delete $database_stat{$db}{nbackend};
				$found++;

			}
			elsif ($has_conflict && ($data_info{$id}{name} eq 'database-canceled_queries'))
			{
				$dbfh = &append_to_html_file("$OUTPUT_DIR/database-conflict-$db.html", $src_base);
				$database_stat{$db}{canceled_queries} =~ s/,$//;
				$data{$db} = $database_stat{$db}{canceled_queries};
				if ($db ne 'all') {
					$dbfh->print( &jqplot_linegraph_array($IDX++, $data_info{$id}{name}, \%{$data_info{$id}}, $db, $database_stat{$db}{canceled_queries}) );
				}
				delete $database_stat{$db}{canceled_queries};
				$found++;

			}
			elsif ($has_temp && ($data_info{$id}{name} eq 'database-deadlocks'))
			{
				$dbfh = &append_to_html_file("$OUTPUT_DIR/database-lock-$db.html", $src_base);
				$database_stat{$db}{deadlocks} =~ s/,$//;
				$data{$db} = $database_stat{$db}{deadlocks};
				if ($db ne 'all') {
					$dbfh->print( &jqplot_linegraph_array($IDX++, $data_info{$id}{name}, \%{$data_info{$id}}, $db, $database_stat{$db}{deadlocks}) );
				}
				delete $database_stat{$db}{deadlocks};
				$found++;

			}
			elsif ($has_temp && ($data_info{$id}{name} eq 'database-temporary_files'))
			{
				$dbfh = &append_to_html_file("$OUTPUT_DIR/database-tmpf-$db.html", $src_base);
				$database_stat{$db}{temp_files} =~ s/,$//;
				$data{$db} = $database_stat{$db}{temp_files};
				if ($db ne 'all') {
					$dbfh->print( &jqplot_linegraph_array($IDX++, $data_info{$id}{name}, \%{$data_info{$id}}, $db, $database_stat{$db}{temp_files}) );
				}
				delete $database_stat{$db}{temp_files};
				$found++;

			}
			elsif ($has_temp && ($data_info{$id}{name} eq 'database-temporary_bytes'))
			{
				$dbfh = &append_to_html_file("$OUTPUT_DIR/database-tmpf-$db.html", $src_base);
				$database_stat{$db}{temp_bytes} =~ s/,$//;
				$data{$db} = $database_stat{$db}{temp_bytes};
				if ($db ne 'all') {
					$dbfh->print( &jqplot_linegraph_array($IDX++, $data_info{$id}{name}, \%{$data_info{$id}}, $db, $database_stat{$db}{temp_bytes}) );
				}
				delete $database_stat{$db}{temp_bytes};
				$found++;

			}
			$dbfh->close() if (defined $dbfh);
		}

		if ($found)
		{
			my $name = $data_info{$id}{name};
			$name =~ s/^database/cluster/;
			my $fhcluster = &append_to_html_file("$OUTPUT_DIR/cluster-$data_info{$id}{name}.html", $src_base);
			if ($has_temp && ($data_info{$id}{name} eq 'database-temporary_files')) {
				print $fhcluster &jqplot_linegraph_hash($IDX++, $name, \%{$data_info{$id}}, 'all', %data);
			}
			if ($has_temp && ($data_info{$id}{name} eq 'database-temporary_bytes')) {
				print $fhcluster &jqplot_linegraph_hash($IDX++, $name, \%{$data_info{$id}}, 'all', %data);
			}
			if ($data_info{$id}{name} eq 'database-backends') {
				print $fhcluster &jqplot_linegraph_hash($IDX++, $name, \%{$data_info{$id}}, 'all', %data);
			}
			if ($has_temp && ($data_info{$id}{name} eq 'database-deadlocks')) {
				print $fhcluster &jqplot_linegraph_hash($IDX++, $name, \%{$data_info{$id}}, 'all', %data);
			}
			if ($has_conflict && ($data_info{$id}{name} eq 'database-canceled_queries')) {
				print $fhcluster &jqplot_linegraph_hash($IDX++, $name, \%{$data_info{$id}}, 'all', %data);
			}
			$fhcluster->close();
		}
	}
}

# Compute statistics of database conflict statistics
sub pg_stat_database_conflicts
{
	my ($in_dir, $file, $offset) = @_;

	my %start_vals = ();
	my $tmp_val = 0;
	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	$curfh->seek($offset,0);
	while (my $l = <$curfh>)
	{
		$offset += length($l);
		my @data = split(/;/, $l);
		next if (!&normalize_line(\@data));
		# timestamp | datid | datname | confl_tablespace | confl_lock | confl_snapshot | confl_bufferpin | confl_deadlock

		# The first line read for a database has no previous value, its
		# delta is unknown: it must not replace a value loaded from cache.
		my $first = ($#{$start_vals{$data[2]}} < 0) ? 1 : 0;
		push(@{$start_vals{$data[2]}}, @data) if ($first);

		if (($data[3] - $start_vals{$data[2]}[3]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[3] - $start_vals{$data[2]}[3]) };
		&set_conflict_delta($data[2], $data[0], 'tablespace', $tmp_val, $first);

		if (($data[4] - $start_vals{$data[2]}[4]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[4] - $start_vals{$data[2]}[4]) };
		&set_conflict_delta($data[2], $data[0], 'lock', $tmp_val, $first);

		if (($data[5] - $start_vals{$data[2]}[5]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[5] - $start_vals{$data[2]}[5]) };
		&set_conflict_delta($data[2], $data[0], 'snapshot', $tmp_val, $first);

		if (($data[6] - $start_vals{$data[2]}[6]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[6] - $start_vals{$data[2]}[6]) };
		&set_conflict_delta($data[2], $data[0], 'bufferpin', $tmp_val, $first);

		if (($data[7] - $start_vals{$data[2]}[7]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[7] - $start_vals{$data[2]}[7]) };
		&set_conflict_delta($data[2], $data[0], 'deadlock', $tmp_val, $first);

		@{$start_vals{$data[2]}} = ();
		push(@{$start_vals{$data[2]}}, @data);

	}
	$curfh->close();

	return $offset || 0;
}

####
# Store the delta of a conflict counter for a database at a timestamp. The
# value is replaced, not added, so that a line read twice gives the same
# result. The first line read for a database has a delta of 0
# because there is no previous value, it must not replace the value of
# the same timestamp loaded from the cache.
####
sub set_conflict_delta
{
	my ($db, $t, $field, $val, $first) = @_;

	if ($first) {
		$all_stat_database_conflicts{$db}{$t}{$field} //= $val;
	} else {
		$all_stat_database_conflicts{$db}{$t}{$field} = $val;
	}
}

# Compute graphs of database conflict statistics
sub pg_stat_database_conflicts_report
{
	my ($src_base, %data_info) = @_;

        my %database_stat = ();
        my $id = &get_data_id('database-conflicts', %data_info);
        my $total_val = 0;
        my $tz = ($STATS_TIMEZONE*3600*1000);
        my %conflict_type = ();
        &set_cluster_total_by_db(\%all_stat_database_conflicts, 'tablespace', 'lock', 'snapshot', 'bufferpin', 'deadlock');
        foreach my $db (sort keys %all_stat_database_conflicts) {
		next if (($db ne 'all') && ($#INCLUDE_DB >= 0) && (!grep($db =~ /^$_$/, @INCLUDE_DB)));
                foreach my $t (sort {$a <=> $b} keys %{$all_stat_database_conflicts{$db}}) {
                                $conflict_type{$db}{tablespace} .= '[' . ($t - $tz) . ',' . ($all_stat_database_conflicts{$db}{$t}{tablespace} || 0) . '],';
                                $conflict_type{$db}{lock} .= '[' . ($t - $tz) . ',' . ($all_stat_database_conflicts{$db}{$t}{lock} || 0) . '],';
                                $conflict_type{$db}{snapshot} .= '[' . ($t - $tz) . ',' . ($all_stat_database_conflicts{$db}{$t}{snapshot} || 0) . '],';
                                $conflict_type{$db}{bufferpin} .= '[' . ($t - $tz) . ',' . ($all_stat_database_conflicts{$db}{$t}{bufferpin} || 0) . '],';
                                $conflict_type{$db}{deadlock} .= '[' . ($t - $tz) . ',' . ($all_stat_database_conflicts{$db}{$t}{deadlock} || 0) . '],';
                }
                $conflict_type{$db}{tablespace} =~ s/,$//;
                $conflict_type{$db}{lock} =~ s/,$//;
                $conflict_type{$db}{snapshot} =~ s/,$//;
                $conflict_type{$db}{bufferpin} =~ s/,$//;
                $conflict_type{$db}{deadlock} =~ s/,$//;
		my $dbfh = &append_to_html_file("$OUTPUT_DIR/database-conflict-$db.html", $src_base);
		if ($db ne 'all') {
			$dbfh->print( &jqplot_linegraph_array($IDX++, $data_info{$id}{name}, \%{$data_info{$id}}, $db, $conflict_type{$db}{tablespace}, $conflict_type{$db}{lock}, $conflict_type{$db}{snapshot}, $conflict_type{$db}{bufferpin}, $conflict_type{$db}{deadlock}) );
		}
		else
		{
			my $fhcluster = &append_to_html_file("$OUTPUT_DIR/cluster-$data_info{$id}{name}.html", $src_base);
			print $fhcluster &jqplot_linegraph_array($IDX++, 'cluster-conflicts', \%{$data_info{$id}}, $db, $conflict_type{$db}{tablespace}, $conflict_type{$db}{lock}, $conflict_type{$db}{snapshot}, $conflict_type{$db}{bufferpin}, $conflict_type{$db}{deadlock});
			$fhcluster->close();
		}
		$dbfh->close();
	}
        %all_stat_database_conflicts = ();
}

# Compute statistics of database size statistics
sub pg_database_size
{
	my ($in_dir, $file, $offset) = @_;

	my %db_list = ();
	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	$curfh->seek($offset,0);
	while (my $l = <$curfh>) {
		$offset += length($l);
		my @data = split(/;/, $l);
		next if (!&normalize_line(\@data));

		# Do not process shared relation
		next if ($data[1] == 0);

		# date_trunc | datid | datname | size

		# Store list of database,
		$db_list{$data[2]} = 1;
		# Get database size statistics
		$all_database_size{$data[0]}{$data[2]} = $data[3];
	}
	$curfh->close();

	# Store the full list of database
	foreach my $d (keys %db_list) {
		push(@global_databases, $d) if (!grep(/^$d$/, @global_databases));
	}
	push(@global_databases, 'all') if (($#global_databases >= 0) && !grep(/^all$/, @global_databases));

	return $offset || 0;
}

# Compute graphs of database size statistics
sub pg_database_size_report
{
	my ($src_base, %data_info) = @_;

	my %database_stat = ();
	my $total_val = 0;
	&set_cluster_total(\%all_database_size);
	foreach my $t (sort {$a <=> $b} keys %all_database_size)
	{
		foreach my $db (@global_databases)
		{
			$database_stat{$db}{size} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_database_size{$t}{$db} || 0) . '],';
			next if ($db eq 'all');
			$OVERALL_STATS{'database'}{$db}{'size'} = $all_database_size{$t}{$db};
			$OVERALL_STATS{'start_date'} = $t if (!$OVERALL_STATS{'start_date'} || ($OVERALL_STATS{'start_date'} gt $t));
			$OVERALL_STATS{'end_date'} = $t if (!$OVERALL_STATS{'end_date'} || ($OVERALL_STATS{'end_date'} lt $t));
		}
	}
	%all_database_size = ();

	my $id = &get_data_id('database-size', %data_info);
	my %data = ();
	foreach my $db (sort keys %database_stat)
	{
		next if (($db ne 'all') && ($#INCLUDE_DB >= 0) && (!grep($db =~ /^$_$/, @INCLUDE_DB)));
		$database_stat{$db}{size} =~ s/,$//;
		$data{$db} = $database_stat{$db}{size};
		my $dbfh = &append_to_html_file("$OUTPUT_DIR/database-$db.html", $src_base);
		if ($db ne 'all') {
			$dbfh->print( &jqplot_linegraph_array($IDX++, 'database-size', \%{$data_info{$id}}, $db, $database_stat{$db}{size}) );
		}
		$dbfh->close();
		delete $database_stat{$db}{size};
	}

	my $fhcluster = &append_to_html_file("$OUTPUT_DIR/cluster-$data_info{$id}{name}.html", $src_base);
	if (!$sysinfo{CONFIGURATION}{'capture'}) {
		print $fhcluster &jqplot_linegraph_hash($IDX++, 'cluster-size', \%{$data_info{$id}}, 'all', %data);
	}
	else
	{
		$data_info{$id}{title} =~ s/\%s/all/;
		print $fhcluster qq{
<li class="slide" id="cluster-size-slide">
      <div id="cluster-size"><br/><br/><br/><br/></div>
	<div class="row">
            <div class="col-md-12">
              <div class="panel panel-default">
              <div class="panel-heading">
		<h2>$data_info{$id}{title}</h2>
		<p>$data_info{$id}{description}</p>
              </div>
              <div class="panel-body">
		<div class="analysis-item row-fluid" id="$data_info{$id}{name}-report">
			<div class="span11">
				<table class="table table-striped" id="$data_info{$id}{name}-table">
					<tbody>
					<tr><th>Database Name</th><th>Size</th></tr>
};
		foreach my $db (sort keys %{$OVERALL_STATS{'database'}})
		{
                        next if (($db ne 'all') && ($#INCLUDE_DB >= 0) && (!grep(/^$db$/, @INCLUDE_DB)));
			my $dbsize = &pretty_print_size($OVERALL_STATS{'database'}{$db}{size});
			print $fhcluster "<tr><td>$db</td><td>$dbsize</td></tr>\n";
		}
		print $fhcluster qq{
					</tbody>
				</table>
			</div>
		</div>
		</div>
	    </div>
	    </div>
	</div>
    </li>
};
	}
	$fhcluster->close();
}

# Compute statistics of prepared transaction statistics
sub pg_prepared_xact
{
	my ($in_dir, $file, $offset) = @_;

	my %db_list = ();
	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	$curfh->seek($offset,0);
	while (my $l = <$curfh>)
	{
		$offset += length($l);
		my @data = split(/;/, $l);
		next if (!&normalize_line(\@data));

		# date_trunc | database | count | oldest

		# Store list of database,
		$db_list{$data[1]} = 1;
		# Get database prepared transaction statistics
		$all_prepared_xact{$data[0]}{$data[1]}{count} = $data[2];
		$all_prepared_xact{$data[0]}{$data[1]}{oldest} = $data[3];
	}
	$curfh->close();

	# Store the full list of database
	foreach my $d (keys %db_list) {
		push(@global_databases, $d) if (!grep(/^$d$/, @global_databases));
	}
	push(@global_databases, 'all') if (($#global_databases >= 0) && !grep(/^all$/, @global_databases));

	return $offset || 0;
}

# Compute graphs of database size statistics
sub pg_prepared_xact_report
{
	my ($src_base, %data_info) = @_;

	return if (scalar keys %all_prepared_xact == 0);

	my %database_stat = ();
	my $total_val = 0;
	&set_cluster_total(\%all_prepared_xact, 'count', 'oldest:max');
	foreach my $t (sort {$a <=> $b} keys %all_prepared_xact)
	{
		foreach my $db (@global_databases)
		{
			$database_stat{$db}{count} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_prepared_xact{$t}{$db}{count} || 0) . '],';
			$database_stat{$db}{oldest} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_prepared_xact{$t}{$db}{oldest} || 0) . '],';
			next if ($db eq 'all');
			$OVERALL_STATS{'database'}{$db}{'prepared_count'} = $all_prepared_xact{$t}{$db}{count};
			$OVERALL_STATS{'database'}{$db}{'prepared_oldest'} = $all_prepared_xact{$t}{$db}{oldest};
			$OVERALL_STATS{'start_date'} = $t if (!$OVERALL_STATS{'start_date'} || ($OVERALL_STATS{'start_date'} gt $t));
			$OVERALL_STATS{'end_date'} = $t if (!$OVERALL_STATS{'end_date'} || ($OVERALL_STATS{'end_date'} lt $t));
		}
	}
	%all_prepared_xact = ();

	my $id = &get_data_id('database-prepared', %data_info);
	foreach my $db (sort keys %database_stat)
	{
		next if (($db ne 'all') && ($#INCLUDE_DB >= 0) && (!grep($db =~ /^$_$/, @INCLUDE_DB)));
		$database_stat{$db}{count} =~ s/,$//;
		$database_stat{$db}{oldest} =~ s/,$//;
		my $dbfh = &append_to_html_file("$OUTPUT_DIR/database-tx-$db.html", $src_base);
		if ($db ne 'all')
		{
			$dbfh->print( &jqplot_linegraph_array($IDX++, 'database-prepared', \%{$data_info{$id}}, $db, $database_stat{$db}{count},$database_stat{$db}{oldest}) );
			delete $database_stat{$db};
		}
		$dbfh->close();
	}

	my $fhcluster = &append_to_html_file("$OUTPUT_DIR/cluster-$data_info{$id}{name}.html", $src_base);
	if (!$sysinfo{CONFIGURATION}{'capture'}) {
		print $fhcluster &jqplot_linegraph_array($IDX++, 'cluster-prepared', \%{$data_info{$id}}, 'all', $database_stat{'all'}{count}, $database_stat{'all'}{oldest});
	}
	else
	{
		$data_info{$id}{title} =~ s/\%s/all/;
		print $fhcluster qq{
<li class="slide" id="cluster-prepared-slide">
      <div id="cluster-prepared"><br/><br/><br/><br/></div>
	<div class="row">
            <div class="col-md-12">
              <div class="panel panel-default">
              <div class="panel-heading">
		<h2>$data_info{$id}{title}</h2>
		<p>$data_info{$id}{description}</p>
              </div>
              <div class="panel-body">
		<div class="analysis-item row-fluid" id="$data_info{$id}{name}-report">
			<div class="span11">
				<table class="table table-striped" id="$data_info{$id}{name}-table">
					<tbody>
					<tr><th>Database Name</th><th>Prepared xact</th><th>Oldest xact</th></tr>
};
		foreach my $db (sort keys %{$OVERALL_STATS{'database'}})
		{
                        next if (($db ne 'all') && ($#INCLUDE_DB >= 0) && (!grep(/^$db$/, @INCLUDE_DB)));
			my $dbsize = &pretty_print_size($OVERALL_STATS{'database'}{$db}{prepared_count});
			my $oldest = &format_duration($OVERALL_STATS{'database'}{$db}{prepared_oldest}*1000);
			print $fhcluster "<tr><td>$db</td><td>$dbsize</td><td>$oldest</td></tr>\n";
		}
		print $fhcluster qq{
					</tbody>
				</table>
			</div>
		</div>
		</div>
	    </div>
	    </div>
	</div>
    </li>
};
	}
	$fhcluster->close();
}



# Compute statistics of tablespace size
sub pg_tablespace_size
{
	my ($in_dir, $file, $offset) = @_;

	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	my $total_val = 0;
	$curfh->seek($offset,0);
	while (my $l = <$curfh>) {
		$offset += length($l);
		my @data = split(/;/, $l);
		next if (!&normalize_line(\@data));

		# timestamp | tbspname | size | path

		push(@global_tbspnames, $data[1]) if (!grep(/^$data[1]$/, @global_tbspnames));

		# Get tablespace size statistics
		$all_tablespace_size{$data[0]}{$data[1]}{size} = $data[2];
		$all_tablespace_size{$data[0]}{$data[1]}{location} = $data[3];
	}
	$curfh->close();
	push(@global_tbspnames, 'all') if (($#global_tbspnames > 0) && !grep(/^all$/, @global_tbspnames));

	return $offset || 0;
}

# Compute graphs of tablespace size
sub pg_tablespace_size_report
{
	my ($src_base, %data_info) = @_;

	my $id = &get_data_id('tablespace-size', %data_info);
	my %data = ();
	my $print_after = '';
	if (!$sysinfo{CONFIGURATION}{'capture'}) {
		my %tablespace_stat = ();
		&set_cluster_total(\%all_tablespace_size, 'size');
		foreach my $t (sort {$a <=> $b} keys %all_tablespace_size) {
			foreach my $tbsp (@global_tbspnames) {
				$tablespace_stat{$tbsp}{size} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_tablespace_size{$t}{$tbsp}{size}||0) . '],';
				if ($tbsp ne 'all') {
					$OVERALL_STATS{'tablespace'}{$tbsp}{'size'} = $all_tablespace_size{$t}{$tbsp}{size};
					$OVERALL_STATS{'tablespace'}{$tbsp}{'location'} = $all_tablespace_size{$t}{$tbsp}{location};
				}
			}
		}
		foreach my $tbsp (sort keys %tablespace_stat) {
			$tablespace_stat{$tbsp}{size} =~ s/,$//;
			$data{$tbsp} = $tablespace_stat{$tbsp}{size};
			if ($tbsp ne 'all') {
				$print_after .= "<p>$tbsp ($OVERALL_STATS{'tablespace'}{$tbsp}{location})</p>\n";
			}
		}
		$data_info{$id}{print_after} = $print_after if ($print_after);
	}
	%all_tablespace_size = ();

	my $fhcluster = &append_to_html_file("$OUTPUT_DIR/cluster-$data_info{$id}{name}.html", $src_base);
	if (!$sysinfo{CONFIGURATION}{'capture'}) {
		print $fhcluster &jqplot_linegraph_hash($IDX++, 'tablespace-cluster-size', \%{$data_info{$id}}, 'all', %data);
	} else {
		my $header = '<tr><th>Tablespace Name</th><th>Location</th><th>Size</th></tr>';
		if (scalar keys %{$OVERALL_STATS{'tablespace'}} == 0) {
			$header = qq{<td><div class="flotr-graph"><blockquote><b>NO DATASET</b></blockquote></div></td>};
		}
		$data_info{$id}{title} =~ s/\%s/all/;
		print $fhcluster qq{
<li class="slide" id="tablespace-cluster-size-slide">
      <div id="tablespace-cluster-size"><br/><br/><br/><br/></div>
	<div class="row">
            <div class="col-md-12">
              <div class="panel panel-default">
              <div class="panel-heading">
		<h2>$data_info{$id}{title}</h2>
		<p>$data_info{$id}{description}</p>
              </div>
              <div class="panel-body">
		<div class="analysis-item row-fluid" id="$data_info{$id}{name}-report">
			<div class="span11">
				<table class="table table-striped" id="$data_info{$id}{name}-table">
					<tbody>
					$header
};
		foreach my $tbsp (sort keys %{$OVERALL_STATS{'tablespace'}}) {
			my $tbsize = &pretty_print_size($OVERALL_STATS{'tablespace'}{$tbsp}{size});
			print $fhcluster "<tr><td>$tbsp</td><td>$OVERALL_STATS{'tablespace'}{$tbsp}{location}</td><td>$tbsize</td></tr>\n";
		}
		print $fhcluster qq{
					</tbody>
				</table>
			</div>
		</div>
		</div>
	    </div>
	</div>
    </div>
};
	}
	$fhcluster->close();
}

# Compute statistics about table accesses and vacuum
sub pg_stat_user_tables
{
	my ($in_dir, $file) = @_;

	return if ($NO_TB_STAT);

	%all_stat_user_tables = ();

	my %start_vals = ();
	my $tmp_val = 0;
	# Read start file
	my $curfh = open_filehdl("$in_dir/$file");
	if (defined $curfh)
	{
		while (my $l = <$curfh>)
		{
			chomp($l);
			next if (!$l);
			my @data = split(/;/, $l);
			next if (!&normalize_line(\@data));

			# timestamp | dbname | relid | schemaname | relname | seq_scan | seq_tup_read | idx_scan | idx_tup_fetch | n_tup_ins | n_tup_upd | n_tup_del | n_tup_hot_upd | n_live_tup | n_dead_tup | last_vacuum | last_autovacuum | last_analyze | last_autoanalyze | vacuum_count | autovacuum_count | analyze_count | autoanalyze_count

			$OVERALL_STATS{'database'}{$data[1]}{last_vacuum} = $data[15] if (!$OVERALL_STATS{'database'}{$data[1]}{last_vacuum} || ($data[15] gt $OVERALL_STATS{'database'}{$data[1]}{last_vacuum}));
			$OVERALL_STATS{'database'}{$data[1]}{last_autovacuum} = $data[16] if (!$OVERALL_STATS{'database'}{$data[1]}{last_autovacuum} || ($data[16] gt $OVERALL_STATS{'database'}{$data[1]}{last_autovacuum}));
			$OVERALL_STATS{'database'}{$data[1]}{last_analyze} = $data[17] if (!$OVERALL_STATS{'database'}{$data[1]}{last_analyze} || ($data[17] gt $OVERALL_STATS{'database'}{$data[1]}{last_analyze}));
			$OVERALL_STATS{'database'}{$data[1]}{last_autoanalyze} = $data[18] if (!$OVERALL_STATS{'database'}{$data[1]}{last_autoanalyze} || ($data[18] gt $OVERALL_STATS{'database'}{$data[1]}{last_autoanalyze}));

			$data[4] = "$data[3].$data[4]";

			# Stores last manual vacuum/analyze
			$all_stat_user_tables{$data[1]}{$data[4]}{last_vacuum} = $data[15] if ($data[15]);
			$all_stat_user_tables{$data[1]}{$data[4]}{last_autovacuum} = $data[16] if ($data[16]);
			$all_stat_user_tables{$data[1]}{$data[4]}{last_analyze} = $data[17] if ($data[17]);
			$all_stat_user_tables{$data[1]}{$data[4]}{last_autoanalyze} = $data[18] if ($data[18]);

			# Get database statistics
			$all_stat_user_tables{$data[1]}{$data[4]}{seq_scan} = $data[5];
			$all_stat_user_tables{$data[1]}{$data[4]}{idx_scan} = $data[6];
			$all_stat_user_tables{$data[1]}{$data[4]}{n_tup_ins} = $data[9];
			$all_stat_user_tables{$data[1]}{$data[4]}{n_tup_upd} = $data[10];
			$all_stat_user_tables{$data[1]}{$data[4]}{n_tup_del} = $data[11];
			$all_stat_user_tables{$data[1]}{$data[4]}{n_tup_hot_upd} = $data[12];
			$all_stat_user_tables{$data[1]}{$data[4]}{n_dead_tup} = $data[14];
			$all_stat_user_tables{$data[1]}{$data[4]}{n_live_tup} = $data[13];
			$all_stat_user_tables{$data[1]}{$data[4]}{dead_vs_live} = sprintf("%.2f", ($data[14]*100)/(($data[13]+$data[14])||1));
			if ($#data > 19) {
				$all_stat_user_tables{$data[1]}{$data[4]}{vacuum_count} = $data[19];
				$all_stat_user_tables{$data[1]}{$data[4]}{autovacuum_count} = $data[20];
				$all_stat_user_tables{$data[1]}{$data[4]}{analyze_count} = $data[21];
				$all_stat_user_tables{$data[1]}{$data[4]}{autoanalyze_count} = $data[22];
			}
		}
		$curfh->close();
	}

	if (!$sysinfo{CONFIGURATION}{'capture'})
	{
		# Read end file and set the final value
		$curfh = open_filehdl("$in_dir/end-$file");
		if (defined $curfh)
		{
			while (my $l = <$curfh>)
			{
				chomp($l);
				next if (!$l);
				my @data = split(/;/, $l);
				next if (!&normalize_line(\@data));

				# timestamp | dbname | relid | schemaname | relname | seq_scan | seq_tup_read | idx_scan | idx_tup_fetch | n_tup_ins | n_tup_upd | n_tup_del | n_tup_hot_upd | n_live_tup | n_dead_tup | last_vacuum | last_autovacuum | last_analyze | last_autoanalyze | vacuum_count | autovacuum_count | analyze_count | autoanalyze_count

				$OVERALL_STATS{'database'}{$data[1]}{last_vacuum} = $data[15] if (!$OVERALL_STATS{'database'}{$data[1]}{last_vacuum} || ($data[15] gt $OVERALL_STATS{'database'}{$data[1]}{last_vacuum}));
				$OVERALL_STATS{'database'}{$data[1]}{last_autovacuum} = $data[16] if (!$OVERALL_STATS{'database'}{$data[1]}{last_autovacuum} || ($data[16] gt $OVERALL_STATS{'database'}{$data[1]}{last_autovacuum}));
				$OVERALL_STATS{'database'}{$data[1]}{last_analyze} = $data[17] if (!$OVERALL_STATS{'database'}{$data[1]}{last_analyze} || ($data[17] gt $OVERALL_STATS{'database'}{$data[1]}{last_analyze}));
				$OVERALL_STATS{'database'}{$data[1]}{last_autoanalyze} = $data[18] if (!$OVERALL_STATS{'database'}{$data[1]}{last_autoanalyze} || ($data[18] gt $OVERALL_STATS{'database'}{$data[1]}{last_autoanalyze}));

				$data[4] = "$data[3].$data[4]";

				# Stores last manual vacuum/analyze
				$all_stat_user_tables{$data[1]}{$data[4]}{last_vacuum} = $data[15] if ($data[15]);
				$all_stat_user_tables{$data[1]}{$data[4]}{last_autovacuum} = $data[16] if ($data[16]);
				$all_stat_user_tables{$data[1]}{$data[4]}{last_analyze} = $data[17] if ($data[17]);
				$all_stat_user_tables{$data[1]}{$data[4]}{last_autoanalyze} = $data[18] if ($data[18]);

				# Get database statistics
				$all_stat_user_tables{$data[1]}{$data[4]}{seq_scan} = $data[5] - ($all_stat_user_tables{$data[1]}{$data[4]}{seq_scan} || 0);
				$all_stat_user_tables{$data[1]}{$data[4]}{seq_scan} = $data[5] if ($all_stat_user_tables{$data[1]}{$data[4]}{seq_scan} < 0);
				$all_stat_user_tables{$data[1]}{$data[4]}{idx_scan} = $data[6] - ($all_stat_user_tables{$data[1]}{$data[4]}{idx_scan} || 0);
				$all_stat_user_tables{$data[1]}{$data[4]}{idx_scan} = $data[6] if ($all_stat_user_tables{$data[1]}{$data[4]}{idx_scan} < 0);
				$all_stat_user_tables{$data[1]}{$data[4]}{n_tup_ins} = $data[9] - ($all_stat_user_tables{$data[1]}{$data[4]}{n_tup_ins} || 0);
				$all_stat_user_tables{$data[1]}{$data[4]}{n_tup_ins} = $data[9] if ($all_stat_user_tables{$data[1]}{$data[4]}{n_tup_ins} < 0);
				$all_stat_user_tables{$data[1]}{$data[4]}{n_tup_upd} = $data[10] - ($all_stat_user_tables{$data[1]}{$data[4]}{n_tup_upd} || 0);
				$all_stat_user_tables{$data[1]}{$data[4]}{n_tup_upd} = $data[10] if ($all_stat_user_tables{$data[1]}{$data[4]}{n_tup_upd} < 0);
				$all_stat_user_tables{$data[1]}{$data[4]}{n_tup_del} = $data[11] - ($all_stat_user_tables{$data[1]}{$data[4]}{n_tup_del} || 0);
				$all_stat_user_tables{$data[1]}{$data[4]}{n_tup_del} = $data[11] if ($all_stat_user_tables{$data[1]}{$data[4]}{n_tup_del} < 0);
				$all_stat_user_tables{$data[1]}{$data[4]}{n_tup_hot_upd} = $data[12] - ($all_stat_user_tables{$data[1]}{$data[4]}{n_tup_hot_upd} || 0);
				$all_stat_user_tables{$data[1]}{$data[4]}{n_tup_hot_upd} = $data[12] if ($all_stat_user_tables{$data[1]}{$data[4]}{n_tup_hot_upd} < 0);
				$all_stat_user_tables{$data[1]}{$data[4]}{n_dead_tup} = $data[14];
				$all_stat_user_tables{$data[1]}{$data[4]}{n_live_tup} = $data[13];
				$all_stat_user_tables{$data[1]}{$data[4]}{dead_vs_live} = sprintf("%.2f", ($data[14]*100)/(($data[13]+$data[14])||1));
				if ($#data > 19) {
					$all_stat_user_tables{$data[1]}{$data[4]}{vacuum_count} = $data[19] - ($all_stat_user_tables{$data[1]}{$data[4]}{vacuum_count} || 0);
					$all_stat_user_tables{$data[1]}{$data[4]}{vacuum_count} = $data[19] if ($all_stat_user_tables{$data[1]}{$data[4]}{vacuum_count} < 0);
					$all_stat_user_tables{$data[1]}{$data[4]}{autovacuum_count} = $data[20] - ($all_stat_user_tables{$data[1]}{$data[4]}{autovacuum_count} || 0);
					$all_stat_user_tables{$data[1]}{$data[4]}{autovacuum_count} = $data[20] if ($all_stat_user_tables{$data[1]}{$data[4]}{autovacuum_count} < 0);
					$all_stat_user_tables{$data[1]}{$data[4]}{analyze_count} = $data[21] - ($all_stat_user_tables{$data[1]}{$data[4]}{analyze_count} || 0);
					$all_stat_user_tables{$data[1]}{$data[4]}{analyze_count} = $data[21] if ($all_stat_user_tables{$data[1]}{$data[4]}{analyze_count} < 0);
					$all_stat_user_tables{$data[1]}{$data[4]}{autoanalyze_count} = $data[22] - ($all_stat_user_tables{$data[1]}{$data[4]}{autoanalyze_count} || 0);
					$all_stat_user_tables{$data[1]}{$data[4]}{autoanalyze_count} = $data[22] if ($all_stat_user_tables{$data[1]}{$data[4]}{autoanalyze_count} < 0);
				}
			}
			$curfh->close();
		}
	}
}

sub pg_stat_all_tables
{
	return &pg_stat_user_tables;
}

# Compute report about table accesses
sub pg_stat_user_tables_report
{
	my ($src_base, %data_info) = @_;

	return if ($NO_TB_STAT);

	my $do_vacuum = 0;
	foreach my $db (keys %all_stat_user_tables) {
		foreach my $t (keys %{$all_stat_user_tables{$db}}) {
			foreach my $k (keys %{$all_stat_user_tables{$db}{$t}}) {
				if (($k =~ /vacuum|analyze/) && $all_stat_user_tables{$db}{$t}{$k}) {
					$do_vacuum = 1;
				}
			}
		}
	}
	foreach my $db (keys %all_stat_user_tables) {
		foreach my $id (sort {$a <=> $b} keys %data_info) {
			next if ($data_info{$id}{name} !~ /^table-/);
			next if (($db ne 'all') && ($#INCLUDE_DB >= 0) && (!grep($db =~ /^$_$/, @INCLUDE_DB)));
			# Open filehandle to cluster file
			my $fhtable = IO::File->new("$OUTPUT_DIR/$db-$data_info{$id}{name}.html", "w");
			die "FATAL: can't write file $OUTPUT_DIR/$db-$data_info{$id}{name}.html, $!" if (not defined $fhtable);
			&html_header($fhtable, $src_base);
			my $table_header = '';
			my $colspan = '';
			if ($data_info{$id}{name} eq 'table-indexes') {
				$table_header = qq{
					<th>Sequencial scan</th>
					<th>Index scan</th>
					<th>Index vs Sequencial</th>
};
				$colspan = ' colspan="5"';
			} elsif ($data_info{$id}{name} eq 'table-query-tuples') {
				$table_header = qq{
					<th>Inserted</th>
					<th>Updated</th>
					<th>Deleted</th>
					<th>Hot Updated</th>
};
				$colspan = ' colspan="6"';
			} elsif ($data_info{$id}{name} eq 'table-kind-tuples') {
				$table_header = qq{
					<th>Live tuples</th>
					<th>Dead tuples</th>
					<th>Dead vs Live</th>
};
				$colspan = ' colspan="5"';
			} elsif ( $do_vacuum && ($data_info{$id}{name} eq 'table-vacuums-analyzes') ) {
				$table_header = qq{
					<th>Vacuum</th>
					<th>Autovacuum</th>
					<th>Analyze</th>
					<th>Autoanalyze</th>
					<th>Last vacuum</th>
					<th>Last autovacuum</th>
					<th>Last analyze</th>
					<th>Last autoanalyze</th>
};
				$colspan = ' colspan="10"';
			}
			print $fhtable qq{
<ul id="slides">
<div class="row">
    <div class="col-md-12">
      <div class="panel panel-default">
      <div class="panel-heading">
	<h2>$data_info{$id}{menu} on $db database tables</h2>
	<p>$data_info{$id}{description}</p>
      </div>
      <div class="panel-body">
	<div class="analysis-item row-fluid" id="$db-$data_info{$id}{name}">
		<div class="span11">
			<table class="table table-striped sortable" id="$db-$data_info{$id}{name}-table">
				<thead>
					<tr>
						<th>Schema.Table</th>
						$table_header
					</tr>
				</thead>
				<tbody>
};
			my $has_table_data = 0;
			foreach my $tb (sort keys %{$all_stat_user_tables{$db}}) {
				next if ($tb eq 'all');
				next if (($#INCLUDE_TB >= 0) && !grep(/^$tb$/, @INCLUDE_TB));
				my $table_data = '';
				if ($data_info{$id}{name} eq 'table-indexes') {
					if (!$all_stat_user_tables{$db}{$tb}{idx_scan} && !$all_stat_user_tables{$db}{$tb}{seq_scan}) {
						next;
					}
					$has_table_data = 1;
					foreach ('idx_scan','seq_scan') {
						$all_stat_user_tables{$db}{$tb}{$_} ||= 0;
					}
					$all_stat_user_tables{$db}{$tb}{idx_scan_vs_seq_scan} = sprintf("%0.2f", ($all_stat_user_tables{$db}{$tb}{idx_scan}*100)/(($all_stat_user_tables{$db}{$tb}{seq_scan}+$all_stat_user_tables{$db}{$tb}{idx_scan})||1));
					$table_data = qq{<tr><th>$tb</th><td>$all_stat_user_tables{$db}{$tb}{seq_scan}</td><td>$all_stat_user_tables{$db}{$tb}{idx_scan}</td><td>$all_stat_user_tables{$db}{$tb}{idx_scan_vs_seq_scan}%</td></tr>};
				} elsif ($data_info{$id}{name} eq 'table-query-tuples') {
					if (!$all_stat_user_tables{$db}{$tb}{n_tup_ins} && !$all_stat_user_tables{$db}{$tb}{n_tup_upd} && !$all_stat_user_tables{$db}{$tb}{n_tup_del} && !$all_stat_user_tables{$db}{$tb}{n_tup_hot_upd}) {
						next;
					}
					$has_table_data = 1;
					foreach ('n_tup_ins','n_tup_upd','n_tup_del','n_tup_hot_upd') {
						$all_stat_user_tables{$db}{$tb}{$_} ||= 0;
					}
					$table_data = qq{<tr><th>$tb</th><td>$all_stat_user_tables{$db}{$tb}{n_tup_ins}</td><td>$all_stat_user_tables{$db}{$tb}{n_tup_upd}</td><td>$all_stat_user_tables{$db}{$tb}{n_tup_del}</td><td>$all_stat_user_tables{$db}{$tb}{n_tup_hot_upd}</td></tr>};
				} elsif ($data_info{$id}{name} eq 'table-kind-tuples') {
					if (!$all_stat_user_tables{$db}{$tb}{n_live_tup} && !$all_stat_user_tables{$db}{$tb}{n_dead_tup}) {
						next;
					}
					$has_table_data = 1;
					foreach ('n_live_tup','n_dead_tup','dead_vs_live') {
						$all_stat_user_tables{$db}{$tb}{$_} ||= 0;
					}
					$table_data = qq{<tr><th>$tb</th><td>$all_stat_user_tables{$db}{$tb}{n_live_tup}</td><td>$all_stat_user_tables{$db}{$tb}{n_dead_tup}</td><td>$all_stat_user_tables{$db}{$tb}{dead_vs_live}%</td></tr>};
				} elsif ( $do_vacuum && ($data_info{$id}{name} eq 'table-vacuums-analyzes') ) {
					if (!$all_stat_user_tables{$db}{$tb}{vacuum_count} && !$all_stat_user_tables{$db}{$tb}{autovacuum_count} && !$all_stat_user_tables{$db}{$tb}{analyze_count} && !$all_stat_user_tables{$db}{$tb}{analyze_count}) {
						next;
					}
					$has_table_data = 1;
					foreach ('vacuum_count','autovacuum_count','analyze_count','autoanalyze_count') {
						$all_stat_user_tables{$db}{$tb}{$_} ||= 0;
					}
					$table_data = qq{<tr><th>$tb</th><td>$all_stat_user_tables{$db}{$tb}{vacuum_count}</td><td>$all_stat_user_tables{$db}{$tb}{autovacuum_count}</td><td>$all_stat_user_tables{$db}{$tb}{analyze_count}</td><td>$all_stat_user_tables{$db}{$tb}{autoanalyze_count}</td>};
					foreach ('last_vacuum','last_autovacuum','last_analyze','last_autoanalyze') {
						$all_stat_user_tables{$db}{$tb}{$_} ||= '-';
					}
					$table_data .= qq{<td>$all_stat_user_tables{$db}{$tb}{last_vacuum}</td><td>$all_stat_user_tables{$db}{$tb}{last_autovacuum}</td><td>$all_stat_user_tables{$db}{$tb}{last_analyze}</td><td>$all_stat_user_tables{$db}{$tb}{last_autoanalyze}</td></tr>};
				}
				if ($table_data) {
					print $fhtable $table_data;
				}
			}
			if (!scalar keys %{$all_stat_user_tables{$db}} || !$has_table_data) {
				print $fhtable qq{<tr><td$colspan><div class="flotr-graph"><blockquote><b>NO DATASET</b></blockquote></div></td></tr>};
			}
			print $fhtable qq{
				</tbody>
			</table>
		</div>
	</div>
};
			# Terminate cluster statistics file
			print $fhtable qq{
	</div>
    </div>
</div>
};
			$fhtable->close;
		}
	}
	%all_stat_user_tables = ();
}

# Compute statistics about index scan
sub pg_stat_user_indexes
{
	my ($in_dir, $file) = @_;

	return if ($NO_TB_STAT);

	%all_stat_user_indexes = ();

	my %start_vals = ();
	my $tmp_val = 0;

	# Read start file
	my $curfh = open_filehdl("$in_dir/$file");
	if (defined $curfh)
	{
		while (my $l = <$curfh>)
		{
			chomp($l);
			next if (!$l);
			my @data = split(/;/, $l);
			next if (!&normalize_line(\@data));

			# timestamp | dbname | relid | indexrelid | schemaname | relname | indexrelname | idx_scan | idx_tup_read | idx_tup_fetch
			# PG16: timestamp | dbname | relid | indexrelid | schemaname | relname | indexrelname | idx_scan | last_idx_scan | idx_tup_read | idx_tup_fetch
			$data[6] = "$data[4].$data[5].$data[6]";

			# Get database statistics
			$all_stat_user_indexes{$data[1]}{$data[6]}{idx_scan} = $data[7];
			my $idx = 8;
			$all_stat_user_indexes{$data[1]}{$data[6]}{last_idx_scan} = '';
			if ($#data > 9)
			{
				$idx = 9;
				$all_stat_user_indexes{$data[1]}{$data[6]}{last_idx_scan} = $data[8];
			}
			$all_stat_user_indexes{$data[1]}{$data[6]}{idx_tup_read} = $data[$idx++];
			$all_stat_user_indexes{$data[1]}{$data[6]}{idx_tup_fetch} = $data[$idx];
		}
		$curfh->close();
	}

	if (!$sysinfo{CONFIGURATION}{'capture'})
	{
		# Read end file and set the final value
		$curfh = open_filehdl("$in_dir/end-$file");
		if (defined $curfh)
		{
			while (my $l = <$curfh>)
			{
				chomp($l);
				next if (!$l);
				my @data = split(/;/, $l);
				next if (!&normalize_line(\@data));

				# timestamp | dbname | relid | indexrelid | schemaname | relname | indexrelname | idx_scan | idx_tup_read | idx_tup_fetch
				# PG16: timestamp | dbname | relid | indexrelid | schemaname | relname | indexrelname | idx_scan | last_idx_scan | idx_tup_read | idx_tup_fetch
				$data[6] = "$data[4].$data[5].$data[6]";

				# Get database statistics
				$all_stat_user_indexes{$data[1]}{$data[6]}{idx_scan} = $data[7] - ($all_stat_user_indexes{$data[1]}{$data[6]}{idx_scan} || 0);
				$all_stat_user_indexes{$data[1]}{$data[6]}{idx_scan} = $data[7] if ($all_stat_user_indexes{$data[1]}{$data[6]}{idx_scan} < 0);
				my $idx = 8;
				$all_stat_user_indexes{$data[1]}{$data[6]}{last_idx_scan} = '';
				if ($#data > 9)
				{
					$idx = 9;
					$all_stat_user_indexes{$data[1]}{$data[6]}{last_idx_scan} = $data[8];
				}
				$all_stat_user_indexes{$data[1]}{$data[6]}{idx_tup_read} = $data[$idx] - ($all_stat_user_indexes{$data[1]}{$data[6]}{idx_tup_read} || 0);
				$all_stat_user_indexes{$data[1]}{$data[6]}{idx_tup_read} = $data[$idx] if ($all_stat_user_indexes{$data[1]}{$data[6]}{idx_tup_read} < 0);
				$idx++;
				$all_stat_user_indexes{$data[1]}{$data[6]}{idx_tup_fetch} = $data[$idx] - ($all_stat_user_indexes{$data[1]}{$data[6]}{idx_tup_fetch} || 0);
				$all_stat_user_indexes{$data[1]}{$data[6]}{idx_tup_fetch} = $data[$idx] if ($all_stat_user_indexes{$data[1]}{$data[6]}{idx_tup_fetch} < 0);
			}
			$curfh->close();
		}
	}
}

sub pg_stat_all_indexes
{
	return &pg_stat_user_indexes;
}

# Compute report about index scan
sub pg_stat_user_indexes_report
{
	my ($src_base, %data_info) = @_;

	return if ($NO_TB_STAT);

	foreach my $db (keys %all_stat_user_indexes) {
		foreach my $id (sort {$a <=> $b} keys %data_info) {
			next if ($data_info{$id}{name} !~ /^index-/);
			next if (($db ne 'all') && ($#INCLUDE_DB >= 0) && (!grep($db =~ /^$_$/, @INCLUDE_DB)));
			# Open filehandle to cluster file
			my $fhtable = IO::File->new("$OUTPUT_DIR/$db-$data_info{$id}{name}.html", "w");
			die "FATAL: can't write file $OUTPUT_DIR/$db-$data_info{$id}{name}.html, $!" if (not defined $fhtable);
			&html_header($fhtable, $src_base);
			my $table_header = '';
			my $colspan =  ' colspan="4"';
			if ($data_info{$id}{name} eq 'index-scan') {
				$table_header = qq{
					<th>Index scan</th>
					<th>Index entries returned</th>
					<th>Live table rows fetched</th>
};
			}
			print $fhtable qq{
<ul id="slides">
<div class="row">
    <div class="col-md-12">
      <div class="panel panel-default">
      <div class="panel-heading">
	<h2>$data_info{$id}{menu} on $db database indexes</h2>
	<p>$data_info{$id}{description}</p>
      </div>
      <div class="panel-body">
	<div class="analysis-item row-fluid" id="$db-$data_info{$id}{name}">
		<div class="span11">
			<table class="table table-striped sortable" id="$db-$data_info{$id}{name}-table">
				<thead>
					<tr>
						<th>Schema.Table.Index</th>
						$table_header
					</tr>
				</thead>
				<tbody>
};
			my $found_table_stat = 0;
			foreach my $idx (sort keys %{$all_stat_user_indexes{$db}}) {
				next if ($idx eq 'all');
				next if (($#INCLUDE_TB >= 0) && !grep(/^$idx$/, @INCLUDE_TB));
				my $table_data = '';
				if ($data_info{$id}{name} eq 'index-scan') {
					if (!$all_stat_user_indexes{$db}{$idx}{idx_scan} && !$all_stat_user_indexes{$db}{$idx}{idx_tup_read} && !$all_stat_user_indexes{$db}{$idx}{idx_tup_fetch}) {
						next;
					}
					$found_table_stat = 1;
					foreach ('idx_scan','idx_tup_read','idx_tup_fetch') {
						$all_stat_user_indexes{$db}{$idx}{$_} ||= 0;
					}
					$table_data = qq{<tr><th>$idx</th><td>$all_stat_user_indexes{$db}{$idx}{idx_scan}</td><td>$all_stat_user_indexes{$db}{$idx}{idx_tup_read}</td><td>$all_stat_user_indexes{$db}{$idx}{idx_tup_fetch}</td></tr>};
				}
				if ($table_data) {
					print $fhtable $table_data;
				}
			}
			if (!$found_table_stat) {
				print $fhtable qq{<tr><td$colspan><div class="flotr-graph"><blockquote><b>NO DATASET</b></blockquote></div></td></tr>};
			}
			print $fhtable qq{
				</tbody>
			</table>
		</div>
	</div>
};
			# Terminate cluster statistics file
			print $fhtable qq{
	</div>
    </div>
</div>
};
			$fhtable->close;
		}
	}
	%all_stat_user_indexes = ();
}

# Compute statistics about invalid index
sub pg_stat_invalid_indexes
{
	my ($in_dir, $file) = @_;

	return if ($NO_TB_STAT);

	%all_stat_invalid_indexes = ();

	my %start_vals = ();
	my $tmp_val = 0;
	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	while (my $l = <$curfh>) {
		chomp($l);
		next if (!$l);
		my @data = split(/;/, $l);
		next if (!&normalize_line(\@data));

		# timestamp | dbname | schemaname | relname | indexrelname | index_definition
		$all_stat_invalid_indexes{$data[1]}{$data[2]}{$data[3]}{$data[4]} = $data[5];
		$OVERALL_STATS{'database'}{$data[1]}{invalid_indexes}++;
		$OVERALL_STATS{'cluster'}{invalid_indexes}++;
		push(@{$OVERALL_STATS{'cluster'}{invalid_indexes_db}}, $data[1]) if (!grep(/^$data[1]$/, @{$OVERALL_STATS{'cluster'}{invalid_indexes_db}}));
	}
	$curfh->close();
}

# Compute report about invalid index
sub pg_stat_invalid_indexes_report
{
	my ($src_base, %data_info) = @_;

	return if ($NO_TB_STAT);

	foreach my $db (keys %all_stat_invalid_indexes) {
		foreach my $id (sort {$a <=> $b} keys %data_info) {
			next if ($data_info{$id}{name} ne 'index-invalid');
			next if (($db ne 'all') && ($#INCLUDE_DB >= 0) && (!grep($db =~ /^$_$/, @INCLUDE_DB)));
			# Open filehandle to cluster file
			my $fhtable = IO::File->new("$OUTPUT_DIR/$db-$data_info{$id}{name}.html", "w");
			die "FATAL: can't write file $OUTPUT_DIR/$db-$data_info{$id}{name}.html, $!" if (not defined $fhtable);
			&html_header($fhtable, $src_base);
			my $table_header = '';
			my $colspan =  ' colspan="4"';
			print $fhtable qq{
<ul id="slides">
<div class="row">
    <div class="col-md-12">
      <div class="panel panel-default">
      <div class="panel-heading">
	<h2>$data_info{$id}{menu} on $db database</h2>
	<p>$data_info{$id}{description}</p>
      </div>
      <div class="panel-body">
	<div class="analysis-item row-fluid" id="$db-$data_info{$id}{name}">
		<div class="span11">
			<table class="table table-striped sortable" id="$db-$data_info{$id}{name}-table">
				<thead>
					<tr>
					<th>Schema</th>
					<th>Table</th>
					<th>Index name</th>
					<th>Index definition</th>
					</tr>
				</thead>
				<tbody>
};
			my $found_stat = 0;
			foreach my $sch (sort keys %{$all_stat_invalid_indexes{$db}}) {
				foreach my $tb (sort keys %{$all_stat_invalid_indexes{$db}{$sch}}) {
					next if (($#INCLUDE_TB >= 0) && !grep(/^$tb$/, @INCLUDE_TB));
					$found_stat = 1;
					foreach my $idx (sort keys %{$all_stat_invalid_indexes{$db}{$sch}{$tb}}) {
						print $fhtable qq{<tr><th>$sch</th><td>$tb</td><td>$idx</td><td>$all_stat_invalid_indexes{$db}{$sch}{$tb}{$idx}</td></tr>};
					}
				}
			}
			if (!$found_stat) {
				print $fhtable qq{<tr><td$colspan><div class="flotr-graph"><blockquote><b>NO DATASET</b></blockquote></div></td></tr>};
			}
			print $fhtable qq{
				</tbody>
			</table>
		</div>
	</div>
};
			# Terminate cluster statistics file
			print $fhtable qq{
	</div>
    </div>
</div>
};
			$fhtable->close;
		}
	}
	%all_stat_invalid_indexes = ();
}

# Compute statistics about unlogged
sub pg_stat_unlogged
{
	my ($in_dir, $file) = @_;

	return if ($NO_TB_STAT);

	%all_stat_unlogged = ();

	my %start_vals = ();
	my $tmp_val = 0;
	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	while (my $l = <$curfh>) {
		chomp($l);
		next if (!$l);
		my @data = split(/;/, $l);
		next if (!&normalize_line(\@data));

		# timestamp | dbname | schemaname | relname | relkind
		$all_stat_unlogged{$data[1]}{$data[2]}{$data[3]} = $data[4];
		$OVERALL_STATS{'database'}{$data[1]}{unlogged}++;
		$OVERALL_STATS{'cluster'}{unlogged}++;
		push(@{$OVERALL_STATS{'cluster'}{unlogged_db}}, $data[1]) if (!grep(/^$data[1]$/, @{$OVERALL_STATS{'cluster'}{unlogged_db}}));
	}
	$curfh->close();
}

# Compute report about invalid index
sub pg_stat_unlogged_report
{
	my ($src_base, %data_info) = @_;

	return if ($NO_TB_STAT);

	foreach my $db (keys %all_stat_unlogged) {
		foreach my $id (sort {$a <=> $b} keys %data_info) {
			next if ($data_info{$id}{name} ne 'table-unlogged');
			next if (($db ne 'all') && ($#INCLUDE_DB >= 0) && (!grep($db =~ /^$_$/, @INCLUDE_DB)));
			# Open filehandle to cluster file
			my $fhtable = IO::File->new("$OUTPUT_DIR/$db-$data_info{$id}{name}.html", "w");
			die "FATAL: can't write file $OUTPUT_DIR/$db-$data_info{$id}{name}.html, $!" if (not defined $fhtable);
			&html_header($fhtable, $src_base);
			my $table_header = '';
			my $colspan =  ' colspan="2"';
			print $fhtable qq{
<ul id="slides">
<div class="row">
    <div class="col-md-12">
      <div class="panel panel-default">
      <div class="panel-heading">
	<h2>$data_info{$id}{menu} on $db database</h2>
	<p>$data_info{$id}{description}</p>
      </div>
      <div class="panel-body">
	<div class="analysis-item row-fluid" id="$db-$data_info{$id}{name}">
		<div class="span11">
			<table class="table table-striped sortable" id="$db-$data_info{$id}{name}-table">
				<thead>
					<tr>
					<th>Schema</th>
					<th>Table</th>
					</tr>
				</thead>
				<tbody>
};
			my $found_stat = 0;
			foreach my $sch (sort keys %{$all_stat_unlogged{$db}}) {
				foreach my $tb (sort keys %{$all_stat_unlogged{$db}{$sch}}) {
					next if (($#INCLUDE_TB >= 0) && !grep(/^$tb$/, @INCLUDE_TB));
					$found_stat = 1;
					print $fhtable qq{<tr><th>$sch</th><td>$tb</td></tr>};
				}
			}
			if (!$found_stat) {
				print $fhtable qq{<tr><td$colspan><div class="flotr-graph"><blockquote><b>NO DATASET</b></blockquote></div></td></tr>};
			}
			print $fhtable qq{
				</tbody>
			</table>
		</div>
	</div>
};
			# Terminate cluster statistics file
			print $fhtable qq{
	</div>
    </div>
</div>
};
			$fhtable->close;
		}
	}
	%all_stat_unlogged = ();
}

# Compute statistics about hash index
sub pg_stat_hash_indexes
{
	my ($in_dir, $file) = @_;

	return if ($NO_TB_STAT);

	%all_stat_hash_indexes = ();

	my %start_vals = ();
	my $tmp_val = 0;
	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	while (my $l = <$curfh>) {
		chomp($l);
		next if (!$l);
		my @data = split(/;/, $l);
		next if (!&normalize_line(\@data));

		# timestamp | dbname | schemaname | relname | indexrelname | index_definition
		$all_stat_hash_indexes{$data[1]}{$data[2]}{$data[3]}{$data[4]} = $data[5];
		$OVERALL_STATS{'database'}{$data[1]}{hash_indexes}++;
		$OVERALL_STATS{'cluster'}{hash_indexes}++;
		push(@{$OVERALL_STATS{'cluster'}{hash_indexes_db}}, $data[1]) if (!grep(/^$data[1]$/, @{$OVERALL_STATS{'cluster'}{hash_indexes_db}}));
	}
	$curfh->close();
}

# Compute report about hash index
sub pg_stat_hash_indexes_report
{
	my ($src_base, %data_info) = @_;

	return if ($NO_TB_STAT);

	foreach my $db (keys %all_stat_hash_indexes) {
		foreach my $id (sort {$a <=> $b} keys %data_info) {
			next if ($data_info{$id}{name} ne 'index-hash');
			next if (($db ne 'all') && ($#INCLUDE_DB >= 0) && (!grep($db =~ /^$_$/, @INCLUDE_DB)));
			# Open filehandle to cluster file
			my $fhtable = IO::File->new("$OUTPUT_DIR/$db-$data_info{$id}{name}.html", "w");
			die "FATAL: can't write file $OUTPUT_DIR/$db-$data_info{$id}{name}.html, $!" if (not defined $fhtable);
			&html_header($fhtable, $src_base);
			my $table_header = '';
			my $colspan =  ' colspan="4"';
			print $fhtable qq{
<ul id="slides">
<div class="row">
    <div class="col-md-12">
      <div class="panel panel-default">
      <div class="panel-heading">
	<h2>$data_info{$id}{menu} on $db database</h2>
	<p>$data_info{$id}{description}</p>
      </div>
      <div class="panel-body">
	<div class="analysis-item row-fluid" id="$db-$data_info{$id}{name}">
		<div class="span11">
			<table class="table table-striped sortable" id="$db-$data_info{$id}{name}-table">
				<thead>
					<tr>
					<th>Schema</th>
					<th>Table</th>
					<th>Index name</th>
					<th>Index definition</th>
					</tr>
				</thead>
				<tbody>
};
			my $found_stat = 0;
			foreach my $sch (sort keys %{$all_stat_hash_indexes{$db}}) {
				foreach my $tb (sort keys %{$all_stat_hash_indexes{$db}{$sch}}) {
					next if (($#INCLUDE_TB >= 0) && !grep(/^$tb$/, @INCLUDE_TB));
					$found_stat = 1;
					foreach my $idx (sort keys %{$all_stat_hash_indexes{$db}{$sch}{$tb}}) {
						print $fhtable qq{<tr><th>$sch</th><td>$tb</td><td>$idx</td><td>$all_stat_hash_indexes{$db}{$sch}{$tb}{$idx}</td></tr>};
					}
				}
			}
			if (!$found_stat) {
				print $fhtable qq{<tr><td$colspan><div class="flotr-graph"><blockquote><b>NO DATASET</b></blockquote></div></td></tr>};
			}
			print $fhtable qq{
				</tbody>
			</table>
		</div>
	</div>
};
			# Terminate cluster statistics file
			print $fhtable qq{
	</div>
    </div>
</div>
};
			$fhtable->close;
		}
	}
	%all_stat_hash_indexes = ();
}


# Compute stats for table I/O
sub pg_statio_user_tables
{
	my ($in_dir, $file, $offset) = @_;

	return if ($NO_TB_STAT);

	my %start_vals = ();
	my $tmp_val = 0;
	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	$curfh->seek($offset,0);
	while (my $l = <$curfh>) {
		$offset += length($l);
		my @data = split(/;/, $l);
		next if (!&normalize_line(\@data));

		# timestamp | dbname | relid | schemaname | relname | heap_blks_read | heap_blks_hit | idx_blks_read | idx_blks_hit | toast_blks_read | toast_blks_hit | tidx_blks_read | tidx_blks_hit
		$data[4] = "$data[3].$data[4]";

		push(@{$start_vals{$data[1]}{$data[4]}}, @data) if ($#{$start_vals{$data[1]}{$data[4]}} < 0);

		# Store interval between previous run
		$all_statio_user_tables{$data[1]}{$data[4]}{interval} = ($data[0] - $start_vals{$data[1]}{$data[4]}[0])/1000;

		if (($data[5] - $start_vals{$data[1]}{$data[4]}[5]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[5] - $start_vals{$data[1]}{$data[4]}[5]) };
		$all_statio_user_tables{$data[1]}{$data[4]}{heap_blks_read} += $tmp_val;

		if (($data[6] - $start_vals{$data[1]}{$data[4]}[6]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[6] - $start_vals{$data[1]}{$data[4]}[6]) };
		$all_statio_user_tables{$data[1]}{$data[4]}{heap_blks_hit} += $tmp_val;

		if (($data[7] - $start_vals{$data[1]}{$data[4]}[7]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[7] - $start_vals{$data[1]}{$data[4]}[7]) };
		$all_statio_user_tables{$data[1]}{$data[4]}{idx_blks_read} += $tmp_val;

		if (($data[8] - $start_vals{$data[1]}{$data[4]}[8]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[8] - $start_vals{$data[1]}{$data[4]}[8]) };
		$all_statio_user_tables{$data[1]}{$data[4]}{idx_blks_hit} += $tmp_val;

		if (($data[9] - $start_vals{$data[1]}{$data[4]}[9]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[9] - $start_vals{$data[1]}{$data[4]}[9]) };
		$all_statio_user_tables{$data[1]}{$data[4]}{toast_blks_read} += $tmp_val;

		if (($data[10] - $start_vals{$data[1]}{$data[4]}[10]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[10] - $start_vals{$data[1]}{$data[4]}[10]) };
		$all_statio_user_tables{$data[1]}{$data[4]}{toast_blks_hit} += $tmp_val;

		if (($data[11] - $start_vals{$data[1]}{$data[4]}[11]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[11] - $start_vals{$data[1]}{$data[4]}[11]) };
		$all_statio_user_tables{$data[1]}{$data[4]}{tidx_blks_read} += $tmp_val;

		if (($data[12] - $start_vals{$data[1]}{$data[4]}[12]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[12] - $start_vals{$data[1]}{$data[4]}[12]) };
		$all_statio_user_tables{$data[1]}{$data[4]}{tidx_blks_hit} += $tmp_val;

		@{$start_vals{$data[1]}{$data[4]}} = ();
		push(@{$start_vals{$data[1]}{$data[4]}}, @data);
	}
	$curfh->close();

	return $offset || 0;
}

# Compute report for table I/O
sub pg_statio_user_tables_report
{
	my ($src_base, %data_info) = @_;

	return if ($NO_TB_STAT);

	foreach my $db (sort keys %all_statio_user_tables) {
		next if (($db ne 'all') && ($#INCLUDE_DB >= 0) && (!grep($db =~ /^$_$/, @INCLUDE_DB)));
		foreach my $id (sort {$a <=> $b} keys %data_info) {
			next if ($data_info{$id}{name} !~ /^statio-table/);
			# Open filehandle to cluster file
			my $fhtable = IO::File->new("$OUTPUT_DIR/$db-$data_info{$id}{name}.html", "w");
			die "FATAL: can't write file $OUTPUT_DIR/$db-$data_info{$id}{name}.html, $!" if (not defined $fhtable);
			&html_header($fhtable, $src_base);

			my $colspan =  ' colspan="6"';
			print $fhtable qq{
<ul id="slides">
<div class="row">
    <div class="col-md-12">
      <div class="panel panel-default">
      <div class="panel-heading">
	<h2>$data_info{$id}{menu} on $db database tables</h2>
	<p>$data_info{$id}{description}</p>
      </div>
      <div class="panel-body">
	<div class="analysis-item row-fluid" id="$db-$data_info{$id}{name}">
		<div class="span11">
			<table class="table table-striped sortable" id="$db-$data_info{$id}{name}-table">
				<thead>
					<tr>
						<th>Schema.Table</th>
						<th>Table blocks read</th>
						<th>Table blocks hit</th>
						<th>Index blocks read</th>
						<th>Index blocks hit</th>
					</tr>
				</thead>
				<tbody>
};

			my $rank = 1;
			my $found_table_stat = 0;
			foreach my $tb (sort keys %{$all_statio_user_tables{$db}}) {
				next if ($tb eq 'all');
				next if (($#INCLUDE_TB >= 0) && !grep(/^$tb$/, @INCLUDE_TB));
				my $table_data = '';
				$all_statio_user_tables{$db}{$tb}{idx_blks_read} ||= 0;
				$all_statio_user_tables{$db}{$tb}{heap_blks_read} ||= 0;
				$all_statio_user_tables{$db}{$tb}{heap_blks_hit} ||= 0;
				$all_statio_user_tables{$db}{$tb}{idx_blks_hit} ||= 0;
				$all_statio_user_tables{$db}{$tb}{toast_blks_read} ||= 0;
				$all_statio_user_tables{$db}{$tb}{toast_blks_hit} ||= 0;
				$all_statio_user_tables{$db}{$tb}{tidx_blks_read} ||= 0;
				$all_statio_user_tables{$db}{$tb}{tidx_blks_hit} ||= 0;
				# if this is a toast table override the normal table values for easy use
				if ($all_statio_user_tables{$db}{$tb}{toast_blks_read} || $all_statio_user_tables{$db}{$tb}{toast_blks_hit} || $all_statio_user_tables{$db}{$tb}{tidx_blks_read} || $all_statio_user_tables{$db}{$tb}{tidx_blks_hit} ) {
					$table_data = qq{<tr><th>$tb</th><td>$all_statio_user_tables{$db}{$tb}{toast_blks_read}</td><td>$all_statio_user_tables{$db}{$tb}{toast_blks_hit}</td><td>$all_statio_user_tables{$db}{$tb}{tidx_blks_read}</td><td>$all_statio_user_tables{$db}{$tb}{tidx_blks_hit}</td></tr>};
				} else {
					$table_data = qq{<tr><th>$tb</th><td>$all_statio_user_tables{$db}{$tb}{heap_blks_read}</td><td>$all_statio_user_tables{$db}{$tb}{heap_blks_hit}</td><td>$all_statio_user_tables{$db}{$tb}{idx_blks_read}</td><td>$all_statio_user_tables{$db}{$tb}{idx_blks_hit}</td></tr>};
				}
				if ($table_data) {
					print $fhtable $table_data;
					$found_table_stat = 1;
				}
				$rank++;
			}
			if (!$found_table_stat) {
				print $fhtable qq{<tr><td$colspan><div class="flotr-graph"><blockquote><b>NO DATASET</b></blockquote></div></td></tr>};
			}
			print $fhtable qq{
				</tbody>
			</table>
		</div>
	</div>
	</div>
    </div>
</div>
</div>
</ul>
};
			$fhtable->close;
		}
	}
}

# Compute stats for relation buffer cache
sub pg_relation_buffercache
{
	my ($in_dir, $file, $offset) = @_;

	return if ($NO_TB_STAT);

	my %start_vals = ();
	my $tmp_val = 0;
	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	$curfh->seek($offset,0);
	while (my $l = <$curfh>) {
		$offset += length($l);
		my @data = split(/;/, $l);
		next if (!&normalize_line(\@data));

		$data[7] = 100 if ($data[7] > 100);
		# date_trunc | datname | relname | buffers | relpages | buffered | buffers % | relation %
		$all_relation_buffercache{$data[0]}{$data[1]}{$data[2]}{buffers}      = ($data[3] || 0);
		$all_relation_buffercache{$data[0]}{$data[1]}{$data[2]}{pages}        = ($data[4] || 0);
		$all_relation_buffercache{$data[0]}{$data[1]}{$data[2]}{buffered}     = ($data[5] || 0);
		$all_relation_buffercache{$data[0]}{$data[1]}{$data[2]}{'buffers %'}  = ($data[6] || 0);
		$all_relation_buffercache{$data[0]}{$data[1]}{$data[2]}{'relation %'} = ($data[7] || 0);

	}
	$curfh->close();

	return $offset || 0;
}

# Compute report for relation buffer cache
sub pg_relation_buffercache_report
{
	my ($src_base, %data_info) = @_;

	return if ($NO_TB_STAT);

	my %rel_stat = ();
	my %to_show = ();
	my %buffercache_stat = ();

	foreach my $t (sort {$a <=> $b} keys %all_relation_buffercache) {
		foreach my $db (@global_databases) {
			foreach my $obj ( keys %{$all_relation_buffercache{$t}{$db}} ) {
				$rel_stat{$db}{$obj}{buffers}      .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_relation_buffercache{$t}{$db}{$obj}{buffers} || 0) . '],';
				$buffercache_stat{$db}{$obj}{buffers} = ($all_relation_buffercache{$t}{$db}{$obj}{buffers} || 0);
				$rel_stat{$db}{$obj}{pages}        .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_relation_buffercache{$t}{$db}{$obj}{pages} || 0) . '],';
				$buffercache_stat{$db}{$obj}{pages} = ($all_relation_buffercache{$t}{$db}{$obj}{pages} || 0);
				$rel_stat{$db}{$obj}{buffered}     .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_relation_buffercache{$t}{$db}{$obj}{buffered} || 0) . '],';
				$buffercache_stat{$db}{$obj}{buffered} = ($all_relation_buffercache{$t}{$db}{$obj}{buffered} || 0);
				$rel_stat{$db}{$obj}{'buffers %'}  .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_relation_buffercache{$t}{$db}{$obj}{'buffers %'} || 0) . '],';
				$buffercache_stat{$db}{$obj}{'buffers %'} = ($all_relation_buffercache{$t}{$db}{$obj}{'buffers %'} || 0);
				$rel_stat{$db}{$obj}{'relation %'} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_relation_buffercache{$t}{$db}{$obj}{'relation %'} || 0) . '],';
				$buffercache_stat{$db}{$obj}{'relation %'} = ($all_relation_buffercache{$t}{$db}{$obj}{'relation %'} || 0);
			}
		}
	}
	%all_relation_buffercache = ();

	# Show list of object in the shared buffers
	foreach my $db (keys %buffercache_stat) {

		next if (($db ne 'all') && ($#INCLUDE_DB >= 0) && (!grep($db =~ /^$_$/, @INCLUDE_DB)));

		foreach my $id (sort {$a <=> $b} keys %data_info) {
			next if ($data_info{$id}{name} !~ /^buffercache-/);

			# Open filehandle to cluster file
			my $fhtable = IO::File->new("$OUTPUT_DIR/$db-$data_info{$id}{name}.html", "w");
			die "FATAL: can't write file $OUTPUT_DIR/$db-$data_info{$id}{name}.html, $!" if (not defined $fhtable);
			&html_header($fhtable, $src_base);
			my $table_header = '';
			my $colspan =  ' colspan="6"';
			if ($data_info{$id}{name} eq 'buffercache-relation') {
				$table_header = qq{
					<th>Relation</th>
					<th>Buffers</th>
					<th>Pages</th>
					<th>Buffered</th>
					<th>Buffers %</th>
					<th>Relation %</th>
};
			}
			print $fhtable qq{
<ul id="slides">

<div class="row">
    <div class="col-md-12">
      <div class="panel panel-default">
      <div class="panel-heading">
	<h2>$data_info{$id}{menu} on $db database</h2>
	<p>$data_info{$id}{description}</p>
      </div>
      <div class="panel-body">
	<div class="analysis-item row-fluid" id="$db-$data_info{$id}{name}">
		<div class="span11">
			<table class="table table-striped sortable" id="$db-$data_info{$id}{name}-table">
				<thead>
					<tr>
						$table_header
					</tr>
				</thead>
				<tbody>
};
			my $found_stat = 0;
			my $rank = 1;
			foreach my $rel (sort {$buffercache_stat{$db}{$b}{buffers} <=> $buffercache_stat{$db}{$a}{buffers}} keys %{$buffercache_stat{$db}}) {
				next if (($#INCLUDE_TB >= 0) && !grep(/^$rel$/, @INCLUDE_TB));
				last if ($TOP_STAT && ($rank > $TOP_STAT));
				my $table_data = '';
				if ($data_info{$id}{name} eq 'buffercache-relation') {
					if (!$buffercache_stat{$db}{$rel}{buffers} && !$buffercache_stat{$db}{$rel}{pages} && !$buffercache_stat{$db}{$rel}{buffered}) {
						next;
					}
					$found_stat = 1;
					$to_show{$db}{$rel} = $rank;
					$table_data = "<tr><th>$rel</th><td>$buffercache_stat{$db}{$rel}{buffers}</td><td>$buffercache_stat{$db}{$rel}{pages}</td><td>" . &pretty_print_size($buffercache_stat{$db}{$rel}{buffered}) . "</td><td>$buffercache_stat{$db}{$rel}{'buffers %'}</td><td>$buffercache_stat{$db}{$rel}{'relation %'}</td></tr>\n";
				}
				$rank++;
				if ($table_data) {
					print $fhtable $table_data;
				}
			}
			if (!$found_stat) {
				print $fhtable qq{<tr><td$colspan><div class="flotr-graph"><blockquote><b>NO DATASET</b></blockquote></div></td></tr>};
			}
			print $fhtable qq{
				</tbody>
			</table>
		</div>
	</div>
};
			# Terminate cluster statistics file
			print $fhtable qq{
	</div>
    </div>
</div>
};
			$fhtable->close;
		}
	}
	%buffercache_stat = ();

	# Show shared buffers usage per object
	foreach my $db (sort keys %rel_stat) {
		next if (($db ne 'all') && ($#INCLUDE_DB >= 0) && (!grep($db =~ /^$_$/, @INCLUDE_DB)));
		foreach my $id (sort {$a <=> $b} keys %data_info) {
			next if ($data_info{$id}{name} !~ /^statio-buffercache/);
			# Open filehandle to cluster file
			my $fhtable = IO::File->new("$OUTPUT_DIR/$db-$data_info{$id}{name}.html", "w");
			die "FATAL: can't write file $OUTPUT_DIR/$db-$data_info{$id}{name}.html, $!" if (not defined $fhtable);
			&html_header($fhtable, $src_base);

			foreach my $rel (sort {$to_show{$db}{$a} <=> $to_show{$db}{$b} } keys %{$to_show{$db}}) {
				my $graph_data = '';
				if ($data_info{$id}{name} eq 'statio-buffercache') {
					foreach ('buffers','pages','buffered','buffers %','relation %') {
						$rel_stat{$db}{$rel}{$_} =~ s/,$//;
					}
					print $fhtable &jqplot_linegraph_array($IDX++, 'statio-buffercache', \%{$data_info{$id}}, $rel, $rel_stat{$db}{$rel}{buffered},$rel_stat{$db}{$rel}{'relation %'});
					delete $rel_stat{$db}{$rel};
				}
			}
			$fhtable->close;
		}
	}

}

# Compute stats for index I/O
sub pg_statio_user_indexes
{
	my ($in_dir, $file, $offset) = @_;

	return if ($NO_TB_STAT);

	my %start_vals = ();
	my $tmp_val = 0;
	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	$curfh->seek($offset,0);
	while (my $l = <$curfh>) {
		$offset += length($l);
		my @data = split(/;/, $l);
		next if (!&normalize_line(\@data));

		# timestamp | dbname | relid | indexrelid | schemaname | relname | indexrelname | idx_blks_read | idx_blks_hit
		$data[6] = "$data[4].$data[5].$data[6]";

		push(@{$start_vals{$data[1]}{$data[6]}}, @data) if ($#{$start_vals{$data[1]}{$data[6]}} < 0);

		# Store interval between previous run
		$all_statio_user_indexes{$data[1]}{$data[6]}{interval} = ($data[0] - $start_vals{$data[1]}{$data[6]}[0])/1000;

		push(@{$start_vals{$data[1]}{$data[6]}}, @data) if ($#{$start_vals{$data[1]}{$data[6]}} < 0);

		if (($data[7] - $start_vals{$data[1]}{$data[6]}[7]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[7] - $start_vals{$data[1]}{$data[6]}[7]) };
		$all_statio_user_indexes{$data[1]}{$data[6]}{idx_blks_read} += $tmp_val;

		if (($data[8] - $start_vals{$data[1]}{$data[6]}[8]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[8] - $start_vals{$data[1]}{$data[6]}[8]) };
		$all_statio_user_indexes{$data[1]}{$data[6]}{idx_blks_hit} += $tmp_val;

		@{$start_vals{$data[1]}{$data[6]}} = ();
		push(@{$start_vals{$data[1]}{$data[6]}}, @data);
	}
	$curfh->close();

	return $offset || 0;
}

# Compute report for index I/O
sub pg_statio_user_indexes_report
{
	my ($src_base, %data_info) = @_;

	return if ($NO_TB_STAT);

	foreach my $db (sort keys %all_statio_user_indexes) {
		next if (($db ne 'all') && ($#INCLUDE_DB >= 0) && (!grep($db =~ /^$_$/, @INCLUDE_DB)));
		foreach my $id (sort {$a <=> $b} keys %data_info) {
			next if ($data_info{$id}{name} !~ /^statio-index/);
			# Open filehandle to cluster file
			my $fhtable = IO::File->new("$OUTPUT_DIR/$db-$data_info{$id}{name}.html", "w");
			die "FATAL: can't write file $OUTPUT_DIR/$db-$data_info{$id}{name}.html, $!" if (not defined $fhtable);
			&html_header($fhtable, $src_base);

			my $colspan =  ' colspan="3"';
			print $fhtable qq{
<ul id="slides">
<div class="row">
    <div class="col-md-12">
      <div class="panel panel-default">
      <div class="panel-heading">
	<h2>$data_info{$id}{menu} on $db database tables</h2>
	<p>$data_info{$id}{description}</p>
      </div>
      <div class="panel-body">
	<div class="analysis-item row-fluid" id="$db-$data_info{$id}{name}">
		<div class="span11">
			<table class="table table-striped sortable" id="$db-$data_info{$id}{name}-table">
				<thead>
					<tr>
						<th>Schema.Table.Index</th>
						<th>Index blocks read</th>
						<th>Index blocks hit</th>
					</tr>
				</thead>
				<tbody>
};

			my $rank = 1;
			my $found_table_stat = 0;
			foreach my $tb (sort keys %{$all_statio_user_indexes{$db}}) {
				next if ($tb eq 'all');
				next if (($#INCLUDE_TB >= 0) && !grep(/^$tb$/, @INCLUDE_TB));
				my $table_data = '';
				$all_statio_user_indexes{$db}{$tb}{idx_blks_read} ||= 0;
				$all_statio_user_indexes{$db}{$tb}{idx_blks_hit} ||= 0;
				if ($all_statio_user_indexes{$db}{$tb}{idx_blks_read} || $all_statio_user_indexes{$db}{$tb}{idx_blks_hit}) {
					$table_data = qq{<tr><th>$tb</th><td>$all_statio_user_indexes{$db}{$tb}{idx_blks_read}</td><td>$all_statio_user_indexes{$db}{$tb}{idx_blks_hit}</td></tr>};
				}
				if ($table_data) {
					print $fhtable $table_data;
					$found_table_stat = 1;
				}
				$rank++;
			}
			if (!$found_table_stat) {
				print $fhtable qq{<tr><td$colspan><div class="flotr-graph"><blockquote><b>NO DATASET</b></blockquote></div></td></tr>};
			}
			print $fhtable qq{
				</tbody>
			</table>
		</div>
	</div>
	</div>
    </div>
</div>
</div>
</ul>
};
			$fhtable->close;
		}
	}
}

# Compute statistics of xlog cluster
sub pg_xlog_stat
{
	my ($in_dir, $file, $offset) = @_;

	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	$curfh->seek($offset,0);
	while (my $l = <$curfh>) {
		$offset += length($l);
		my @data = split(/;/, $l);
		next if (!&normalize_line(\@data));

		# timestamp | total_file | last_wal_name | wal_recycled | wal_written | max_wal

		# case of pgstats file content
		if ($#data == 3) {
			$all_xlog_stat{$data[0]}{total}++;
		} else {
			$all_xlog_stat{$data[0]}{total} = ($data[1] || 0);
			if ($#data == 5) {
				$all_xlog_stat{$data[0]}{recycled} = ($data[3] || 0);
				$all_xlog_stat{$data[0]}{written}  = ($data[4] || 0);
				$all_xlog_stat{$data[0]}{max_wal}  = (POSIX::ceil($data[5]) || 0);
			}
		}
	}
	$curfh->close();

	return $offset || 0;
}

# Compute graphs of xlog cluster statistics
sub pg_xlog_stat_report
{
	my ($src_base, %data_info) = @_;

	my %xlog_stat = ();
	foreach my $t (sort {$a <=> $b} keys %all_xlog_stat) {
		$xlog_stat{total} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_xlog_stat{$t}{total} || 0) . '],';
		$xlog_stat{recycled} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_xlog_stat{$t}{recycled} || 0) . '],';
		$xlog_stat{written}  .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_xlog_stat{$t}{written} || 0) . '],';
		$xlog_stat{max_wal}  .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_xlog_stat{$t}{max_wal} || 0) . '],';
	}
	%all_xlog_stat = ();

	my $id = &get_data_id('cluster-xlog_files', %data_info);
	$xlog_stat{total} =~ s/,$// if (defined $xlog_stat{total});
	my $fhcluster = &append_to_html_file("$OUTPUT_DIR/cluster-$data_info{$id}{name}.html", $src_base);
	if (exists $xlog_stat{recycled}) {
		push(@{$data_info{$id}{legends}}, 'recycled', 'written', 'max_wal');
		print $fhcluster &jqplot_linegraph_array($IDX++, 'cluster-xlog_files', \%{$data_info{$id}}, '', $xlog_stat{total}, $xlog_stat{recycled}, $xlog_stat{written}, $xlog_stat{max_wal});
	} else {
		print $fhcluster &jqplot_linegraph_array($IDX++, 'cluster-xlog_files', \%{$data_info{$id}}, '', $xlog_stat{total});
	}
	$fhcluster->close();
}

# Compute statistics of bgwriter cluster
sub pg_stat_bgwriter
{
	my ($in_dir, $file, $offset) = @_;

	my @start_vals = ();
	my %total_count = ();
	my $tmp_val = 0;
	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	$curfh->seek($offset,0);
	while (my $l = <$curfh>) {
		$offset += length($l);
		my @data = split(/;/, $l);
		next if (!&normalize_line(\@data));

		push(@start_vals, @data) if ($#start_vals < 0);

		# Store interval between previous run
		$all_stat_bgwriter{$data[0]}{interval} = ($data[0] - $start_vals[0])/1000;

		if (($data[1] - $start_vals[1]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[1] - $start_vals[1]) };
		$all_stat_bgwriter{$data[0]}{checkpoints_timed} = $tmp_val;
		if (($data[2] - $start_vals[2]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[2] - $start_vals[2]) };
		$all_stat_bgwriter{$data[0]}{checkpoints_req} = $tmp_val;
		my $id = 0;
		if ($#data > 10) {
			$id += 2;
			if (($data[3] - $start_vals[3]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[3] - $start_vals[3]) };
			$all_stat_bgwriter{$data[0]}{checkpoint_write_time} = $tmp_val;
			if (($data[4] - $start_vals[4]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[4] - $start_vals[4]) };
			$all_stat_bgwriter{$data[0]}{checkpoint_sync_time} = $tmp_val;
		}
		if (($data[3+$id] - $start_vals[3+$id]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[3+$id] - $start_vals[3+$id]) };
		$all_stat_bgwriter{$data[0]}{buffers_checkpoint} = $tmp_val*8192;
		if (($data[4+$id] - $start_vals[4+$id]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[4+$id] - $start_vals[4+$id]) };
		$all_stat_bgwriter{$data[0]}{buffers_clean} = $tmp_val*8192;
		if (($data[5+$id] - $start_vals[5+$id]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[5+$id] - $start_vals[5+$id]) };
		$all_stat_bgwriter{$data[0]}{maxwritten_clean} = $tmp_val;
		if (($data[6+$id] - $start_vals[6+$id]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[6+$id] - $start_vals[6+$id]) };
		$all_stat_bgwriter{$data[0]}{buffers_backend} = $tmp_val*8192;
		if ($#data >= 9) {
			if (($data[7+$id] - $start_vals[7+$id]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[7+$id] - $start_vals[7+$id]) };
			$all_stat_bgwriter{$data[0]}{buffers_backend_fsync} = $tmp_val;
			if (($data[8+$id] - $start_vals[8+$id]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[8+$id] - $start_vals[8+$id]) };
			$all_stat_bgwriter{$data[0]}{buffers_alloc} = $tmp_val*8192;
			$OVERALL_STATS{'bgwriter'}{stats_reset} = $data[9+$id] if (!exists $OVERALL_STATS{'bgwriter'}{stats_reset} || ($OVERALL_STATS{'bgwriter'}{stats_reset} lt $data[9+$id]));
		}

		@start_vals = ();
		push(@start_vals, @data);
	}
	$curfh->close();

	return $offset || 0;
}

# Compute graphs of bgwriter cluster statistics
sub pg_stat_bgwriter_report
{
	my ($src_base, %data_info) = @_;

	my %bgwriter_stat = ();
	my %data = ();
	foreach my $t (sort {$a <=> $b} keys %all_stat_bgwriter) {
		$all_stat_bgwriter{$t}{interval} = 1 if ($sysinfo{CONFIGURATION}{'capture'});
		next if (!$all_stat_bgwriter{$t}{interval});
		$data{'Checkpoint timed'} += ($all_stat_bgwriter{$t}{checkpoints_timed} || 0);
		$data{'Checkpoint requested'} += ($all_stat_bgwriter{$t}{checkpoints_req} || 0);
		$bgwriter_stat{checkpoints_timed} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . $all_stat_bgwriter{$t}{checkpoints_timed} . '],';
		$bgwriter_stat{checkpoints_req} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . $all_stat_bgwriter{$t}{checkpoints_req} . '],';
		$bgwriter_stat{checkpoint_write_time} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_stat_bgwriter{$t}{checkpoint_write_time}||0) . '],';
		$bgwriter_stat{checkpoint_sync_time} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_stat_bgwriter{$t}{checkpoint_sync_time}||0) . '],';
		$bgwriter_stat{buffers_checkpoint} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . int(($all_stat_bgwriter{$t}{buffers_checkpoint}||0)/$all_stat_bgwriter{$t}{interval}) . '],';
		$bgwriter_stat{buffers_clean} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . int(($all_stat_bgwriter{$t}{buffers_clean}||0)/$all_stat_bgwriter{$t}{interval}) . '],';
		$bgwriter_stat{maxwritten_clean} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_stat_bgwriter{$t}{maxwritten_clean}||0) . '],';
		$bgwriter_stat{buffers_backend} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . int(($all_stat_bgwriter{$t}{buffers_backend}||0)/$all_stat_bgwriter{$t}{interval}) . '],';
		$bgwriter_stat{buffers_alloc} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . int(($all_stat_bgwriter{$t}{buffers_alloc}||0)/$all_stat_bgwriter{$t}{interval}) . '],';
		my $buff_backend_fsync = '0';
		$buff_backend_fsync = $all_stat_bgwriter{$t}{buffers_backend_fsync} if (exists $all_stat_bgwriter{$t}{buffers_backend_fsync});
		$bgwriter_stat{buffers_backend_fsync} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . $buff_backend_fsync . '],';
	}
	%all_stat_bgwriter = ();

	my $total_checkpoint = ($data{'Checkpoint timed'} || 0) + ($data{'Checkpoint requested'} || 0);
	foreach my $id (sort {$a <=> $b} keys %data_info)
	{
		next if (!grep(/^$data_info{$id}{name}$/, 'cluster-checkpoints', 'cluster-checkpoints_time', 'cluster-bgwriter_write', 'cluster-bgwriter_read', 'cluster-bgwriter_count'));
		my $fhcluster = &append_to_html_file("$OUTPUT_DIR/cluster-$data_info{$id}{name}.html", $src_base);
		if ($data_info{$id}{name} eq 'cluster-checkpoints')
		{
			my $bkup0 = $data_info{$id}{legends}[0];
			my $bkup1 = $data_info{$id}{legends}[1];
			if ($total_checkpoint)
			{
				$data_info{$id}{legends}[0] .= ' (' . sprintf("%0.2f", $data{'Checkpoint timed'}*100/($total_checkpoint||1)) . '%)';
				$data_info{$id}{legends}[1] .= ' (' . sprintf("%0.2f", $data{'Checkpoint requested'}*100/($total_checkpoint||1)) . '%)';
			}
			$bgwriter_stat{checkpoints_timed} =~ s/,$// if (exists $bgwriter_stat{checkpoints_timed});
			$bgwriter_stat{checkpoints_req} =~ s/,$// if (exists $bgwriter_stat{checkpoints_req});
			print $fhcluster &jqplot_linegraph_array($IDX++, 'cluster-checkpoints', \%{$data_info{$id}}, '', $bgwriter_stat{checkpoints_timed}, $bgwriter_stat{checkpoints_req});
			$data_info{$id}{legends}[0] = $bkup0;
			$data_info{$id}{legends}[1] = $bkup1;
		}
		elsif ($data_info{$id}{name} eq 'cluster-checkpoints_time')
		{
			if (exists $bgwriter_stat{checkpoint_write_time})
			{
				$bgwriter_stat{checkpoint_sync_time} =~ s/,$//;
				$bgwriter_stat{checkpoint_write_time} =~ s/,$//;
				print $fhcluster &jqplot_linegraph_array($IDX++, 'cluster-checkpoints_time', \%{$data_info{$id}}, '', $bgwriter_stat{checkpoint_write_time}, $bgwriter_stat{checkpoint_sync_time});
			}
		}
		elsif ($data_info{$id}{name} eq 'cluster-bgwriter_write')
		{
			$bgwriter_stat{buffers_checkpoint} =~ s/,$// if (exists $bgwriter_stat{buffers_checkpoint});
			$bgwriter_stat{buffers_clean} =~ s/,$// if (exists $bgwriter_stat{buffers_clean});
			$bgwriter_stat{buffers_backend} =~ s/,$// if (exists $bgwriter_stat{buffers_backend});
			print $fhcluster &jqplot_linegraph_array($IDX++, 'cluster-bgwriter_write', \%{$data_info{$id}}, '', $bgwriter_stat{buffers_checkpoint}, $bgwriter_stat{buffers_clean}, $bgwriter_stat{buffers_backend});
		}
		elsif ($data_info{$id}{name} eq 'cluster-bgwriter_read')
		{
			$bgwriter_stat{buffers_alloc} =~ s/,$// if (exists $bgwriter_stat{buffers_alloc});
			print $fhcluster &jqplot_linegraph_array($IDX++, 'cluster-bgwriter_read', \%{$data_info{$id}}, '', $bgwriter_stat{buffers_alloc});
		}
		elsif ($data_info{$id}{name} eq 'cluster-bgwriter_count')
		{
			$bgwriter_stat{maxwritten_clean} =~ s/,$// if (exists $bgwriter_stat{maxwritten_clean});
			$bgwriter_stat{buffers_backend_fsync} =~ s/,$// if (exists $bgwriter_stat{buffers_backend_fsync});
			print $fhcluster &jqplot_linegraph_array($IDX++, 'cluster-bgwriter_count', \%{$data_info{$id}}, '',  $bgwriter_stat{maxwritten_clean}, $bgwriter_stat{buffers_backend_fsync});
		}
		$fhcluster->close();
	}
}

# Compute statistics of pg_subxact_counters
sub pg_subxact_counters
{
	my ($in_dir, $file, $offset) = @_;

	my @start_vals = ();
	my %total_count = ();
	my $tmp_val = 0;
	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	$curfh->seek($offset,0);
	while (my $l = <$curfh>)
	{
		$offset += length($l);
		my @data = split(/;/, $l);
		next if (!&normalize_line(\@data));

		push(@start_vals, @data) if ($#start_vals < 0);

		# Store interval between previous run
		$all_subxact_counters{$data[0]}{interval} = ($data[0] - $start_vals[0])/1000;

		if (($data[2] - $start_vals[2]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[2] - $start_vals[2]) };
		$all_subxact_counters{$data[0]}{subxact_start} = $tmp_val;
		if (($data[3] - $start_vals[3]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[3] - $start_vals[3]) };
		$all_subxact_counters{$data[0]}{subxact_commit} = $tmp_val;
		if (($data[4] - $start_vals[4]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[4] - $start_vals[4]) };
		$all_subxact_counters{$data[0]}{subxact_abort} = $tmp_val;
		if (($data[5] - $start_vals[5]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[5] - $start_vals[5]) };
		$all_subxact_counters{$data[0]}{subxact_overflow} = $tmp_val;

		@start_vals = ();
		push(@start_vals, @data);
	}
	$curfh->close();

	return $offset || 0;
}

# Compute graphs of subxact counters
sub pg_subxact_counters_report
{
	my ($src_base, %data_info) = @_;

	my %subxact_stat = ();
	foreach my $t (sort {$a <=> $b} keys %all_subxact_counters)
	{
		$subxact_stat{start} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_subxact_counters{$t}{subxact_start} || 0) . '],';
		$subxact_stat{commit} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_subxact_counters{$t}{subxact_commit} || 0) . '],';
		$subxact_stat{abort} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_subxact_counters{$t}{subxact_abort} || 0) . '],';
		$subxact_stat{overflow} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_subxact_counters{$t}{subxact_overflow} || 0) . '],';
	}
	%all_subxact_counters = ();

	# Build graph dataset
	foreach my $id (sort {$a <=> $b} keys %data_info)
	{
		my $dbfh = &append_to_html_file("$OUTPUT_DIR/cluster-subxact_counters.html", $src_base);
		if ($data_info{$id}{name} eq 'cluster-subxact_counters') {
			$subxact_stat{start} =~ s/,$//;
			$subxact_stat{commit} =~ s/,$//;
			$subxact_stat{abort} =~ s/,$//;
			$subxact_stat{overflow} =~ s/,$//;
			$dbfh->print( &jqplot_linegraph_array($IDX++, 'cluster-subxact_counters', \%{$data_info{$id}}, '', $subxact_stat{start}, $subxact_stat{commit}, $subxact_stat{abort}, $subxact_stat{overflow}) );
		}
		$dbfh->close();
	}
}
####
# I/O statistics from pg_stat_io (PG16+)
#
# CSV format produced by pgcluu_collectd (same for all PostgreSQL versions):
#   0 timestamp, 1 backend_type, 2 object, 3 context, 4 reads, 5 read_bytes,
#   6 read_time, 7 writes, 8 write_bytes, 9 write_time, 10 writebacks,
#   11 writeback_time, 12 extends, 13 extend_bytes, 14 extend_time, 15 hits,
#   16 evictions, 17 reuses, 18 fsyncs, 19 fsync_time, 20 block_size
#
# Values in pg_stat_io are cumulative, the deltas between two snapshots are
# computed here. Last raw values are kept in %all_stat_io_prev, which is saved
# in the binary cache, so that deltas are continuous in incremental mode.
# Only non zero deltas are stored in %all_stat_io:
#   $all_stat_io{$time}{interval} = seconds since the previous snapshot
#   $all_stat_io{$time}{"backend_type|object|context"}{metric} = delta
# where metric is one of the column names above plus read_blocks, the number
# of blocks read (since PG18 reads are counted in I/O operations, not blocks).
####

sub pg_stat_io
{
	my ($in_dir, $file, $offset) = @_;

	my $cur_time = '';
	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	$curfh->seek($offset,0);
	while (my $l = <$curfh>)
	{
		$offset += length($l);
		my @data = split(/;/, $l);
		next if ($#data < 20);
		next if (!&normalize_line(\@data));

		my $t = $data[0];
		# A new snapshot is starting
		if ($t ne $cur_time)
		{
			# Skip snapshot already seen in a previous run
			next if ($all_stat_io_prev{time} && $t <= $all_stat_io_prev{time});
			if ($all_stat_io_prev{time}) {
				$all_stat_io{$t}{interval} = ($t - $all_stat_io_prev{time})/1000;
			}
			$all_stat_io_prev{lasttime} = $all_stat_io_prev{time} || 0;
			$all_stat_io_prev{time} = $t;
			$cur_time = $t;
		}

		my $key = "$data[1]|$data[2]|$data[3]";
		my $block_size = $data[20] || 8192;
		for (my $i = 0; $i <= $#STAT_IO_COLUMNS; $i++)
		{
			my $col = $STAT_IO_COLUMNS[$i];
			my $val = $data[$i+4] || 0;
			# When the row was not collected in the previous snapshot it had
			# no activity so its previous value is 0. On the very first
			# snapshot there is no delta, this is just the starting point.
			if ($all_stat_io_prev{lasttime})
			{
				my $delta = $val - ($all_stat_io_prev{vals}{$key}{$col} || 0);
				if ($delta > 0)
				{
					$all_stat_io{$t}{$key}{$col} = $delta;
					if ($col eq 'read_bytes') {
						$all_stat_io{$t}{$key}{read_blocks} = $delta/$block_size;
					}
				}
			}
			$all_stat_io_prev{vals}{$key}{$col} = $val;
		}
	}
	$curfh->close();

	return $offset || 0;
}

####
# Helpers used to build the pg_stat_io reports
####

# Return the list of snapshot times with a valid interval
sub stat_io_times
{
	my @times = ();
	foreach my $t (sort {$a <=> $b} keys %all_stat_io)
	{
		$all_stat_io{$t}{interval} = 1 if ($sysinfo{CONFIGURATION}{'capture'});
		next if (!$all_stat_io{$t}{interval});
		push(@times, $t);
	}
	return @times;
}

# Return the sum of a metric at time $t for all rows matching the filters.
# Filters are regexp applied to backend_type, object and context, undef
# means no filter.
sub stat_io_sum
{
	my ($t, $metric, $btype, $object, $context) = @_;

	my $sum = 0;
	foreach my $key (keys %{$all_stat_io{$t}})
	{
		next if ($key eq 'interval');
		my ($b, $o, $c) = split(/\|/, $key);
		next if (defined $btype && $b !~ /^(?:$btype)$/);
		next if (defined $object && $o !~ /^(?:$object)$/);
		next if (defined $context && $c !~ /^(?:$context)$/);
		$sum += ($all_stat_io{$t}{$key}{$metric} || 0);
	}
	return $sum;
}

# Return the sorted list of backend types (pos 0), objects (pos 1) or
# contexts (pos 2) having a non zero value for one of the given metrics
# in the rows matching the object and context filters.
sub stat_io_list
{
	my ($pos, $object, $context, @metrics) = @_;

	my %list = ();
	foreach my $t (keys %all_stat_io)
	{
		foreach my $key (keys %{$all_stat_io{$t}})
		{
			next if ($key eq 'interval');
			my @k = split(/\|/, $key);
			next if (defined $object && $k[1] !~ /^(?:$object)$/);
			next if (defined $context && $k[2] !~ /^(?:$context)$/);
			next if ($#metrics >= 0 && !grep { $all_stat_io{$t}{$key}{$_} } @metrics);
			$list{$k[$pos]} = 1;
		}
	}
	return sort keys %list;
}

# Return a jqplot point
sub stat_io_point
{
	my ($t, $val) = @_;

	return '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . $val . '],';
}

# Write a graph with one serie per entry of the hash %series into the
# html page associated to the graph ('page' key in the graph definition).
# Legends are the hash keys, they can be renamed using %legends.
sub stat_io_print_graph
{
	my ($src_base, $id, $data_info, $series, $legends) = @_;

	my @legends = ();
	my @graphs = ();
	foreach my $s (sort keys %{$series})
	{
		next if (!$series->{$s});
		$series->{$s} =~ s/,$//;
		push(@legends, (defined $legends && exists $legends->{$s}) ? $legends->{$s} : $s);
		push(@graphs, $series->{$s});
	}
	return if ($#graphs < 0);

	my $page = $data_info->{$id}{page} || $data_info->{$id}{name};
	my $fh = &append_to_html_file("$OUTPUT_DIR/$page.html", $src_base);
	my %infos = %{$data_info->{$id}};
	$infos{legends} = \@legends;
	$fh->print( &jqplot_linegraph_array($IDX++, $data_info->{$id}{name}, \%infos, '', @graphs) );
	$fh->close();
}

# Build a graph of a metric per second with one serie per backend type
# ($pos = 0), object ($pos = 1) or context ($pos = 2), limited to the rows
# matching the object and context filters. The legend of each serie shows
# its share of the total over the whole period. Groups matching the
# optional regexp $exclude are not reported.
sub stat_io_rate_graph
{
	my ($src_base, $id, $data_info, $metric, $pos, $object, $context, $exclude) = @_;

	my @groups = &stat_io_list($pos, $object, $context, $metric);
	@groups = grep { $_ !~ /^(?:$exclude)$/ } @groups if ($exclude);
	return if ($#groups < 0);

	my %series = ();
	my %total = ();
	my $grand_total = 0;
	foreach my $t (&stat_io_times())
	{
		foreach my $g (@groups)
		{
			my @filters = (undef, $object, $context);
			$filters[$pos] = quotemeta($g);
			my $val = &stat_io_sum($t, $metric, @filters);
			$total{$g} += $val;
			$grand_total += $val;
			$series{$g} .= &stat_io_point($t, sprintf("%.2f", $val/$all_stat_io{$t}{interval}));
		}
	}
	return if (!$grand_total);

	my %legends = ();
	foreach my $g (@groups) {
		$legends{$g} = sprintf("%s (%0.2f%%)", $g, $total{$g}*100/$grand_total);
	}
	&stat_io_print_graph($src_base, $id, $data_info, \%series, \%legends);
}


# Build the graph of the buffer hit ratio per I/O context on relations.
# The number of blocks read is used because since PG18 reads are counted
# in I/O operations that can read several blocks.
sub stat_io_hit_ratio_graph
{
	my ($src_base, $id, $data_info) = @_;

	my @contexts = &stat_io_list(2, 'relation', undef, 'hits', 'read_blocks');
	my %series = ();
	foreach my $t (&stat_io_times())
	{
		foreach my $c (@contexts)
		{
			my $hits = &stat_io_sum($t, 'hits', undef, 'relation', quotemeta($c));
			my $reads = &stat_io_sum($t, 'read_blocks', undef, 'relation', quotemeta($c));
			next if (($hits + $reads) == 0);
			$series{$c} .= &stat_io_point($t, sprintf("%.2f", $hits*100/($hits+$reads)));
		}
	}
	&stat_io_print_graph($src_base, $id, $data_info, \%series);
}

# Build the graph of reuses and evictions per second in the contexts using
# a buffer access strategy (ring buffer).
sub stat_io_ring_graph
{
	my ($src_base, $id, $data_info) = @_;

	my $strategy = 'bulkread|bulkwrite|vacuum';
	my @contexts = &stat_io_list(2, 'relation', $strategy, 'reuses', 'evictions');
	my %series = ();
	foreach my $t (&stat_io_times())
	{
		foreach my $c (@contexts)
		{
			foreach my $m ('reuses', 'evictions')
			{
				my $val = &stat_io_sum($t, $m, undef, 'relation', quotemeta($c));
				$series{"$c $m"} .= &stat_io_point($t, sprintf("%.2f", $val/$all_stat_io{$t}{interval}));
			}
		}
	}
	&stat_io_print_graph($src_base, $id, $data_info, \%series);
}

# Build a graph of the average duration of an operation ($time/$ops) with
# one serie per backend type ($pos = 0), object ($pos = 1) or context
# ($pos = 2). Points without operation are not reported. When there are
# operations but no timing at all, the timing parameter (key 'timing' of
# the graph definition) is most likely disabled: no graph is produced and
# a notice is written instead.
sub stat_io_latency_graph
{
	my ($src_base, $id, $data_info, $time, $ops, $pos, $object, $context) = @_;

	my @groups = &stat_io_list($pos, $object, $context, $ops);
	return if ($#groups < 0);

	my %series = ();
	my $total_ops = 0;
	my $total_time = 0;
	foreach my $t (&stat_io_times())
	{
		foreach my $g (@groups)
		{
			my @filters = (undef, $object, $context);
			$filters[$pos] = quotemeta($g);
			my $nops = &stat_io_sum($t, $ops, @filters);
			next if (!$nops);
			my $duration = &stat_io_sum($t, $time, @filters);
			$total_ops += $nops;
			$total_time += $duration;
			$series{$g} .= &stat_io_point($t, sprintf("%.3f", $duration/$nops));
		}
	}
	return if (!$total_ops);

	if (!$total_time)
	{
		my $param = $data_info->{$id}{timing} || 'track_io_timing';
		my $page = $data_info->{$id}{page} || $data_info->{$id}{name};
		my $fh = &append_to_html_file("$OUTPUT_DIR/$page.html", $src_base);
		$fh->print(qq{
<li class="slide active-slide" id="$data_info->{$id}{name}-slide">
      <div id="$data_info->{$id}{name}"><br/><br/><br/><br/></div>
      <div class="row">
            <div class="col-md-12">
              <div class="panel panel-default">
              <div class="panel-heading">
              <h2>$data_info->{$id}{title}</h2>
		<p>$data_info->{$id}{description}</p>
              </div>
              <div class="panel-body">
		<blockquote><b>NO TIMING DATA</b>: $total_ops operations reported without any timing, $param seems to be disabled.</blockquote>
              </div>
              </div>
            </div>
      </div>
</li>
});
		$fh->close();
		return;
	}

	&stat_io_print_graph($src_base, $id, $data_info, \%series);
}

# Build the graph of the average size of read, write and extend operations
# on relations. Before PG18 an operation is always one block, so the graph
# is only produced with PostgreSQL 18 and later.
sub stat_io_size_graph
{
	my ($src_base, $id, $data_info) = @_;

	return if (!&backend_minimum_version(18));

	my %series = ();
	foreach my $t (&stat_io_times())
	{
		foreach my $op ('read', 'write', 'extend')
		{
			my $nops = &stat_io_sum($t, "${op}s", undef, 'relation', undef);
			next if (!$nops);
			my $bytes = &stat_io_sum($t, "${op}_bytes", undef, 'relation', undef);
			$series{$op} .= &stat_io_point($t, sprintf("%.0f", $bytes/$nops));
		}
	}
	&stat_io_print_graph($src_base, $id, $data_info, \%series);
}


# Build a graph with one serie per metric (per second) summed over all
# rows matching the object and context filters. %metrics associates the
# label of the serie to the metric name.
sub stat_io_ops_rate_graph
{
	my ($src_base, $id, $data_info, $object, $context, %metrics) = @_;

	my %series = ();
	my $total = 0;
	foreach my $t (&stat_io_times())
	{
		foreach my $label (keys %metrics)
		{
			my $val = &stat_io_sum($t, $metrics{$label}, undef, $object, $context);
			$total += $val;
			$series{$label} .= &stat_io_point($t, sprintf("%.2f", $val/$all_stat_io{$t}{interval}));
		}
	}
	return if (!$total);
	&stat_io_print_graph($src_base, $id, $data_info, \%series);
}

# Build the graph of the local buffers hit ratio for temporary relations
sub stat_io_temp_hit_ratio_graph
{
	my ($src_base, $id, $data_info) = @_;

	my %series = ();
	foreach my $t (&stat_io_times())
	{
		my $hits = &stat_io_sum($t, 'hits', undef, 'temp relation', undef);
		my $reads = &stat_io_sum($t, 'read_blocks', undef, 'temp relation', undef);
		next if (($hits + $reads) == 0);
		$series{'hit ratio'} .= &stat_io_point($t, sprintf("%.2f", $hits*100/($hits+$reads)));
	}
	&stat_io_print_graph($src_base, $id, $data_info, \%series);
}

####
# Asynchronous I/O statistics (PG18+). CSV format:
#   0 timestamp, 1 io_method, 2 io_workers, 3 io_min_workers,
#   4 io_max_workers, 5 running_io_workers, 6 aio_in_progress, 7 aio_readv,
#   8 aio_writev
# These are gauges, no delta to compute.
####
sub pg_stat_aio
{
	my ($in_dir, $file, $offset) = @_;

	my $curfh = open_filehdl("$in_dir/$file");
	$curfh->seek($offset,0);
	while (my $l = <$curfh>)
	{
		$offset += length($l);
		my @data = split(/;/, $l);
		next if ($#data < 8);
		next if (!&normalize_line(\@data));

		$all_stat_aio{$data[0]}{io_method} = $data[1];
		my @cols = qw(io_workers io_min_workers io_max_workers running_io_workers aio_in_progress aio_readv aio_writev);
		for (my $i = 0; $i <= $#cols; $i++) {
			$all_stat_aio{$data[0]}{$cols[$i]} = $data[$i+2] || 0;
		}
	}
	$curfh->close();

	return $offset || 0;
}

# Compute graphs of asynchronous I/O statistics
sub pg_stat_aio_report
{
	my ($src_base, %data_info) = @_;

	my %workers = ();
	my %inflight = ();
	my $has_worker = 0;
	my $has_inflight = 0;
	foreach my $t (sort {$a <=> $b} keys %all_stat_aio)
	{
		my $s = $all_stat_aio{$t};
		if ($s->{io_method} eq 'worker')
		{
			$has_worker = 1;
			$workers{'running'} .= &stat_io_point($t, $s->{running_io_workers});
			foreach my $p ('io_workers', 'io_min_workers', 'io_max_workers') {
				$workers{$p} .= &stat_io_point($t, $s->{$p}) if ($s->{$p});
			}
		}
		$has_inflight = 1 if ($s->{aio_in_progress});
		$inflight{'total'} .= &stat_io_point($t, $s->{aio_in_progress});
		$inflight{'readv'} .= &stat_io_point($t, $s->{aio_readv});
		$inflight{'writev'} .= &stat_io_point($t, $s->{aio_writev});
	}
	%all_stat_aio = ();

	foreach my $id (sort {$a <=> $b} keys %data_info)
	{
		if ($data_info{$id}{name} eq 'cluster-io_workers' && $has_worker) {
			&stat_io_print_graph($src_base, $id, \%data_info, \%workers);
		} elsif ($data_info{$id}{name} eq 'cluster-io_aio_inflight' && $has_inflight) {
			&stat_io_print_graph($src_base, $id, \%data_info, \%inflight);
		}
	}
}

####
# Kernel pressure stall information and memory events (kernel_stats.csv)
#
# CSV format produced by pgcluu_collectd, one cumulative counter per line:
#   timestamp;source;metric;value
# source is 'host' or 'cgroup' (cgroup v2 of the postmaster). The deltas
# between two snapshots are computed here, the last raw values are kept in
# %kernel_stats_prev which is saved in the binary cache:
#   $kernel_stats{$time}{interval} = seconds since the previous snapshot
#   $kernel_stats{$time}{"source|metric"} = delta
####
sub kernel_stats
{
	my ($in_dir, $file, $offset) = @_;

	my $cur_time = '';
	my $curfh = open_filehdl("$in_dir/$file");
	$curfh->seek($offset,0);
	while (my $l = <$curfh>)
	{
		$offset += length($l);
		chomp($l);
		my @data = split(/;/, $l);
		next if ($#data < 3);
		next if (!&normalize_line(\@data));

		my $t = $data[0];
		if ($t ne $cur_time)
		{
			# Skip snapshot already seen in a previous run
			next if ($kernel_stats_prev{time} && $t <= $kernel_stats_prev{time});
			if ($kernel_stats_prev{time}) {
				$kernel_stats{$t}{interval} = ($t - $kernel_stats_prev{time})/1000;
			}
			$kernel_stats_prev{lasttime} = $kernel_stats_prev{time} || 0;
			$kernel_stats_prev{time} = $t;
			$cur_time = $t;
		}
		my $key = "$data[1]|$data[2]";
		# A counter that was not in the previous snapshot has no delta
		if ($kernel_stats_prev{lasttime} && exists $kernel_stats_prev{vals}{$key})
		{
			my $delta = $data[3] - $kernel_stats_prev{vals}{$key};
			$kernel_stats{$t}{$key} = ($delta > 0) ? $delta : 0;
		}
		$kernel_stats_prev{vals}{$key} = $data[3];
	}
	$curfh->close();

	return $offset || 0;
}

# Compute graphs of the kernel statistics. Each graph definition gives the
# source, the metrics and how values are shown (mode):
#   psi:   percentage of the interval time with stalled tasks
#   rate:  events per second
#   count: number of events per interval
sub kernel_stats_report
{
	my ($src_base, %data_info) = @_;

	my @times = ();
	foreach my $t (sort {$a <=> $b} keys %kernel_stats)
	{
		$kernel_stats{$t}{interval} = 1 if ($sysinfo{CONFIGURATION}{'capture'});
		push(@times, $t) if ($kernel_stats{$t}{interval});
	}

	foreach my $id (sort {$a <=> $b} keys %data_info)
	{
		my $g = $data_info{$id};
		my %series = ();
		foreach my $m (@{$g->{metrics}})
		{
			my $key = "$g->{source}|$m";
			# Only metrics collected on this host are shown
			next if (!grep { exists $kernel_stats{$_}{$key} } @times);
			my $label = $m;
			$label =~ s/^(psi|memory_events)_//;
			$label =~ s/_(some|full)$//;
			foreach my $t (@times)
			{
				next if (!exists $kernel_stats{$t}{$key});
				my $val = $kernel_stats{$t}{$key};
				if ($g->{mode} eq 'psi') {
					$val = sprintf("%.2f", $val*100/($kernel_stats{$t}{interval}*1000000));
				} elsif ($g->{mode} eq 'rate') {
					$val = sprintf("%.2f", $val/$kernel_stats{$t}{interval});
				}
				$series{$label} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . $val . '],';
			}
		}
		next if (scalar keys %series == 0);

		my @legends = sort keys %series;
		my @graphs = map { my $s = $series{$_}; $s =~ s/,$//; $s } @legends;
		my %infos = %{$g};
		$infos{legends} = \@legends;
		my $fh = &append_to_html_file("$OUTPUT_DIR/$g->{page}.html", $src_base);
		$fh->print( &jqplot_linegraph_array($IDX++, $g->{name}, \%infos, '', @graphs) );
		$fh->close();
	}
	%kernel_stats = ();
}

# Compute graphs of pg_stat_io statistics
sub pg_stat_io_report
{
	my ($src_base, %data_info) = @_;

	foreach my $id (sort {$a <=> $b} keys %data_info)
	{
		next if (!exists $STAT_IO_GRAPHS{$data_info{$id}{name}});
		$STAT_IO_GRAPHS{$data_info{$id}{name}}->($src_base, $id, \%data_info);
	}
	%all_stat_io = ();
}

sub pg_stat_waitevent
{
	my ($in_dir, $file, $offset) = @_;

	my %total_count = ();
	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	$curfh->seek($offset,0);
	my @etype = ();
	my @wevent = ();
	my %total_wait_event = ();
	my $total_count = 0;
	while (my $l = <$curfh>)
	{
		my @data = split(/;/, $l);
		next if (!&normalize_line(\@data));

		# events types
		$all_wait_events{$data[0]}{type}{$data[2]} += $data[4];
		push(@etype, $data[2]) if (!grep(/^$data[2]$/, @etype));
		# wait events
		$all_wait_events{$data[0]}{event}{$data[3]} += $data[4];
		push(@wevent, $data[3]) if (!grep(/^$data[3]$/, @wevent));
		$total_wait_event{$data[3]} += $data[4];
		$total_count += $data[4];
	}
	$curfh->close();

	foreach my $t (sort {$a <=> $b } keys %all_wait_events)
	{
		foreach my $e (@etype)
		{
			if (!exists $all_wait_events{$t}{type}{$e}) {
				$all_wait_events{$t}{type}{$e} = 0;
			}
			foreach my $e (@wevent)
			{
				if (!exists $all_wait_events{$t}{event}{$e}) {
					$all_wait_events{$t}{event}{$e} = 0;
				}
			}
		}
	}
	# Remove unused wait events
	foreach my $e (keys %total_wait_event)
	{
		if ($total_wait_event{$e} < ($total_count*0.1/100))
		{
			foreach my $t (sort {$a <=> $b } keys %all_wait_events)
			{
				delete $all_wait_events{$t}{event}{$e};
			}
		}
	}

	my $prev_time = '';
	my %prev_value = ();
	my $wprev_time = '';
	my %wprev_value = ();
	foreach my $t (sort {$a <=> $b} keys %all_wait_events)
	{
		foreach my $e (@etype)
		{
			if (!$prev_time)
			{
				$prev_value{$e} = $all_wait_events{$t}{type}{$e};
				$all_wait_events{$t}{type}{$e} = 0;
			}
			else
			{
				my $tmp_val = $all_wait_events{$t}{type}{$e} - $prev_value{$e};
				$prev_value{$e} = $all_wait_events{$t}{type}{$e};
				$all_wait_events{$t}{type}{$e} = $tmp_val;
			}
		}
		foreach my $w (@wevent)
		{
			next if not exists $all_wait_events{$t}{event}{$w};
			if (!$wprev_time)
			{
				$wprev_value{$w} = $all_wait_events{$t}{event}{$w};
				$all_wait_events{$t}{event}{$w} = 0;
			}
			else
			{
				my $tmp_val = $all_wait_events{$t}{event}{$w} - $wprev_value{$w};
				$wprev_value{$w} = $all_wait_events{$t}{event}{$w};
				$all_wait_events{$t}{event}{$w} = $tmp_val;
			}
		}
		if ($prev_time) {
			$all_wait_events{$t}{interval} = ($t - $prev_time)/1000;
		}
		$prev_time = $t;
		$wprev_time = $t;
	}

	return $offset || 0;
}

# Compute graphs of wait event statistics
sub pg_stat_waitevent_report
{
	my ($src_base, %data_info) = @_;

	my %waitevent_type_stat = ();
	my %waitevent_event_stat = ();
	foreach my $t (sort {$a <=> $b} keys %all_wait_events)
	{
		foreach my $e (sort keys %{$all_wait_events{$t}{type}})
		{
			$waitevent_type_stat{$e} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_wait_events{$t}{type}{$e} || 0) . '],';
		}
		foreach my $e (sort keys %{$all_wait_events{$t}{event}})
		{
			$waitevent_event_stat{$e} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_wait_events{$t}{event}{$e} || 0) . '],';
		}
	}

	%all_wait_events = ();

	# Build graph dataset
	foreach my $id (sort {$a <=> $b} keys %data_info)
	{
		if ($data_info{$id}{name} eq 'cluster-waitevent_types')
		{
			my $dbfh = &append_to_html_file("$OUTPUT_DIR/cluster-waitevent_types.html", $src_base);
			my @legends = ();
			my @graphs = ();
			foreach my $e (sort keys %waitevent_type_stat)
			{
				push(@legends, $e);
				$waitevent_type_stat{$e} =~ s/,$//;
				push(@graphs, $waitevent_type_stat{$e});
			}
			$data_info{$id}{legends} = \@legends;
			$dbfh->print( &jqplot_linegraph_array($IDX++, 'cluster-waitevent_types', \%{$data_info{$id}}, '', @graphs) );
			$dbfh->close();
		}
		if ($data_info{$id}{name} eq 'cluster-waitevent_events')
		{
			my $dbfh = &append_to_html_file("$OUTPUT_DIR/cluster-waitevent_events.html", $src_base);
			my @legends = ();
			my @graphs = ();
			foreach my $e (sort keys %waitevent_event_stat)
			{
				push(@legends, $e);
				$waitevent_event_stat{$e} =~ s/,$//;
				push(@graphs, $waitevent_event_stat{$e});
			}
			$data_info{$id}{legends} = \@legends;
			$dbfh->print( &jqplot_linegraph_array($IDX++, 'cluster-waitevent_events', \%{$data_info{$id}}, '', @graphs) );
			$dbfh->close();
		}
	}
}


# Compute statistics of connections
sub pg_stat_connections
{
	my ($in_dir, $file, $offset) = @_;

	my @start_vals = ();
	my $tmp_val = 0;
	my %db_list = ();

	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	$curfh->seek($offset,0);
	while (my $l = <$curfh>)
	{
		$offset += length($l);
		my @data = split(/;/, $l);
		next if (!&normalize_line(\@data, 5));

		# timestamp | total | active | waiting | idle_in_xact | datname

		# Store list of database
		$db_list{$data[5]} = 1;

		$all_stat_connections{$data[0]}{$data[5]}{total} = $data[1];
		$all_stat_connections{$data[0]}{$data[5]}{active} = $data[2];
		$all_stat_connections{$data[0]}{$data[5]}{waiting} = $data[3];
		$all_stat_connections{$data[0]}{$data[5]}{idle_in_xact} = $data[4];
		$all_stat_connections{$data[0]}{$data[5]}{idle} = ($data[1] - $data[2] - $data[4]);
	}
	$curfh->close();

	# Store the full list of database
	foreach my $d (keys %db_list) {
		push(@global_databases, $d) if (!grep(/^$d$/, @global_databases));
	}
	push(@global_databases, 'all') if (($#global_databases >= 0) && !grep(/^all$/, @global_databases));

	return $offset || 0;
}

# Compute graphs of connections statistics
sub pg_stat_connections_report
{
	my ($src_base, %data_info) = @_;

	my %connections_stat = ();
	&set_cluster_total(\%all_stat_connections, 'total', 'active', 'waiting', 'idle_in_xact', 'idle');
	foreach my $t (sort {$a <=> $b} keys %all_stat_connections)
	{
		foreach my $db (@global_databases)
		{
			$connections_stat{$db}{total} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_stat_connections{$t}{$db}{total}||0) . '],';
			$connections_stat{$db}{active} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_stat_connections{$t}{$db}{active}||0) . '],';
			$connections_stat{$db}{waiting} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_stat_connections{$t}{$db}{waiting}||0) . '],';
			$connections_stat{$db}{idle_in_xact} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_stat_connections{$t}{$db}{idle_in_xact}||0) . '],';
			$connections_stat{$db}{idle} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_stat_connections{$t}{$db}{idle}||0) . '],';
		}
	}
	%all_stat_connections = ();

	my $id = &get_data_id('database-connections', %data_info);
	foreach my $db (sort keys %connections_stat)
	{
		next if (($db ne 'all') && ($#INCLUDE_DB >= 0) && (!grep($db =~ /^$_$/, @INCLUDE_DB)));
		$connections_stat{$db}{total} =~ s/,$//;
		$connections_stat{$db}{active} =~ s/,$//;
		$connections_stat{$db}{waiting} =~ s/,$//;
		$connections_stat{$db}{idle_in_xact} =~ s/,$//;
		$connections_stat{$db}{idle} =~ s/,$//;
		my $dbfh = &append_to_html_file("$OUTPUT_DIR/database-conn-$db.html", $src_base);
		if ($db ne 'all') {
			$dbfh->print( &jqplot_linegraph_array($IDX++, 'database-connections', \%{$data_info{$id}}, $db, $connections_stat{$db}{active}, $connections_stat{$db}{idle}, $connections_stat{$db}{idle_in_xact}, $connections_stat{$db}{waiting}) );
		}
		else
		{
			my $fhcluster = &append_to_html_file("$OUTPUT_DIR/cluster-$data_info{$id}{name}.html", $src_base);
			print $fhcluster &jqplot_linegraph_array($IDX++, 'cluster-connections', \%{$data_info{$id}}, 'all', $connections_stat{$db}{active}, $connections_stat{$db}{idle}, $connections_stat{$db}{idle_in_xact}, $connections_stat{$db}{waiting});
			$fhcluster->close();
		}
		$dbfh->close();
	}
}

# Compute statistics of user functions call
sub pg_stat_user_functions
{
	my ($in_dir, $file) = @_;

	my %start_vals = ();
	my $tmp_val = 0;

	%all_stat_user_functions = ();
	# Read start file
	my $curfh = open_filehdl("$in_dir/$file");
	while (my $l = <$curfh>) {
		chomp($l);
		next if (!$l);
		my @data = split(/;/, $l);
		next if (!&normalize_line(\@data));

		# timestamp | datname | funcid | schemaname | funcname | calls | total_time | self_time
		$data[4] = "$data[3].$data[4]";

		$all_stat_user_functions{$data[1]}{$data[4]}{calls}      = $data[5];
		$all_stat_user_functions{$data[1]}{$data[4]}{total_time} = $data[6];
		$all_stat_user_functions{$data[1]}{$data[4]}{self_time}  = $data[7];
	}
	$curfh->close();

	# Read end file and set the final value
	$curfh = open_filehdl("$in_dir/end-$file");
	while (my $l = <$curfh>) {
		chomp($l);
		next if (!$l);
		my @data = split(/;/, $l);
		next if (!&normalize_line(\@data));

		# timestamp | datname | funcid | schemaname | funcname | calls | total_time | self_time
		$data[4] = "$data[3].$data[4]";

		$all_stat_user_functions{$data[1]}{$data[4]}{calls}      = $data[5] - ($all_stat_user_functions{$data[1]}{$data[4]}{calls} || 0);
		$all_stat_user_functions{$data[1]}{$data[4]}{calls}      = $data[5] if ($all_stat_user_functions{$data[1]}{$data[4]}{calls} < 0);
		$all_stat_user_functions{$data[1]}{$data[4]}{total_time} = $data[6] - ($all_stat_user_functions{$data[1]}{$data[4]}{total_time} || 0);
		$all_stat_user_functions{$data[1]}{$data[4]}{total_time} = $data[6] if ($all_stat_user_functions{$data[1]}{$data[4]}{total_time} < 0);
		$all_stat_user_functions{$data[1]}{$data[4]}{self_time}  = $data[7] - ($all_stat_user_functions{$data[1]}{$data[4]}{self_time} || 0);
		$all_stat_user_functions{$data[1]}{$data[4]}{self_time}  = $data[7] if ($all_stat_user_functions{$data[1]}{$data[4]}{self_time} < 0);
	}
	$curfh->close();
}

sub pg_stat_all_functions
{
	return &pg_stat_user_functions;
}

# Compute graphs of user functions call statistics
sub pg_stat_user_functions_report
{
	my ($src_base, %data_info) = @_;

	my $id = &get_data_id('database-functions', %data_info);
	foreach my $db (keys %all_stat_user_functions) {
		next if (($db ne 'all') && ($#INCLUDE_DB >= 0) && (!grep($db =~ /^$_$/, @INCLUDE_DB)));
		my $colspan =  ' colspan="4"';
		my $dbfh = &append_to_html_file("$OUTPUT_DIR/database-fct-$db.html", $src_base);
		$dbfh->print (qq{
<li class="slide" id="database-functions-slide">
<div id="database-functions"><br/><br/><br/><br/></div>

<div class="row">
    <div class="col-md-12">
      <div class="panel panel-default">
      <div class="panel-heading">
	<h2>$data_info{$id}{menu} on $db database</h2>
	<p>$data_info{$id}{description}</p>
      </div>
      <div class="panel-body">
	<div class="analysis-item row-fluid" id="$db-$data_info{$id}{name}">
		<div class="span11">
			<table class="table table-striped sortable" id="$db-$data_info{$id}{name}-table">
				<thead>
					<tr>
					<th>Schema.function</th>
					<th>Calls</th>
					<th>Total time</th>
					<th>Self time</th>
					</tr>
				</thead>
				<tbody>
});
			my $found_fct_stat = 0;
			foreach my $fct (sort keys %{$all_stat_user_functions{$db}}) {
				if (!$all_stat_user_functions{$db}{$fct}{calls} && !$all_stat_user_functions{$db}{$fct}{total_time} && !$all_stat_user_functions{$db}{$fct}{self_time}) {
					next;
				}
				$found_fct_stat = 1;
				foreach ('calls','total_time','self_time') {
					$all_stat_user_functions{$db}{$fct}{$_} ||= 0;
				}
				$dbfh->print( "<tr><th>$fct</th><td>$all_stat_user_functions{$db}{$fct}{calls}</td><td>" . &format_duration($all_stat_user_functions{$db}{$fct}{total_time}) . "</td><td>" . &format_duration($all_stat_user_functions{$db}{$fct}{self_time}) . "</td></tr>\n");
			}
			if (!$found_fct_stat) {
				$dbfh->print( qq{<tr><td$colspan><div class="flotr-graph"><blockquote><b>NO DATASET</b></blockquote></div></td></tr>} );
			}
			$dbfh->print( qq{
				</tbody>
			</table>
		</div>
	</div>
	</div>
    </div>
</div>
</div>
</li>
});
		$dbfh->close();
	}
}

sub pg_stat_all_functions_report
{
	return &pg_stat_user_functions_report;
}

# Compute graphs of replication cluster statistics
sub pg_stat_replication
{
	my ($in_dir, $file, $offset) = @_;

	my @start_vals = ();
	my $tmp_val = 0;
	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	$curfh->seek($offset,0);
	while (my $l = <$curfh>) {
		$offset += length($l);
		my @data = split(/;/, $l);
		next if (!&normalize_line(\@data));
		# timestamp | pid | usesysid | usename | application_name | client_addr | client_hostname | client_port | backend_start | state | master_location | sent_location | write_location | flush_location | replay_location | sync_priority | sync_state
		# Do not care about BACKUP and pg_basebackup connection
		if ( (uc($data[9]) eq 'STREAMING') || (uc($data[4]) eq 'WALRECEIVER') ) {
			my $name = $data[5];
			$data[6] =~ s/"//g;
			$name .= " - $data[6]" if ($data[6]);

			push(@start_vals, @data) if ($#start_vals < 0);

			# Store interval between previous run
			$all_stat_replication{$data[0]}{interval} = ($data[0] - $start_vals[0])/1000;

			if ($sysinfo{CONFIGURATION}{'capture'}) {
				$all_stat_replication{$data[0]}{master_location} = 0;
			} else {
				if ((&getNumericalOffset($data[10]) - &getNumericalOffset($start_vals[10])) > 0) {
					$all_stat_replication{$data[0]}{master_location} = &getNumericalOffset($data[10]) -&getNumericalOffset($start_vals[10]);
				} else {
					$all_stat_replication{$data[0]}{master_location} = 0;
				}
			}

			if (!$data[14]) {
				$all_stat_replication{$data[0]}{$name}{replay_location} = 0;
			} else {
				if ((&getNumericalOffset($data[10]) - &getNumericalOffset($data[14])) < 0) { $tmp_val = 0 } else { $tmp_val = (&getNumericalOffset($data[10]) - &getNumericalOffset($data[14])) };
				$all_stat_replication{$data[0]}{$name}{replay_location} = $tmp_val;
			}
			if (!$data[11]) {
				$all_stat_replication{$data[0]}{$name}{sent_location} = 0;
			} else {
				if ((&getNumericalOffset($data[10]) - &getNumericalOffset($data[11])) < 0) { $tmp_val = 0 } else { $tmp_val = (&getNumericalOffset($data[10]) - &getNumericalOffset($data[11])) };
				$all_stat_replication{$data[0]}{$name}{sent_location} = $tmp_val;
			}
			if (!$data[12]) {
				$all_stat_replication{$data[0]}{$name}{write_location} = 0;
			} else {
				if ((&getNumericalOffset($data[10]) - &getNumericalOffset($data[12])) < 0) { $tmp_val = 0 } else { $tmp_val = (&getNumericalOffset($data[10]) - &getNumericalOffset($data[12])) };
				$all_stat_replication{$data[0]}{$name}{write_location} = $tmp_val;
			}
			if (!$data[12]) {
				$all_stat_replication{$data[0]}{$name}{flush_location} = 0;
			} else {
				if ((&getNumericalOffset($data[10]) - &getNumericalOffset($data[13])) < 0) { $tmp_val = 0 } else { $tmp_val = (&getNumericalOffset($data[10]) - &getNumericalOffset($data[13])) };
				$all_stat_replication{$data[0]}{$name}{flush_location} = $tmp_val;
			}
			if ($sysinfo{CONFIGURATION}{'capture'}) {
				$all_stat_replication{$data[0]}{$name}{replay_location} = ($data[14] || 0);
				$all_stat_replication{$data[0]}{$name}{sent_location}  = ($data[11] || 0);
				$all_stat_replication{$data[0]}{$name}{write_location} = ($data[12] || 0);
				$all_stat_replication{$data[0]}{$name}{flush_location} = ($data[13] || 0);
			}
			@start_vals = ();
			push(@start_vals, @data);
		}
	}
	$curfh->close();

	return $offset || 0;
}

# Compute graphs of replication cluster statistics
sub pg_stat_replication_report
{
	my ($src_base, %data_info) = @_;

	my %xlog_stat = ();
	foreach my $t (sort {$a <=> $b} keys %all_stat_replication)
	{
		foreach my $name (sort {$a cmp $b} keys %{$all_stat_replication{$t}})
		{
			next if ($name eq 'interval');
			$all_stat_replication{$t}{interval} = 1 if ($sysinfo{CONFIGURATION}{'capture'});
			if (!$sysinfo{CONFIGURATION}{'capture'})
			{
				if ($name eq 'master_location')
				{
					next if (!$all_stat_replication{$t}{interval});
					$all_stat_replication{$t}{master_location} ||= 0;
					$xlog_stat{master_location} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . sprintf("%0.2f", ($all_stat_replication{$t}{master_location}||0)) . '],';
					next;
				}
				$xlog_stat{$name}{replay_location} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . sprintf("%0.2f", ($all_stat_replication{$t}{$name}{replay_location} || 0)) . '],';
				$xlog_stat{$name}{sent_location} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . sprintf("%0.2f", ($all_stat_replication{$t}{$name}{sent_location} || 0)) . '],';
				$xlog_stat{$name}{write_location} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . sprintf("%0.2f", ($all_stat_replication{$t}{$name}{write_location} || 0)) . '],';
				$xlog_stat{$name}{flush_location} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . sprintf("%0.2f", ($all_stat_replication{$t}{$name}{flush_location} || 0)) . '],';
			}
		}
	}
	%all_stat_replication = ();
	return if (scalar keys %xlog_stat == 0);

	if (!$sysinfo{CONFIGURATION}{'capture'}) {
		foreach my $id (sort {$a <=> $b} keys %data_info) {
			my $fhcluster = &append_to_html_file("$OUTPUT_DIR/cluster-$data_info{$id}{name}.html", $src_base);
			if (exists $xlog_stat{master_location} && ($data_info{$id}{name} eq 'cluster-xlog')) {
				$xlog_stat{master_location} =~ s/,$//;
				print $fhcluster &jqplot_linegraph_array($IDX++, 'cluster-xlog', \%{$data_info{$id}}, '', $xlog_stat{master_location});
				delete $xlog_stat{master_location};

			} elsif ($data_info{$id}{name} eq 'cluster-replication') {
				foreach my $host (sort {$a cmp $b} keys %xlog_stat) {
					next if ($host eq 'master_location');
					$xlog_stat{$host}{sent_location} =~ s/,$//;
					$xlog_stat{$host}{write_location} =~ s/,$//;
					$xlog_stat{$host}{flush_location} =~ s/,$//;
					$xlog_stat{$host}{replay_location} =~ s/,$//;
					print $fhcluster &jqplot_linegraph_array($IDX++, 'cluster-replication', \%{$data_info{$id}}, $host, $xlog_stat{$host}{sent_location}, $xlog_stat{$host}{write_location}, $xlog_stat{$host}{replay_location});
				}
			}
			$fhcluster->close();
		}
	} else {
		my $id = &get_data_id('cluster-replication', %data_info);
		my $fhcluster = &append_to_html_file("$OUTPUT_DIR/cluster-$data_info{$id}{name}.html", $src_base);
		$data_info{$id}{title} =~ s/ with \%s//;
		print $fhcluster qq{
<li class="slide" id="cluster-replication-slide">
      <div id="cluster-replication"><br/><br/><br/><br/></div>
	<div class="row">
            <div class="col-md-12">
              <div class="panel panel-default">
              <div class="panel-heading">
		<h2>$data_info{$id}{title}</h2>
		<p>$data_info{$id}{description}</p>
              </div>
              <div class="panel-body">
		<div class="analysis-item row-fluid" id="$data_info{$id}{name}-report">
			<div class="span11">
				<table class="table table-striped" id="$data_info{$id}{name}-table">
					<tbody>
					<tr><th>Name</th><th>Master location</th><th>Sent location</th><th>Replay location</th><th>Flushed location</th><th>Write location</th></tr>
};
		foreach my $name (sort {$a cmp $b} keys %xlog_stat) {
			print $fhcluster "<tr><td>$name</td><td>$xlog_stat{$name}{master_location}</td><td>$xlog_stat{$name}{sent_location}</td><td>$xlog_stat{$name}{replay_location}</td><td>$xlog_stat{$name}{flush_location}</td><td>$xlog_stat{$name}{write_location}</td></tr>\n";
		}
		print $fhcluster qq{
					</tbody>
				</table>
			</div>
		</div>
		</div>
	    </div>
	    </div>
	</div>
    </li>
};
		$fhcluster->close();
	}
}

# Compute statistics of pgbouncer
sub pgbouncer_stats
{
	my ($in_dir, $file, $offset) = @_;

	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	$curfh->seek($offset,0);
	while (my $l = <$curfh>) {
		$offset += length($l);
		my @data = split(/;/, $l);
		next if (!&normalize_line(\@data));
		next if ($data[1] eq 'pgbouncer');

		# timestamp|database|user|cl_active|cl_waiting|sv_active|sv_idle|sv_used|sv_tested|sv_login|maxwait
		$all_pgbouncer_stats{$data[0]}{$data[1]}{$data[2]}{cl_active} += ($data[3] || 0);
		$all_pgbouncer_stats{$data[0]}{$data[1]}{$data[2]}{cl_waiting} += ($data[4] || 0);
		$all_pgbouncer_stats{$data[0]}{$data[1]}{$data[2]}{sv_active} += ($data[5] || 0);
		$all_pgbouncer_stats{$data[0]}{$data[1]}{$data[2]}{sv_idle} += ($data[6] || 0);
		$all_pgbouncer_stats{$data[0]}{$data[1]}{$data[2]}{sv_used} += ($data[7] || 0);
		$all_pgbouncer_stats{$data[0]}{$data[1]}{$data[2]}{sv_tested} += ($data[8] || 0);
		$all_pgbouncer_stats{$data[0]}{$data[1]}{$data[2]}{sv_login} += ($data[9] || 0);
		$all_pgbouncer_stats{$data[0]}{$data[1]}{$data[2]}{maxwait} += ($data[10] || 0);
	}
	$curfh->close();

	return $offset || 0;
}

# Compute graphs of pgbouncer statistics
sub pgbouncer_stats_report
{
	my ($src_base, %data_info) = @_;

	my %pgbouncer_stat = ();
	my %total_pool = ();
	foreach my $t (sort {$a <=> $b} keys %all_pgbouncer_stats) {
		foreach my $db (keys %{$all_pgbouncer_stats{$t}}) {
			foreach my $usr (keys %{$all_pgbouncer_stats{$t}{$db}}) {
				$pgbouncer_stat{"$db/$usr"}{cl_active} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_pgbouncer_stats{$t}{$db}{$usr}{cl_active} || 0) . '],';
				$pgbouncer_stat{"$db/$usr"}{cl_waiting} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_pgbouncer_stats{$t}{$db}{$usr}{cl_waiting} || 0) . '],';
				$pgbouncer_stat{"$db/$usr"}{sv_active} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_pgbouncer_stats{$t}{$db}{$usr}{sv_active} || 0) . '],';
				$pgbouncer_stat{"$db/$usr"}{sv_idle} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_pgbouncer_stats{$t}{$db}{$usr}{sv_idle} || 0) . '],';
				$pgbouncer_stat{"$db/$usr"}{sv_used} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_pgbouncer_stats{$t}{$db}{$usr}{sv_used} || 0) . '],';
				$pgbouncer_stat{"$db/$usr"}{sv_tested} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_pgbouncer_stats{$t}{$db}{$usr}{sv_tested} || 0) . '],';
				$pgbouncer_stat{"$db/$usr"}{sv_login} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_pgbouncer_stats{$t}{$db}{$usr}{sv_login} || 0) . '],';
				$pgbouncer_stat{"$db/$usr"}{maxwait} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_pgbouncer_stats{$t}{$db}{$usr}{maxwait} || 0) . '],';
				$total_pool{$db}{cl_active} += $all_pgbouncer_stats{$t}{$db}{$usr}{cl_active};
				$total_pool{$db}{cl_waiting} += $all_pgbouncer_stats{$t}{$db}{$usr}{cl_waiting};
				$total_pool{$db}{sv_active} += $all_pgbouncer_stats{$t}{$db}{$usr}{sv_active};
				$total_pool{$db}{sv_idle} += $all_pgbouncer_stats{$t}{$db}{$usr}{sv_idle};
				$total_pool{$db}{sv_used} += $all_pgbouncer_stats{$t}{$db}{$usr}{sv_used};
				$total_pool{$db}{sv_tested} += $all_pgbouncer_stats{$t}{$db}{$usr}{sv_tested};
				$total_pool{$db}{sv_login} += $all_pgbouncer_stats{$t}{$db}{$usr}{sv_login};
				$total_pool{$db}{maxwait} += $all_pgbouncer_stats{$t}{$db}{$usr}{maxwait};
			}
			$pgbouncer_stat{$db}{cl_active} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($total_pool{$db}{cl_active} || 0) . '],';
			$pgbouncer_stat{$db}{cl_waiting} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($total_pool{$db}{cl_waiting} || 0) . '],';
			$pgbouncer_stat{$db}{sv_active} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($total_pool{$db}{sv_active} || 0) . '],';
			$pgbouncer_stat{$db}{sv_idle} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($total_pool{$db}{sv_idle} || 0) . '],';
			$pgbouncer_stat{$db}{sv_used} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($total_pool{$db}{sv_used} || 0) . '],';
			$pgbouncer_stat{$db}{sv_tested} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($total_pool{$db}{sv_tested} || 0) . '],';
			$pgbouncer_stat{$db}{sv_login} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($total_pool{$db}{sv_login} || 0) . '],';
			$pgbouncer_stat{$db}{maxwait} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($total_pool{$db}{maxwait} || 0) . '],';
#			$total_pool{'all'}{cl_active} += $total_pool{$db}{cl_active};
#			$total_pool{'all'}{cl_waiting} += $total_pool{$db}{cl_waiting};
#			$total_pool{'all'}{sv_active} += $total_pool{$db}{sv_active};
#			$total_pool{'all'}{sv_idle} += $total_pool{$db}{sv_idle};
#			$total_pool{'all'}{sv_used} += $total_pool{$db}{sv_used};
#			$total_pool{'all'}{sv_tested} += $total_pool{$db}{sv_tested};
#			$total_pool{'all'}{sv_login} += $total_pool{$db}{sv_login};
#			$total_pool{'all'}{maxwait} += $total_pool{$db}{maxwait};
			delete $total_pool{$db};
		}
#		$pgbouncer_stat{'all'}{cl_active} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($total_pool{'all'}{cl_active} || 0) . '],';
#		$pgbouncer_stat{'all'}{cl_waiting} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($total_pool{'all'}{cl_waiting} || 0) . '],';
#		$pgbouncer_stat{'all'}{sv_active} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($total_pool{'all'}{sv_active} || 0) . '],';
#		$pgbouncer_stat{'all'}{sv_idle} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($total_pool{'all'}{sv_idle} || 0) . '],';
#		$pgbouncer_stat{'all'}{sv_used} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($total_pool{'all'}{sv_used} || 0) . '],';
#		$pgbouncer_stat{'all'}{sv_tested} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($total_pool{'all'}{sv_tested} || 0) . '],';
#		$pgbouncer_stat{'all'}{sv_login} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($total_pool{'all'}{sv_login} || 0) . '],';
#		$pgbouncer_stat{'all'}{maxwait} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($total_pool{'all'}{maxwait} || 0) . '],';
	}

	# Build graph dataset for all pgbouncer pool
	foreach my $id (sort {$a <=> $b} keys %data_info) {
		foreach my $db (sort {$a cmp $b} keys %pgbouncer_stat) {
			next if ($db eq 'all');
			next if ($db =~ /\//);
			my $pgbfh = &append_to_html_file("$OUTPUT_DIR/pgbouncer-$db.html", $src_base);
			if ($data_info{$id}{name} eq 'pgbouncer-connections') {
				$pgbouncer_stat{$db}{cl_active} =~ s/,$//;
				$pgbouncer_stat{$db}{cl_waiting} =~ s/,$//;
				$pgbouncer_stat{$db}{sv_active} =~ s/,$//;
				$pgbouncer_stat{$db}{sv_idle} =~ s/,$//;
				$pgbouncer_stat{$db}{sv_used} =~ s/,$//;
				$pgbouncer_stat{$db}{maxwait} =~ s/,$//;
				$pgbfh->print( &jqplot_linegraph_array($IDX++, 'pgbouncer-connections', \%{$data_info{$id}}, $db, $pgbouncer_stat{$db}{cl_active}, $pgbouncer_stat{$db}{cl_waiting}, $pgbouncer_stat{$db}{sv_active}, $pgbouncer_stat{$db}{sv_idle},$pgbouncer_stat{$db}{sv_used}, $pgbouncer_stat{$db}{maxwait}) );
				foreach my $pool (sort {$a cmp $b} keys %pgbouncer_stat) {
					next if ($pool !~ /^$db\//);
					$pgbouncer_stat{$pool}{cl_active} =~ s/,$//;
					$pgbouncer_stat{$pool}{cl_waiting} =~ s/,$//;
					$pgbouncer_stat{$pool}{sv_active} =~ s/,$//;
					$pgbouncer_stat{$pool}{sv_idle} =~ s/,$//;
					$pgbouncer_stat{$pool}{sv_used} =~ s/,$//;
					$pgbouncer_stat{$pool}{maxwait} =~ s/,$//;
					$pgbfh->print( &jqplot_linegraph_array($IDX++, 'pgbouncer-connections+', \%{$data_info{$id}}, $pool, $pgbouncer_stat{$pool}{cl_active}, $pgbouncer_stat{$pool}{cl_waiting}, $pgbouncer_stat{$pool}{sv_active}, $pgbouncer_stat{$pool}{sv_idle},$pgbouncer_stat{$pool}{sv_used}, $pgbouncer_stat{$pool}{maxwait}) );
				}
				$pgbfh->print("</li>\n");
			}
			$pgbfh->close();
		}
	}
}

sub get_diff
{
	my $file = shift;
	my $diff_hashref = shift;

	return if (! -e $file);

	my $curfh = open_filehdl($file);
	my $key = '';
	while (my $l = <$curfh>) {
		chomp($l);
		$l =~ s/\r//;
		next if ($l =~ /^\+\+\+/);
		if ($l =~ /^\-\-\-.*\s(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+)/) {
			my $tz = ((0-$TIMEZONE)*3600);
			$key = &timegm_nocheck($6, $5, $4, $3, $2 - 1, $1 - 1900) + $tz;
			delete $diff_hashref->{$key} if (exists $diff_hashref->{$key});
			next;
		}
		if ($key) {
			$diff_hashref->{$key} .= "$l\n";
		}
	}
	$curfh->close();
}

sub show_diff
{
	my ($fh, %diff) = @_;

	foreach my $k (sort { $b cmp $a } keys %diff) {
		my $date = localtime($k);
		print $fh qq{
	<div class="row">
	    <div class="col-md-12">
	      <div class="panel panel-default">
	      <div class="panel-heading">
		<h4>Change on $date</h4>
	      </div>
	      <div class="panel-body">
		<div class="analysis-item row-fluid">
			<div class="span11">
				<pre>$diff{$k}</pre>
			</div>
		</div>
	      </div>
	      </div>
	    </div>
	</div>
};
	}
}

# Get content of pgbouncer.ini
sub pgbouncer_ini
{
	my ($in_dir, $file) = @_;

	return if (!-e "$in_dir/pgbouncer.ini");

	%all_pgbouncer_ini = ();

	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	while (my $l = <$curfh>) {
		chomp($l);
		$l =~ s/\r//;
		next if ($l !~ /^[a-z]/);
		$l =~ s/\s*;.*//;
		$all_pgbouncer_ini{content} .= "$l\n";
	}
	$curfh->close();

	return if (!exists $all_pgbouncer_ini{content});

	# Load change on configuration file from diff files
	&get_diff("$in_dir/$file.diff", \%all_pgbouncer_ini_diff);

}

# Show relevant content of pgbouncer.ini
sub pgbouncer_ini_report
{
	my ($src_base, %data_info) = @_;

	my $output = "<div style=\"white-space: pre\">\n";
	$output .= $all_pgbouncer_ini{content} || '';
	$output .= "</div>\n";

	my $id = &get_data_id('cluster-pgbouncer', %data_info);
	my $fhcluster = &append_to_html_file("$OUTPUT_DIR/cluster-$data_info{$id}{name}.html", $src_base);
	print $fhcluster qq{
      <div id="cluster-pgbouncer"><br><br><br><br></div>
	<div class="row">
            <div class="col-md-12">
              <div class="panel panel-default">
              <div class="panel-heading">
		<h2>$data_info{$id}{menu}</h2>
		<p>$data_info{$id}{description}</p>
              </div>
              <div class="panel-body">
		<div class="analysis-item row-fluid" id="cluster-pgbouncer-report">
			<div class="span11">
				$output
			</div>
		</div>
	      </div>
	      </div>
	    </div>
	</div>
};

	%all_pgbouncer_ini = ();

	&show_diff($fhcluster, %all_pgbouncer_ini_diff);

	%all_pgbouncer_ini_diff = ();

	$fhcluster->close();
}

# Collect statistics about pgbouncer queries
sub pgbouncer_req_stats
{
	my ($in_dir, $file, $offset) = @_;


	my @start_vals = ();
	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	$curfh->seek($offset,0);
	while (my $l = <$curfh>) {
		$offset += length($l);
		my @data = split(/;/, $l);
		next if (!&normalize_line(\@data));
		next if ($data[1] eq 'pgbouncer');

		push(@start_vals, @data) if ($#start_vals < 0);
		my $tmp_val = 0;

		# timestamp|database|total_requests|total_received|total_sent|total_query_time|avg_req|avg_recv|avg_sent|avg_query
		# Since 1.8:
		# timestamp|database|total_xact_count|total_query_count|total_received|total_sent|total_xact_time|total_query_time|total_wait_time|avg_xact_count|avg_query_count|avg_recv|avg_sent|avg_xact_time|avg_query_time|avg_wait_time
		if ($#data == 9) {
			if (($data[2] - $start_vals[2]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[2] - $start_vals[2]) };
			$all_pgbouncer_req_stats{$data[0]}{$data[1]}{total_requests} += $tmp_val;
			if (($data[3] - $start_vals[3]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[3] - $start_vals[3]) };
			$all_pgbouncer_req_stats{$data[0]}{$data[1]}{total_received} += $tmp_val;
			if (($data[4] - $start_vals[4]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[4] - $start_vals[4]) };
			$all_pgbouncer_req_stats{$data[0]}{$data[1]}{total_sent} += $tmp_val;
			if (($data[5] - $start_vals[5]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[5] - $start_vals[5]) };
			$all_pgbouncer_req_stats{$data[0]}{$data[1]}{total_query_time} += $tmp_val;
			$all_pgbouncer_req_stats{$data[0]}{$data[1]}{avg_req} += $data[6];
			$all_pgbouncer_req_stats{$data[0]}{$data[1]}{avg_recv} += $data[7];
			$all_pgbouncer_req_stats{$data[0]}{$data[1]}{avg_sent} += $data[8];
			$all_pgbouncer_req_stats{$data[0]}{$data[1]}{avg_query} += $data[9];
		} else {
			if (($data[3] - $start_vals[3]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[3] - $start_vals[3]) };
			$all_pgbouncer_req_stats{$data[0]}{$data[1]}{total_requests} += $tmp_val;
			if (($data[4] - $start_vals[4]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[4] - $start_vals[4]) };
			$all_pgbouncer_req_stats{$data[0]}{$data[1]}{total_received} += $tmp_val;
			if (($data[5] - $start_vals[5]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[5] - $start_vals[5]) };
			$all_pgbouncer_req_stats{$data[0]}{$data[1]}{total_sent} += $tmp_val;
			if (($data[7] - $start_vals[7]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[7] - $start_vals[7]) };
			$all_pgbouncer_req_stats{$data[0]}{$data[1]}{total_query_time} += $tmp_val;
			if (($data[8] - $start_vals[8]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[8] - $start_vals[8]) };
			$all_pgbouncer_req_stats{$data[0]}{$data[1]}{total_wait_time} += $tmp_val;
			$all_pgbouncer_req_stats{$data[0]}{$data[1]}{avg_query_count} += $data[10];
			$all_pgbouncer_req_stats{$data[0]}{$data[1]}{avg_recv} += $data[11];
			$all_pgbouncer_req_stats{$data[0]}{$data[1]}{avg_sent} += $data[12];
			$all_pgbouncer_req_stats{$data[0]}{$data[1]}{avg_query_time} += $data[14];
			$all_pgbouncer_req_stats{$data[0]}{$data[1]}{avg_wait_time} += $data[15];
		}
		@start_vals = ();
		push(@start_vals, @data);
	}
	$curfh->close();

	return $offset || 0;
}

# Show report about pgbouncer queries
sub pgbouncer_req_stats_report
{
	my ($src_base, %data_info) = @_;

	my %pgbouncer_stat = ();
	foreach my $t (sort {$a <=> $b} keys %all_pgbouncer_req_stats) {
		foreach my $db (keys %{$all_pgbouncer_req_stats{$t}}) {
			foreach my $k (keys %{$all_pgbouncer_req_stats{$t}{$db}}) {
				$pgbouncer_stat{$db}{$k} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . $all_pgbouncer_req_stats{$t}{$db}{$k} . '],';
			}
		}
	}
	foreach my $id (sort {$a <=> $b} keys %data_info) {
		foreach my $db (sort {$a cmp $b} keys %pgbouncer_stat) {
			next if ($db eq 'all');
			my $pgbfh = &append_to_html_file("$OUTPUT_DIR/pgbouncer-$db.html", $src_base);
			if ($data_info{$id}{name} eq 'pgbouncer-duration') {
				# Assure backward compatibility with cached file with pgbouncer < 1.8
				# avg_query have been renamed into avg_query_time
				if (exists $pgbouncer_stat{$db}{avg_query_time}) {
					if (exists $pgbouncer_stat{$db}{avg_query}) {
						$pgbouncer_stat{$db}{avg_query} .= $pgbouncer_stat{$db}{avg_query_time};
						$pgbouncer_stat{$db}{avg_query_time} = $pgbouncer_stat{$db}{avg_query};
					}
					$pgbouncer_stat{$db}{avg_query_time} =~ s/,$//;
					$data_info{$id}{legends} = ['avg_query_time'];
					$pgbfh->print( &jqplot_linegraph_array($IDX++, 'pgbouncer-duration', \%{$data_info{$id}}, $db, $pgbouncer_stat{$db}{avg_query_time}) );
				} else {
					$pgbouncer_stat{$db}{avg_query} =~ s/,$//;
					$pgbfh->print( &jqplot_linegraph_array($IDX++, 'pgbouncer-duration', \%{$data_info{$id}}, $db, $pgbouncer_stat{$db}{avg_query}) );
				}
			} elsif ($data_info{$id}{name} eq 'pgbouncer-number') {
				# Assure backward compatibility with cached file with pgbouncer < 1.8
				# avg_req have been renamed into avg_query_count
				if (exists $pgbouncer_stat{$db}{avg_query_count}) {
					if (exists $pgbouncer_stat{$db}{avg_req}) {
						$pgbouncer_stat{$db}{avg_req} .= $pgbouncer_stat{$db}{avg_query_count};
						$pgbouncer_stat{$db}{avg_query_count} = $pgbouncer_stat{$db}{avg_req};
					}
					$pgbouncer_stat{$db}{avg_query_count} =~ s/,$//;
					$data_info{$id}{legends} = ['avg_query_count'];
					$pgbfh->print( &jqplot_linegraph_array($IDX++, 'pgbouncer-number', \%{$data_info{$id}}, $db, $pgbouncer_stat{$db}{avg_query_count}) );
				} else {
					$pgbouncer_stat{$db}{avg_req} =~ s/,$//;
					$pgbfh->print( &jqplot_linegraph_array($IDX++, 'pgbouncer-number', \%{$data_info{$id}}, $db, $pgbouncer_stat{$db}{avg_req}) );
				}
			} elsif ($data_info{$id}{name} eq 'pgbouncer-wait-total' && exists $pgbouncer_stat{$db}{total_wait_time}) {
				$pgbouncer_stat{$db}{total_wait_time} =~ s/,$//;
				$pgbfh->print( &jqplot_linegraph_array($IDX++, 'pgbouncer-wait-total', \%{$data_info{$id}}, $db, $pgbouncer_stat{$db}{total_wait_time}) );
			} elsif ($data_info{$id}{name} eq 'pgbouncer-wait-average' && exists $pgbouncer_stat{$db}{avg_wait_time}) {
				$pgbouncer_stat{$db}{avg_wait_time} =~ s/,$//;
				$pgbfh->print( &jqplot_linegraph_array($IDX++, 'pgbouncer-wait-average', \%{$data_info{$id}}, $db, $pgbouncer_stat{$db}{avg_wait_time}) );
			}
			$pgbfh->close();
		}
	}
}

# Compute graphs of object size statistics
sub pg_class_size
{
	my ($in_dir, $file) = @_;

	my $total_val = 0;
	my %table_changed = ();

	%all_class_size = ();

	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	while (my $l = <$curfh>) {
		chomp($l);
		next if (!$l);
		my @data = split(/;/, $l);
		next if (!&normalize_line(\@data));
		if ($data[4] !~ /^[a-zA-Z]$/) {
			print STDERR "WARNING: incompatible type of file pg_class_size.csv, the second field should be the database name\n";
			last;
		}

		# timestamp | dbname | nspname | relname | relkind | reltuples | relpages | relsize
		my $size = $data[6]*8192;
		$size = $data[7] if ($#data == 7);
		$all_class_size{$data[1]}{$data[4]}{"$data[2].$data[3]"}{size} = $size;
		$all_class_size{$data[1]}{$data[4]}{"$data[2].$data[3]"}{tuples} = $data[5];
		if ($data[5] > 0) {
			$all_class_size{$data[1]}{$data[4]}{"$data[2].$data[3]"}{width} = sprintf("%.2f", $size/$data[5]);
		} else {
			$all_class_size{$data[1]}{$data[4]}{"$data[2].$data[3]"}{width} = '-';
		}
	}
	$curfh->close();

}

# Compute graphs of object size statistics
sub pg_class_size_report
{
	my ($src_base, %data_info) = @_;

	my %data = ();
	foreach my $db (sort keys %all_class_size) {
		next if (($db ne 'all') && ($#INCLUDE_DB >= 0) && (!grep($db =~ /^$_$/, @INCLUDE_DB)));
		foreach my $k (sort keys %RELKIND) {
			# Count the number of object
			if (exists $all_class_size{$db}{$k}) {
				$OVERALL_STATS{'class'}{$db}{$k} = scalar keys %{$all_class_size{$db}{$k}};
			} else {
				$OVERALL_STATS{'class'}{$db}{$k} = 0;
			}
		}
		foreach my $id (sort {$a <=> $b} keys %data_info) {
			next if ($data_info{$id}{name} !~ /^(table|index)-/);
			# Open filehandle to cluster file
			my $fhtable = IO::File->new("$OUTPUT_DIR/$db-$data_info{$id}{name}.html", "w");
			die "FATAL: can't write file $OUTPUT_DIR/$db-$data_info{$id}{name}.html, $!" if (not defined $fhtable);
			&html_header($fhtable, $src_base);
			my $table_header = '';
			my $kind = '';
			if ($data_info{$id}{name} eq 'table-size') {
				$kind = 'tables';
				$table_header = qq{
					<th>Size</th>
					<th>Tuples</th>
					<th>Avg width</th>
};
			} elsif ($data_info{$id}{name} eq 'index-size') {
				$kind = 'indexes';
				$table_header = qq{
					<th>Size</th>
					<th>Tuples</th>
					<th>Avg width</th>
};
			}
			print $fhtable qq{
<ul id="slides">
<div class="row">
    <div class="col-md-12">
      <div class="panel panel-default">
      <div class="panel-heading">
	<h2>$data_info{$id}{menu} on $db database $kind</h2>
	<p>$data_info{$id}{description}</p>
      </div>
      <div class="panel-body">
	<div class="analysis-item row-fluid" id="$db-$data_info{$id}{name}">
		<div class="span11">
			<table class="table table-striped sortable" id="$db-$data_info{$id}{name}-table">
				<thead>
					<tr>
						<th>Object name</th>
						$table_header
					</tr>
				</thead>
				<tbody>
};
			my $found_table_stat = 0;
			foreach my $k (sort keys %{$all_class_size{$db}}) {
				next if (($k ne 't') && ($k ne 'r') && ($data_info{$id}{name} eq 'table-size'));
				next if (($k ne 'i') && ($data_info{$id}{name} eq 'index-size'));
				my $colspan = ' colspan="5"';
				foreach my $tb (sort {$all_class_size{$db}{$k}{$b}{size} <=> $all_class_size{$db}{$k}{$a}{size} } keys %{$all_class_size{$db}{$k}}) {
					next if (!$all_class_size{$db}{$k}{$tb}{size} && !$all_class_size{$db}{$k}{$tb}{tuples});
					next if (($#INCLUDE_TB >= 0) && !grep(/^$tb$/, @INCLUDE_TB));
					my $table_data = '';
					if ($data_info{$id}{name} =~ /^(table|index)-size$/) {
						$found_table_stat = 1;
						foreach ('size','tuples','width') {
							$all_class_size{$db}{$k}{$tb}{$_} ||= 0;
						}
						$table_data = "<tr><th>$tb</th><td>" . &pretty_print_size($all_class_size{$db}{$k}{$tb}{size}) . "</td><td>" . int($all_class_size{$db}{$k}{$tb}{tuples}) . "</td><td>$all_class_size{$db}{$k}{$tb}{width}</td></tr>\n";
					}
					if ($table_data) {
						print $fhtable $table_data;
					}
				}
				if (!$found_table_stat) {
					print $fhtable qq{<tr><td$colspan><div class="flotr-graph"><blockquote><b>NO DATASET</b></blockquote></div></td></tr>};
				}
			}
			print $fhtable qq{
				</tbody>
			</table>
		</div>
	</div>
};
			# Terminate cluster statistics file
			print $fhtable qq{
	</div>
	</div>
    </div>
</div>
};
			$fhtable->close;
		}
	}

	%all_class_size = ();
}

# Compute graphs of locks statistics
sub pg_stat_locks
{
	my ($in_dir, $file, $offset) = @_;

	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	$curfh->seek($offset,0);
	while (my $l = <$curfh>)
	{
		$offset += length($l);
		my @data = split(/;/, $l);
		next if (!&normalize_line(\@data));

		# timestamp|database|label|(type|mode|granted)|count
		$data[3] = 'granted' if ($data[2] eq 'lock_granted' && $data[3] eq 't');
		$data[3] = 'waiting' if ($data[2] eq 'lock_granted' && $data[3] eq 'f');
		$all_stat_locks{$data[0]}{$data[1]}{$data[2]}{$data[3]} += $data[4];
		if ($data[3] eq 'granted') {
			$all_stat_locks{$data[0]}{$data[1]}{$data[2]}{'waiting'} += 0;
		} elsif ($data[3] eq 'waiting') {
			$all_stat_locks{$data[0]}{$data[1]}{$data[2]}{'granted'} += 0;
		}
	}
	$curfh->close();

	return $offset || 0;
}

# Compute graphs of locks statistics
sub pg_stat_locks_report
{
	my ($src_base, %data_info) = @_;

	my %locks_stat = ();
	my %legends = ();
	foreach my $t (keys %all_stat_locks) {
		foreach my $db (keys %{$all_stat_locks{$t}}) {
			foreach my $lbl (keys %{$all_stat_locks{$t}{$db}}) {
				foreach my $k (sort keys %{$all_stat_locks{$t}{$db}{$lbl}}) {
					push(@{$legends{$db}{$lbl}}, $k) if (!grep(/^$k$/, @{$legends{$db}{$lbl}}));
				}
			}
		}
	}
	foreach my $t (sort {$a <=> $b} keys %all_stat_locks) {
		foreach my $db (keys %{$all_stat_locks{$t}}) {
			foreach my $lbl (keys %{$all_stat_locks{$t}{$db}}) {
				foreach my $k (sort keys %{$all_stat_locks{$t}{$db}{$lbl}}) {
					$locks_stat{$db}{$lbl}{$k} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_stat_locks{$t}{$db}{$lbl}{$k}||0) . '],';
				}
				# Complete inexisting values for other labels
				foreach my $e (@{$legends{$db}{$lbl}}) {
					next if (exists $all_stat_locks{$t}{$db}{$lbl}{$e});
					$locks_stat{$db}{$lbl}{$e} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',0],';
				}
			}
		}
	}
	%all_stat_locks = ();
	foreach my $id (sort {$a <=> $b} keys %data_info)
	{
		foreach my $db (sort keys %locks_stat)
		{
			next if (($db ne 'all') && ($#INCLUDE_DB >= 0) && (!grep($db =~ /^$_$/, @INCLUDE_DB)));
			my @graph_data = ();
			my $dbfh = &append_to_html_file("$OUTPUT_DIR/database-lock-$db.html", $src_base);
			if ($data_info{$id}{name} eq 'database-lock-types')
			{
				foreach my $k (sort keys %{$locks_stat{$db}{lock_type}})
				{
					$locks_stat{$db}{lock_type}{$k} =~ s/,$//;
					push(@{$data_info{$id}{legends}}, $k);
					push(@graph_data, $locks_stat{$db}{lock_type}{$k});
				}
				$dbfh->print( &jqplot_linegraph_array($IDX++, 'database-lock-types', \%{$data_info{$id}}, $db, @graph_data) );
			}
			elsif ($data_info{$id}{name} eq 'database-lock-modes')
			{
				foreach my $k (sort keys %{$locks_stat{$db}{lock_mode}})
				{
					$locks_stat{$db}{lock_mode}{$k} =~ s/,$//;
					push(@{$data_info{$id}{legends}}, $k);
					push(@graph_data, $locks_stat{$db}{lock_mode}{$k});
				}
				$dbfh->print( &jqplot_linegraph_array($IDX++, 'database-lock-modes', \%{$data_info{$id}}, $db, @graph_data) );
			}
			elsif ($data_info{$id}{name} eq 'database-lock-granted')
			{
				foreach my $k (sort keys %{$locks_stat{$db}{lock_granted}})
				{
					$locks_stat{$db}{lock_granted}{$k} =~ s/,$//;
					push(@{$data_info{$id}{legends}}, $k);
					push(@graph_data, $locks_stat{$db}{lock_granted}{$k});
				}
				$dbfh->print( &jqplot_linegraph_array($IDX++, 'database-lock-granted', \%{$data_info{$id}}, $db, @graph_data) );
			}
			$dbfh->close();
		}
	}
}

# Compute statistics about unused index
sub pg_stat_unused_indexes
{
	my ($in_dir, $file) = @_;

	return if ($NO_TB_STAT);

	%all_stat_unused_indexes = ();

	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	while (my $l = <$curfh>) {
		chomp($l);
		next if (!$l);
		my @data = split(/;/, $l);

		# timestamp | dbname | schemaname | relname | indexrelname | index_code
		push(@{$all_stat_unused_indexes{$data[1]}},  [ ($data[2], $data[3], $data[4], $data[5]) ] );
	}
	$curfh->close();
}

# Compute report about unused index
sub pg_stat_unused_indexes_report
{
	my ($src_base, %data_info) = @_;

	return if ($NO_TB_STAT);

	my $id = &get_data_id('unused-index', %data_info);
	foreach my $db (sort keys %all_stat_unused_indexes) {
		next if (($db ne 'all') && ($#INCLUDE_DB >= 0) && (!grep($db =~ /^$_$/, @INCLUDE_DB)));
		# Open filehandle to cluster file
		my $fhtable = IO::File->new("$OUTPUT_DIR/$db-$data_info{$id}{name}.html", "w");
		die "FATAL: can't write file $OUTPUT_DIR/$db-$data_info{$id}{name}.html, $!" if (not defined $fhtable);
		&html_header($fhtable, $src_base);
		print $fhtable qq{
<ul id="slides">
<div class="row">
    <div class="col-md-12">
      <div class="panel panel-default">
      <div class="panel-heading">
	<h2>$data_info{$id}{menu} on $db database</h2>
	<p>$data_info{$id}{description}</p>
      </div>
      <div class="panel-body">
	<div class="analysis-item row-fluid" id="$db-$data_info{$id}{name}">
		<div class="span11">
			<table class="table table-striped" id="$db-$data_info{$id}{name}-table">
				<thead>
					<tr>
					<th>Schema</th>
					<th>Table</th>
					<th>Index</th>
					<th>Code</th>
					</tr>
				</thead>
				<tbody>
};
		foreach my $r (@{$all_stat_unused_indexes{$db}}) {
			print $fhtable '<tr><td>', join('</td><td>', @$r), "</td></tr>\n";
		}
		print $fhtable qq{
				</tbody>
			</table>
		</div>
	</div>
	</div>
    </div>
</div>
};
		$fhtable->close;
	}
	%all_stat_unused_indexes = ();
}

# Compute statistics about redundant index
sub pg_stat_redundant_indexes
{
	my ($in_dir, $file) = @_;

	return if ($NO_TB_STAT);

	%all_stat_redundant_indexes = ();

	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	while (my $l = <$curfh>)
	{
		chomp($l);
		next if (!$l);
		my @data = split(/;/, $l);

		# Do not report indexes when one is partial and not the other one
		# otherwise keep it for user recheck
		next if (grep(/\bWHERE\b/i, $data[2], $data[3]) == 1);

		if ($data[2] =~ / USING ([^\s]+)/)
		{
			my $using = $1;
			next if ($data[3] !~ / USING $using/);
		}

		# timestamp | dbname | contained | containing
		push(@{$all_stat_redundant_indexes{$data[1]}}, [ ($data[2], $data[3]) ] );
	}
	$curfh->close();
}

# Compute report about redundant index
sub pg_stat_redundant_indexes_report
{
	my ($src_base, %data_info) = @_;

	return if ($NO_TB_STAT);

	my $id = &get_data_id('redundant-index', %data_info);

	foreach my $db (sort keys %all_stat_redundant_indexes) {
		next if (($db ne 'all') && ($#INCLUDE_DB >= 0) && (!grep($db =~ /^$_$/, @INCLUDE_DB)));
		# Open filehandle to cluster file
		my $fhtable = IO::File->new("$OUTPUT_DIR/$db-$data_info{$id}{name}.html", "w");
		die "FATAL: can't write file $OUTPUT_DIR/$db-$data_info{$id}{name}.html, $!" if (not defined $fhtable);
		&html_header($fhtable, $src_base);
		print $fhtable qq{
<ul id="slides">
<div class="row">
    <div class="col-md-12">
      <div class="panel panel-default">
      <div class="panel-heading">
	<h2>$data_info{$id}{menu} on $db database</h2>
	<p>$data_info{$id}{description}</p>
      </div>
      <div class="panel-body">
	<div class="analysis-item row-fluid" id="$db-$data_info{$id}{name}">
		<div class="span11">
			<table class="table table-striped" id="$db-$data_info{$id}{name}-table">
				<thead>
					<tr>
					<th>Contained</th>
					<th>Containing</th>
					</tr>
				</thead>
				<tbody>
};
		foreach my $r (@{$all_stat_redundant_indexes{$db}}) {
			print $fhtable '<tr><td>', join('</td><td>', @$r), "</td></tr>\n";
		}
		print $fhtable qq{
				</tbody>
			</table>
		</div>
	</div>
	</div>
    </div>
</div>
};
		$fhtable->close;
	}
	%all_stat_redundant_indexes = ();
}

# Compute statistics about indexes count
sub pg_stat_count_indexes
{
	my ($in_dir, $file) = @_;

	return if ($NO_TB_STAT);

	%all_stat_count_indexes = ();

	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	while (my $l = <$curfh>) {
		chomp($l);
		next if (!$l);
		my @data = split(/;/, $l);
		# timestamp | dbname | schema | table | count
		$all_stat_count_indexes{$data[1]}{$data[2]}{$data[3]} = $data[4];
	}
	$curfh->close();
}

# Compute report about table without indexes or with too many indexes
sub pg_stat_count_indexes_report
{
	my ($src_base, %data_info) = @_;

	return if ($NO_TB_STAT);

	foreach my $db (sort keys %all_stat_count_indexes) {
		next if (($db ne 'all') && ($#INCLUDE_DB >= 0) && (!grep($db =~ /^$_$/, @INCLUDE_DB)));
		my $id = &get_data_id('count-index', %data_info);
		# Open filehandle to cluster file
		my $fhtable = IO::File->new("$OUTPUT_DIR/$db-$data_info{$id}{name}.html", "w");
		die "FATAL: can't write file $OUTPUT_DIR/$db-$data_info{$id}{name}.html, $!" if (not defined $fhtable);
		&html_header($fhtable, $src_base);
		print $fhtable qq{
<ul id="slides">
<div class="row">
    <div class="col-md-12">
      <div class="panel panel-default">
      <div class="panel-heading">
	<h2>$data_info{$id}{menu} on $db database</h2>
	<p>$data_info{$id}{description}</p>
      </div>
      <div class="panel-body">
	<div class="analysis-item row-fluid" id="$db-$data_info{$id}{name}">
		<div class="span11">
			<table class="table table-striped sortable" id="$db-$data_info{$id}{name}-table">
				<thead>
					<tr>
					<th>Schema</th>
					<th>table</th>
					<th>Number of indexes</th>
					</tr>
				</thead>
				<tbody>
};
		foreach my $s (sort keys %{$all_stat_count_indexes{$db}}) {
			foreach my $t (sort keys %{$all_stat_count_indexes{$db}{$s}}) {
				next if ($all_stat_count_indexes{$db}{$s}{$t} < $MAX_INDEXES);
				print $fhtable "<tr><td>$s</td><td>$t</td><td>$all_stat_count_indexes{$db}{$s}{$t}</td></tr>\n";
			}
		}
		print $fhtable qq{
				</tbody>
			</table>
		</div>
	</div>
	</div>
    </div>
</div>
};

		$id = &get_data_id('zero-index', %data_info);
		print $fhtable qq{
<div class="row">
    <div class="col-md-12">
      <div class="panel panel-default">
      <div class="panel-heading">
	<h2>$data_info{$id}{menu} on $db database</h2>
	<p>$data_info{$id}{description}</p>
      </div>
      <div class="panel-body">
	<div class="analysis-item row-fluid" id="$db-$data_info{$id}{name}">
		<div class="span11">
			<table class="table table-striped" id="$db-$data_info{$id}{name}-table">
				<thead>
					<tr>
					<th>Schema</th>
					<th>table</th>
					</tr>
				</thead>
				<tbody>
};
		foreach my $s (sort keys %{$all_stat_count_indexes{$db}}) {
			foreach my $t (sort keys %{$all_stat_count_indexes{$db}{$s}}) {
				next if ($all_stat_count_indexes{$db}{$s}{$t} > 0);
				print $fhtable "<tr><td>$s</td><td>$t</td></tr>\n";
			}
		}
		print $fhtable qq{
				</tbody>
			</table>
		</div>
	</div>
	</div>
    </div>
</div>
};

		$fhtable->close;
	}
	%all_stat_count_indexes = ();
}

# Compute statistics about missing index
sub pg_stat_missing_fkindexes
{
	my ($in_dir, $file) = @_;

	return if ($NO_TB_STAT);

	%all_stat_missing_fkindexes = ();

	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	while (my $l = <$curfh>) {
		chomp($l);
		next if (!$l);
		my @data = split(/;/, $l);

		# timestamp | dbname | relname | ddl
		push(@{$all_stat_missing_fkindexes{$data[1]}}, [ ($data[2], $data[3]) ] );
	}
	$curfh->close();
}

# Compute report about missing index
sub pg_stat_missing_fkindexes_report
{
	my ($src_base, %data_info) = @_;

	return if ($NO_TB_STAT);

	my $id = &get_data_id('missing-index', %data_info);
	foreach my $db (sort keys %all_stat_missing_fkindexes) {
		next if (($db ne 'all') && ($#INCLUDE_DB >= 0) && (!grep($db =~ /^$_$/, @INCLUDE_DB)));
		# Open filehandle to cluster file
		my $fhtable = IO::File->new("$OUTPUT_DIR/$db-$data_info{$id}{name}.html", "w");
		die "FATAL: can't write file $OUTPUT_DIR/$db-$data_info{$id}{name}.html, $!" if (not defined $fhtable);
		&html_header($fhtable, $src_base);
		print $fhtable qq{
<ul id="slides">
<div class="row">
    <div class="col-md-12">
      <div class="panel panel-default">
      <div class="panel-heading">
	<h2>$data_info{$id}{menu} on $db database</h2>
	<p>$data_info{$id}{description}</p>
      </div>
      <div class="panel-body">
	<div class="analysis-item row-fluid" id="$db-$data_info{$id}{name}">
		<div class="span11">
			<table class="table table-striped" id="$db-$data_info{$id}{name}-table">
				<thead>
					<tr>
					<th>Table</th>
					<th>Missing index</th>
					</tr>
				</thead>
				<tbody>
};
		foreach my $r (@{$all_stat_missing_fkindexes{$db}}) {
			print $fhtable '<tr><td>', join('</td><td>', @$r), "</td></tr>\n";
		}
		print $fhtable qq{
				</tbody>
			</table>
		</div>
	</div>
	</div>
    </div>
</div>
};
		$fhtable->close;
	}
	%all_stat_missing_fkindexes = ();
}

# Compute statistics about extended statistics
sub pg_stat_ext
{
	my ($in_dir, $file) = @_;

	return if ($NO_TB_STAT);

	%all_stat_extended_statistics = ();

	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	while (my $l = <$curfh>) {
		chomp($l);
		next if (!$l);
		my @data = split(/;/, $l);

		# timestamp | dbname | schemaname | tablename | stats_schemaname | stats_name | stats_owner | attnames | kinds
		push(@{$all_stat_extended_statistics{$data[1]}}, [ ($data[4], $data[5], $data[8], $data[7], $data[2], $data[3]) ] );
	}
	$curfh->close();
}

# Compute report about extended statistics
sub pg_stat_ext_report
{
	my ($src_base, %data_info) = @_;

	return if ($NO_TB_STAT);

	my $id = &get_data_id('table-extended', %data_info);

	foreach my $db (sort keys %all_stat_extended_statistics) {
		next if (($db ne 'all') && ($#INCLUDE_DB >= 0) && (!grep($db =~ /^$_$/, @INCLUDE_DB)));
		# Open filehandle to cluster file
		my $fhtable = IO::File->new("$OUTPUT_DIR/$db-$data_info{$id}{name}.html", "w");
		die "FATAL: can't write file $OUTPUT_DIR/$db-$data_info{$id}{name}.html, $!" if (not defined $fhtable);
		&html_header($fhtable, $src_base);
		print $fhtable qq{
<ul id="slides">
<div class="row">
    <div class="col-md-12">
      <div class="panel panel-default">
      <div class="panel-heading">
	<h2>$data_info{$id}{menu} on $db database</h2>
	<p>$data_info{$id}{description}</p>
      </div>
      <div class="panel-body">
	<div class="analysis-item row-fluid" id="$db-$data_info{$id}{name}">
		<div class="span11">
			<table class="table table-striped" id="$db-$data_info{$id}{name}-table">
				<thead>
					<tr>
					<th>Table</th>
					<th>Extended Statistic</th>
					</tr>
				</thead>
				<tbody>
};
		my %stat_kinds = ('f' => 'dependencies', 'd' => 'ndistinct', 'm' => 'mcv', 'e' => 'expression');
		foreach my $r (sort {"$a->[4].$a->[5]" cmp "$b->[4].$b->[5]"} @{$all_stat_extended_statistics{$db}})
		{
			$r->[2] =~ s/\{//;
			$r->[2] =~ s/\}//;
			my @skind = split(',', $r->[2]);
			map { s/(.*)/$stat_kinds{$1}/; } @skind;
			$r->[3] =~ s/\{//;
			$r->[3] =~ s/\}//;
			print $fhtable "<tr><td>$r->[4].$r->[5]</td><td>CREATE STATISTICS $r->[0].$r->[1] (", join(',', @skind), ") ON $r->[3] FROM $r->[4].$r->[5];</td></tr>\n";
		}
		print $fhtable qq{
				</tbody>
			</table>
		</div>
	</div>
	</div>
    </div>
</div>
};
		$fhtable->close;
	}
	%all_stat_extended_statistics = ();
}

# Get relevant content of postgresql.conf
sub postgresql_conf
{
	my ($in_dir, $file) = @_;

	%all_postgresql_conf = ();

	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	while (my $l = <$curfh>) {
		chomp($l);
		$l =~ s/\r//;
		next if ($l !~ /^[a-z]/);
		$l =~ s/\s*#.*//;
		$all_postgresql_conf{content} .= "$l\n";
	}
	$curfh->close();

	return if (!exists $all_postgresql_conf{content});

	# Load change on configuration file from diff files
	&get_diff("$in_dir/$file.diff", \%all_postgresql_conf_diff);

}

# Show content of postgresql.conf
sub postgresql_conf_report
{
	my ($src_base, %data_info) = @_;

	my $output = $all_postgresql_conf{content} || '';
	return if (!$output);

	if (!$output) {
		$output = '<div class="flotr-graph"><blockquote><b>NO DATASET</b></blockquote></div>';
	} else {
		$output = "<div style=\"white-space: pre\">\n$output</div>\n";
	}
	my $id = &get_data_id('cluster-pgconf', %data_info);
	my $fhcluster = &append_to_html_file("$OUTPUT_DIR/cluster-$data_info{$id}{name}.html", $src_base);
	print $fhcluster qq{
      <div id="cluster-pgconf"><br><br><br><br></div>
	<div class="row">
            <div class="col-md-12">
              <div class="panel panel-default">
              <div class="panel-heading">
		<h2>$data_info{$id}{menu}</h2>
		<p>$data_info{$id}{description}</p>
              </div>
              <div class="panel-body">
		<div class="analysis-item row-fluid" id="cluster-pgconf-report">
			<div class="span11">
				$output
			</div>
		</div>
	      </div>
	      </div>
	    </div>
	</div>
};

	%all_postgresql_conf = ();

	&show_diff($fhcluster, %all_postgresql_conf_diff);

	%all_postgresql_conf_diff = ();

	$fhcluster->close();
}

# Get relevant content of recovery.conf
sub recovery_conf
{
	my ($in_dir, $file) = @_;

	%all_recovery_conf = ();

	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	while (my $l = <$curfh>) {
		chomp($l);
		$l =~ s/\r//;
		next if ($l !~ /^[a-z]/);
		$l =~ s/\s*#.*//;
		$all_recovery_conf{content} .= "$l\n";
	}
	$curfh->close();

	return if (!exists $all_recovery_conf{content});

	# Load change on configuration file from diff files
	&get_diff("$in_dir/$file.diff", \%all_recovery_conf_diff);

}

# Show content of recovery.conf
sub recovery_conf_report
{
	my ($src_base, %data_info) = @_;

	my $output = $all_recovery_conf{content} || '';
	return if (!$output);

	if (!$output) {
		$output = '<div class="flotr-graph"><blockquote><b>NO DATASET</b></blockquote></div>';
	} else {
		$output = "<div style=\"white-space: pre\">\n$output</div>\n";
	}
	my $id = &get_data_id('cluster-recoveryconf', %data_info);
	my $fhcluster = &append_to_html_file("$OUTPUT_DIR/cluster-$data_info{$id}{name}.html", $src_base);
	print $fhcluster qq{
      <div id="cluster-recoveryconf"><br><br><br><br></div>
	<div class="row">
            <div class="col-md-12">
              <div class="panel panel-default">
              <div class="panel-heading">
		<h2>$data_info{$id}{menu}</h2>
		<p>$data_info{$id}{description}</p>
              </div>
              <div class="panel-body">
		<div class="analysis-item row-fluid" id="cluster-ercoveryconf-report">
			<div class="span11">
				$output
			</div>
		</div>
	      </div>
	      </div>
	    </div>
	</div>
};

	%all_recovery_conf = ();

	&show_diff($fhcluster, %all_recovery_conf_diff);

	%all_recovery_conf_diff = ();

	$fhcluster->close();
}

# Show relevant content of postgresql.auto.conf
sub postgresql_auto_conf
{
	my ($in_dir, $file) = @_;

	%all_postgresql_auto_conf = ();

	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	while (my $l = <$curfh>) {
		chomp($l);
		$l =~ s/\r//;
		next if ($l !~ /^[a-z]/);
		$l =~ s/\s*#.*//;
		$all_postgresql_auto_conf{content} .= "$l\n";
	}
	$curfh->close();

	return if (!exists $all_postgresql_auto_conf{content});

	# Load change on configuration file from diff files
	&get_diff("$in_dir/$file.diff", \%all_postgresql_auto_conf_diff);

}

# Show relevant content of postgresql.auto.conf
sub postgresql_auto_conf_report
{
	my ($src_base, %data_info) = @_;

	my $output = $all_postgresql_auto_conf{content} || '';
	return if (!$output);

	if (!$output) {
		$output = '<div class="flotr-graph"><blockquote><b>NO DATASET</b></blockquote></div>';
	} else {
		$output = "<div style=\"white-space: pre\">\n$output</div>\n";
	}
	my $id = &get_data_id('cluster-alterconf', %data_info);
	my $fhcluster = &append_to_html_file("$OUTPUT_DIR/cluster-$data_info{$id}{name}.html", $src_base);
	print $fhcluster qq{
      <div id="cluster-alterconf"><br><br><br><br></div>
	<div class="row">
            <div class="col-md-12">
              <div class="panel panel-default">
              <div class="panel-heading">
		<h2>$data_info{$id}{menu}</h2>
		<p>$data_info{$id}{description}</p>
              </div>
              <div class="panel-body">
		<div class="analysis-item row-fluid" id="cluster-alterconf-report">
			<div class="span11">
				$output
			</div>
		</div>
	      </div>
	      </div>
	    </div>
	</div>
};

	%all_postgresql_auto_conf = ();

	&show_diff($fhcluster, %all_postgresql_auto_conf_diff);

	%all_postgresql_auto_conf_diff = ();

	$fhcluster->close();
}

# Get relevant content of pg_hba.conf
sub pg_hba_conf
{
	my ($in_dir, $file) = @_;

	%all_pg_hba_conf = ();

	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	while (my $l = <$curfh>) {
		chomp($l);
		$l =~ s/\r//;
		next if ($l !~ /^[a-z]/);
		$l =~ s/\s*#.*//;
		$all_pg_hba_conf{content} .= "$l\n";
	}
	$curfh->close();

	return if (!exists $all_pg_hba_conf{content});

	# Load change on configuration file from diff files
	&get_diff("$in_dir/$file.diff", \%all_pg_hba_conf_diff);

}

# Show content of pg_hba.conf
sub pg_hba_conf_report
{
	my ($src_base, %data_info) = @_;

	my $output = $all_pg_hba_conf{content} || '';
	return if (!$output);

	if (!$output) {
		$output = '<div class="flotr-graph"><blockquote><b>NO DATASET</b></blockquote></div>';
	} else {
		$output = "<div style=\"white-space: pre\">\n$output</div>\n";
	}

	my $id = &get_data_id('cluster-pghba', %data_info);
	my $fhcluster = &append_to_html_file("$OUTPUT_DIR/cluster-$data_info{$id}{name}.html", $src_base);
	print $fhcluster qq{
      <div id="cluster-pghba"><br><br><br><br></div>

	<div class="row">
            <div class="col-md-12">
              <div class="panel panel-default">
              <div class="panel-heading">
		<h2>$data_info{$id}{menu}</h2>
		<p>$data_info{$id}{description}</p>
              </div>
              <div class="panel-body">
		<div class="analysis-item row-fluid" id="cluster-pghba-report">
			<div class="span11">
				$output
			</div>
		</div>
	      </div>
	      </div>
	    </div>
	</div>
};

	%all_pg_hba_conf = ();

	&show_diff($fhcluster, %all_pg_hba_conf_diff);

	%all_pg_hba_conf_diff = ();

	$fhcluster->close();
}

# Get relevant content of pg_ident.conf
sub pg_ident_conf
{
	my ($in_dir, $file) = @_;

	%all_pg_ident_conf = ();

	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	while (my $l = <$curfh>) {
		chomp($l);
		$l =~ s/\r//;
		next if ($l !~ /^[a-z]/);
		$l =~ s/\s*#.*//;
		$all_pg_ident_conf{content} .= "$l\n";
	}
	$curfh->close();

	return if (!exists $all_pg_ident_conf{content});

	# Load change on configuration file from diff files
	&get_diff("$in_dir/$file.diff", \%all_pg_ident_conf_diff);

}

# Show content of pg_ident.conf
sub pg_ident_conf_report
{
	my ($src_base, %data_info) = @_;

	my $output = $all_pg_ident_conf{content} || '';
	return if (!$output);

	if (!$output) {
		$output = '<div class="flotr-graph"><blockquote><b>NO DATASET</b></blockquote></div>';
	} else {
		$output = "<div style=\"white-space: pre\">\n$output</div>\n";
	}
	my $id = &get_data_id('cluster-pgident', %data_info);
	my $fhcluster = &append_to_html_file("$OUTPUT_DIR/cluster-$data_info{$id}{name}.html", $src_base);
	print $fhcluster qq{
      <div id="cluster-pgident"><br><br><br><br></div>

	<div class="row">
            <div class="col-md-12">
              <div class="panel panel-default">
              <div class="panel-heading">
		<h2>$data_info{$id}{menu}</h2>
		<p>$data_info{$id}{description}</p>
              </div>
              <div class="panel-body">
		<div class="analysis-item row-fluid" id="cluster-pgident-report">
			<div class="span11">
				$output
			</div>
		</div>
	      </div>
	      </div>
	    </div>
	</div>
};

	%all_pg_ident_conf = ();

	&show_diff($fhcluster, %all_pg_ident_conf_diff);

	%all_pg_ident_conf_diff = ();

	$fhcluster->close();
}

# Get configuration from pg_settings
sub pg_settings
{
	my ($in_dir, $file) = @_;

	%all_settings = ();

	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	while (my $l = <$curfh>) {
		chomp($l);
		next if (!$l);
		my @data = split(/;/, $l);
		next if (!&normalize_line(\@data));

		# timestamp | label | setting | value | unit | context | source | boot_val | reset_val | pending_restart
		$all_settings{$data[1]}{$data[2]}{value} = $data[3];
		$all_settings{$data[1]}{$data[2]}{unit} = '';
		$all_settings{$data[1]}{$data[2]}{bootval} = '';
		$all_settings{$data[1]}{$data[2]}{resetval} = '';
		if ($#data >= 6) {
			$all_settings{$data[1]}{$data[2]}{unit} = $data[4];
			$all_settings{$data[1]}{$data[2]}{bootval} = $data[7];
			$all_settings{$data[1]}{$data[2]}{resetval} = $data[8];
			if ($#data >= 9) {
				$all_settings{$data[1]}{$data[2]}{pending_restart} = $data[9];
			}
		}
		if ($data[2] eq 'data_checksums') {
			$OVERALL_STATS{'cluster'}{'data_checksums'} = $data[3];
		}
	}
	$curfh->close();

	# Load change on pg_settings from diff file
	$file =~ s/\.csv/.diff/;
	&get_diff("$in_dir/$file", \%all_settings_diff);
}

# Show configuration from pg_settings
sub pg_settings_report
{
	my ($src_base, %data_info) = @_;

	return if (scalar keys %all_settings == 0);

	my $id = &get_data_id('cluster-settings', %data_info);
	my $fhcluster = &append_to_html_file("$OUTPUT_DIR/cluster-$data_info{$id}{name}.html", $src_base);
	print $fhcluster qq{
      <div id="cluster-settings"><br><br><br><br></div>

	<div class="row">
            <div class="col-md-12">
              <div class="panel panel-default">
              <div class="panel-heading">
		<h2>$data_info{$id}{menu}</h2>
		<p>$data_info{$id}{description}</p>
              </div>
              <div class="panel-body">
		<div class="analysis-item row-fluid" id="$data_info{$id}{name}-report">
			<div class="span11">
				<table class="table table-striped" id="$data_info{$id}{name}-table">
					<tbody>
};
	foreach my $lbl (sort keys %all_settings) {
		print $fhcluster "<tr><th colspan=\"5\">$lbl</th></tr>\n";
		print $fhcluster "<tr><th>Name</th><th>Current</th><th>Unit</th><th>Reset val</th><th>Boot val</th><th>Pending restart</th></tr>\n";
		foreach my $set (sort { lc($a) cmp lc($b) } keys %{$all_settings{$lbl}}) {
			print $fhcluster "<tr><td>$set</td><td>$all_settings{$lbl}{$set}{value}</td><td>$all_settings{$lbl}{$set}{unit}</td>";
			if ($all_settings{$lbl}{$set}{resetval}) {
				print $fhcluster "<td>$all_settings{$lbl}{$set}{resetval}</td>";
			} else {
				print $fhcluster "<td></td>";
			}
			if ($all_settings{$lbl}{$set}{bootval}) {
				print $fhcluster "<td>$all_settings{$lbl}{$set}{bootval}</td>";
			} else {
				print $fhcluster "<td></td>";
			}
			if (exists $all_settings{$lbl}{$set}{pending_restart}) {
				if ($all_settings{$lbl}{$set}{pending_restart} eq 't') {
					print $fhcluster "<td><b>$all_settings{$lbl}{$set}{pending_restart}</b></td>";
				} else {
					print $fhcluster "<td>$all_settings{$lbl}{$set}{pending_restart}</td>";
				}
			} else {
				print $fhcluster "<td>n/a</td>";
			}
			print $fhcluster "</tr>\n";
		}
	}
	print $fhcluster qq{
					</tbody>
				</table>
			</div>
		</div>
		</div>
	    </div>
	    </div>
	</div>
};
	%all_settings = ();

	&show_diff($fhcluster, %all_settings_diff);

	%all_settings_diff = ();

	$fhcluster->close();
}

# Get non default configuration from pg_settings
sub pg_nondefault_settings
{
	my ($in_dir, $file) = @_;

	%all_nondefault_settings = ();

	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	while (my $l = <$curfh>) {
		chomp($l);
		next if (!$l);
		my @data = split(/;/, $l);
		next if (!&normalize_line(\@data));

		# timestamp | label | setting | value
		$all_nondefault_settings{$data[1]}{$data[2]}{value} = $data[3];
		$all_nondefault_settings{$data[1]}{$data[2]}{unit} = '';
		$all_nondefault_settings{$data[1]}{$data[2]}{bootval} = '';
		$all_nondefault_settings{$data[1]}{$data[2]}{resetval} = '';
		if ($#data >= 6) {
			$all_nondefault_settings{$data[1]}{$data[2]}{unit} = $data[4];
			$all_nondefault_settings{$data[1]}{$data[2]}{bootval} = $data[7];
			$all_nondefault_settings{$data[1]}{$data[2]}{resetval} = $data[8];
		}
	}
	$curfh->close();
}

# Show non default configuration from pg_settings
sub pg_nondefault_settings_report
{
	my ($src_base, %data_info) = @_;

	return if (scalar keys %all_nondefault_settings == 0);

	my $id = &get_data_id('cluster-nondefault-settings', %data_info);
	my $fhcluster = &append_to_html_file("$OUTPUT_DIR/cluster-$data_info{$id}{name}.html", $src_base);
	print $fhcluster qq{
      <div id="cluster-nondefault-settings"><br><br><br><br></div>

	<div class="row">
            <div class="col-md-12">
              <div class="panel panel-default">
              <div class="panel-heading">
		<h2>$data_info{$id}{menu}</h2>
		<p>$data_info{$id}{description}</p>
              </div>
              <div class="panel-body">
		<div class="analysis-item row-fluid" id="$data_info{$id}{name}-report">
			<div class="span11">
				<table class="table table-striped" id="$data_info{$id}{name}-table">
					<tbody>
};
	foreach my $lbl (sort keys %all_nondefault_settings) {
		print $fhcluster "<tr><th colspan=\"5\">$lbl</th></tr>\n";
		print $fhcluster "<tr><th>Name</th><th>Current</th><th>Unit</th><th>Reset val</th><th>Boot val</th></tr>\n";
		foreach my $set (sort { lc($a) cmp lc($b) } keys %{$all_nondefault_settings{$lbl}}) {
			print $fhcluster "<tr><td>$set</td><td>$all_nondefault_settings{$lbl}{$set}{value}</td><td>$all_nondefault_settings{$lbl}{$set}{unit}</td>";
			if ($all_nondefault_settings{$lbl}{$set}{resetval}) {
				print $fhcluster "<td>$all_nondefault_settings{$lbl}{$set}{resetval}</td>";
			} else {
				print $fhcluster "<td></td>";
			}
			if ($all_nondefault_settings{$lbl}{$set}{bootval}) {
				print $fhcluster "<td>$all_nondefault_settings{$lbl}{$set}{bootval}</td>";
			} else {
				print $fhcluster "<td></td>";
			}
			print $fhcluster "</tr>\n";
		}
	}
	print $fhcluster qq{
					</tbody>
				</table>
			</div>
		</div>
		</div>
	    </div>
	    </div>
	</div>
};
	$fhcluster->close();
	%all_nondefault_settings = ();
}

# Get configuration from pg_db_role_setting
sub pg_db_role_setting
{
	my ($in_dir, $file) = @_;

	%all_db_role_setting = ();

	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	while (my $l = <$curfh>) {
		chomp($l);
		next if (!$l);
		my @data = split(/;/, $l);
		next if (!&normalize_line(\@data));

		# timestamp | database | role | settings
		$data[1] ||= 'All';
		$data[2] ||= 'All';
		$all_db_role_setting{$data[1]}{$data[2]} = $data[3];
	}
	$curfh->close();

	# Load change on pg_settings from diff file
	$file =~ s/\.csv/.diff/;
	&get_diff("$in_dir/$file", \%all_db_role_setting_diff);

}

# Show configuration from pg_db_role_setting
sub pg_db_role_setting_report
{
	my ($src_base, %data_info) = @_;

	return if (scalar keys %all_db_role_setting == 0);

	my $id = &get_data_id('cluster-dbrolesetting', %data_info);
	my $fhcluster = &append_to_html_file("$OUTPUT_DIR/cluster-$data_info{$id}{name}.html", $src_base);
	print $fhcluster qq{
      <div id="cluster-dbrolesetting"><br><br><br><br></div>

	<div class="row">
            <div class="col-md-12">
              <div class="panel panel-default">
              <div class="panel-heading">
		<h2>$data_info{$id}{menu}</h2>
		<p>$data_info{$id}{description}</p>
              </div>
              <div class="panel-body">
		<div class="analysis-item row-fluid" id="$data_info{$id}{name}-report">
			<div class="span11">
				<table class="table table-striped" id="$data_info{$id}{name}-table">
					<tbody>
};
	print $fhcluster "<tr><th>Database</th><th>Role</th><th>Settings</th></tr>\n";
	foreach my $lbl (sort keys %all_db_role_setting) {
		foreach my $set (sort { lc($a) cmp lc($b) } keys %{$all_db_role_setting{$lbl}}) {
			print $fhcluster "<tr><td>$lbl</td><td>$set</td><td>$all_db_role_setting{$lbl}{$set}</td></tr>\n";
		}
	}
	print $fhcluster qq{
					</tbody>
				</table>
			</div>
		</div>
		</div>
	    </div>
	    </div>
	</div>
};
	%all_db_role_setting = ();

	&show_diff($fhcluster, %all_db_role_setting_diff);

	%all_db_role_setting_diff = ();

	$fhcluster->close();
}

# Get configuration from pg_hba_files_rules
sub pg_hba_rules
{
	my ($in_dir, $file) = @_;

	%all_hba_rules = ();

	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	while (my $l = <$curfh>)
	{
		chomp($l);
		next if (!$l);
		my @data = split(/;/, $l);
		next if (!&normalize_line(\@data));

		# timestamp | type | database | user | address | netmask | auth_method | optuions | errors
		my $line = shift(@data);

		$all_hba_rules{$line} = join(' ', @data);;
	}
	$curfh->close();

	# Load change on pg_settings from diff file
	#$file =~ s/\.csv/.diff/;
	#&get_diff("$in_dir/$file", \%all_hba_rules_diff);
}

# Show configuration from pg_settings
sub pg_hba_rules_report
{
	my ($src_base, %data_info) = @_;

	return if (scalar keys %all_hba_rules == 0);

	my $id = &get_data_id('cluster-hba', %data_info);
	my $fhcluster = &append_to_html_file("$OUTPUT_DIR/cluster-$data_info{$id}{name}.html", $src_base);
	print $fhcluster qq{
      <div id="cluster-hba"><br><br><br><br></div>

	<div class="row">
            <div class="col-md-12">
              <div class="panel panel-default">
              <div class="panel-heading">
		<h2>$data_info{$id}{menu}</h2>
		<p>$data_info{$id}{description}</p>
              </div>
              <div class="panel-body">
		<div class="analysis-item row-fluid" id="$data_info{$id}{name}-report">
			<div class="span11">
				<table class="table table-striped" id="$data_info{$id}{name}-table">
					<tbody>
};
	print $fhcluster "<tr><th>Line</th><th>Rule</th></tr>\n";
	foreach my $line (sort {$a <=> $b} keys %all_hba_rules)
	{
		print $fhcluster "<tr><th>$line</th><th>$all_hba_rules{$line}</th></tr>\n";
	}
	print $fhcluster qq{
					</tbody>
				</table>
			</div>
		</div>
		</div>
	    </div>
	    </div>
	</div>
};
	%all_hba_rules = ();

	#&show_diff($fhcluster, %all_hba_rules_diff);

	#%all_hba_rules_diff = ();

	$fhcluster->close();
}

# Compute statistics of buffercache database
sub pg_database_buffercache
{
	my ($in_dir, $file, $offset) = @_;

	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	$curfh->seek($offset,0);
	while (my $l = <$curfh>) {
		$offset += length($l);
		my @data = split(/;/, $l);
		next if (!&normalize_line(\@data));

		# date_trunc | datname | buffers | buffered | buffers % | database %
		$all_database_buffercache{$data[0]}{$data[1]}{shared_buffers_used} = ($data[4]||0);
		$all_database_buffercache{$data[0]}{$data[1]}{database_loaded} = ($data[5]||0);
	}
	$curfh->close();

	return $offset || 0;
}

# Compute report of buffercache database statistics
sub pg_database_buffercache_report
{
	my ($src_base, %data_info) = @_;

	my %shared_stat = ();
	&set_cluster_total(\%all_database_buffercache, 'shared_buffers_used', 'database_loaded');
	foreach my $t (sort keys %all_database_buffercache) {
		foreach my $db (@global_databases) {
			$shared_stat{$db}{shared_buffers_used} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_database_buffercache{$t}{$db}{shared_buffers_used}||0) . '],';
			$shared_stat{$db}{database_loaded} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . ($all_database_buffercache{$t}{$db}{database_loaded}||0) . '],';
		}
	}
	%all_database_buffercache = ();
	foreach my $id (sort {$a <=> $b} keys %data_info) {
		next if (!grep(/^$data_info{$id}{name}$/, 'cluster-buffersused', 'cluster-databaseloaded'));
		my $fhcluster = &append_to_html_file("$OUTPUT_DIR/cluster-$data_info{$id}{name}.html", $src_base);
		if ($data_info{$id}{name} eq 'cluster-buffersused') {
			my @graph_data = ();
			foreach my $db (sort keys %shared_stat) {
				next if (($db ne 'all') && ($#INCLUDE_DB >= 0) && (!grep($db =~ /^$_$/, @INCLUDE_DB)));
				push(@{$data_info{$id}{legends}}, "$db");
				$shared_stat{$db}{shared_buffers_used} =~ s/,$//;
				push(@graph_data, $shared_stat{$db}{shared_buffers_used});
			}
			$fhcluster->print( &jqplot_linegraph_array($IDX++, 'cluster-buffersused', \%{$data_info{$id}}, '', @graph_data) );
		} elsif ($data_info{$id}{name} eq 'cluster-databaseloaded') {
			my @graph_data = ();
			foreach my $db (sort keys %shared_stat) {
				next if ($db eq 'all');
				next if (($db ne 'all') && ($#INCLUDE_DB >= 0) && (!grep($db =~ /^$_$/, @INCLUDE_DB)));
				push(@{$data_info{$id}{legends}}, $db);
				$shared_stat{$db}{database_loaded} =~ s/,$//;
				push(@graph_data, $shared_stat{$db}{database_loaded});
			}
			$fhcluster->print( &jqplot_linegraph_array($IDX++, 'cluster-databaseloaded', \%{$data_info{$id}}, '', @graph_data) );
		}
		$fhcluster->close();
	}
}

# Compute statistics of usagecount in shared buffers
sub pg_database_usagecount
{
	my ($in_dir, $file, $offset) = @_;

	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	$curfh->seek($offset,0);
	while (my $l = <$curfh>) {
		$offset += length($l);
		my @data = split(/;/, $l);
		next if (!&normalize_line(\@data));

		# date_trunc | datname | usagecount | buffer | buffers %
		$all_database_usagecount{$data[0]}{$data[2]} += ($data[4]||0);
	}
	$curfh->close();

	return $offset || 0;
}

# Compute graph of usagecount in shared buffers
sub pg_database_usagecount_report
{
	my ($src_base, %data_info) = @_;

	my %shared_stat = ();
	foreach my $t (sort keys %all_database_usagecount) {
		foreach my $u (sort keys %{$all_database_usagecount{$t}}) {
			$shared_stat{$u}{usagecount} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . $all_database_usagecount{$t}{$u} . '],';
		}
	}
	%all_database_usagecount = ();
	foreach my $id (sort {$a <=> $b} keys %data_info) {
		if ($data_info{$id}{name} eq 'cluster-usagecount') {
			my $fhcluster = &append_to_html_file("$OUTPUT_DIR/cluster-$data_info{$id}{name}.html", $src_base);
			my @graph_data = ();
			foreach my $u (sort keys %shared_stat) {
				push(@{$data_info{$id}{legends}}, "$u");
				$shared_stat{$u}{usagecount} =~ s/,$//;
				push(@graph_data, $shared_stat{$u}{usagecount});
			}
			$fhcluster->print( &jqplot_linegraph_array($IDX++, 'cluster-usagecount', \%{$data_info{$id}}, '', @graph_data) );
			$fhcluster->close();
		}
	}
}

# Compute statistics of dirty buffer in cache
sub pg_database_isdirty
{
	my ($in_dir, $file, $offset) = @_;

	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	$curfh->seek($offset,0);
	while (my $l = <$curfh>) {
		$offset += length($l);
		my @data = split(/;/, $l);
		next if (!&normalize_line(\@data));

		# date_trunc | datname | usagecount | isdirty | buffer | buffers %
		$all_database_isdirty{$data[0]}{$data[2]} += $data[5] if ($data[3] eq 't');
	}
	$curfh->close();

	return $offset || 0;
}

# Compute graphs of dirty buffer in cache
sub pg_database_isdirty_report
{
	my ($src_base, %data_info) = @_;

	my %shared_stat = ();
	foreach my $t (sort keys %all_database_isdirty) {
		foreach my $u (sort keys %{$all_database_isdirty{$t}}) {
			$shared_stat{$u}{usagecount} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . $all_database_isdirty{$t}{$u} . '],';
		}
	}
	%all_database_isdirty = ();
	foreach my $id (sort {$a <=> $b} keys %data_info) {
		if ($data_info{$id}{name} eq 'cluster-isdirty') {
			my $fhcluster = &append_to_html_file("$OUTPUT_DIR/cluster-$data_info{$id}{name}.html", $src_base);
			my @graph_data = ();
			foreach my $u (sort keys %shared_stat) {
				push(@{$data_info{$id}{legends}}, "$u");
				$shared_stat{$u}{usagecount} =~ s/,$//;
				push(@graph_data, $shared_stat{$u}{usagecount});
			}
			$fhcluster->print( &jqplot_linegraph_array($IDX++, 'cluster-isdirty', \%{$data_info{$id}}, '', @graph_data) );
			$fhcluster->close();
		}
	}
}

# Compute statistics of archiver
sub pg_stat_archiver
{
	my ($in_dir, $file, $offset) = @_;

	my @start_vals = ();
	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	$curfh->seek($offset,0);
	while (my $l = <$curfh>) {
		$offset += length($l);
		my @data = split(/;/, $l);
		next if (!&normalize_line(\@data));

		# timestamp | archived_count | last_archived_wal | last_archived_time | failed_count | last_failed_wal | last_failed_time | stats_reset
                push(@start_vals, @data) if ($#start_vals < 0);

		# Get archiver size statistics
		my $tmp_val = '';
                if (($data[1] - $start_vals[1]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[1] - $start_vals[1]) };
		$all_stat_archiver{$data[0]}{archived_count} = $tmp_val;
                if (($data[4] - $start_vals[4]) < 0) { $tmp_val = 0 } else { $tmp_val = ($data[4] - $start_vals[4]) };
		$all_stat_archiver{$data[0]}{failed_count} = $tmp_val;
		$all_stat_archiver{$data[0]}{last_archived_wal} = $data[2];
		$data[3] =~ s/\..*//;
		$all_stat_archiver{$data[0]}{last_archived_time} = $data[3];
		$all_stat_archiver{$data[0]}{last_failed_wal} = $data[5];
		$data[6] =~ s/\..*//;
		$all_stat_archiver{$data[0]}{last_failed_time} = $data[6];
		$data[7] =~ s/\..*//;
		$all_stat_archiver{$data[0]}{stats_reset} = $data[7];

		@start_vals = ();
		push(@start_vals, @data);
	}
	$curfh->close();

	return $offset || 0;
}

# Compute graphs of archiver statistics
sub pg_stat_archiver_report
{
	my ($src_base, %data_info) = @_;

	my %archiver_stat = ();
	foreach my $t (sort {$a <=> $b} keys %all_stat_archiver) {
		$archiver_stat{archived_count} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . $all_stat_archiver{$t}{archived_count}. '],';
		$archiver_stat{failed_count} .= '[' . ($t - ($STATS_TIMEZONE*3600*1000)) . ',' . $all_stat_archiver{$t}{failed_count}. '],';
		if (!$OVERALL_STATS{'archiver'}{last_archived_time} || ($all_stat_archiver{$t}{last_archived_time} gt $OVERALL_STATS{'archiver'}{last_archived_time})) {
			$OVERALL_STATS{'archiver'}{last_archived_wal} = $all_stat_archiver{$t}{last_archived_wal};
			$OVERALL_STATS{'archiver'}{last_archived_time} = $all_stat_archiver{$t}{last_archived_time};
		}
		if (!$OVERALL_STATS{'archiver'}{last_failed_time} || ($all_stat_archiver{$t}{last_failed_time} gt $OVERALL_STATS{'archiver'}{last_failed_time})) {
			$OVERALL_STATS{'archiver'}{last_failed_wal} = $all_stat_archiver{$t}{last_failed_wal};
			$OVERALL_STATS{'archiver'}{last_failed_time} = $all_stat_archiver{$t}{last_failed_time};
		}
		if (!$OVERALL_STATS{'archiver'}{stats_reset} || ($all_stat_archiver{$t}{stats_reset} gt $OVERALL_STATS{'archiver'}{stats_reset})) {
			$OVERALL_STATS{'archiver'}{stats_reset} = $all_stat_archiver{$t}{stats_reset};
		}

	}
	%all_stat_archiver = ();
	foreach my $id (sort {$a <=> $b} keys %data_info) {
		if ($data_info{$id}{name} eq 'cluster-archive') {
			my $fhcluster = &append_to_html_file("$OUTPUT_DIR/$data_info{$id}{name}.html", $src_base);
			print $fhcluster &jqplot_linegraph_array($IDX++, 'cluster-archive', \%{$data_info{$id}}, '', $archiver_stat{archived_count}, $archiver_stat{failed_count});
			$fhcluster->close();
		}
	}
}

# Compute statistics of replication slots
sub pg_replication_slots
{
	my ($in_dir, $file, $offset) = @_;

	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	$curfh->seek($offset,0);
	while (my $l = <$curfh>)
	{
		$offset += length($l);
		my @data = split(/;/, $l);
		next if (!&normalize_line(\@data));

		# timestamp | slot_name | plugin | slot_type | database | active
		# timestamp | slot_name | plugin | slot_type | database | active | wal_status | safe_wal_size | inactive_since | conflicting | invalidation_reason | failover | synced

		# Get replication slot statistics
		push(@all_stat_slots, $data[1] || '');
		push(@all_stat_slots, $data[2] || '');
		push(@all_stat_slots, $data[3] || '');
		push(@all_stat_slots, $data[4] || '');
		push(@all_stat_slots, $data[5] || '');
		if ($#data > 5)
		{
			push(@all_stat_slots, $data[6] || '');
			push(@all_stat_slots, $data[7] || '');
			push(@all_stat_slots, $data[8] || '');
			push(@all_stat_slots, $data[9] || '');
			push(@all_stat_slots, $data[10] || '');
			push(@all_stat_slots, $data[11] || '');
			push(@all_stat_slots, $data[12] || '');
		}
		else
		{
			push(@all_stat_slots, '', '', '', '', '', '', '');
		}
	}
	$curfh->close();

	return $offset || 0;
}

# Compute graphs of statements statistics
sub pg_stat_statements
{
	my ($in_dir, $file) = @_;

	my $total_val = 0;
	my @start_vals = ();
	my $has_temp = 0;

	%all_stat_statements = ();

	# Load data from file
	my $curfh = open_filehdl("$in_dir/$file");
	while (my $l = <$curfh>) {
		chomp($l);
		next if (!$l);
		my @data = split(/;/, $l);
		next if (!&normalize_line(\@data));

		next if (($#INCLUDE_DB >= 0) && (!grep($data[2] =~ /^$_$/, @INCLUDE_DB)));

		# pg 8.4
		# timestamp | userid | datname | query | calls | total_time | rows
		# pg 9.0-9.1
		# timestamp | userid | datname | query | calls | total_time | rows | shared_blks_hit | shared_blks_read | shared_blks_written | local_blks_hit | local_blks_read | local_blks_written | temp_blks_read | temp_blks_written
		# pg 9.2+
		# timestamp | userid | datname | query | calls | total_time | rows | shared_blks_hit | shared_blks_read | shared_blks_dirtied | shared_blks_written | local_blks_hit | local_blks_read | local_blks_dirtied | local_blks_written | temp_blks_read | temp_blks_written | blk_read_time | blk_write_time |
		# pg 17.0
		# timestamp | userid | datname | query | calls | total_time | rows | shared_blks_hit | shared_blks_read | shared_blks_dirtied | shared_blks_written | local_blks_hit | local_blks_read | local_blks_dirtied | local_blks_written | temp_blks_read | temp_blks_written | shared_blk_read_time | shared_blk_write_time |

		my $id = 3;
		#$id++ if ($#data == 20);
		next if (!$data[$id]);

		$all_stat_statements{$data[2]}{$data[$id]}{calls} = ($data[$id+1] || 0);
		$all_stat_statements{$data[2]}{$data[$id]}{total_time} = ($data[$id+2] || 0);
		$all_stat_statements{$data[2]}{$data[$id]}{rows} = ($data[$id+3] || 0);
		if ($#data > 6) {
			$all_stat_statements{$data[2]}{$data[$id]}{shared_blks_hit} = $data[$id+4];
			$all_stat_statements{$data[2]}{$data[$id]}{shared_blks_read} = $data[$id+5];
			if ($#data < 18) {
				$all_stat_statements{$data[2]}{$data[$id]}{shared_blks_written} = $data[$id+6];
				$all_stat_statements{$data[2]}{$data[$id]}{local_blks_hit} = $data[$id+7];
				$all_stat_statements{$data[2]}{$data[$id]}{local_blks_read} = $data[$id+8];
				$all_stat_statements{$data[2]}{$data[$id]}{local_blks_written} = $data[$id+9];
				$all_stat_statements{$data[2]}{$data[$id]}{temp_blks_read} = $data[$id+10];
				$all_stat_statements{$data[2]}{$data[$id]}{temp_blks_written} = $data[$id+11];
				# This is just a flag, the total_time key is not used but must exists to not generate
				# error on use of unitialised value later. This is ugly but useful
				$all_stat_statements{$data[2]}{has_temp}{total_time} = 1;
			} else {
				$all_stat_statements{$data[2]}{$data[$id]}{shared_blks_dirtied} = ($data[$id+6]*8192);
				$all_stat_statements{$data[2]}{$data[$id]}{shared_blks_written} = $data[$id+7];
				$all_stat_statements{$data[2]}{$data[$id]}{local_blks_hit} = $data[$id+8];
				$all_stat_statements{$data[2]}{$data[$id]}{local_blks_read} = $data[$id+9];
				$all_stat_statements{$data[2]}{$data[$id]}{local_blks_dirtied} = $data[$id+10];
				$all_stat_statements{$data[2]}{$data[$id]}{local_blks_written} = $data[$id+11];
				$all_stat_statements{$data[2]}{$data[$id]}{temp_blks_read} = ($data[$id+12]*8192);
				$all_stat_statements{$data[2]}{$data[$id]}{temp_blks_written} = ($data[$id+13]*8192);
				$all_stat_statements{$data[2]}{$data[$id]}{shared_blk_read_time} = $data[$id+14];
				$all_stat_statements{$data[2]}{$data[$id]}{shared_blk_write_time} = $data[$id+15];
				# This is just a flag, the total_time key is not used but must exists to not generate
				# error on use of unitialised value later. This is ugly but useful
				$all_stat_statements{$data[2]}{has_temp}{total_time} = 2;
				if ($data[$id+14] || $data[$id+15]) {
					$all_stat_statements{$data[2]}{has_temp}{total_time} = 3;
				}
			}
		}

	}
	$curfh->close();
}

# Compute graphs of statements statistics
sub pg_stat_statements_report
{
	my ($src_base, %data_info) = @_;

	my $id = &get_data_id('database-queries', %data_info);
	foreach my $db (keys %all_stat_statements)
	{
		next if (($db ne 'all') && ($#INCLUDE_DB >= 0) && (!grep($db =~ /^$_$/, @INCLUDE_DB)));
		my $header = '';
		if (exists $all_stat_statements{$db}{has_temp}) {
			$header = qq{<th>Temp blocks written</th>};
		}
		if ($all_stat_statements{$db}{has_temp}{total_time} >= 2) {
			$header .= qq{<th>Blocks read</th><th>Blocks hit</th><th>Blocks dirtied</th><th>Blocks written</th>};
		}
		if ($all_stat_statements{$db}{has_temp}{total_time} == 3) {
			$header .= qq{<th>I/O time</th>};
		}
		my $dbfh = &append_to_html_file("$OUTPUT_DIR/database-queries-$db.html", $src_base);
		$dbfh->print (qq{
<li class="slide" id="database-queries-slide">
<div id="database-queries"><br/><br/><br/><br/></div>

<div class="row">
    <div class="col-md-12">
      <div class="panel panel-default">
      <div class="panel-heading">
	<h2>$data_info{$id}{menu} on $db database</h2>
	<p>$data_info{$id}{description}</p>
      </div>
      <div class="panel-body">
	<div class="analysis-item row-fluid" id="$db-$data_info{$id}{name}">
		<div class="span11">
			<table class="table table-striped sortable" id="$db-$data_info{$id}{name}-table">
				<thead>
					<tr>
					<th>Calls</th>
					<th>Avg time</th>
					<th>Total time</th>
					<th>Rows</th>
					$header
					<th>Query</th>
					</tr>
				</thead>
				<tbody>
});
			foreach my $q (sort {$all_stat_statements{$db}{$b}{total_time} <=> $all_stat_statements{$db}{$a}{total_time}} keys %{$all_stat_statements{$db}}) {
				next if ($q eq 'has_temp');
				my $additional_cols = '';
				if (exists $all_stat_statements{$db}{has_temp}) {
					$additional_cols = "<td>" .  &pretty_print_number($all_stat_statements{$db}{$q}{temp_blks_written}) . "</td>";
				}
				if ($all_stat_statements{$db}{has_temp}{total_time} >= 2) {
					$additional_cols .= "<td>" . &pretty_print_number($all_stat_statements{$db}{$q}{shared_blks_read}) . "</td><td>" . &pretty_print_number($all_stat_statements{$db}{$q}{shared_blks_hit}) . "</td><td>" . &pretty_print_number($all_stat_statements{$db}{$q}{shared_blks_dirtied}) . "</td><td>" . &pretty_print_number($all_stat_statements{$db}{$q}{shared_blks_written}) . "</td>";
				}
				if ($all_stat_statements{$db}{has_temp}{total_time} == 3) {
					$additional_cols .= "<td>" . sprintf("%0.2d", ($all_stat_statements{$db}{$q}{shared_blk_read_time}+$all_stat_statements{$db}{$q}{shared_blk_write_time})/($all_stat_statements{$db}{$q}{calls}||1)) . "</td>";
				}
				my $query = $q;
				$query =~ s/#SMCLN#/;/g;
				$dbfh->print( "<tr><td>$all_stat_statements{$db}{$q}{calls}</td><td>" . &format_duration(int($all_stat_statements{$db}{$q}{total_time}/($all_stat_statements{$db}{$q}{calls}||1))) . "</td><td>" . &format_duration($all_stat_statements{$db}{$q}{total_time}) . "</td><td>$all_stat_statements{$db}{$q}{rows}</td>$additional_cols<th>$query</th></tr>\n");
			}
			$dbfh->print( qq{
				</tbody>
			</table>
		</div>
	</div>
	</div>
    </div>
</div>
</div>
</li>
});
		$dbfh->close();
	}
	%all_stat_statements = ();

}

####
# Set the cluster wide total ('all') of a statistic for each timestamp as
# the sum of the per database values. It must be computed when the report
# is built, not when the csv lines are read: a line read twice (csv file
# read again over the cache, overlapping runs of pgcluu -C) or two lines
# with the same timestamp only overwrite the per database value but were
# summed twice in the total. Any 'all' value coming from an old cache file
# is replaced.
#
# The hash is indexed by timestamp then by database name (or tablespace).
# With a list of fields, the per database values are hashes of these fields;
# a field written 'name:max' gets the highest value instead of the sum.
####
sub set_cluster_total
{
	my ($stats, @fields) = @_;

	foreach my $t (keys %{$stats})
	{
		my %total = ();
		foreach my $db (keys %{$stats->{$t}})
		{
			next if ($db eq 'all');
			if ($#fields < 0) {
				$total{''} += ($stats->{$t}{$db} || 0);
			} else {
				&add_to_total(\%total, $stats->{$t}{$db}, @fields);
			}
		}
		if ($#fields < 0) {
			$stats->{$t}{'all'} = $total{''} || 0;
		} else {
			$stats->{$t}{'all'} = \%total;
		}
	}
}

####
# Same as set_cluster_total() for a hash indexed by database name then by
# timestamp, the per database values are hashes of the given fields.
####
sub set_cluster_total_by_db
{
	my ($stats, @fields) = @_;

	my %total = ();
	foreach my $db (keys %{$stats})
	{
		next if ($db eq 'all');
		foreach my $t (keys %{$stats->{$db}}) {
			$total{$t} //= {};
			&add_to_total($total{$t}, $stats->{$db}{$t}, @fields);
		}
	}
	if (scalar keys %total) {
		$stats->{'all'} = \%total;
	} else {
		delete $stats->{'all'};
	}
}

# Add the fields of a per database value to a total
sub add_to_total
{
	my ($total, $val, @fields) = @_;

	foreach my $field (@fields)
	{
		my ($f, $agg) = split(/:/, $field);
		$total->{$f} //= 0;
		if (($agg || '') eq 'max') {
			$total->{$f} = $val->{$f} if (($val->{$f} || 0) > $total->{$f});
		} else {
			$total->{$f} += ($val->{$f} || 0);
		}
	}
}

sub normalize_line
{
	my $data = shift;

	# Get position of the database name
	my $pos  = shift;
	$pos ||= 2;

	return 0 if ($data->[0] !~ /^\d+/);

	$data->[0] = &convert_time($data->[0]);

	# Skip unwanted lines
	return 0 if ($BEGIN && ($data->[0] < $BEGIN));
	return 0 if ($END   && ($data->[0] > $END));

	chomp($data->[-1]);
	map { s/,/\./g; s/^$/0/; } @$data;

	# Always skip default template database
	return 0 if ($data->[$pos] =~ /template/);

	return 1;
}

####
# Format a value of the POSTMASTER section of sysinfo.txt for display
####
sub format_postmaster_value
{
	my ($key, $val) = @_;

	# Values above 2^62 are the cgroup v1 way to say no limit
	return 'unlimited' if ($val eq 'max' || $val eq '-1' || ($val =~ /^\d+$/ && $val >= 2**62));
	if ($key =~ /^memory\.(max|high|swap\.max|limit_in_bytes|memsw\.limit_in_bytes)$/) {
		return &pretty_print_size($val) if ($val =~ /^\d+$/);
	} elsif ($key eq 'limit locked memory') {
		return join(' / ', map { /^\d+$/ ? &pretty_print_size($_) : $_ } split(/\s*\/\s*/, $val));
	} elsif ($key eq 'cpu.max') {
		my ($quota, $period) = split(/\s+/, $val);
		return 'unlimited' if ($quota eq 'max');
		return sprintf("%.2f CPUs", $quota/$period) if ($period);
	} elsif ($key =~ /^limit (open files|processes)$/) {
		$val =~ s/unlimited/-/g;
	}
	return $val;
}

# Return the html list of the postmaster limits
sub postmaster_info_html
{
	return '' if (!exists $sysinfo{POSTMASTER} || $#{$sysinfo{POSTMASTER}} < 0);

	my %tips = (
		'oom_score_adj' => 'Should be -1000 for the postmaster so that it is not chosen by the OOM killer, see PG_OOM_ADJUST_FILE',
		'limit open files' => 'Soft / hard limits, compare with max_files_per_process * max_connections',
		'limit processes' => 'Soft / hard limits, compare with max_connections and the background workers',
	);
	my $html = qq{
                <span class="figure-label"><b>postmaster process limits</b></span>
                <ul>
                <li></li>
};
	foreach my $r (@{$sysinfo{POSTMASTER}})
	{
		my ($k, $v) = @{$r};
		my $val = &format_postmaster_value($k, $v);
		my $tip = $tips{$k} || $k;
		$html .= qq{\t\t<li><span class="figure-label" data-toggle="tooltip" data-placement="top" title="$tip">$k</span> <span class="figure">$val</span></li>\n};
	}
	$html .= "\t\t</ul>\n";

	return $html;
}

sub pretty_print_size
{
        my $val = shift;
        return 0 if (!$val || $val eq '-');

        if ($val >= 1125899906842624) {
                $val = ($val / 1125899906842624);
                $val = sprintf("%0.2f", $val) . " PB";
        } elsif ($val >= 1099511627776) {
                $val = ($val / 1099511627776);
                $val = sprintf("%0.2f", $val) . " TB";
        } elsif ($val >= 1073741824) {
                $val = ($val / 1073741824);
                $val = sprintf("%0.2f", $val) . " GB";
        } elsif ($val >= 1048576) {
                $val = ($val / 1048576);
                $val = sprintf("%0.2f", $val) . " MB";
        } elsif ($val >= 1024) {
                $val = ($val / 1024);
                $val = sprintf("%0.2f", $val) . " KB";
        } else {
                $val = $val . " B";
        }

        return $val;
}

sub pretty_print_number
{
        my $val = shift;
        return 0 if (!$val);

	if ($val >= 1000000000000000) {
		$val = ($val / 1000000000000000);
		$val = sprintf("%0.2f", $val) . " P";
	} elsif ($val >= 1000000000000) {
		$val = ($val / 1000000000000);
		$val = sprintf("%0.2f", $val) . " T";
	} elsif ($val >= 1000000000) {
		$val = ($val / 1000000000);
		$val = sprintf("%0.2f", $val) . " G";
	} elsif ($val >= 1000000) {
		$val = ($val / 1000000);
		$val = sprintf("%0.2f", $val) . " M";
	} elsif ($val >= 1000) {
		$val = ($val / 1000);
		$val = sprintf("%0.2f", $val) . " K";
	}

	return $val;
}

sub generate_html_index
{
	my $in_dir = shift;
	my $src_base = shift;

	my $fh = IO::File->new("$OUTPUT_DIR/index.html", 'w');
	if (not defined $fh) {
		die "FATAL: can't write to $OUTPUT_DIR/index.html, $!\n";
	}

	&html_header($fh, $src_base);

	# Compute global statistics for home page dashboard
	my %overall_stat_databases = ();
	if ($sysinfo{CONFIGURATION}{'capture'} || exists $OVERALL_STATS{'cluster'}) {
		$OVERALL_STATS{'cluster'}{'blks_hit'} ||= 0;
		$OVERALL_STATS{'cluster'}{'blks_read'} ||= 0;
		$OVERALL_STATS{'cluster'}{'cache_ratio'} = sprintf("%3d", ($OVERALL_STATS{'cluster'}{'blks_hit'} * 100) / (($OVERALL_STATS{'cluster'}{'blks_read'} + $OVERALL_STATS{'cluster'}{'blks_hit'}) || 1)) . "%";
		$OVERALL_STATS{'cluster'}{'temp_bytes'} = &pretty_print_size($OVERALL_STATS{'cluster'}{'temp_bytes'});
		foreach my $db (keys %{$OVERALL_STATS{'database'}}) {
			next if ($db eq 'all');
			$OVERALL_STATS{'database'}{$db}{'blks_hit'} ||= 0;
			$OVERALL_STATS{'database'}{$db}{'blks_read'} ||= 0;
			$OVERALL_STATS{'database'}{$db}{'blks_hit'} ||= 0;
			$OVERALL_STATS{'database'}{$db}{'cache_ratio'} = sprintf("%3d", ($OVERALL_STATS{'database'}{$db}{'blks_hit'} * 100) / (($OVERALL_STATS{'database'}{$db}{'blks_read'} + $OVERALL_STATS{'database'}{$db}{'blks_hit'}) || 1));
		}
		foreach my $db (keys %{$OVERALL_STATS{'database'}}) {
			next if ($db eq 'all' || !$db);
			$OVERALL_STATS{'cluster'}{'size'} += ($OVERALL_STATS{'database'}{$db}{'size'}||0);
			next if (($db ne 'all') && ($#INCLUDE_DB >= 0) && (!grep($db =~ /^$_$/, @INCLUDE_DB)));
			if (exists $OVERALL_STATS{'database'}{$db}{'size'}) {
				if (!exists $overall_stat_databases{'size'} || ($OVERALL_STATS{'database'}{$db}{'size'}||0) > ($overall_stat_databases{'size'}[1]||0)) {
					@{$overall_stat_databases{'size'}} = ($db, $OVERALL_STATS{'database'}{$db}{'size'});
				}
			}
			if (exists $OVERALL_STATS{'database'}{$db}{'nbackend'}) {
				if (!exists $overall_stat_databases{'nbackend'} || ($OVERALL_STATS{'database'}{$db}{'nbackend'} > $overall_stat_databases{'nbackend'}[1])) {
					@{$overall_stat_databases{'nbackend'}} = ($db, $OVERALL_STATS{'database'}{$db}{'nbackend'});
				}
			}
			if (exists $OVERALL_STATS{'database'}{$db}{'returned'}) {
				if (!exists $overall_stat_databases{'returned'} || $OVERALL_STATS{'database'}{$db}{'returned'} > $overall_stat_databases{'returned'}[1]) {
					@{$overall_stat_databases{'returned'}} = ($db, $OVERALL_STATS{'database'}{$db}{'returned'});
				}
			}
			if (exists $OVERALL_STATS{'database'}{$db}{'temp_files'}) {
				if (!exists $overall_stat_databases{'temp_files'} || $OVERALL_STATS{'database'}{$db} {'temp_files'} > $overall_stat_databases{'temp_files'}[1]) {
					@{$overall_stat_databases{'temp_files'}} = ($db, $OVERALL_STATS{'database'}{$db}{'temp_files'});
				}
			}
			if (exists $OVERALL_STATS{'database'}{$db}{'temp_bytes'}) {
				if (!exists $overall_stat_databases{'temp_bytes'} || $OVERALL_STATS{'database'}{$db}{'temp_bytes'} > $overall_stat_databases{'temp_bytes'}[1]) {
					@{$overall_stat_databases{'temp_bytes'}} = ($db, $OVERALL_STATS{'database'}{$db}{'temp_bytes'});
				}
			}
			if (exists $OVERALL_STATS{'database'}{$db}{'deadlocks'}) {
				if (!exists $overall_stat_databases{'deadlocks'} || $OVERALL_STATS{'database'}{$db}{'deadlocks'} > $overall_stat_databases{'deadlocks'}[1]) {
					@{$overall_stat_databases{'deadlocks'}} = ($db, $OVERALL_STATS{'database'}{$db}{'deadlocks'});
				}
			}
			if (exists $OVERALL_STATS{'database'}{$db}{'cache_ratio'}) {
				if (!exists $overall_stat_databases{'cache_ratio'} || $OVERALL_STATS{'database'}{$db}{'cache_ratio'} < $overall_stat_databases{'cache_ratio'}[1]) {
					@{$overall_stat_databases{'cache_ratio'}} = ($db, $OVERALL_STATS{'database'}{$db}{'cache_ratio'});
				}
			}
		}
		@{$overall_stat_databases{'size'}} = ('unknown', 0) if (!exists $overall_stat_databases{'size'});
		if (exists $overall_stat_databases{'size'}) {
			$overall_stat_databases{'size'}[1] = &pretty_print_size($overall_stat_databases{'size'}[1]);
		}
		if (exists $overall_stat_databases{'temp_bytes'}) {
			$overall_stat_databases{'temp_bytes'}[1] = &pretty_print_size($overall_stat_databases{'temp_bytes'}[1]);
		}
	}

	my %overall_system_stats = ();
	if (!$DISABLE_SAR) {
		if (!exists $OVERALL_STATS{'system'}{'cpu'}) {
			@{$OVERALL_STATS{'system'}{'cpu'}} = ('unknown', 0);
		} elsif (${$OVERALL_STATS{'system'}{'cpu'}}[0] !~ /\D/) {
			${$OVERALL_STATS{'system'}{'cpu'}}[0] = localtime(${$OVERALL_STATS{'system'}{'cpu'}}[0]/1000);
		}
		if (!exists $OVERALL_STATS{'system'}{'load'}) {
			@{$OVERALL_STATS{'system'}{'load'}} = ('unknown', 0);
		} elsif (${$OVERALL_STATS{'system'}{'load'}}[0] !~ /\D/) {
			${$OVERALL_STATS{'system'}{'load'}}[0] = localtime(${$OVERALL_STATS{'system'}{'load'}}[0]/1000);
		}
		if (!exists $OVERALL_STATS{'system'}{'blocked'}) {
			@{$OVERALL_STATS{'system'}{'blocked'}} = ('unknown', 0);
		} elsif (${$OVERALL_STATS{'system'}{'blocked'}}[0] !~ /\D/) {
			${$OVERALL_STATS{'system'}{'blocked'}}[0] = localtime(${$OVERALL_STATS{'system'}{'blocked'}}[0]/1000);
		}
		if (!exists $OVERALL_STATS{'system'}{'kbcached'}) {
			@{$OVERALL_STATS{'system'}{'kbcached'}} = ('unknown', 0);
		} elsif (${$OVERALL_STATS{'system'}{'kbcached'}}[0] !~ /\D/) {
			${$OVERALL_STATS{'system'}{'kbcached'}}[0] = localtime(${$OVERALL_STATS{'system'}{'kbcached'}}[0]/1000);
		}
		if (!exists $OVERALL_STATS{'system'}{'kbdirty'}) {
			@{$OVERALL_STATS{'system'}{'kbdirty'}} = ('unknown', 0);
		} elsif (${$OVERALL_STATS{'system'}{'kbdirty'}}[0] !~ /\D/) {
			${$OVERALL_STATS{'system'}{'kbdirty'}}[0] = localtime(${$OVERALL_STATS{'system'}{'kbdirty'}}[0]/1000);
		}
		if (!exists $OVERALL_STATS{'system'}{'bread'}) {
			@{$OVERALL_STATS{'system'}{'bread'}} = ('unknown', 0);
		} elsif (${$OVERALL_STATS{'system'}{'bread'}}[0] !~ /\D/) {
			${$OVERALL_STATS{'system'}{'bread'}}[0] = localtime(${$OVERALL_STATS{'system'}{'bread'}}[0]/1000);
		}
		if (!exists $OVERALL_STATS{'system'}{'bwrite'}) {
			@{$OVERALL_STATS{'system'}{'bwrite'}} = ('unknown', 0);
		} elsif (${$OVERALL_STATS{'system'}{'bwrite'}}[0] !~ /\D/) {
			${$OVERALL_STATS{'system'}{'bwrite'}}[0] = localtime(${$OVERALL_STATS{'system'}{'bwrite'}}[0]/1000);
		}

		if (!$SAR_UPPER_12_1_1)  # Service time (disappears in 12.1.2)
		{
			if (!exists $OVERALL_STATS{'system'}{'svctm'}) {
				@{$OVERALL_STATS{'system'}{'svctm'}} = ('unknown', 0, 'unknown');
			} elsif (${$OVERALL_STATS{'system'}{'svctm'}}[0] !~ /\D/) {
				${$OVERALL_STATS{'system'}{'svctm'}}[0] = localtime(${$OVERALL_STATS{'system'}{'svctm'}}[0]/1000);
			}
		}
		if (!exists $OVERALL_STATS{'system'}{'await'}) {
			@{$OVERALL_STATS{'system'}{'await'}} = ('unknown', 0, 'unknown');
		} elsif (${$OVERALL_STATS{'system'}{'await'}}[0] !~ /\D/) {
			${$OVERALL_STATS{'system'}{'await'}}[0] = localtime(${$OVERALL_STATS{'system'}{'await'}}[0]/1000);
		}

		if (exists $OVERALL_STATS{'system'}{'devices'})
		{
			foreach my $d (sort keys %{$OVERALL_STATS{'system'}{'devices'}}) {
				if (exists $OVERALL_STATS{'system'}{'devices'}{$d}{read}) {
					if (! exists $overall_system_stats{read} || ($overall_system_stats{read}[1] < $OVERALL_STATS{'system'}{'devices'}{$d}{read})) {
						@{$overall_system_stats{read}} = ($d, $OVERALL_STATS{'system'}{'devices'}{$d}{read});
					}
					if (! exists $overall_system_stats{write} || ($overall_system_stats{write}[1] < $OVERALL_STATS{'system'}{'devices'}{$d}{write})) {
						@{$overall_system_stats{write}} = ($d, $OVERALL_STATS{'system'}{'devices'}{$d}{write});
					}
					if (! exists $overall_system_stats{tps} || ($overall_system_stats{tps}[1] < $OVERALL_STATS{'system'}{'devices'}{$d}{tps})) {
						@{$overall_system_stats{tps}} = ($d, $OVERALL_STATS{'system'}{'devices'}{$d}{tps});
					}
				}
			}
		}

		if (exists $OVERALL_STATS{'system'}{'space'}) {
			foreach my $d (sort keys %{$OVERALL_STATS{'system'}{'space'}}) {
				if (! exists $overall_system_stats{'fsused'} || ($overall_system_stats{'fsused'}[1] < $OVERALL_STATS{'system'}{'space'}{$d}{'fsused'})) {
					@{$overall_system_stats{'fsused'}} = ($d, $OVERALL_STATS{'system'}{'space'}{$d}{'fsused'});
				}
				if (! exists $overall_system_stats{'iused'} || ($overall_system_stats{'iused'}[1] < $OVERALL_STATS{'system'}{'space'}{$d}{'iused'})) {
					@{$overall_system_stats{'iused'}} = ($d, $OVERALL_STATS{'system'}{'space'}{$d}{'iused'});
				}
			}
		}

		if (!exists $overall_system_stats{read}) {
			@{$overall_system_stats{read}} = ('unknown', 0);
		}
		if (!exists $overall_system_stats{write}) {
			@{$overall_system_stats{write}} = ('unknown', 0);
		}
		if (!exists $overall_system_stats{tps}) {
			@{$overall_system_stats{tps}} = ('unknown', 0);
		}
		if (!exists $overall_system_stats{fsused}) {
			@{$overall_system_stats{fsused}} = ('unknown', 0);
		}
		if (!exists $overall_system_stats{iused}) {
			@{$overall_system_stats{iused}} = ('unknown', 0);
		}
		$overall_system_stats{tps}[1] = ($overall_system_stats{tps}[1]||0);
		$overall_system_stats{read}[1] = &pretty_print_size($overall_system_stats{read}[1]);
		$overall_system_stats{write}[1] = &pretty_print_size($overall_system_stats{write}[1]);
		@{$overall_system_stats{kbcached}} =  ($OVERALL_STATS{'system'}{'kbcached'}[0], &pretty_print_size($OVERALL_STATS{'system'}{'kbcached'}[1]));
		@{$overall_system_stats{kbdirty}} =  ($OVERALL_STATS{'system'}{'kbdirty'}[0], &pretty_print_size($OVERALL_STATS{'system'}{'kbdirty'}[1]));
		@{$overall_system_stats{bread}} =  ($OVERALL_STATS{'system'}{'bread'}[0], &pretty_print_size($OVERALL_STATS{'system'}{'bread'}[1]));
		@{$overall_system_stats{bwrite}} =  ($OVERALL_STATS{'system'}{'bwrite'}[0], &pretty_print_size($OVERALL_STATS{'system'}{'bwrite'}[1]));

	}

	my $numcol = 4;
	if ($DISABLE_SAR) {
		$numcol = 6;
	} elsif (!exists $OVERALL_STATS{'system'}) {
		$numcol = 12;
	}
	print $fh <<EOF;
<ul id="slides">
<li class="slide active-slide" id="home-slide">
    <div id="home"><br/><br/><br/><br/></div>
EOF
	my $tz = ((0-$STATS_TIMEZONE)*3600);
	if (exists $OVERALL_STATS{'start_date'}) {
		$OVERALL_STATS{'start_date'} = ($OVERALL_STATS{'start_date'}/1000) + $tz;
		$OVERALL_STATS{'end_date'}   = ($OVERALL_STATS{'end_date'}/1000) + $tz;
	}
	if (exists $OVERALL_STATS{'sar_start_date'}) {
		$OVERALL_STATS{'sar_start_date'} = ($OVERALL_STATS{'sar_start_date'}/1000);
		$OVERALL_STATS{'sar_end_date'}   = ($OVERALL_STATS{'sar_end_date'}/1000);
	}
	my $start_date = localtime($OVERALL_STATS{'start_date'}||0) || 'Unknown start date';
	my $end_date = localtime($OVERALL_STATS{'end_date'}||0) || 'Unknown end date';
	my $sar_start_date = localtime($OVERALL_STATS{'sar_start_date'}||0) || 'Unknown start date';
	my $sar_end_date = localtime($OVERALL_STATS{'sar_end_date'}||0) || 'Unknown end date';

	my $parts_info = '';
	if (exists $OVERALL_STATS{'cluster'}) {
		$OVERALL_STATS{'cluster'}{'size'} ||= 0;
		$OVERALL_STATS{'cluster'}{'nbackend'} ||= 0;
		$OVERALL_STATS{'cluster'}{'returned'} ||= 0;
		$OVERALL_STATS{'cluster'}{'cache_ratio'} ||= 0;
		$OVERALL_STATS{'cluster'}{'temp_files'} ||= 0;
		$OVERALL_STATS{'cluster'}{'temp_bytes'} ||= 0;
		$OVERALL_STATS{'cluster'}{'deadlocks'} ||= 0;
		my $temp_file_info = '';
		if ($OVERALL_STATS{'cluster'}{'temp_files'}) {
			$temp_file_info = qq{
		<li><span class="figure">$OVERALL_STATS{'cluster'}{'temp_files'}</span> <span class="figure-label">Temporary files</span></li>
		<li><span class="figure">$OVERALL_STATS{'cluster'}{'temp_bytes'}</span> <span class="figure-label">Temporary files size</span></li>
};
		}
		my $deadlock_info = '';
		if (exists $OVERALL_STATS{'cluster'}{'deadlocks'}) {
			$deadlock_info = qq{
		<li><span class="figure">$OVERALL_STATS{'cluster'}{'deadlocks'}</span> <span class="figure-label">Deadlocks</span></li>
};
		}
		$deadlock_info = '' if ($sysinfo{CONFIGURATION}{'capture'});

		my $extnum = $#{$OVERALL_STATS{'cluster'}{'extensions'}} + 1;
		my $extensions_info = '';
		if ($extnum) {
			my $extlist = join(', ', @{$OVERALL_STATS{'cluster'}{'extensions'}});
			$extensions_info = qq{<li><span class="figure">$extnum</span> <span class="figure-label">Extensions ($extlist)</span></li>};
		}
		my $nparts = $#{$OVERALL_STATS{'cluster'}{'partitionned_tables'}} + 1;
		if ($nparts) {
			my %partitions = ();
			foreach my $pt (sort @{$OVERALL_STATS{'cluster'}{'partitionned_tables'}}) {
				$pt =~ s/^([^\.]+)\.//;
				$partitions{$1} .= "$pt;";
			}
			$parts_info = qq{<li><span class="figure">$nparts</span> <span class="figure-label">Partitioned tables</span></li><ul>};
			foreach my $t (keys %partitions) {
				$parts_info .= qq{<li><span class="figure">$t</span> <span class="figure-label">$partitions{$t}</span></li></ul>};
			}
		}
		$sysinfo{PGVERSION}{'full_version'} ||= '';
		$sysinfo{PGVERSION}{'uptime'} ||= '';
		my $database_number = scalar keys %{$OVERALL_STATS{'database'}};
		$OVERALL_STATS{'cluster'}{'size'} ||= '-';
		$OVERALL_STATS{'cluster'}{'nbackend'} ||= '-';
		$OVERALL_STATS{'cluster'}{'returned'} ||= '-';
		$OVERALL_STATS{'cluster'}{'cache_ratio'} ||= '-';
		my $bgwriter_reset = '';
		if (exists $OVERALL_STATS{'bgwriter'}{stats_reset}) {
			$bgwriter_reset = "<li><span class=\"figure\"> $OVERALL_STATS{'bgwriter'}{stats_reset}</span> <span class=\"figure-label\">Last bgwriter stats reset</span></li>";
		}
		my $cluster_size = &pretty_print_size($OVERALL_STATS{'cluster'}{'size'});
		$OVERALL_STATS{'cluster'}{unlogged} ||= 0;
		my $unlogged_dblist = '';
		if (exists $OVERALL_STATS{'cluster'}{unlogged_db}) {
			$unlogged_dblist = ' (' . join(', ', @{$OVERALL_STATS{'cluster'}{unlogged_db}}) . ')';
		}
		$OVERALL_STATS{'cluster'}{invalid_indexes} ||= 0;
		my $invalid_dblist = '';
		if (exists $OVERALL_STATS{'cluster'}{invalid_indexes_db}) {
			$invalid_dblist = ' (' . join(', ', @{$OVERALL_STATS{'cluster'}{invalid_indexes_db}}) . ')';
		}
		$OVERALL_STATS{'cluster'}{hash_indexes} ||= 0;
		my $hash_dblist = '';
		if (exists $OVERALL_STATS{'cluster'}{hash_indexes_db}) {
			$hash_dblist = ' (' . join(', ', @{$OVERALL_STATS{'cluster'}{hash_indexes_db}}) . ')';
		}
		# On version prior to 9.3 this is not applicable
		$OVERALL_STATS{'cluster'}{'data_checksums'} ||= 'N/A';

		print $fh <<EOF;
      <div class="row">
            <div class="col-md-$numcol">
              <div class="panel panel-default">
              <div class="panel-heading">
              <i class="glyphicon icon-cogs icon-2x pull-left"></i><h2>Cluster</h2>
              </div>
              <div class="panel-body panel-xlheight">
		<div class="key-figures">
		<span class="figure-date">$start_date to $end_date</span>
		<ul>
		<li></li>
		<li><span class="figure">$OVERALL_STATS{'cluster'}{'data_checksums'}</span> <span class="figure-label">Data checksums</span></li>
		<li><span class="figure">$cluster_size</span> <span class="figure-label">Cluster size</span></li>
		<li><span class="figure">$database_number</span> <span class="figure-label">Databases</span></li>
EOF
		if (!$sysinfo{CONFIGURATION}{'capture'}) {
			print $fh <<EOF;
		<li><span class="figure">$OVERALL_STATS{'cluster'}{'nbackend'}</span> <span class="figure-label">Connections</span></li>
		<li><span class="figure">$OVERALL_STATS{'cluster'}{'returned'}</span> <span class="figure-label">Tuples returned</span></li>
		<li><span class="figure">$OVERALL_STATS{'cluster'}{'cache_ratio'}</span> <span class="figure-label">Hit cache ratio</span></li>
EOF
		}
		print $fh <<EOF;
		<li><span class="figure">$OVERALL_STATS{'cluster'}{'unlogged'}</span> <span class="figure-label">Unlogged tables$unlogged_dblist</span></li>
		<li><span class="figure">$OVERALL_STATS{'cluster'}{'invalid_indexes'}</span> <span class="figure-label">Invalid indexes$invalid_dblist</span></li>
		<li><span class="figure">$OVERALL_STATS{'cluster'}{'hash_indexes'}</span> <span class="figure-label">Hash indexes$hash_dblist</span></li>
		$temp_file_info
		$deadlock_info
		$bgwriter_reset
		</ul>
		</div>
              </div>
              </div>
            </div><!--/span-->
EOF
		# Perform some initialization in case
		print $fh <<EOF;
            <div class="col-md-$numcol">
              <div class="panel panel-default">
              <div class="panel-heading">
              <i class="glyphicon icon-th icon-2x pull-left"></i><h2>Databases</h2>
              </div>
              <div class="panel-body panel-xlheight">
		<div class="key-figures">
		<ul>
		<li></li>
EOF
		if (exists $overall_stat_databases{'size'}) {
			print $fh <<EOF;
		<li><span class="figure">$overall_stat_databases{'size'}[1]</span> <span class="figure-label">Largest database</span><br/><span class="figure-date">($overall_stat_databases{'size'}[0])</span></li>
EOF
		}

		if (!$sysinfo{CONFIGURATION}{'capture'}) {
			if (exists $overall_stat_databases{'nbackend'}) {
				print $fh <<EOF;
		<li><span class="figure">$overall_stat_databases{'nbackend'}[1]</span> <span class="figure-label">Most connections</span><br/><span class="figure-date">($overall_stat_databases{'nbackend'}[0])</span></li>
EOF
			}
			if (exists $overall_stat_databases{'returned'}) {
				print $fh qq{<li><span class="figure">$overall_stat_databases{'returned'}[1]</span> <span class="figure-label">Most tuples returned</span><br/><span class="figure-date">($overall_stat_databases{'returned'}[0])</span></li>
};
			}
			if (exists $overall_stat_databases{'cache_ratio'}) {
				push(@{$overall_stat_databases{'cache_ratio'}}, '-', '-') if ($#{$overall_stat_databases{'cache_ratio'}} < 0);
				print $fh <<EOF;
		<li><span class="figure">$overall_stat_databases{'cache_ratio'}[1]%</span> <span class="figure-label">Worst cache utilization</span><br/><span class="figure-date">($overall_stat_databases{'cache_ratio'}[0])</span></li>
EOF
			}
			if (exists $overall_stat_databases{'temp_files'} && $overall_stat_databases{'temp_files'}[1]) {
				print $fh <<EOF;
		<li><span class="figure">$overall_stat_databases{'temp_files'}[1]</span> <span class="figure-label">Most temporary files</span><br/><span class="figure-date">($overall_stat_databases{'temp_files'}[0])</span></li>
EOF
			}
			if (exists $overall_stat_databases{'temp_bytes'} && $overall_stat_databases{'temp_bytes'}[1]) {
				print $fh <<EOF;
		<li><span class="figure">$overall_stat_databases{'temp_bytes'}[1]</span> <span class="figure-label">Most temporary bytes</span><br/><span class="figure-date">($overall_stat_databases{'temp_bytes'}[0])</span></li>
EOF
			}
			if (exists $overall_stat_databases{'deadlocks'} && $overall_stat_databases{'deadlocks'}[1]) {
				print $fh <<EOF;
		<li><span class="figure">$overall_stat_databases{'deadlocks'}[1]</span> <span class="figure-label">Most deadlocks</span><br/><span class="figure-date">($overall_stat_databases{'deadlocks'}[0])</span></li>
EOF
			}
		}
		print $fh <<EOF;
		$extensions_info
		</ul>
		</div>
              </div>
              </div>
            </div><!--/span-->
EOF

	}
	if (!$DISABLE_SAR) {
		if (!exists $OVERALL_STATS{'cluster'}) {
			print $fh <<EOF;
      <div class="row">
EOF
		}
		print $fh <<EOF;
            <div class="col-md-$numcol">
              <div class="panel panel-default">
              <div class="panel-heading">
              <i class="glyphicon icon-desktop icon-2x pull-left"></i><h2>System</h2>
              </div>
              <div class="panel-body panel-xlheight">
		<div class="key-figures">
		<span class="figure-date">$sar_start_date to $sar_end_date</span>
		<ul>
		<li></li>
		<li><span class="figure">$OVERALL_STATS{'system'}{'cpu'}[1]%</span> <span class="figure-label">Highest CPU utilization</span><br/><span class="figure-date">($OVERALL_STATS{'system'}{'cpu'}[0])</span></li>
		<li><span class="figure">$OVERALL_STATS{'system'}{'load'}[1]</span> <span class="figure-label">Highest system load</span><br/><span class="figure-date">($OVERALL_STATS{'system'}{'load'}[0])</span></li>
		<li><span class="figure">$OVERALL_STATS{'system'}{'blocked'}[1]</span> <span class="figure-label">Highest blocked processes</span><br/><span class="figure-date">($OVERALL_STATS{'system'}{'blocked'}[0])</span></li>
EOF
		# service time or await depending on sar version
		if (!$SAR_UPPER_12_1_1) {
			print $fh qq{<li><span class="figure">$OVERALL_STATS{'system'}{'svctm'}[1] ms</span> <span class="figure-label">Highest device service time</span><br/><span class="figure-date">($OVERALL_STATS{'system'}{'svctm'}[0] on device $OVERALL_STATS{'system'}{'svctm'}[2])</span></li>\n};
		} else {
			print $fh qq{<li><span class="figure">$OVERALL_STATS{'system'}{'await'}[1] ms</span> <span class="figure-label">Highest device wait time</span><br/><span class="figure-date">($OVERALL_STATS{'system'}{'await'}[0] on device $OVERALL_STATS{'system'}{'await'}[2])</span></li>\n};
		}
		print $fh <<EOF;
		<li><span class="figure">$overall_system_stats{kbcached}[1]</span> <span class="figure-label">Lowest system cache</span><br/><span class="figure-date">($overall_system_stats{kbcached}[0])</span></li>
		<li><span class="figure">$overall_system_stats{kbdirty}[1]</span> <span class="figure-label">Highest dirty memory</span><br/><span class="figure-date">($overall_system_stats{kbdirty}[0])</span></li>
		<!-- li><span class="figure">$overall_system_stats{bread}[1]</span> <span class="figure-label">Highest block read</span><br/><span class="figure-date">($overall_system_stats{bread}[0])</span></li -->
		<!-- li><span class="figure">$overall_system_stats{bwrite}[1]</span> <span class="figure-label">Highest block write</span><br/><span class="figure-date">($overall_system_stats{bwrite}[0])</span> </li -->
		<li><span class="figure">$overall_system_stats{read}[1]</span> <span class="figure-label">Most read device</span><br/><span class="figure-date"> ($overall_system_stats{read}[0])</span></li>
		<li><span class="figure">$overall_system_stats{write}[1]</span> <span class="figure-label">Most written device</span><br/><span class="figure-date">($overall_system_stats{write}[0])</span></li>
		<li><span class="figure">$overall_system_stats{tps}[1]</span> <span class="figure-label">Highest tps on device</span><br/><span class="figure-date">($overall_system_stats{tps}[0])</span></li>
		</ul>
		</div>
              </div>
              </div>
            </div><!--/span-->
EOF
	}
	if (exists $OVERALL_STATS{'cluster'} || (!$DISABLE_SAR)) {
		print $fh <<EOF;
      </div>
EOF
	}

       if (exists $sysinfo{PGVERSION}) {
		my $uptime = '';
		$uptime = "<li><span class=\"figure-label\">Up since $sysinfo{PGVERSION}{'uptime'}</span></li>" if ($sysinfo{PGVERSION}{'uptime'});
		print $fh <<EOF;
      <div class="row">
	    <div class="col-md-12">
	      <div class="panel panel-default">
	      <div class="panel-body">
	       <div class="key-figures">
	       <ul>
	       <li></li>
	       <li><span class="figure-label">$sysinfo{PGVERSION}{'full_version'}</span></li>
		$uptime
	       </ul>
	       </div>
	      </div>
	      </div>
	    </div><!--/span-->
	</div>
EOF
       }

	if (exists $OVERALL_STATS{'archiver'})
	{
		my $archiver_infos = '';
		if (exists $OVERALL_STATS{'archiver'}{last_archived_wal}) {
			$archiver_infos = qq{<li><span class="figure">$OVERALL_STATS{'archiver'}{last_archived_wal}</span> <span class="figure-label">Last archived wal</span></li>};
			$archiver_infos .= qq{<li><span class="figure">$OVERALL_STATS{'archiver'}{last_archived_time}</span> <span class="figure-label">Last archived time</span></li>};
		}
		if (exists $OVERALL_STATS{'archiver'}{last_failed_wal}) {
			$archiver_infos .= qq{<li><span class="figure">$OVERALL_STATS{'archiver'}{last_failed_wal}</span> <span class="figure-label">Last failed wal</span></li>};
			$archiver_infos .= qq{<li><span class="figure">$OVERALL_STATS{'archiver'}{last_failed_time}</span> <span class="figure-label">Last failed time</span></li>};
		}
		if (exists $OVERALL_STATS{'archiver'}{stats_reset}) {
			$archiver_infos .= qq{<li><span class="figure">$OVERALL_STATS{'archiver'}{stats_reset}</span> <span class="figure-label">Last stats reset</span></li>};
		}

		print $fh <<EOF;
      <div class="row">
            <div class="col-md-12">
              <div class="panel panel-default">
              <div class="panel-heading">
              <i class="glyphicon icon-archive icon-2x pull-left"></i><h2>Archiver</h2>
              </div>
              <div class="panel-body">
		<div class="key-figures">
		<ul>
		<li></li>
		$archiver_infos
		</ul>
		</div>
              </div>
              </div>
            </div><!--/span-->
	</div>
EOF
	}

	if ($#all_stat_slots >= 0)
	{
		# timestamp | slot_name | plugin | slot_type | database | active
		my $slots_infos = "<table>\n<tr><th>timestamp</th><th>slot_name</th><th>plugin</th><th>slot_type</th><th>database</th><th>active</th><th>wal_status</th><th>safe_wal_size</th><th>inactive_since</th><th>conflicting</th><th>invalidation_reason</th><th>failover</th><th>synced</th></tr>\n";
		# Get archiver size statistics
		$slots_infos .= "<tr>";
		$slots_infos .= "<td>$all_stat_slots[0]</td>";
		$slots_infos .= "<td>$all_stat_slots[0]</td>";
		$slots_infos .= "<td>$all_stat_slots[0]</td>";
		$slots_infos .= "<td>$all_stat_slots[0]</td>";
		$slots_infos .= "<td>$all_stat_slots[0]</td>";
		$slots_infos .= "<td>$all_stat_slots[0]</td>";
		$slots_infos .= "<td>$all_stat_slots[0]</td>";
		$slots_infos .= "<td>$all_stat_slots[0]</td>";
		$slots_infos .= "<td>$all_stat_slots[0]</td>";
		$slots_infos .= "<td>$all_stat_slots[0]</td>";
		$slots_infos .= "<td>$all_stat_slots[0]</td>";
		$slots_infos .= "<td>$all_stat_slots[0]</td>";
		$slots_infos .= "</tr>\n</table>";

		print $fh <<EOF;
      <div class="row">
            <div class="col-md-12">
              <div class="panel panel-default">
              <div class="panel-heading">
              <i class="glyphicon icon-archive icon-2x pull-left"></i><h2>Replication Slots</h2>
              </div>
              <div class="panel-body">
		<div class="key-figures">
		<ul>
		<li></li>
		$slots_infos
		</ul>
		</div>
              </div>
              </div>
            </div><!--/span-->
	</div>
EOF
	}

	if ($parts_info)
	{
		print $fh <<EOF;
      <div class="row">
            <div class="col-md-12">
              <div class="panel panel-default">
              <div class="panel-heading">
              <i class="glyphicon icon-th icon-2x pull-left"></i><h2>Partitioning</h2>
              </div>
              <div class="panel-body">
		<div class="key-figures">
		<ul>
		<li></li>
		$parts_info
		</ul>
		</div>
              </div>
              </div>
            </div><!--/span-->
	</div>
EOF
	}

	if (exists $sysinfo{INSTALLATION}) {
		my $package_infos = join('', @{$sysinfo{INSTALLATION}});
		print $fh <<EOF;
      <div class="row">
            <div class="col-md-12">
              <div class="panel panel-default">
              <div class="panel-heading">
              <i class="glyphicon icon-briefcase icon-2x pull-left"></i><h2>Packages</h2>
              </div>
              <div class="panel-body">
		<div class="key-figures">
		<ul>
		<li></li>
		<pre>$package_infos</pre>
		</ul>
		</div>
              </div>
              </div>
            </div><!--/span-->
	</div>
EOF
	}

	if (exists $sysinfo{CRONTAB}) {
		my $cron_infos = join('', @{$sysinfo{CRONTAB}});
		print $fh <<EOF;
      <div class="row">
            <div class="col-md-12">
              <div class="panel panel-default">
              <div class="panel-heading">
              <i class="glyphicon icon-coffee icon-2x pull-left"></i><h2>Crontab entries</h2>
              </div>
              <div class="panel-body">
		<div class="key-figures">
		<ul>
		<li></li>
		<pre>$cron_infos</pre>
		</ul>
		</div>
              </div>
              </div>
            </div><!--/span-->
	</div>
EOF
	}

	if (exists $sysinfo{PGDATA}) {
		my $pgdata_infos = join('', @{$sysinfo{PGDATA}});
		print $fh <<EOF;
      <div class="row">
            <div class="col-md-12">
              <div class="panel panel-default">
              <div class="panel-heading">
              <i class="glyphicon icon-briefcase icon-2x pull-left"></i><h2>PGDATA</h2>
              </div>
              <div class="panel-body">
		<div class="key-figures">
		<ul>
		<li></li>
		<pre>$pgdata_infos</pre>
		</ul>
		</div>
              </div>
              </div>
            </div><!--/span-->
	</div>
EOF
	}


	print $fh <<EOF;
</li>

<li class="slide" id="about-slide">

	<div id="about"><br/><br/><br/><br/><br/></div>
	<div class="jumbotron">
	<h1>About $PROGRAM</h1>
	<p>$PROGRAM is a Perl program used to perform a full audit of a PostgreSQL Cluster. It is divided in two parts, a collector used to grab statistics on the PostgreSQL cluster using psql and sysstat, a grapher that will generate all HTML output. It is fully open source and free of charge.</p>
	</div>
	<div class="row">
            <div class="col-md-4">
              <div class="panel panel-default">
              <div class="panel-heading">
              <i class="glyphicon icon-link icon-2x pull-left"></i><h2>License</h2>
              </div>
              <div class="panel-body panel-height">
              <p>$PROGRAM is licenced under the PostgreSQL Licence a liberal Open Source license, similar to the BSD or MIT licenses.</p>
	      <p>That mean that all parts of the program are open source and free of charge.</p>
	      <p>This is the case for both, the collector and the grapher programs.</p>
              </div>
              </div>
            </div><!--/span-->
            <div class="col-md-4">
              <div class="panel panel-default">
              <div class="panel-heading">
              <i class="glyphicon icon-download-alt icon-2x pull-left"></i><h2>Download</h2>
              </div>
              <div class="panel-body panel-height">
              <p>Official releases at SourceForge:<br/>
	      [ <a href="http://sourceforge.net/projects/pgcluu/">http://sourceforge.net/projects/pgcluu/</a> ].</p>
	      <p>Source code at github:<br/>
	      [ <a href="https://github.com/darold/pgcluu">https://github.com/darold/pgcluu</a> ].</p>
	      <p>ChangeLog can be read on-line on GitHub repository <a href="https://github.com/darold/pgcluu/blob/master/ChangeLog">here</a>
	      <p>Offical web site is hosted at <a href="http://pgcluu.darold.net/">pgcluu.darold.net</a>
              </div>
              </div>
            </div><!--/span-->
            <div class="col-md-4">
              <div class="panel panel-default">
              <div class="panel-heading">
              <i class="glyphicon icon-wrench icon-2x pull-left"></i><h2>Authors</h2>
              </div>
              <div class="panel-body panel-height">
	      <p>$PROGRAM is an original development of <a href="http://www.darold.net/">Gilles Darold</a>.</p>
	      <p>Some parts of the collector are taken from <a href="https://github.com/gleu/pgstats">pgstats</a> a C program writen by Guillaume Lelarge and especially the SQL queries including the compatibility with all PostgreSQL versions.</p>
	      <p>Btw $PROGRAM grapher is compatible with files generated by pgstats, sar and sadc so you can use it independently to graph those data. Some part of the sar output parser are taken from <a href="http://sysusage.darold.net/">SysUsage</a></p>
              </div>
              </div>
            </div><!--/span-->
	</div>
</li>

EOF

	if ( (-e "$in_dir/sysinfo.txt") || (-e "$in_dir/sysinfo.txt.gz") || (-e "$in_dir/sys_cache.bin") ) {
		$sysinfo{UPTIME}{'uptime'} = '-' if (!exists $sysinfo{UPTIME}{'uptime'});
		my $release_version = '';
		if ($sysinfo{RELEASE}{'version'}) {
			$release_version = qq{<li><span class="figure">$sysinfo{RELEASE}{'version'}</span> <span class="figure-label">Version</span></li>};
		}

		my $sysctl_info = '';
		my $postmaster_info = &postmaster_info_html();
		my $hugepage_info = '';
		my $cpu_info = '';
		foreach my $k (sort keys %{$sysinfo{SYSTEM}}) {
			# shmmax and shmall are useless since PostgreSQL 9.3, they can
			# still be found in the files collected by older versions
			next if ($k =~ /^kernel.*shm/);
			if ($k =~ /transparent_hugepage/) {
				my $k2 = $k;
				$k2 =~ s/\/sys\/kernel\/mm\/transparent_hugepage\///;
				$sysinfo{SYSTEM}{$k} =~ s/.*\[(.*)\].*/$1/;
				$hugepage_info .= <<EOF;
		<li><span class="figure-label" data-toggle="tooltip" data-placement="top" title="$k">$k2</span> <span class="figure">$sysinfo{SYSTEM}{$k}</span></li>
EOF
			} elsif ($k =~ /scaling_governor|cpuidle|intel_pstate|energy_performance_preference|numa_nodes/) {
				my $k2 = basename($k);
				$k2 =~ s/_/ /g;
				$k2 =~ ucfirst($k2);;
				$cpu_info .= <<EOF;
		<li><span class="figure-label" data-toggle="tooltip" data-placement="top" title="$k">$k2</span> <span class="figure">$sysinfo{SYSTEM}{$k}</span></li>
EOF
			} else {
				my $lbl = $k;
				$lbl =~ s/kernel\.//;
				$sysctl_info .= "<li><span class=\"figure-label\">$lbl</span> <span class=\"figure\">$sysinfo{SYSTEM}{$k}</span></li>\n";
			}
		}
		my $core_info = '';
		if (exists $sysinfo{CPU}{'cpu cores'}) {
			my $nsockets = $sysinfo{CPU}{'processor'}/($sysinfo{CPU}{'cpu cores'}||1);
			$core_info = qq{
	      <li><span class="figure">$nsockets</span> <span class="figure-label">Sockets</span></li>
	      <li><span class="figure">$sysinfo{CPU}{'cpu cores'}</span> <span class="figure-label">Cores per CPU</span></li>
};
		}

		if ($hugepage_info) {
			$hugepage_info = <<EOF;
               <span class="figure-label"><b>/sys/kernel/mm/transparent_hugepage/</b></span>
               <ul>
               <li></li>
		$hugepage_info
		</ul>
EOF
		}
		if (exists $sysinfo{KERNEL}{'kernel'} || exists  $sysinfo{CPU}{'processor'}) {
			print $fh <<EOF;
<li class="slide" id="info-slide">

	<div id="info"><br/><br/><br/><br/><br/></div>
	<div class="row">
            <div class="col-md-3">
              <div class="panel panel-default">
              <div class="panel-heading">
              <i class="glyphicon icon-desktop icon-2x pull-left"></i><h2>System</h2>
              </div>
              <div class="panel-body panel-xlheight">
		<div class="key-figures">
              <span class="figure-label"><b>OS information</b></span>
		<ul>
		<li></li>
	      <li><span class="figure">$sysinfo{UPTIME}{'uptime'}</span> <span class="figure-label">Uptime</span></li>
	      <li><span class="figure">$sysinfo{KERNEL}{'hostname'}</span> <span class="figure-label">Hostname</span></li>
	      <li><span class="figure">$sysinfo{KERNEL}{'kernel'}</span> <span class="figure-label">Kernel</span></li>
	      <li><span class="figure">$sysinfo{KERNEL}{'arch'}</span> <span class="figure-label">Arch</span></li>
	      <li><span class="figure">$sysinfo{RELEASE}{'name'}</span> <span class="figure-label">Distribution</span></li>
               $release_version
               </ul>
               </div>
		<div class="key-figures">
	      <span class="figure-label"><b>Devices information in /sys/block/</b></span>
		<ul>
		<li></li>
EOF
		foreach my $k (sort keys %{ $sysinfo{DEVICES} })
		{
			foreach my $r (@{ $sysinfo{DEVICES}{$k} }) {
		print $fh <<EOF;
	      <li><span class="figure-label">$k$r</span> <span class="figure-label"></span></li>
EOF
			}
		}
		print $fh <<EOF;
               </ul>
               </div>

              </div>
              </div>
            </div><!--/span-->
            <div class="col-md-3">
              <div class="panel panel-default">
              <div class="panel-heading">
              <i class="glyphicon icon-gear icon-2x pull-left"></i><h2>Kernel</h2>
              </div>
              <div class="panel-body panel-xlheight">
               <div class="key-figures">
		$hugepage_info
                <span class="figure-label"><b>sysctl parameters</b></span>
                <ul>
                <li></li>
                $sysctl_info
		</ul>
		$postmaster_info
		</div>
              </div>
              </div>
            </div><!--/span-->
            <div class="col-md-3">
              <div class="panel panel-default">
              <div class="panel-heading">
              <i class="glyphicon icon-dashboard icon-2x pull-left"></i><h2>CPU</h2>
              </div>
              <div class="panel-body panel-xlheight">
		<div class="key-figures">
              <span class="figure-label"><b>CPUs information</b></span>
		<ul>
		<li></li>
	      <li><span class="figure">$sysinfo{CPU}{'model name'}</span></li>
	      <li><span class="figure">$sysinfo{CPU}{'cpu MHz'}</span> <span class="figure-label">Speed</span></li>
	      <li><span class="figure">$sysinfo{CPU}{'cache size'}</span> <span class="figure-label">Cache</span></li>
	      $core_info
	      <li><span class="figure">$sysinfo{CPU}{'processor'}</span> <span class="figure-label">Cores</span></li>
	      $cpu_info
		</ul>
		</div>
              </div>
              </div>
            </div><!--/span-->
            <div class="col-md-3">
              <div class="panel panel-default">
              <div class="panel-heading">
              <i class="glyphicon icon-tasks icon-2x pull-left"></i><h2>Memory</h2>
              </div>
              <div class="panel-body panel-xlheight">
		<div class="key-figures">
              <span class="figure-label"><b>Memory information</b></span>
		<ul>
		<li></li>
	      <li><span class="figure">$sysinfo{MEMORY}{'memtotal'}</span> <span class="figure-label">Total memory</span></li>
	      <li><span class="figure">$sysinfo{MEMORY}{'memfree'}</span> <span class="figure-label">Free memory</span></li>
	      <li><span class="figure">$sysinfo{MEMORY}{'buffers'}</span> <span class="figure-label">Buffers</span></li>
	      <li><span class="figure">$sysinfo{MEMORY}{'cached'}</span> <span class="figure-label">Cached</span></li>
	      <li><span class="figure">$sysinfo{MEMORY}{'swaptotal'}</span> <span class="figure-label">Total swap</span></li>
	      <li><span class="figure">$sysinfo{MEMORY}{'swapfree'}</span> <span class="figure-label">Free swap</span></li>
	      <li><span class="figure">$sysinfo{MEMORY}{'pagetables'}</span> <span class="figure-label">Page Tables</span></li>
EOF
		if (exists $sysinfo{MEMORY}{'shmem'}) {
			print $fh <<EOF;
	      <li><span class="figure">$sysinfo{MEMORY}{'shmem'}</span> <span class="figure-label">Shared memory</span></li>
EOF
		}
		if (exists $sysinfo{MEMORY}{'commit_limit'}) {
			print $fh <<EOF;
	      <li><span class="figure">$sysinfo{MEMORY}{'commit_limit'}</span> <span class="figure-label">Commit limit</span></li>
	      <li><span class="figure">$sysinfo{MEMORY}{'committed_as'}</span> <span class="figure-label">Committed</span></li>
EOF
		}
                my @df_infos = ();
                push(@df_infos, @{$sysinfo{DF}}) if (exists $sysinfo{DF});
                my @mount_infos = ();
                push(@mount_infos, @{$sysinfo{MOUNT}}) if (exists $sysinfo{MOUNT});
		print $fh <<EOF;
		</ul>
		</div>
              </div>
              </div>
            </div><!--/span-->
	</div>

	<div class="row">
            <div class="col-md-12">
              <div class="panel panel-default">
              <div class="panel-heading">
              <i class="glyphicon icon-hdd icon-2x pull-left"></i><h2>Filesystem</h2>
              </div>
              <div class="panel-body panel-lheight">
		<div class="key-figures">
		<ul>
		<li></li>
		<li>
		<table>
		<tr><th>Filesystem</th><th>Size</th><th>Used</th><th>Free</th><th>Use%</th><th>Mount</th></tr>
		@df_infos
		</table>
		</li>
		<li>
		<table>
		<tr><th>Filesystem</th><th>Mount</th><th>type</th><th>Options</th></tr>
		@mount_infos
		</table>
		</li>
		</ul>
		</div>
              </div>
              </div>
            </div><!--/span-->
	</div>
EOF
		} else {
			print $fh <<EOF;
<li class="slide" id="info-slide">

	<div id="info"><br/><br/><br/><br/><br/></div>
	<div class="row">
            <div class="col-md-12">
              <div class="panel panel-default">
              <div class="panel-heading">
              <i class="glyphicon icon-desktop icon-2x pull-left"></i><h2>System</h2>
              </div>
              <div class="panel-body panel-xlheight">
		<div class="key-figures">
              <span class="figure-label"><b>No data collected</b></span>
               </div>
              </div>
              </div>
            </div><!--/span-->
	</div>
  </li>
EOF
		}
		if (exists $sysinfo{PROCESS}) {
			print $fh <<EOF;
	<div class="row">
            <div class="col-md-12">
              <div class="panel panel-default">
              <div class="panel-heading">
              <i class="glyphicon icon-list icon-2x pull-left"></i><h2>Process list</h2>
              </div>
              <div class="panel-body panel-lheight">
		<div class="key-figures">
		<ul>
		<li></li>
		<li>
		<table>
		<tr><th>USER</th><th>PID</th><th>%CPU</th><th>%MEM</th><th>VSZ</th><th>RSS</th><th>TTY</th><th>STAT</th><th>START</th><th>TIME</th><th>COMMAND</th></tr>
		@{$sysinfo{PROCESS}}
		</table>
		</li>
		</ul>
		</div>
              </div>
              </div>
            </div><!--/span-->
	</div>
  </li>
EOF
		}
	}

	print $fh <<EOF;
</ul> <!-- end of slides -->
EOF
        &html_footer($fh);
        $fh->close;
}

sub html_header
{
	my $fh = shift();
	my $base = shift();
	$base ||= '.';

	my @db_list = @_;
        my $date = localtime(time);

	print $fh &build_head($PROGRAM, $base);
        print $fh qq{
 <body>

<!-- Load navbar -->
<div id="navigation"></div>

<div class="container" id="main-container">
};

}

sub html_footer
{
	my $fh = shift();
	my $db = shift();

        print $fh qq{
	$COPYRIGHT
  <!-- Modal -->
  <div class="modal fade" id="pgcluuModal" role="dialog">
    <div class="modal-dialog">

      <!-- Modal content-->
      <div class="modal-content">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal">&times;</button>
          <h4 class="modal-title">Right click + "Save image as ..." to save the graph as PNG image</h4>
        </div>
        <div class="modal-body">
          <img src="" />
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        </div>
      </div>

    </div>
  </div>

    </div><!--/.container-->
  </body>
</html>
};

}

sub generate_html_menu
{
	my ($in_dir, $out_dir) = @_;

        my $date = localtime(time);

        my $menu_str = qq{
    <div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
      <a class="navbar-brand" href="http://pgcluu.darold.net/">
      <img src="$pgcluu_logo" title="$PROGRAM"></a>
      <div class="container mainmenu">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
        </div>
        <div class="navbar-inverse navbar-collapse collapse">
          <ul class="nav navbar-nav">
              <li id="menu-home" class="dropdown"><a href="index.html#home">Home</a></li>
};
	if ( (-e "$in_dir/sysinfo.txt") || (-e "$in_dir/sysinfo.txt.gz") || (-e "$in_dir/sys_cache.bin") ) {
		$menu_str .= qq{
              <li id="menu-info" class="dropdown"><a href="index.html#info">SysInfo</a></li>
} if (exists $sysinfo{KERNEL}{'kernel'} || exists  $sysinfo{CPU}{'processor'});
	}

	opendir(ODIR, "$OUTPUT_DIR") || die "FATAL: can't opendir $OUTPUT_DIR: $!";
	my @database_list = grep { !/^database-all.html$/ && !/^database-(queries|fct|conflict|conn|lock|tx|io|tmpf)-.*.html$/ && s/^database-(.*)\.html$/$1/; } readdir(ODIR);
	closedir(ODIR);
	if ($#database_list >= 0)
	{
		my $disable_size = ' class="disabled"';
		my $disable_tablespace = ' class="disabled"';
		my $disable_backend = ' class="disabled"';
		my $disable_conntype = ' class="disabled"';
		my $disable_connection = ' disabled';
		my $disable_cache = ' class="disabled"';
		my $disable_deadlock = ' class="disabled"';
		my $disable_buffercache = ' class="disabled"';
		my $disable_buffer = ' disabled';
		my $disable_bgwriter_write = ' class="disabled"';
		my $disable_bgwriter_read = ' class="disabled"';
		my $disable_bgwriter_count = ' class="disabled"';
		my $disable_writer = ' disabled';
		my $disable_tempfile = ' class="disabled"';
		my $disable_tempfile_bytes = ' class="disabled"';
		my $disable_temporary = ' disabled';
		my $disable_wal = ' disabled';
		my $disable_xlog_files = ' class="disabled"';
		my $disable_xlog = ' class="disabled"';
		my $disable_checkpoints = ' class="disabled"';
		my $disable_checkpoint_time = ' class="disabled"';
		my $disable_archive = ' class="disabled"';
		my $disable_rw_ratio = ' disabled';
		my $disable_read_ratio = ' class="disabled"';
		my $disable_write_ratio = ' class="disabled"';
		my $disable_write_query = ' class="disabled"';
		my $disable_commit = ' class="disabled"';
		my $disable_conflicts = ' class="disabled"';
		my $disable_canceled = ' class="disabled"';
		my $disable_replication = ' class="disabled"';
		my $disable_allrepli = ' disabled';
		my $disable_conf = ' disabled';
		my $disable_pgconf = ' class="disabled"';
		my $disable_alterconf = ' class="disabled"';
		my $disable_recoveryconf = ' class="disabled"';
		my $disable_pghba = ' class="disabled"';
		my $disable_pgident = ' class="disabled"';
		my $disable_pgsettings = ' class="disabled"';
		my $disable_pgnondefaultsettings = ' class="disabled"';
		my $disable_pgdb_role_setting = ' class="disabled"';
		my $disable_pgbouncer = ' class="disabled"';
		my $disable_transactions = ' class="disabled"';
		my $disable_prepared = ' class="disabled"';
		my $disable_subxact_counters = ' class="disabled"';
		my $disable_waitevent_types = ' class="disabled"';
		my $disable_waitevent_events = ' class="disabled"';
		my $disable_waitevents = ' disabled';

		# Enable all menu that have a dedicated report.
		if (-e "$OUTPUT_DIR/cluster-database-size.html") {
			$disable_size = '';
		}
		if (-e "$OUTPUT_DIR/cluster-tablespace-size.html") {
			$disable_tablespace = '';
		}
		if (-e "$OUTPUT_DIR/cluster-database-backends.html") {
			$disable_backend = '';
			$disable_connection = '';
		}
		if (-e "$OUTPUT_DIR/cluster-database-connections.html") {
			$disable_conntype = '';
			$disable_connection = '';
		}
		if (-e "$OUTPUT_DIR/cluster-database-cache_ratio.html") {
			$disable_cache = '';
		}
		if (&backend_minimum_version(9.2) && (-e "$OUTPUT_DIR/cluster-database-deadlocks.html")) {
			$disable_deadlock = '';
		}
		if (-e "$OUTPUT_DIR/cluster-buffersused.html") {
			$disable_buffercache = '';
			$disable_buffer = '';
		}
		if (-e "$OUTPUT_DIR/cluster-bgwriter_write.html") {
			$disable_bgwriter_write = "";
			$disable_writer = "";
		}
		if (-e "$OUTPUT_DIR/cluster-bgwriter_read.html") {
			$disable_bgwriter_read = "";
			$disable_writer = "";
		}
		if (-e "$OUTPUT_DIR/cluster-bgwriter_count.html") {
			$disable_bgwriter_count = "";
			$disable_writer = "";
		}
		if (&backend_minimum_version(9.2) && (-e "$OUTPUT_DIR/cluster-database-temporary_files.html")) {
			$disable_tempfile = "";
			$disable_temporary = "";
		}
		if (&backend_minimum_version(9.2) && (-e "$OUTPUT_DIR/cluster-database-temporary_bytes.html")) {
			$disable_tempfile_bytes = "";
			$disable_temporary = "";
		}
		if (-e "$OUTPUT_DIR/cluster-xlog_files.html") {
			$disable_xlog_files = '';
			$disable_wal = '';
		}
		if (-e "$OUTPUT_DIR/cluster-xlog.html") {
			$disable_xlog = '';
			$disable_wal = '';
		}
		if (-e "$OUTPUT_DIR/cluster-checkpoints.html") {
			$disable_checkpoints = '';
			$disable_wal = '';
		}
		if (-e "$OUTPUT_DIR/cluster-checkpoints_time.html") {
			$disable_checkpoint_time = '';
			$disable_wal = '';
		}
		if (-e "$OUTPUT_DIR/cluster-database-read_ratio.html") {
			$disable_read_ratio = "";
			$disable_rw_ratio = "";
		}
		if (-e "$OUTPUT_DIR/cluster-database-write_ratio.html") {
			$disable_write_ratio = "";
			$disable_rw_ratio = "";
		}
		if (-e "$OUTPUT_DIR/cluster-database-read_write_query.html") {
			$disable_write_query = "";
			$disable_rw_ratio = "";
		}
		if (-e "$OUTPUT_DIR/cluster-database-commits_rollbacks.html") {
			$disable_commit = "";
			$disable_rw_ratio = "";
		}
		if (-e "$OUTPUT_DIR/cluster-database-transactions.html") {
			$disable_transactions = "";
		}
		if (-e "$OUTPUT_DIR/cluster-database-conflicts.html") {
			$disable_conflicts = "";
			$disable_allrepli = "";
		}
		if (-e "$OUTPUT_DIR/cluster-database-canceled_queries.html") {
			$disable_canceled = "";
			$disable_allrepli = "";
		}
		if (-e "$OUTPUT_DIR/cluster-database-prepared.html") {
			$disable_prepared = "";
		}
		if (-e "$OUTPUT_DIR/cluster-replication.html") {
			$disable_replication = "";
			$disable_allrepli = "";
		}
		if (-e "$OUTPUT_DIR/cluster-archive.html") {
			$disable_archive = '';
			$disable_wal = '';
		}
		if (-e "$OUTPUT_DIR/cluster-pgconf.html") {
			$disable_conf = '';
			$disable_pgconf = '';
		}
		if (-e "$OUTPUT_DIR/cluster-settings.html") {
			$disable_conf = '';
			$disable_pgsettings = '';
		}
		if (-e "$OUTPUT_DIR/cluster-nondefault-settings.html") {
			$disable_conf = '';
			$disable_pgnondefaultsettings = '';
		}
		if (-e "$OUTPUT_DIR/cluster-dbrolesetting.html") {
			$disable_conf = '';
			$disable_pgdb_role_setting = '';
		}
		if (-e "$OUTPUT_DIR/cluster-alterconf.html") {
			$disable_conf = '';
			$disable_alterconf = '';
		}
		if (-e "$OUTPUT_DIR/cluster-recoveryconf.html") {
			$disable_conf = '';
			$disable_recoveryconf = '';
		}
		if (-e "$OUTPUT_DIR/cluster-pghba.html") {
			$disable_conf = '';
			$disable_pghba = '';
		}
		if (-e "$OUTPUT_DIR/cluster-pgident.html") {
			$disable_conf = '';
			$disable_pgident = ''
		}
		if (-e "$OUTPUT_DIR/cluster-pgbouncer.html") {
			$disable_conf = '';
			$disable_pgbouncer = '';
		}
		if (-e "$OUTPUT_DIR/cluster-subxact_counters.html") {
			$disable_subxact_counters = '';
		}
		if (-e "$OUTPUT_DIR/cluster-waitevent_types.html") {
			$disable_waitevent_types = '';
			$disable_waitevents = '';
		}
		if (-e "$OUTPUT_DIR/cluster-waitevent_events.html") {
			$disable_waitevent_events = '';
			$disable_waitevents = '';
		}
		my $disable_stat_io = ' disabled';
		my $stat_io_menu = '';
		foreach my $p (@STAT_IO_PAGES)
		{
			my $disable_page = ' class="disabled"';
			if (-e "$OUTPUT_DIR/$p->[0].html") {
				$disable_page = '';
				$disable_stat_io = '';
			}
			$stat_io_menu .= qq{			      <li id="menu-$p->[0]"$disable_page><a href="$p->[0].html">$p->[1]</a></li>\n};
		}
		if ($stat_io_menu) {
			$stat_io_menu = qq{
			<li id="menu-stat_io" class="dropdown-submenu$disable_stat_io">
			   <a href="#" tabindex="-1">I/O statistics </a>
			      <ul class="dropdown-menu">
$stat_io_menu			      </ul>
		        </li>
};
		}

		$menu_str .= qq{
              <li id="menu-cluster" class="dropdown">
                <a href="#" class="dropdown-toggle" data-toggle="dropdown">Cluster <b class="caret"></b></a>
                <ul class="dropdown-menu">
		      <li id="menu-cluster-size"$disable_size><a href="cluster-database-size.html">Databases sizes</a></li>
		      <li id="menu-tablespace-cluster-size"$disable_tablespace><a href="cluster-tablespace-size.html">Tablespaces sizes</a></li>
};
		if (!$sysinfo{CONFIGURATION}{'capture'}) {
			$menu_str .= qq{
			<li id="menu-connectionbackend" class="dropdown-submenu$disable_connection">
			   <a href="#" tabindex="-1">Connections </a>
			      <ul class="dropdown-menu">
			      <li id="menu-cluster-backends"$disable_backend><a href="cluster-database-backends.html">Connections</a></li>
			      <li id="menu-cluster-connections"$disable_conntype><a href="cluster-database-connections.html">Connections by type</a></li>
			      </ul>
			</li>
		      <li id="menu-cluster-deadlocks"$disable_deadlock><a href="cluster-database-deadlocks.html">Deadlocks</a></li>
		      <li class="divider"></li>
		       <li id="menu-cluster-cache_ratio"$disable_cache><a href="cluster-database-cache_ratio.html">Cache utilization</a></li>
			<li id="menu-pgbuffercache" class="dropdown-submenu$disable_buffer">
			   <a href="#" tabindex="-1">Shared buffers statistics </a>
			      <ul class="dropdown-menu">
			      <li id="menu-cluster-buffersused"$disable_buffercache><a href="cluster-buffersused.html">Shared buffers utilization</a></li>
			      <li id="menu-cluster-databaseloaded"$disable_buffercache><a href="cluster-databaseloaded.html">Database in shared buffers</a></li>
			      <li id="menu-cluster-usagecount"$disable_buffercache><a href="cluster-usagecount.html">Usagecount in shared buffers</a></li>
			      <li id="menu-cluster-isdirty"$disable_buffercache><a href="cluster-isdirty.html">Usagecount in dirty buffers</a></li>
			      </ul>
			</li>
		      <li class="divider"></li>
			<li id="menu-backgroundwriter" class="dropdown-submenu $disable_writer">
			   <a href="#" tabindex="-1">Background writer </a>
			      <ul class="dropdown-menu">
			      <li id="menu-cluster-bgwriter_write"$disable_bgwriter_write><a href="cluster-bgwriter_write.html">Bgwriter buffers written</a></li>
			      <li id="menu-cluster-bgwriter_read"$disable_bgwriter_read><a href="cluster-bgwriter_read.html">Bgwriter buffers allocated</a></li>
			      <li id="menu-cluster-bgwriter_count"$disable_bgwriter_count><a href="cluster-bgwriter_count.html">Bgwriter counters</a></li>
			      </ul>
		        </li>
			<li id="menu-temporaryfiles" class="dropdown-submenu$disable_temporary">
			   <a href="#" tabindex="-1">Temporary files </a>
			      <ul class="dropdown-menu">
			      <li id="menu-cluster-temporary_files"$disable_tempfile><a href="cluster-database-temporary_files.html">Temporary files</a></li>
			      <li id="menu-cluster-temporary_bytes"$disable_tempfile_bytes><a href="cluster-database-temporary_bytes.html">Temporary files size</a></li>
			      </ul>
		        </li>
			<li id="menu-walcheckpoint" class="dropdown-submenu$disable_wal">
			   <a href="#" tabindex="-1">Wal / Checkpoint </a>
			      <ul class="dropdown-menu">
			      <li id="menu-cluster-xlog_files"$disable_xlog_files><a href="cluster-xlog_files.html">Wal files</a></li>
			      <li id="menu-cluster-checkpoints"$disable_checkpoints><a href="cluster-checkpoints.html">Checkpoints counter</a></li>
			      <li id="menu-cluster-checkpoints_time"$disable_checkpoint_time><a href="cluster-checkpoints_time.html">Checkpoints write time</a></li>
			      <li id="menu-cluster-archive"$disable_archive><a href="cluster-archive.html">Archiver stats</a></li>
			      </ul>
		        </li>
			<li id="menu-rw" class="dropdown-submenu$disable_rw_ratio">
			   <a href="#" tabindex="-1">Queries Reads / Writes </a>
			      <ul class="dropdown-menu">
			      <li id="menu-cluster-read_ratio"$disable_read_ratio><a href="cluster-database-read_ratio.html">Read tuples</a></li>
			      <li id="menu-cluster-write_ratio"$disable_write_ratio><a href="cluster-database-write_ratio.html">Write ratio</a></li>
			      <li id="menu-cluster-read_write_query"$disable_write_query><a href="cluster-database-read_write_query.html">Read vs Write queries</a></li>
			      <li id="menu-cluster-commits_rollbacks"$disable_commit><a href="cluster-database-commits_rollbacks.html">Commits vs Rollbacks</a></li>
			      </ul>
		        </li>
		      <li id="menu-cluster-transactions"$disable_transactions><a href="cluster-database-transactions.html">Transaction throughput</a></li>
		      <li id="menu-cluster-prepared"$disable_prepared><a href="cluster-database-prepared.html">Prepared transactions</a></li>
		      <li id="menu-cluster-canceled_queries"$disable_canceled><a href="cluster-database-canceled_queries.html">Canceled queries</a></li>
		      <li id="menu-cluster-subxact_counters"$disable_subxact_counters><a href="cluster-subxact_counters.html">Subxact counters</a></li>
			<li id="menu-rw" class="dropdown-submenu$disable_waitevents">
			   <a href="#" tabindex="-1">Wait Events </a>
			      <ul class="dropdown-menu">
			      <li id="menu-cluster-waitevent_types"$disable_waitevent_types><a href="cluster-waitevent_types.html">Wait Event types</a></li>
			      <li id="menu-cluster-waitevent_events"$disable_waitevent_events><a href="cluster-waitevent_events.html">Wait Event events</a></li>
			      </ul>
		        </li>
$stat_io_menu		      <li class="divider"></li>
			<li id="menu-replication" class="dropdown-submenu$disable_allrepli">
			   <a href="#" tabindex="-1">Replication statistics </a>
			      <ul class="dropdown-menu">
			      <li id="menu-cluster-xlog"$disable_xlog><a href="cluster-xlog.html">Wal bytes written</a></li>
			      <li id="menu-cluster-replication"$disable_replication><a href="cluster-replication.html">Replication lag</a></li>
			      <li id="menu-cluster-conflicts"$disable_conflicts><a href="cluster-database-conflicts.html">Conflicts</a></li>
			      </ul>
		        </li>
};
		}
		$menu_str .= qq{
		      <li class="divider"></li>
			<li id="menu-configuration" class="dropdown-submenu$disable_conf">
			   <a href="#" tabindex="-1">Configurations </a>
			      <ul class="dropdown-menu">
			      <li id="menu-cluster-pgconf"$disable_pgconf><a href="cluster-pgconf.html">PostgreSQL configuration</a></li>
			      <li id="menu-cluster-settings"$disable_pgsettings><a href="cluster-settings.html">PostgreSQL settings</a></li>
			      <li id="menu-cluster-nondefault-settings"$disable_pgnondefaultsettings><a href="cluster-nondefault-settings.html">PostgreSQL non default settings</a></li>
			      <li id="menu-cluster-dbrolesetting"$disable_pgdb_role_setting><a href="cluster-dbrolesetting.html">Database/Roles settings</a></li>
			      <li id="menu-cluster-alterconf"$disable_alterconf><a href="cluster-alterconf.html">PostgreSQL ALTER SYSTEM configuration</a></li>
			      <li id="menu-cluster-recoveryconf"$disable_recoveryconf><a href="cluster-recoveryconf.html">PostgreSQL recovery configuration</a></li>
			      <li id="menu-cluster-pghba"$disable_pghba><a href="cluster-pghba.html">PostgreSQL authorization</a></li>
			      <li id="menu-cluster-pgident"$disable_pgident><a href="cluster-pgident.html">User Name Maps</a></li>
			      <li id="menu-cluster-pgbouncer"$disable_pgbouncer><a href="cluster-pgbouncer.html">Pgbouncer settings</a></li>
			     </ul>
			</li>
                </ul>
              </li>
};
	}

	if ($#database_list >= 0) {
		$menu_str .= qq{
              <li id="menu-database" class="dropdown">
                <a href="#" class="dropdown-toggle" data-toggle="dropdown">Databases <b class="caret"></b></a>
                <ul class="dropdown-menu">
};
	}

	my $dbidx = 0;
	my $l = 0;
	foreach my $db (sort @database_list) {
		next if (($db ne 'all') && ($#INCLUDE_DB >= 0) && (!grep($db =~ /^$_$/, @INCLUDE_DB)));
		if ($#database_list >= 10) {
			my $md = $l % 10;
			if ($md == 0) {
				$dbidx++;
				if ($l > 0) {
					$menu_str .= qq{
                    </ul>
                  </li>
};
				}
				my $lbl = '';
				$lbl = " (part $dbidx)" if ($#database_list >= 10);
				$menu_str .= qq{
                  <li id="menu-device$dbidx" class="dropdown-submenu">
                     <a href="#" tabindex="-1">Database $lbl</a>
                      <ul class="dropdown-menu">
};
			}
			$l++;
		}

		$menu_str .= qq{
		<li id="menu-$db" class="dropdown-submenu">
		   <a href="#" tabindex="-1">$db </a>
		      <ul class="dropdown-menu">
};
		if ( (-e "$in_dir/sysinfo.txt") || (-e "$in_dir/sysinfo.txt.gz") || (-e "$in_dir/sys_cache.bin") ) {
			$menu_str .= qq{
		      <li id="menu-database-info"><a href="database-$db.html#database-info">Database info</a></li>
};
		}

		my $disable_parttables = ' class="disabled"';
		$disable_parttables = '' if (exists $sysinfo{PARTITIONNED_TABLE}{$db});
		$menu_str .= qq{
		    <li id="menu-partitionned-tbl"$disable_parttables><a href="database-$db.html#partitionned-tbl">Partitionned Tables</a></li>
};

		my %data_info = %{$DB_GRAPH_INFOS{'pg_stat_user_tables.csv'}};
		my $table_str = '';
		foreach my $id (sort {$a <=> $b} keys %data_info)
		{
			next if ($data_info{$id}{name} !~ /^table-/);
			next if ($sysinfo{CONFIGURATION}{'capture'} && grep(/^$data_info{$id}{name}$/, 'table-vacuums-analyzes', 'table-indexes'));
			$table_str .= qq{
			      <li id="menu-database-$data_info{$id}{name}"><a href="$db-$data_info{$id}{name}.html">$data_info{$id}{menu}</a></li>
} if (-e "$OUTPUT_DIR/$db-$data_info{$id}{name}.html");
		}
		%data_info = %{$DB_GRAPH_INFOS{'pg_class_size.csv'}};
		foreach my $id (sort {$a <=> $b} keys %data_info)
		{
			next if ($data_info{$id}{name} !~ /^table-/);
			$table_str .= qq{
			      <li id="menu-database-$data_info{$id}{name}"><a href="$db-$data_info{$id}{name}.html">$data_info{$id}{menu}</a></li>
} if (-e "$OUTPUT_DIR/$db-$data_info{$id}{name}.html");
		}
		%data_info = %{$DB_GRAPH_INFOS{'pg_stat_unlogged.csv'}};
		foreach my $id (sort {$a <=> $b} keys %data_info) {
			next if ($data_info{$id}{name} !~ /^table-/);
			$table_str .= qq{
			      <li id="menu-database-$data_info{$id}{name}"><a href="$db-$data_info{$id}{name}.html">$data_info{$id}{menu}</a></li>
} if (-e "$OUTPUT_DIR/$db-$data_info{$id}{name}.html");
		}
		%data_info = %{$DB_GRAPH_INFOS{'pg_stat_ext.csv'}};
		foreach my $id (sort {$a <=> $b} keys %data_info) {
			next if ($data_info{$id}{name} !~ /^table-/);
			$table_str .= qq{
			      <li id="menu-database-$data_info{$id}{name}"><a href="$db-$data_info{$id}{name}.html">$data_info{$id}{menu}</a></li>
} if (-e "$OUTPUT_DIR/$db-$data_info{$id}{name}.html");
		}
		if (!$sysinfo{CONFIGURATION}{'capture'}) {
			%data_info = %{$DB_GRAPH_INFOS{'pg_statio_user_tables.csv'}};
			foreach my $id (sort {$a <=> $b} keys %data_info) {
				next if ($data_info{$id}{name} !~ /^statio-/);
				$table_str .= qq{
				      <li id="menu-database-$data_info{$id}{name}"><a href="$db-$data_info{$id}{name}.html">$data_info{$id}{menu}</a></li>
	} if (-e "$OUTPUT_DIR/$db-$data_info{$id}{name}.html");
			}
		}
		my $disable_table = ' disabled';
		$disable_table = '' if ($table_str);
		$menu_str .= qq{
			<li id="menu-$db-table" class="dropdown-submenu $disable_table">
			   <a href="#" tabindex="-1">Tables statistics </a>
			      <ul class="dropdown-menu">
				$table_str
			  </ul>
		      </li>
};
		$table_str = '';

		my $idx_str = '';
		%data_info = %{$DB_GRAPH_INFOS{'pg_stat_user_indexes.csv'}};
		foreach my $id (sort {$a <=> $b} keys %data_info) {
			next if ($data_info{$id}{name} !~ /^index-/);
			$idx_str .= qq{
			      <li id="menu-database-$data_info{$id}{name}"><a href="$db-$data_info{$id}{name}.html">$data_info{$id}{menu}</a></li>
} if (-e "$OUTPUT_DIR/$db-$data_info{$id}{name}.html");
		}
		%data_info = %{$DB_GRAPH_INFOS{'pg_class_size.csv'}};
		foreach my $id (sort {$a <=> $b} keys %data_info) {
			next if ($data_info{$id}{name} !~ /^index-/);
			next if ($sysinfo{CONFIGURATION}{'capture'} && $data_info{$id}{name} eq 'index-scan');
			$idx_str .= qq{
			      <li id="menu-database-$data_info{$id}{name}"><a href="$db-$data_info{$id}{name}.html">$data_info{$id}{menu}</a></li>
} if (-e "$OUTPUT_DIR/$db-$data_info{$id}{name}.html");
		}
		%data_info = %{$DB_GRAPH_INFOS{'pg_stat_invalid_indexes.csv'}};
		foreach my $id (sort {$a <=> $b} keys %data_info) {
			next if ($data_info{$id}{name} !~ /^index-/);
			$idx_str .= qq{
			      <li id="menu-database-$data_info{$id}{name}"><a href="$db-$data_info{$id}{name}.html">$data_info{$id}{menu}</a></li>
} if (-e "$OUTPUT_DIR/$db-$data_info{$id}{name}.html");
		}
		%data_info = %{$DB_GRAPH_INFOS{'pg_stat_hash_indexes.csv'}};
		foreach my $id (sort {$a <=> $b} keys %data_info) {
			next if ($data_info{$id}{name} !~ /^index-/);
			$idx_str .= qq{
			      <li id="menu-database-$data_info{$id}{name}"><a href="$db-$data_info{$id}{name}.html">$data_info{$id}{menu}</a></li>
} if (-e "$OUTPUT_DIR/$db-$data_info{$id}{name}.html");
		}
		%data_info = %{$DB_GRAPH_INFOS{'pg_statio_user_indexes.csv'}};
		foreach my $id (sort {$a <=> $b} keys %data_info) {
			next if ($data_info{$id}{name} !~ /^statio-/);
			next if ($sysinfo{CONFIGURATION}{'capture'});
			$idx_str .= qq{
				      <li id="menu-database-$data_info{$id}{name}"><a href="$db-$data_info{$id}{name}.html">$data_info{$id}{menu}</a></li>
	} if (-e "$OUTPUT_DIR/$db-$data_info{$id}{name}.html");
		}
		%data_info = %{$DB_GRAPH_INFOS{'pg_stat_unused_indexes.csv'}};
		foreach my $id (sort {$a <=> $b} keys %data_info) {
			$idx_str .= qq{
			      <li id="menu-database-$data_info{$id}{name}"><a href="$db-$data_info{$id}{name}.html">$data_info{$id}{menu}</a></li>
} if (-e "$OUTPUT_DIR/$db-$data_info{$id}{name}.html");
		}
		%data_info = %{$DB_GRAPH_INFOS{'pg_stat_redundant_indexes.csv'}};
		foreach my $id (sort {$a <=> $b} keys %data_info) {
			$idx_str .= qq{
			      <li id="menu-database-$data_info{$id}{name}"><a href="$db-$data_info{$id}{name}.html">$data_info{$id}{menu}</a></li>
} if (-e "$OUTPUT_DIR/$db-$data_info{$id}{name}.html");
		}
		%data_info = %{$DB_GRAPH_INFOS{'pg_stat_missing_fkindexes.csv'}};
		foreach my $id (sort {$a <=> $b} keys %data_info) {
			$idx_str .= qq{
			      <li id="menu-database-$data_info{$id}{name}"><a href="$db-$data_info{$id}{name}.html">$data_info{$id}{menu}</a></li>
} if (-e "$OUTPUT_DIR/$db-$data_info{$id}{name}.html");
		}
		%data_info = %{$DB_GRAPH_INFOS{'pg_stat_count_indexes.csv'}};
		my $idx = &get_data_id('count-index', %data_info);
		$idx_str .= qq{
			      <li id="menu-database-$data_info{$idx}{name}"><a href="$db-$data_info{$idx}{name}.html">Number of indexes</a></li>
} if (-e "$OUTPUT_DIR/$db-$data_info{$idx}{name}.html");
		my $disable_idx = ' disabled';
		$disable_idx = '' if ($idx_str);
		$menu_str .= qq{
			<li id="menu-$db-table" class="dropdown-submenu $disable_idx">
			   <a href="#" tabindex="-1">Indexes statistics </a>
				<ul class="dropdown-menu">
				$idx_str
				</ul>
			</li>
};
		$idx_str = '';

		if (-e "$OUTPUT_DIR/database-fct-$db.html") {
			$menu_str .= qq{
			<li id="menu-database-functions"><a href="database-fct-$db.html#database-functions">Functions statistics</a></li>
};
		}

		%data_info = %{$DB_GRAPH_INFOS{'pg_relation_buffercache.csv'}};
		my $buffer_str = '';
		foreach my $id (sort {$a <=> $b} keys %data_info) {
			next if ($data_info{$id}{name} !~ /buffercache/);
			$buffer_str .= qq{
			      <li id="menu-database-$data_info{$id}{name}"><a href="$db-$data_info{$id}{name}.html">$data_info{$id}{menu}</a></li>
} if (-e "$OUTPUT_DIR/$db-$data_info{$id}{name}.html");
		}
		my $disable_buffer = ' disabled';
		$disable_buffer = '' if ($buffer_str);
		$menu_str .= qq{
			<li id="menu-$db-buffercache-relation" class="dropdown-submenu $disable_buffer">
			   <a href="#" tabindex="-1">Buffercache Statistics </a>
			      <ul class="dropdown-menu">
				$buffer_str
			  </ul>
		      </li>
};
		$buffer_str = '';

		if (-e "$OUTPUT_DIR/database-queries-$db.html")
		{
			$menu_str .= qq{
		      <li id="menu-database-queries"><a href="database-queries-$db.html#database-queries">Statements statistics</a></li>
};
		}

		my $disable_size = ' class="disabled"';
		my $disable_backend = ' class="disabled"';
		my $disable_conntype = ' class="disabled"';
		my $disable_connection = ' disabled';
		my $disable_lock = ' class="disabled"';
		my $disable_locks = ' disabled';
		my $disable_cache = ' class="disabled"';
		my $disable_rw_ratio = ' disabled';
		my $disable_read_ratio = ' class="disabled"';
		my $disable_write_ratio = ' class="disabled"';
		my $disable_write_query = ' class="disabled"';
		my $disable_commit = ' class="disabled"';
		my $disable_canceled = ' class="disabled"';
		my $disable_conflicts = ' class="disabled"';
		my $disable_temporary = ' disabled';
		my $disable_tempbytes = ' class="disabled"';
		my $disable_tempfile = ' class="disabled"';
		my $disable_deadlock = ' class="disabled"';
		my $disable_transaction = ' class="disabled"';
		my $disable_prepared = ' class="disabled"';
		my $fh = IO::File->new("$OUTPUT_DIR/database-$db.html", 'r');
		if (defined $fh)
		{
			while (<$fh>)
			{
				if (/<div id="database-size">/) {
					$disable_size = '';
				} elsif (/<div id="database-cache_ratio">/) {
					$disable_cache = '';
				}
			}
			close($fh);
		}
		if (-e "$OUTPUT_DIR/database-io-$db.html")
		{
			$disable_read_ratio = "";
			$disable_write_query = "";
			$disable_rw_ratio = "";
		}
		if (-e "$OUTPUT_DIR/database-conn-$db.html")
		{
			$disable_backend = '';
			$disable_connection = '';
			$disable_conntype = '';
		}
		if (-e "$OUTPUT_DIR/database-conflict-$db.html")
		{
			$disable_conflicts = "";
			$disable_canceled = "";
		}
		if (-e "$OUTPUT_DIR/database-tmpf-$db.html")
		{
			$disable_tempfile = "";
			$disable_temporary = "";
			$disable_tempbytes = "";
			$disable_temporary = "";
		}
		if (-e "$OUTPUT_DIR/database-lock-$db.html")
		{
			$disable_deadlock = "";
			$disable_locks = "";
			$disable_lock = "";
		}
		if (-e "$OUTPUT_DIR/database-tx-$db.html")
		{
			$disable_transaction = "";
			$disable_prepared = "";
			$disable_commit = "";
		}

		if (!$sysinfo{CONFIGURATION}{'capture'}) {
			$menu_str .= qq{
		      <li class="divider"></li>
		      <li id="menu-database-size"$disable_size><a href="database-$db.html#database-size">Database size</a></li>
		      <li id="menu-${db}_connections" class="dropdown-submenu$disable_connection">
			<a href="#" tabindex="-1">Connections </a>
			  <ul class="dropdown-menu">
			      <li id="menu-database-backends"$disable_backend><a href="database-conn-$db.html#database-backends">Connections</a></li>
			      <li id="menu-database-connections"$disable_conntype><a href="database-conn-$db.html#database-connections">Connections by type</a></li>
			  </ul>
		      </li>
		      <li id="menu-database-cache_ratio"$disable_cache><a href="database-$db.html#database-cache_ratio">Cache utilization</a></li>
		      <li class="divider"></li>
		      <li id="menu-${db}_locks" class="dropdown-submenu $disable_locks">
			<a href="#" tabindex="-1">Locks </a>
			  <ul class="dropdown-menu">
			      <li id="menu-database-deadlocks"$disable_deadlock><a href="database-lock-$db.html#database-deadlocks">Deadlocks</a></li>
			      <li id="menu-database-lock-types"$disable_lock><a href="database-lock-$db.html#database-lock-types">Locks per types</a></li>
			      <li id="menu-database-lock-modes"$disable_lock><a href="database-lock-$db.html#database-lock-modes">Locks per modes</a></li>
			      <li id="menu-database-lock-granted"$disable_lock><a href="database-lock-$db.html#database-lock-granted">Locks granted or not</a></li>
			  </ul>
		      </li>
		      <li class="divider"></li>
		      <li id="menu-${db}_temporaryfiles" class="dropdown-submenu $disable_temporary">
			<a href="#" tabindex="-1">Temporary files </a>
			  <ul class="dropdown-menu">
			      <li id="menu-database-temporary_files"$disable_tempfile><a href="database-tmpf-$db.html#database-temporary_files">Temporary files</a></li>
			      <li id="menu-database-temporary_bytes"$disable_tempbytes><a href="database-tmpf-$db.html#database-temporary_bytes">Temporary files size</a></li>
			  </ul>
		      </li>
		      <li id="menu-${db}_rw" class="dropdown-submenu $disable_rw_ratio">
			<a href="#" tabindex="-1">Queries Reads / Writes </a>
			  <ul class="dropdown-menu">
			      <li id="menu-database-read_ratio"$disable_read_ratio><a href="database-io-$db.html#database-read_ratio">Read tuples</a></li>
			      <li id="menu-database-write_ratio"$disable_write_ratio><a href="database-io-$db.html#database-write_ratio">Write ratio</a></li>
			      <li id="menu-database-read_write_query"$disable_write_query><a href="database-io-$db.html#database-read_write_query">Read vs Write queries</a></li>
			      <li id="menu-database-commits_rollbacks"$disable_commit><a href="database-tx-$db.html#database-commits_rollbacks">Commits vs Rollbacks</a></li>
			  </ul>
		      </li>
		      <li id="menu-database-transactions"$disable_transaction><a href="database-tx-$db.html#database-transactions">Transaction thoughput</a></li>
		      <li id="menu-database-prepared"$disable_prepared><a href="database-tx-$db.html#database-prepared">Prepared transactions</a></li>
		      <li class="divider"></li>
		      <li id="menu-database-canceled_queries"$disable_canceled><a href="database-conflict-$db.html#database-canceled_queries">Canceled queries</a></li>
		      <li id="menu-database-conflicts"$disable_conflicts><a href="database-conflict-$db.html#database-conflicts">Conflicts</a></li>
};
		}
		$menu_str .= qq{
                      </ul>
                </li>
};
	}
	if ($#database_list >= 0) {
		if ($#database_list >= 10) {
			$menu_str .= qq{
                    </ul>
                  </li>
};
		}
                $menu_str .= qq{
                </ul>
              </li>
};
	}

	opendir(ODIR, "$OUTPUT_DIR") || die "FATAL: can't opendir $OUTPUT_DIR: $!";
	my @pgbouncer_list = grep { !/^pgbouncer-all.html$/ && s/^pgbouncer-(.*).html$/$1/; } readdir(ODIR);
	closedir(ODIR);
	if ($#pgbouncer_list >= 0) {
		$menu_str .= qq{
              <li id="menu-database" class="dropdown">
                <a href="#" class="dropdown-toggle" data-toggle="dropdown">pgBouncer <b class="caret"></b></a>
                <ul class="dropdown-menu">
};
		foreach my $db (sort @pgbouncer_list) {

			my $disable_wait_total = ' class="disabled"';
			my $disable_wait_avg = ' class="disabled"';
			my $fh = IO::File->new("$OUTPUT_DIR/pgbouncer-$db.html", 'r');
			if (defined $fh) {
				while (<$fh>) {
					if (/<div id="pgbouncer-wait-total">/) {
						$disable_wait_total = '';
					} elsif (/<div id="pgbouncer-wait-average">/) {
						$disable_wait_avg = '';
					}
				}
				close($fh);
			}

			$menu_str .= qq{
			<li id="menu-$db" class="dropdown-submenu">
			   <a href="#" tabindex="-1">$db </a>
			      <ul class="dropdown-menu">
			      <li id="menu-pgbouncer-connections"><a href="pgbouncer-$db.html#pgbouncer-connections">Clients / servers connections</a></li>
			      <li id="menu-pgbouncer-duration"><a href="pgbouncer-$db.html#pgbouncer-duration">Average queries duration</a></li>
			      <li id="menu-pgbouncer-number"><a href="pgbouncer-$db.html#pgbouncer-number">Queries per second</a></li>
			      <li id="menu-pgbouncer-wait-total"$disable_wait_total><a href="pgbouncer-$db.html#pgbouncer-wait-total">Total wait time</a></li>
			      <li id="menu-pgbouncer-wait-average"$disable_wait_avg><a href="pgbouncer-$db.html#pgbouncer-wait-average">Average of wait time</a></li>
                             </ul>
                        </li>
};
		}
		$menu_str .= qq{
                </ul>
              </li>
};
	}

	# Kernel pressure and memory events pages, they do not depend on sar
	my $kernel_menu = '';
	foreach my $p (['kernel-pressure', 'Pressure stall information'], ['kernel-events', 'Kernel memory events']) {
		my $disable = (-e "$OUTPUT_DIR/$p->[0].html") ? '' : ' class="disabled"';
		$kernel_menu .= qq{                  <li id="menu-$p->[0]"$disable><a href="$p->[0].html">$p->[1]</a></li>\n};
	}
	if ($DISABLE_SAR && (-e "$OUTPUT_DIR/kernel-pressure.html" || -e "$OUTPUT_DIR/kernel-events.html"))
	{
		$menu_str .= qq{
              <li id="menu-system" class="dropdown">
                <a href="#" class="dropdown-toggle" data-toggle="dropdown">System <b class="caret"></b></a>
                <ul class="dropdown-menu">
$kernel_menu                </ul>
              </li>
};
	}

	if (!$DISABLE_SAR)
	{
		my $disable_cpu = ' class="disabled"';
		my $disable_memory = ' class="disabled"';
		my $disable_dirty = ' class="disabled"';
		my $disable_swap = ' class="disabled"';
		my $disable_commitmem = ' class="disabled"';
		my $disable_load = ' class="disabled"';
		my $disable_process = ' class="disabled"';
		my $disable_runqueue = ' class="disabled"';
		my $disable_cswch = ' class="disabled"';
		my $disable_fault = ' class="disabled"';
		my $disable_pcrea = ' class="disabled"';
		my $disable_block = ' class="disabled"';
		my $disable_tps = ' class="disabled"';
		my $disable_page = ' class="disabled"';
		my $disable_scanpage = ' class="disabled"';
		if (-e "$OUTPUT_DIR/system-cpu.html") {
			$disable_cpu = '';
		}
		if (-e "$OUTPUT_DIR/system-memory.html") {
			$disable_memory = '';
		}
		if (-e "$OUTPUT_DIR/system-swap.html") {
			$disable_swap = '';
		}
		if (-e "$OUTPUT_DIR/system-commit_memory.html") {
			$disable_commitmem = '';
		}
		if (-e "$OUTPUT_DIR/system-dirty.html") {
			$disable_dirty = '';
		}
		if (-e "$OUTPUT_DIR/system-load.html") {
			$disable_load = '';
		}
		if (-e "$OUTPUT_DIR/system-process.html") {
			$disable_process = '';
		}
		if (-e "$OUTPUT_DIR/system-runqueue.html") {
			$disable_runqueue = '';
		}
		if (-e "$OUTPUT_DIR/system-cswch.html") {
			$disable_cswch = '';
		}
		if (-e "$OUTPUT_DIR/system-pcrea.html") {
			$disable_pcrea = '';
		}
		if (-e "$OUTPUT_DIR/system-block.html") {
			$disable_block = '';
		}
		if (-e "$OUTPUT_DIR/system-tps.html") {
			$disable_tps = '';
		}
		if (-e "$OUTPUT_DIR/system-page.html") {
			$disable_page = '';
		}
		if (-e "$OUTPUT_DIR/system-fault.html") {
			$disable_fault = '';
		}
		if (-e "$OUTPUT_DIR/system-scanpage.html") {
			$disable_scanpage = '';
		}
		my $disable_pgcpu = ' class="disabled"';
		my $disable_pgmemory = ' class="disabled"';
		my $disable_pgmempercent = ' class="disabled"';
		my $disable_pgcswch = ' class="disabled"';
		my $disable_pgfault = ' class="disabled"';
		my $disable_pgio = ' class="disabled"';
		my $disable_pgiodelay = ' class="disabled"';
		if (-e "$OUTPUT_DIR/pidstat-postgres-cpu.html") {
			$disable_pgcpu = '';
		}
		if (-e "$OUTPUT_DIR/pidstat-postgres-memory.html") {
			$disable_pgmemory = '';
		}
		if (-e "$OUTPUT_DIR/pidstat-postgres-mempercent.html") {
			$disable_pgmempercent = '';
		}
		if (-e "$OUTPUT_DIR/pidstat-postgres-cswch.html") {
			$disable_pgcswch = '';
		}
		if (-e "$OUTPUT_DIR/pidstat-postgres-fault.html") {
			$disable_pgfault = '';
		}
		if (-e "$OUTPUT_DIR/pidstat-postgres-io.html") {
			$disable_pgio = '';
		}
		if (-e "$OUTPUT_DIR/pidstat-postgres-iodelay.html") {
			$disable_pgiodelay = '';
		}

		$menu_str .= qq{
              <li id="menu-system" class="dropdown">
                <a href="#" class="dropdown-toggle" data-toggle="dropdown">System <b class="caret"></b></a>
                <ul class="dropdown-menu">
		  <li id="menu-system-cpu"$disable_cpu><a href="system-cpu.html">Cpu</a></li>
                  <li class="divider"></li>
                  <li id="menu-system-memory"$disable_memory><a href="system-memory.html">Memory</a></li>
                  <li id="menu-system-dirty"$disable_dirty><a href="system-dirty.html">Dirty memory</a></li>
                  <li id="menu-system-swap"$disable_swap><a href="system-swap.html">Swap</a></li>
                  <li id="menu-system-commit_memory"$disable_commitmem><a href="system-commit_memory.html">Memory workload</a></li>
                  <li class="divider"></li>
                  <li id="menu-system-load"$disable_load><a href="system-load.html">Load</a></li>
                  <li id="menu-system-process"$disable_process><a href="system-process.html">Task list</a></li>
                  <li id="menu-system-runqueue"$disable_runqueue><a href="system-runqueue.html">Run queue</a></li>
                  <li id="menu-system-cswch"$disable_cswch><a href="system-cswch.html">Context switches</a></li>
                  <li id="menu-system-pcrea"$disable_pcrea><a href="system-pcrea.html">Tasks created per second</a></li>
                  <li class="divider"></li>
$kernel_menu                  <li class="divider"></li>
                  <li id="menu-system-block"$disable_block><a href="system-block.html">Blocks</a></li>
                  <li id="menu-system-tps"$disable_tps><a href="system-tps.html">Transfers per second</a></li>
		  <li id="menu-system-pageall" class="dropdown-submenu">
		     <a href="#" tabindex="-1">Pages</a>
		      <ul class="dropdown-menu">
			  <li id="menu-system-page"$disable_page><a href="system-page.html">Pages in/out</a></li>
			  <li id="menu-system-fault"$disable_fault><a href="system-fault.html">Pages faults</a></li>
			  <li id="menu-system-scanpage"$disable_scanpage><a href="system-scanpage.html">Pages scan</a></li>
		      </ul>
		  </li>
                  <li class="divider"></li>
};
		my $idx = 0;
		for (my $i = 0; $i <= $#DEVICE_LIST; $i++) {
			next if (!&device_in_report($DEVICE_LIST[$i]));
			my $md = $i % 10;
			if ($md == 0) {
				$idx++;
				if ($i > 0) {
					$menu_str .= qq{
		    </ul>
		  </li>
};
				}
				my $lbl = '';
				$lbl = " (part $idx)" if ($#DEVICE_LIST >= 10);
				$menu_str .= qq{
		  <li id="menu-device$idx" class="dropdown-submenu">
		     <a href="#" tabindex="-1">Devices $lbl</a>
		      <ul class="dropdown-menu">
};
			}
			my $disable_device_cpu = ' class="disabled"';
			my $disable_device_read_write = ' class="disabled"';
			my $disable_device_tps = ' class="disabled"';
			my $disable_device_service_time = ' class="disabled"';
			my $disable_device_await_time = ' class="disabled"';
			if (-e "$OUTPUT_DIR/system-cpudevice-$DEVICE_LIST[$i].html") {
				$disable_device_cpu = '';
			}
			if (-e "$OUTPUT_DIR/system-device-$DEVICE_LIST[$i].html") {
				$disable_device_read_write = '';
			}
			if (-e "$OUTPUT_DIR/system-tpsdevice-$DEVICE_LIST[$i].html") {
				$disable_device_tps = '';
			}
			if (-e "$OUTPUT_DIR/system-srvtime-$DEVICE_LIST[$i].html") {
				$disable_device_service_time = '';
			}
			if (-e "$OUTPUT_DIR/system-await-$DEVICE_LIST[$i].html") {
				$disable_device_await_time = '';
			}
			$menu_str .= qq{
			  <li id="menu-device$i" class="dropdown-submenu">
			     <a href="#" tabindex="-1">$DEVICE_LIST[$i] </a>
			      <ul class="dropdown-menu">
			      <li id="menu-device-cpu"$disable_device_cpu><a href="system-cpudevice-$DEVICE_LIST[$i].html">Cpu utilization</a></li>
			      <li id="menu-device-read_write"$disable_device_read_write><a href="system-device-$DEVICE_LIST[$i].html">Read/write bytes per second</a></li>
			      <li id="menu-device-tps"$disable_device_tps><a href="system-tpsdevice-$DEVICE_LIST[$i].html">Transfert per second</a></li>
};
			if (-e "$OUTPUT_DIR/system-await-$DEVICE_LIST[$i].html") {
				$menu_str .= qq{
			      <li id="menu-device-await_time"$disable_device_await_time><a href="system-await-$DEVICE_LIST[$i].html">Average I/O wait time</a></li>
			      </ul>
};
			} else {
				$menu_str .= qq{
			      <li id="menu-device-service_time"$disable_device_service_time><a href="system-srvtime-$DEVICE_LIST[$i].html">Average service time</a></li>
			      </ul>
};
			}
			$menu_str .= qq{
			  </li>
};
		}
		$menu_str .= qq{
		    </ul>
		  </li>
} if ($#DEVICE_LIST >= 0);

		my $disable_network = ' disabled';
		$disable_network = '' if (($#IFACE_LIST >= 0) || (!$SADC_INPUT_FILE && $SAR_INPUT_FILE));
		$menu_str .= qq{
		  <li id="menu-network" class="dropdown-submenu$disable_network">
		     <a href="#" tabindex="-1">Network </a>
		      <ul class="dropdown-menu">
} if ($#IFACE_LIST >= 0);
		for (my $i = 0; $i <= $#IFACE_LIST; $i++) {
			next if (!&interface_in_report($IFACE_LIST[$i]));
			my $disable_network_utilization = ' class="disabled"';
			my $disable_network_error = ' class="disabled"';
			if (-e "$OUTPUT_DIR/network-utilization-$IFACE_LIST[$i].html") {
				$disable_network_utilization = '';
			}
			if (-e "$OUTPUT_DIR/network-error-$IFACE_LIST[$i].html") {
				$disable_network_error = '';
			}
			$menu_str .= qq{
			  <li id="menu-device$i" class="dropdown-submenu">
			     <a href="#" tabindex="-1">$IFACE_LIST[$i] </a>
			      <ul class="dropdown-menu">
			      <li id="menu-network-utilization"$disable_network_utilization><a href="network-utilization-$IFACE_LIST[$i].html">Network utilization</a></li>
			      <li id="menu-network-error"$disable_network_error><a href="network-error-$IFACE_LIST[$i].html">Network errors</a></li>
			      </ul>
			  </li>
};
		}
		$menu_str .= qq{
		  <li id="menu-tcp" class="dropdown-submenu">
		     <a href="#" tabindex="-1">TCP </a>
		      <ul class="dropdown-menu">
		      <li id="menu-network-utilization"><a href="network-utilization-tcp.html">TCP utilization</a></li>
		      <li id="menu-network-error"><a href="network-error-tcp.html">TCP errors</a></li>
		      </ul>
		  </li>
};
		$menu_str .= qq{
		    </ul>
		  </li>
} if ($#IFACE_LIST >= 0);
		if (scalar keys %sar_space_devices_stat > 0)
		{
			$menu_str .= qq{
		  <li id="menu-space" class="dropdown-submenu">
		     <a href="#" tabindex="-1">Disk space use </a>
		      <ul class="dropdown-menu">
};
			foreach my $dev (sort keys %{$OVERALL_STATS{'system'}{'space'}}) {
				next if (!&interface_in_report($dev));
				$menu_str .= qq{
			      <li id="menu-space-$dev"><a href="system-space-$dev.html#space-used">Device $dev</a></li>
};
			}
			$menu_str .= qq{
		      </ul>
		    </li>
};
		}

		$menu_str .= qq{
                  <li class="divider"></li>
		  <li id="menu-postgres-stats" class="dropdown-submenu">
		     <a href="#" tabindex="-1">PostgreSQL</a>
		      <ul class="dropdown-menu">
			  <li id="menu-postgres-cpu"$disable_pgcpu><a href="pidstat-postgres-cpu.html">CPU</a></li>
			  <li id="menu-postgres-cswch"$disable_pgcswch><a href="pidstat-postgres-cswch.html">Context switches</a></li>
			  <li id="menu-postgres-memory"$disable_pgmemory><a href="pidstat-postgres-memory.html">Memory</a></li>
			  <li id="menu-postgres-mempercent"$disable_pgmempercent><a href="pidstat-postgres-mempercent.html">Percent Memory use</a></li>
			  <li id="menu-postgres-fault"$disable_pgfault><a href="pidstat-postgres-fault.html">Pages faults</a></li>
			  <li id="menu-postgres-iodelay"$disable_pgiodelay><a href="pidstat-postgres-iodelay.html">I/O delay</a></li>
			  <li id="menu-postgres-io"$disable_pgio><a href="pidstat-postgres-io.html">Kb I/O</a></li>
		      </ul>
		  </li>
                </ul>
              </li>
};
	}
	$menu_str .= qq{
              <li id="menu-about" class="dropdown"><a href="index.html#about">About</a></li>
          </ul>
        </div><!--/.nav-collapse -->
      </div>
    </div>

};
	if ($EXTERNAL_MENU)
	{
		if (!-e "$out_dir/menu.html")
		{
			print "DEBUG: generating external menu into $out_dir/menu.html\n" if ($DEBUG);
			my $mfh = IO::File->new("$OUTPUT_DIR/menu.html", 'w');
			if (defined $mfh) {
				print $mfh $menu_str;
				$mfh->close;
			} else {
				die "FATAL: can't write to $out_dir/menu.html, $!\n";
			}
		}
		$menu_str = qq{
<div w3-include-html="menu.html"></div>
<script>
w3.includeHTML();
</script>
};
	}

	return $menu_str;
}

sub device_in_report
{
	my $device = shift;

	return 0 if ($device =~ /^loop\d+/);

	return 1 if ($#INCLUDE_DEV == -1);

	foreach my $g (@INCLUDE_DEV) {
		return 1 if (grep(/^$g$/, $device));
	}
	return 0;
}

sub interface_in_report
{
	my $device = shift;

	return 1 if ($#INCLUDE_IFACE == -1);

	foreach my $g (@INCLUDE_IFACE) {
		return 1 if (grep(/^$g$/, $device));
	}
	return 0;
}

sub compute_cpu_stat
{
	for (my $i = 0; $i <= $#_; $i++) {
		my @data = split(/;/, $_[$i]);
		next if ($data[2] !~ /^\d+/ || $data[3] ne 'all');
		# hostname;interval;timestamp;CPU;%user;%nice;%system;%iowait;%steal;%idle
		# hostname;interval;timestamp;CPU;%usr;%nice;%sys;%iowait;%steal;%irq;%soft;%guest;%idle

		# Skip unwanted lines
		next if ($BEGIN && ($data[2] < $BEGIN_STAT));
		next if ($END   && ($data[2] > $END_STAT));

		map { s/,/\./ } @data ;
		# we only store all cpu statistics
		if ($data[3] eq 'all') {
			my $total_cpu = ($data[6]||0) + ($data[4]||0);
			$sar_cpu_stat{$data[2]}{$data[3]}{total}  = $total_cpu;
			$sar_cpu_stat{$data[2]}{$data[3]}{system} = ($data[6]||0);
			$sar_cpu_stat{$data[2]}{$data[3]}{user}   = ($data[4]||0);
			$sar_cpu_stat{$data[2]}{$data[3]}{iowait} = ($data[7]||0);
			$sar_cpu_stat{$data[2]}{$data[3]}{idle}   = ($data[-1]||0);
		}
	}
}

sub compute_cpu_report
{
	my $data_info = shift();

	my %cpu_stat = ();
	foreach my $t (sort {$a <=> $b} keys %sar_cpu_stat) {
		foreach my $cpu (keys %{$sar_cpu_stat{$t}}) {

			# We only process values from total CPU
			next if ($cpu ne 'all');

			if (!exists $OVERALL_STATS{'system'}{'cpu'} || ($OVERALL_STATS{'system'}{'cpu'}[1] < $sar_cpu_stat{$t}{$cpu}{total})) {
				@{$OVERALL_STATS{'system'}{'cpu'}} = ($t, $sar_cpu_stat{$t}{$cpu}{total});
			}
			$cpu_stat{$cpu}{total}  .= '[' . $t . ',' . $sar_cpu_stat{$t}{$cpu}{total} . '],';
			$cpu_stat{$cpu}{system} .= '[' . $t . ',' . $sar_cpu_stat{$t}{$cpu}{system} . '],';
			$cpu_stat{$cpu}{user}   .= '[' . $t . ',' . $sar_cpu_stat{$t}{$cpu}{user} . '],';
			$cpu_stat{$cpu}{iowait} .= '[' . $t . ',' . $sar_cpu_stat{$t}{$cpu}{iowait} . '],';
			$cpu_stat{$cpu}{idle}   .= '[' . $t . ',' . $sar_cpu_stat{$t}{$cpu}{idle} . '],';
		}
		$OVERALL_STATS{'system'}{'ncpu'} = (scalar keys %{$sar_cpu_stat{$t}}) - 1;
		$OVERALL_STATS{'sar_start_date'} = $t if (!$OVERALL_STATS{'sar_start_date'} || ($OVERALL_STATS{'sar_start_date'} gt $t));
		$OVERALL_STATS{'sar_end_date'} = $t if (!$OVERALL_STATS{'sar_end_date'} || ($OVERALL_STATS{'sar_end_date'} lt $t));
	}
	%sar_cpu_stat = ();

	if (scalar keys %cpu_stat > 0) {
		$cpu_stat{'all'}{total} =~ s/,$//;
		$cpu_stat{'all'}{system} =~ s/,$//;
		$cpu_stat{'all'}{user} =~ s/,$//;
		$cpu_stat{'all'}{iowait} =~ s/,$//;
		$cpu_stat{'all'}{idle} =~ s/,$//;

		print $FH &jqplot_linegraph_array($IDX++, 'system-cpu', $data_info, 'all', $cpu_stat{'all'}{total}, $cpu_stat{'all'}{system}, $cpu_stat{'all'}{user}, $cpu_stat{'all'}{idle}, $cpu_stat{'all'}{iowait});
	}

}

####
# Parse a header line of a pidstat report. Returns the type of the report
# and the position of the columns kept for this type (%PIDSTAT_COLUMNS) in
# the values of a line, the timestamp excluded. Reports not used (the CHILD
# reports of -T ALL for example) have no type.
####
sub parse_pidstat_header
{
	my $line = shift;

	my $type = &find_report_type($line);
	return ('') if (!$type || !exists $PIDSTAT_COLUMNS{$type});

	my @headers = split(m#\s+#, $line);
	shift(@headers);
	# AM/PM of the timestamp with 12 hours time format
	shift(@headers) if ($#headers >= 0 && $headers[0] =~ /^(AM|PM)$/);

	my %pos = ();
	for (my $i = 0; $i <= $#headers; $i++) {
		$pos{$headers[$i]} = $i;
	}
	my @columns = ();
	foreach my $c (@{$PIDSTAT_COLUMNS{$type}}) {
		# A column can have several names following the sysstat version
		my ($found) = grep { exists $pos{$_} } split(/\|/, $c);
		push(@columns, defined $found ? $pos{$found} : -1);
	}

	return ($type, scalar @headers, @columns);
}

####
# Return the statistics of the timestamp where the values of a process
# must be added, or undef when the line must be skipped. The values of all
# the processes of a sample are summed. A sample is the output of a run of
# pidstat, identified by the offset of its first line in the file. For each
# type of report the offset of the end of the last line counted is kept for
# each sample: a line before this offset was already counted, it is read
# again over the cache. When an other sample has the same timestamp (hour
# repeated by a DST change) it replaces the previous one.
####
sub pidstat_sample_stats
{
	my ($stats, $type, $t, $sample, $pos, $end) = @_;

	my $done = $pidstat_samples{'end'}{$type}{$sample};
	return undef if (defined $done && $pos < $done);

	my $owner = $pidstat_samples{'owner'}{$type}{$t};
	delete $stats->{$t} if (defined $owner && $owner != $sample);

	$pidstat_samples{'end'}{$type}{$sample} = $end;
	$pidstat_samples{'owner'}{$type}{$t} = $sample;

	$stats->{$t} //= {};
	return $stats->{$t};
}

# Split a line stored by load_pidstatfile_stats(), returns the timestamp,
# the sample, the offsets of the line and the values of the columns kept,
# undef for a column not reported by this pidstat version.
sub split_pidstat_line
{
	my ($t, $sample, $pos, $end, @values) = split(/;/, shift, -1);
	return ($t, $sample, $pos, $end, map { ($_ eq '') ? undef : $_ } @values);
}

sub compute_pidstatcpu_stat
{
	foreach my $l (@_)
	{
		my ($t, $sample, $pos, $end, $usr, $system, $guest, $wait, $cpu) = &split_pidstat_line($l);

		# Skip unwanted lines
		next if ($BEGIN && ($t < $BEGIN_STAT));
		next if ($END   && ($t > $END_STAT));

		my $s = &pidstat_sample_stats(\%pidstat_cpu_stat, 'pcpu', $t, $sample, $pos, $end) or next;
		$s->{'all'}{total}  += ($usr||0) + ($system||0);
		$s->{'all'}{user}   += ($usr||0);
		$s->{'all'}{system} += ($system||0);
		$s->{'all'}{cpu}    += ($cpu||0);
		# %wait is reported since sysstat 12.5.1
		$s->{'all'}{wait}   += $wait if (defined $wait);
	}
}

sub compute_pidstatcpu_report
{
	my $data_info = shift();

	my %pidstatcpu_stat = ();
	my $has_wait = 0;
	foreach my $t (sort {$a <=> $b} keys %pidstat_cpu_stat)
	{
		# We only process values from total CPU
		next if (!exists $pidstat_cpu_stat{$t}{'all'});
		my $s = $pidstat_cpu_stat{$t}{'all'};
		$pidstatcpu_stat{total}  .= '[' . $t . ',' . ($s->{total}||0) . '],';
		$pidstatcpu_stat{system} .= '[' . $t . ',' . ($s->{system}||0) . '],';
		$pidstatcpu_stat{user}   .= '[' . $t . ',' . ($s->{user}||0) . '],';
		$pidstatcpu_stat{wait}   .= '[' . $t . ',' . ($s->{wait}||0) . '],';
		# %wait is only reported by recent versions of pidstat
		$has_wait = 1 if (exists $s->{wait});
	}
	%pidstat_cpu_stat = ();

	if (scalar keys %pidstatcpu_stat > 0)
	{
		map { $pidstatcpu_stat{$_} =~ s/,$//; } keys %pidstatcpu_stat;
		if ($has_wait) {
			print $FH &jqplot_linegraph_array($IDX++, 'postgres-cpu', $data_info, 'all', $pidstatcpu_stat{total}, $pidstatcpu_stat{system}, $pidstatcpu_stat{user}, $pidstatcpu_stat{wait});
		} else {
			print $FH &jqplot_linegraph_array($IDX++, 'postgres-cpu', $data_info, 'all', $pidstatcpu_stat{total}, $pidstatcpu_stat{system}, $pidstatcpu_stat{user});
		}
	}
}

sub compute_load_stat
{
	for (my $i = 0; $i <= $#_; $i++) {
		# hostname;interval;timestamp;runq-sz;plist-sz;ldavg-1;ldavg-5;ldavg-15;blocked
		my @data = split(/;/, $_[$i]);
		next if ($data[2] !~ /^\d+/);

		# Skip unwanted lines
		next if ($BEGIN && ($data[2] < $BEGIN_STAT));
		next if ($END   && ($data[2] > $END_STAT));

		map { s/,/\./ } @data ;
		$sar_load_stat{$data[2]}{'ldavg-1'}  = ($data[5]||0);
		$sar_load_stat{$data[2]}{'ldavg-5'}  = ($data[6]||0);
		$sar_load_stat{$data[2]}{'ldavg-15'} = ($data[7]||0);
	}
}

sub compute_load_report
{
	my $data_info = shift();

	my %load_stat = ();
	foreach my $t (sort { $a <=> $b } keys %sar_load_stat) {
		if (!exists $OVERALL_STATS{'system'}{'load'} || ($OVERALL_STATS{'system'}{'load'}[1] < $sar_load_stat{$t}{'ldavg-1'})) {
			@{$OVERALL_STATS{'system'}{'load'}} = ($t, $sar_load_stat{$t}{'ldavg-1'});
		}
		$load_stat{'ldavg-1'}  .= '[' . $t . ',' . $sar_load_stat{$t}{'ldavg-1'} . '],';
		$load_stat{'ldavg-5'}  .= '[' . $t . ',' . $sar_load_stat{$t}{'ldavg-5'} . '],';
		$load_stat{'ldavg-15'} .= '[' . $t . ',' . $sar_load_stat{$t}{'ldavg-15'} . '],';
	}
	%sar_load_stat = ();

	if (scalar keys %load_stat > 0) {
		$load_stat{'ldavg-1'} =~ s/,$//;
		$load_stat{'ldavg-5'} =~ s/,$//;
		$load_stat{'ldavg-15'} =~ s/,$//;
		print $FH &jqplot_linegraph_array($IDX++, 'system-load', $data_info, '', $load_stat{'ldavg-1'}, $load_stat{'ldavg-5'}, $load_stat{'ldavg-15'});
	}
}

sub compute_process_stat
{

	for (my $i = 0; $i <= $#_; $i++) {
		# hostname;interval;timestamp;runq-sz;plist-sz;ldavg-1;ldavg-5;ldavg-15;blocked
		my @data = split(/;/, $_[$i]);
		next if ($data[2] !~ /^\d+/);

		# Skip unwanted lines
		next if ($BEGIN && ($data[2] < $BEGIN_STAT));
		next if ($END   && ($data[2] > $END_STAT));

		map { s/,/\./ } @data ;
		$sar_process_stat{$data[2]}{'plist-sz'}= ($data[4]||0);
		$sar_process_stat{$data[2]}{'runq-sz'} = ($data[3]||0);
		if ($#data > 7) {
			$sar_process_stat{$data[2]}{'blocked'} = ($data[8]||0);
		} else {
			$sar_process_stat{$data[2]}{'blocked'} = 0;
		}
	}
}

sub compute_process_report
{
	my $data_info = shift();

	my %process_stat = ();
	foreach my $t (sort {$a <=> $b} keys %sar_process_stat) {
		if (!exists $OVERALL_STATS{'system'}{'process'} || ($OVERALL_STATS{'system'}{'process'}[1] < $sar_process_stat{$t}{'plist-sz'})) {
			@{$OVERALL_STATS{'system'}{'process'}} = ($t, $sar_process_stat{$t}{'plist-sz'});
		}
		$process_stat{'plist-sz'} .= '[' . $t . ',' . $sar_process_stat{$t}{'plist-sz'} . '],' if (exists $sar_process_stat{$t}{'plist-sz'});
		$process_stat{'runq-sz'}  .= '[' . $t . ',' . $sar_process_stat{$t}{'runq-sz'} . '],' if (exists $sar_process_stat{$t}{'runq-sz'});
		$process_stat{'blocked'}  .= '[' . $t . ',' . $sar_process_stat{$t}{'blocked'} . '],' if (exists $sar_process_stat{$t}{'blocked'});
		if (!exists $OVERALL_STATS{'system'}{'blocked'} || ($OVERALL_STATS{'system'}{'blocked'}[1] < $sar_process_stat{$t}{'blocked'})) {
			@{$OVERALL_STATS{'system'}{'blocked'}} = ($t, $sar_process_stat{$t}{'blocked'});
		}
	}
	if (scalar keys %process_stat > 0) {
		if ($data_info->{name} eq 'system-process') {
			$process_stat{'plist-sz'} =~ s/,$//;
			print $FH &jqplot_linegraph_array($IDX++, 'system-process', $data_info, '', $process_stat{'plist-sz'});
		} elsif ($data_info->{name} eq 'system-runqueue') {
			$process_stat{'runq-sz'} =~ s/,$//;
			$process_stat{'blocked'} =~ s/,$//;
			print $FH &jqplot_linegraph_array($IDX++, 'system-runqueue', $data_info, '', $process_stat{'runq-sz'}, $process_stat{'blocked'});
		}
	}
}

sub compute_context_stat
{

	for (my $i = 0; $i <= $#_; $i++) {
		# hostname;interval;timestamp;proc;cswch
		my @data = split(/;/, $_[$i]);
		next if ($data[2] !~ /^\d+/);

		# Skip unwanted lines
		next if ($BEGIN && ($data[2] < $BEGIN_STAT));
		next if ($END   && ($data[2] > $END_STAT));

		map { s/,/\./ } @data ;
		$sar_context_stat{$data[2]}{'cswch'}  = ($data[4]||0);
		$sar_context_stat{$data[2]}{'pcrea'}  = ($data[3]||0);
	}
}

sub compute_context_report
{
	my $data_info = shift();

	my %context_stat = ();
	foreach my $t (sort {$a <=> $b} keys %sar_context_stat) {
		if (!exists $OVERALL_STATS{'system'}{'cswch'} || ($OVERALL_STATS{'system'}{'cswch'}[1] < $sar_context_stat{$t}{'cswch'})) {
			@{$OVERALL_STATS{'system'}{'cswch'}} = ($t, $sar_context_stat{$t}{'cswch'});
		}
		if ($data_info->{name} eq 'system-cswch') {
			$context_stat{'cswch'}  .= '[' . $t . ',' . $sar_context_stat{$t}{'cswch'} . '],';
		} elsif ($data_info->{name} eq 'system-pcrea') {
			$context_stat{'pcrea'}   .= '[' . $t . ',' . $sar_context_stat{$t}{'pcrea'} . '],';
		}
	}
	if (scalar keys %context_stat > 0) {
		if ($data_info->{name} eq 'system-cswch') {
			$context_stat{'cswch'} =~ s/,$//;
			print $FH &jqplot_linegraph_array($IDX++, 'system-cswch', $data_info, '', $context_stat{'cswch'});
		} elsif ($data_info->{name} eq 'system-pcrea') {
			$context_stat{'pcrea'} =~ s/,$//;
			print $FH &jqplot_linegraph_array($IDX++, 'system-pcrea', $data_info, '', $context_stat{'pcrea'});
		}
	}
}

sub compute_pidstatcontext_stat
{
	foreach my $l (@_)
	{
		my ($t, $sample, $pos, $end, $cswch, $nvcswch) = &split_pidstat_line($l);

		# Skip unwanted lines
		next if ($BEGIN && ($t < $BEGIN_STAT));
		next if ($END   && ($t > $END_STAT));

		my $s = &pidstat_sample_stats(\%pidstat_context_stat, 'pcswch', $t, $sample, $pos, $end) or next;
		$s->{'cswch'}   += ($cswch||0);
		$s->{'nvcswch'} += ($nvcswch||0);
	}
}

sub compute_pidstatcontext_report
{
	my $data_info = shift();
	my %pidstatcontext_stat = ();
	foreach my $t (sort {$a <=> $b} keys %pidstat_context_stat)
	{
		if ($data_info->{name} eq 'postgres-cswch') {
			$pidstatcontext_stat{'cswch'}  .= '[' . $t . ',' . $pidstat_context_stat{$t}{'cswch'} . '],';
			$pidstatcontext_stat{'nvcswch'}   .= '[' . $t . ',' . $pidstat_context_stat{$t}{'nvcswch'} . '],';
		}
	}
	if (exists $pidstatcontext_stat{'cswch'} && exists $pidstatcontext_stat{'nvcswch'})
	{
		$pidstatcontext_stat{'cswch'} =~ s/,$//;
		$pidstatcontext_stat{'nvcswch'} =~ s/,$//;
		print $FH &jqplot_linegraph_array($IDX++, 'postgres-cswch', $data_info, '', $pidstatcontext_stat{'cswch'}, $pidstatcontext_stat{'nvcswch'});
	}
}

sub compute_memory_stat
{
	for (my $i = 0; $i <= $#_; $i++) {
		# hostname;interval;timestamp;kbmemfree;kbmemused;%memused;kbbuffers;kbcached;kbcommit;%commit;kbactive;kbinact;kbdirty
		# hostname;interval;timestamp;kbmemfree;kbavail;kbmemused;%memused;kbbuffers;kbcached;kbcommit;%commit;kbactive;kbinact;kbdirty;kbanonpg;kbslab;kbkstack;kbpgtbl;kbvmused
		my @data = split(/;/, $_[$i]);
		next if ($data[2] !~ /^\d+/);

		# Skip unwanted lines
		next if ($BEGIN && ($data[2] < $BEGIN_STAT));
		next if ($END   && ($data[2] > $END_STAT));

		map { s/,/\./ } @data ;
		$sar_memory_stat{$data[2]}{'kbmemfree'} = ($data[3]*1024)||0;
		# kbavail have been added which change other data indices (sysstat v11.7.4)
		my $i = 0;
		if ($#data > 13) {
			$i = 1;
			$sar_memory_stat{$data[2]}{'kbavail'}  = ($data[4]*1024)||0;
		}
		my $kbcached = ($data[7+$i]*1024) || 0;
		$sar_memory_stat{$data[2]}{'kbcached'}  = $kbcached;
		$sar_memory_stat{$data[2]}{'kbbuffers'} = ($data[6+$i]*1024)||0;
		# New sar version has dirty memory information: kbactive;kbinact;kbdirty
		if ($#data > 9) {
			$sar_memory_stat{$data[2]}{'kbactive'}= ($data[10+$i]*1024)||0;
			$sar_memory_stat{$data[2]}{'kbinact'} = ($data[11+$i]*1024)||0;
			$sar_memory_stat{$data[2]}{'kbdirty'} = ($data[12+$i]*1024)||0;
		}
		if ($#data > 13) {
			$sar_memory_stat{$data[2]}{'kbanonpg'}= ($data[14]*1024)||0;
			$sar_memory_stat{$data[2]}{'kbslab'}= ($data[15]*1024)||0;
			$sar_memory_stat{$data[2]}{'kbkstac'}= ($data[16]*1024)||0;
			$sar_memory_stat{$data[2]}{'kbpgtbl'}= ($data[17]*1024)||0;
			$sar_memory_stat{$data[2]}{'kbvmused'}= ($data[18]*1024)||0;
		}
	}
}

sub compute_memory_report
{
	my $data_info = shift();

	my %memory_stat = ();
	foreach my $t (sort {$a <=> $b} keys %sar_memory_stat) {
		if (!exists $OVERALL_STATS{'system'}{'kbcached'} || ($OVERALL_STATS{'system'}{'kbcached'}[1] > $sar_memory_stat{$t}{'kbcached'})) {
			@{$OVERALL_STATS{'system'}{'kbcached'}} = ($t, $sar_memory_stat{$t}{'kbcached'});
		}
		$memory_stat{'kbcached'}  .= '[' . $t . ',' . $sar_memory_stat{$t}{'kbcached'} . '],';
		$memory_stat{'kbbuffers'} .= '[' . $t . ',' . $sar_memory_stat{$t}{'kbbuffers'} . '],';
		$memory_stat{'kbmemfree'} .= '[' . $t . ',' . $sar_memory_stat{$t}{'kbmemfree'} . '],';
	}
	%sar_memory_stat = ();
	if (scalar keys %memory_stat > 0) {
		$memory_stat{'kbcached'} =~ s/,$//;
		$memory_stat{'kbbuffers'} =~ s/,$//;
		$memory_stat{'kbmemfree'} =~ s/,$//;
		print $FH &jqplot_linegraph_array($IDX++, 'system-memory', $data_info, '', $memory_stat{'kbcached'}, $memory_stat{'kbbuffers'}, $memory_stat{'kbmemfree'});
	}
}

sub compute_pidstatmemory_stat
{
	foreach my $l (@_)
	{
		my ($t, $sample, $pos, $end, $minflt, $majflt, $vsz, $rss, $mem) = &split_pidstat_line($l);

		# Skip unwanted lines
		next if ($BEGIN && ($t < $BEGIN_STAT));
		next if ($END   && ($t > $END_STAT));

		my $s = &pidstat_sample_stats(\%pidstat_memory_stat, 'pmem', $t, $sample, $pos, $end) or next;
		$s->{'minflt/s'} += ($minflt||0);
		$s->{'majflt/s'} += ($majflt||0);
		$s->{'VSZ'}      += ($vsz||0);
		$s->{'RSS'}      += ($rss||0);
		$s->{'%MEM'}     += ($mem||0);
	}
}

sub compute_pidstatmemory_report
{
	my $data_info = shift();

	my %pidstatmemory_stat = ();
	foreach my $t (sort {$a <=> $b} keys %pidstat_memory_stat)
	{
		$pidstatmemory_stat{'VSZ'}  .= '[' . $t . ',' . $pidstat_memory_stat{$t}{'VSZ'} . '],';
		$pidstatmemory_stat{'RSS'} .= '[' . $t . ',' . $pidstat_memory_stat{$t}{'RSS'} . '],';
		$pidstatmemory_stat{'%MEM'} .= '[' . $t . ',' . $pidstat_memory_stat{$t}{'%MEM'} . '],';
	}
	if (scalar keys %pidstatmemory_stat > 0)
	{
		if ($data_info->{name} eq 'postgres-memory')
		{
			$pidstatmemory_stat{'VSZ'} =~ s/,$//;
			$pidstatmemory_stat{'RSS'} =~ s/,$//;
			print $FH &jqplot_linegraph_array($IDX++, 'postgres-memory', $data_info, '', $pidstatmemory_stat{'VSZ'}, $pidstatmemory_stat{'RSS'});
		}
		elsif ($data_info->{name} eq 'postgres-mempercent')
		{
			$pidstatmemory_stat{'%MEM'} =~ s/,$//;
			print $FH &jqplot_linegraph_array($IDX++, 'postgres-mempercent', $data_info, '',  $pidstatmemory_stat{'%MEM'});
		}
	}
}

sub compute_dirty_stat
{
	for (my $i = 0; $i <= $#_; $i++)
	{
		# hostname;interval;timestamp;kbmemfree;kbmemused;%memused;kbbuffers;kbcached;kbcommit;%commit;kbactive;kbinact;kbdirty
		my @data = split(/;/, $_[$i]);
		next if ($data[2] !~ /^\d+/);

		# New sar version has dirty memory information: kbactive;kbinact;kbdirty
		next if ($#data <= 9);

		# Skip unwanted lines
		next if ($BEGIN && ($data[2] < $BEGIN_STAT));
		next if ($END   && ($data[2] > $END_STAT));

		map { s/,/\./ } @data ;

		$sar_dirty_stat{$data[2]}{'kbactive'}= ($data[10]*1024)||0;
		$sar_dirty_stat{$data[2]}{'kbinact'} = ($data[11]*1024)||0;
		$sar_dirty_stat{$data[2]}{'kbdirty'} = ($data[12]*1024)||0;
	}
}

sub compute_dirty_report
{
	my $data_info = shift();

	my %dirty_stat = ();
	foreach my $t (sort {$a <=> $b} keys %sar_dirty_stat) {
		$dirty_stat{'kbactive'}  .= '[' . $t . ',' . $sar_dirty_stat{$t}{'kbactive'} . '],';
		$dirty_stat{'kbinact'} .= '[' . $t . ',' . $sar_dirty_stat{$t}{'kbinact'} . '],';
		$dirty_stat{'kbdirty'} .= '[' . $t . ',' . $sar_dirty_stat{$t}{'kbdirty'} . '],';
		if (!exists $OVERALL_STATS{'system'}{'kbdirty'} || ($OVERALL_STATS{'system'}{'kbdirty'}[1] < $sar_dirty_stat{$t}{'kbdirty'})) {
			@{$OVERALL_STATS{'system'}{'kbdirty'}} = ($t, $sar_dirty_stat{$t}{'kbdirty'});
		}
	}
	%sar_dirty_stat = ();
	if (scalar keys %dirty_stat > 0) {
		$dirty_stat{'kbactive'} =~ s/,$//;
		$dirty_stat{'kbinact'} =~ s/,$//;
		$dirty_stat{'kbdirty'} =~ s/,$//;
		print $FH &jqplot_linegraph_array($IDX++, 'system-dirty', $data_info, '', $dirty_stat{'kbactive'}, $dirty_stat{'kbinact'}, $dirty_stat{'kbdirty'});
	}
}

sub compute_swap_stat
{
	for (my $i = 0; $i <= $#_; $i++) {
		# hostname;interval;timestamp;pswpin/s;pswpout/s
		my @data = split(/;/, $_[$i]);
		next if ($data[2] !~ /^\d+/);

		# Skip unwanted lines
		next if ($BEGIN && ($data[2] < $BEGIN_STAT));
		next if ($END   && ($data[2] > $END_STAT));

		map { s/,/\./ } @data ;
		$sar_swap_stat{$data[2]}{'pswpin/s'}  = ($data[3]||0);
		$sar_swap_stat{$data[2]}{'pswpout/s'} = ($data[4]||0);
	}
}

sub compute_swap_report
{
	my $data_info = shift();

	my %swap_stat = ();
	foreach my $t (sort {$a <=> $b} keys %sar_swap_stat) {
		if (!exists $OVERALL_STATS{'system'}{'pswpin'} || ($OVERALL_STATS{'system'}{'pswpin'}[1] < $sar_swap_stat{$t}{'pswpin/s'})) {
			@{$OVERALL_STATS{'system'}{'pswpin'}} = ($t, $sar_swap_stat{$t}{'pswpin/s'});
		}
		if (!exists $OVERALL_STATS{'system'}{'pswpout'} || ($OVERALL_STATS{'system'}{'pswpout'}[1] < $sar_swap_stat{$t}{'pswpout/s'})) {
			@{$OVERALL_STATS{'system'}{'pswpout'}} = ($t, $sar_swap_stat{$t}{'pswpout/s'});
		}
		$swap_stat{'pswpin/s'}  .= '[' . $t . ',' . $sar_swap_stat{$t}{'pswpin/s'} . '],';
		$swap_stat{'pswpout/s'} .= '[' . $t . ',' . $sar_swap_stat{$t}{'pswpout/s'} . '],';
	}
	%sar_swap_stat = ();
	if (scalar keys %swap_stat > 0) {
		$swap_stat{'pswpin/s'} =~ s/,$//;
		$swap_stat{'pswpout/s'} =~ s/,$//;
		print $FH &jqplot_linegraph_array($IDX++, 'system-swap', $data_info, '', $swap_stat{'pswpin/s'}, $swap_stat{'pswpout/s'});
	}
}

sub compute_page_stat
{
	for (my $i = 0; $i <= $#_; $i++) {
		# hostname;interval;timestamp;pgpgin/s;pgpgout/s;fault/s;majflt/s;pgfree/s;pgscank/s;pgscand/s;pgsteal/s;%vmeff
		my @data = split(/;/, $_[$i]);
		next if ($data[2] !~ /^\d+/);

		# Skip unwanted lines
		next if ($BEGIN && ($data[2] < $BEGIN_STAT));
		next if ($END   && ($data[2] > $END_STAT));

		map { s/,/\./ } @data ;
		$sar_pageswap_stat{$data[2]}{'pgpgin/s'}  = ($data[3]||0);
		$sar_pageswap_stat{$data[2]}{'pgpgout/s'} = ($data[4]||0);
		$sar_pageswap_stat{$data[2]}{'majflt/s'}  = ($data[6]||0);
		$sar_pageswap_stat{$data[2]}{'minflt/s'}   = (($data[5]-$data[6])||0);
		$sar_pageswap_stat{$data[2]}{'pgfree/s'}  = ($data[7]||0);
		$sar_pageswap_stat{$data[2]}{'pgscank/s'}  = ($data[8]||0);
		$sar_pageswap_stat{$data[2]}{'pgscand/s'}  = ($data[9]||0);
		$sar_pageswap_stat{$data[2]}{'pgsteal/s'}  = ($data[10]||0);
		$sar_pageswap_stat{$data[2]}{'%vmeff'}  = ($data[11]||0);
	}
}

sub compute_page_report
{
	my $data_info = shift();

	my %pageswap_stat = ();
	foreach my $t (sort {$a <=> $b} keys %sar_pageswap_stat)
	{
		if (!exists $OVERALL_STATS{'system'}{'pgpgin'} || ($OVERALL_STATS{'system'}{'pgpgin'}[1] < $sar_pageswap_stat{$t}{'pgpgin/s'})) {
			@{$OVERALL_STATS{'system'}{'pgpgin'}} = ($t, $sar_pageswap_stat{$t}{'pgpgin/s'});
		}
		if (!exists $OVERALL_STATS{'system'}{'pgpgout'} || ($OVERALL_STATS{'system'}{'pgpgout'}[1] < $sar_pageswap_stat{$t}{'pgpgout/s'})) {
			@{$OVERALL_STATS{'system'}{'pgpgout'}} = ($t, $sar_pageswap_stat{$t}{'pgpgout/s'});
		}
		$pageswap_stat{'pgpgin/s'}  .= '[' . $t . ',' . $sar_pageswap_stat{$t}{'pgpgin/s'} . '],';
		$pageswap_stat{'pgpgout/s'} .= '[' . $t . ',' . $sar_pageswap_stat{$t}{'pgpgout/s'} . '],';
	}
	if (scalar keys %pageswap_stat > 0)
	{
		$pageswap_stat{'pgpgin/s'} =~ s/,$//;
		$pageswap_stat{'pgpgout/s'} =~ s/,$//;
		print $FH &jqplot_linegraph_array($IDX++, 'system-page', $data_info, '', $pageswap_stat{'pgpgin/s'}, $pageswap_stat{'pgpgout/s'});
	}
}

sub compute_fault_report
{
	my $data_info = shift();

	my %pageswap_stat = ();
	foreach my $t (sort {$a <=> $b} keys %sar_pageswap_stat)
	{
		if (!exists $OVERALL_STATS{'system'}{'majflt'} || ($OVERALL_STATS{'system'}{'majflt'}[1] < $sar_pageswap_stat{$t}{'majflt/s'})) {
			@{$OVERALL_STATS{'system'}{'majflt'}} = ($t, $sar_pageswap_stat{$t}{'majflt/s'});
		}
		if (!exists $OVERALL_STATS{'system'}{'minflt'} || ($OVERALL_STATS{'system'}{'minflt'}[1] < $sar_pageswap_stat{$t}{'minflt/s'})) {
			@{$OVERALL_STATS{'system'}{'minflt'}} = ($t, $sar_pageswap_stat{$t}{'minflt/s'});
		}
		$pageswap_stat{'majflt/s'}  .= '[' . $t . ',' . $sar_pageswap_stat{$t}{'majflt/s'} . '],';
		$pageswap_stat{'minflt/s'}   .= '[' . $t . ',' . $sar_pageswap_stat{$t}{'minflt/s'} . '],';
	}
	if (scalar keys %pageswap_stat > 0) {
		$pageswap_stat{'majflt/s'} =~ s/,$//;
		$pageswap_stat{'minflt/s'} =~ s/,$//;
		print $FH &jqplot_linegraph_array($IDX++, 'system-fault', $data_info, '', $pageswap_stat{'majflt/s'}, $pageswap_stat{'minflt/s'});
	}
}

sub compute_pidstatfault_report
{
	my $data_info = shift();

	my %pidstatfault_stat = ();
	foreach my $t (sort {$a <=> $b} keys %pidstat_memory_stat)
	{
		$pidstatfault_stat{'majflt/s'} .= '[' . $t . ',' . $pidstat_memory_stat{$t}{'majflt/s'} . '],';
		$pidstatfault_stat{'minflt/s'} .= '[' . $t . ',' . $pidstat_memory_stat{$t}{'minflt/s'} . '],';
	}
	if (scalar keys %pidstatfault_stat > 0)
	{
		$pidstatfault_stat{'majflt/s'} =~ s/,$//;
		$pidstatfault_stat{'minflt/s'} =~ s/,$//;
		print $FH &jqplot_linegraph_array($IDX++, 'postgres-fault', $data_info, '', $pidstatfault_stat{'minflt/s'}, $pidstatfault_stat{'majflt/s'});
		%pidstat_memory_stat = ();
	}
}

sub compute_scanpage_report
{
	my $data_info = shift();

	my %pageswap_stat = ();
	foreach my $t (sort {$a <=> $b} keys %sar_pageswap_stat) {
		if (!exists $OVERALL_STATS{'system'}{'pgfree'} || ($OVERALL_STATS{'system'}{'pgfree'}[1] < $sar_pageswap_stat{$t}{'pgfree/s'})) {
			@{$OVERALL_STATS{'system'}{'pgfree'}} = ($t, $sar_pageswap_stat{$t}{'pgfree/s'});
		}
		if (!exists $OVERALL_STATS{'system'}{'pgscank'} || ($OVERALL_STATS{'system'}{'pgscank'}[1] < $sar_pageswap_stat{$t}{'pgscank/s'})) {
			@{$OVERALL_STATS{'system'}{'pgscank'}} = ($t, $sar_pageswap_stat{$t}{'pgscank/s'});
		}
		if (!exists $OVERALL_STATS{'system'}{'pgscand'} || ($OVERALL_STATS{'system'}{'pgscand'}[1] < $sar_pageswap_stat{$t}{'pgscand/s'})) {
			@{$OVERALL_STATS{'system'}{'pgscand'}} = ($t, $sar_pageswap_stat{$t}{'pgscand/s'});
		}
		if (!exists $OVERALL_STATS{'system'}{'pgsteal'} || ($OVERALL_STATS{'system'}{'pgsteal'}[1] < $sar_pageswap_stat{$t}{'pgsteal/s'})) {
			@{$OVERALL_STATS{'system'}{'pgsteal'}} = ($t, $sar_pageswap_stat{$t}{'pgsteal/s'});
		}
		if (!exists $OVERALL_STATS{'system'}{'vmeff'} || ($OVERALL_STATS{'system'}{'vmeff'}[1] < $sar_pageswap_stat{$t}{'%vmeff'})) {
			@{$OVERALL_STATS{'system'}{'vmeff'}} = ($t, $sar_pageswap_stat{$t}{'%vmeff'});
		}
		$pageswap_stat{'pgfree/s'}   .= '[' . $t . ',' . $sar_pageswap_stat{$t}{'pgfree/s'} . '],';
		$pageswap_stat{'pgscank/s'}   .= '[' . $t . ',' . $sar_pageswap_stat{$t}{'pgscank/s'} . '],';
		$pageswap_stat{'pgscand/s'}   .= '[' . $t . ',' . $sar_pageswap_stat{$t}{'pgscand/s'} . '],';
		$pageswap_stat{'pgsteal/s'}   .= '[' . $t . ',' . $sar_pageswap_stat{$t}{'pgsteal/s'} . '],';
		$pageswap_stat{'%vmeff'}   .= '[' . $t . ',' . $sar_pageswap_stat{$t}{'%vmeff'} . '],';
	}
	%sar_pageswap_stat = ();
	if (scalar keys %pageswap_stat > 0) {
		$pageswap_stat{'pgfree/s'} =~ s/,$//;
		$pageswap_stat{'pgscank/s'} =~ s/,$//;
		$pageswap_stat{'pgscand/s'} =~ s/,$//;
		$pageswap_stat{'pgsteal/s'} =~ s/,$//;
		$pageswap_stat{'%vmeff'} =~ s/,$//;
		print $FH &jqplot_linegraph_array($IDX++, 'system-scanpage', $data_info, '', $pageswap_stat{'pgscank/s'}, $pageswap_stat{'pgscand/s'}, $pageswap_stat{'pgsteal/s'}, $pageswap_stat{'%vmeff'});
	}
}

sub compute_block_stat
{
	for (my $i = 0; $i <= $#_; $i++) {
		# hostname;interval;timestamp;tps;rtps;wtps;bread/s;bwrtn/s
		my @data = split(/;/, $_[$i]);
		next if ($data[2] !~ /^\d+/);

		# Skip unwanted lines
		next if ($BEGIN && ($data[2] < $BEGIN_STAT));
		next if ($END   && ($data[2] > $END_STAT));

		map { s/,/\./ } @data;
		$sar_block_stat{$data[2]}{'bread/s'} = ($data[6]||0);
		$sar_block_stat{$data[2]}{'bwrtn/s'} = ($data[7]||0);
		$sar_block_stat{$data[2]}{'tps'} = ($data[3]||0);
		$sar_block_stat{$data[2]}{'rtps'} = ($data[4]||0);
		$sar_block_stat{$data[2]}{'wtps'} = ($data[5]||0);
	}
}

sub compute_block_report
{
	my $data_info = shift();

	my %block_stat = ();
	foreach my $t (sort {$a <=> $b} keys %sar_block_stat) {
		if (!exists $OVERALL_STATS{'system'}{'bread'} || ($OVERALL_STATS{'system'}{'bread'}[1] < $sar_block_stat{$t}{'bread/s'})) {
			@{$OVERALL_STATS{'system'}{'bread'}} = ($t, $sar_block_stat{$t}{'bread/s'});
		}
		if (!exists $OVERALL_STATS{'system'}{'bwrite'} || ($OVERALL_STATS{'system'}{'bwrite'}[1] < $sar_block_stat{$t}{'bwrtn/s'})) {
			@{$OVERALL_STATS{'system'}{'bwrite'}} = ($t, $sar_block_stat{$t}{'bwrtn/s'});
		}
		$block_stat{'bread/s'} .= '[' . $t . ',' . $sar_block_stat{$t}{'bread/s'} . '],';
		$block_stat{'bwrtn/s'} .= '[' . $t . ',' . $sar_block_stat{$t}{'bwrtn/s'} . '],';
		$block_stat{'tps'} .= '[' . $t . ',' . $sar_block_stat{$t}{'tps'} . '],';
		$block_stat{'rtps'} .= '[' . $t . ',' . $sar_block_stat{$t}{'rtps'} . '],';
		$block_stat{'wtps'} .= '[' . $t . ',' . $sar_block_stat{$t}{'wtps'} . '],';
	}
	if (scalar keys %block_stat > 0) {
		if ($data_info->{name} eq 'system-block') {
			%sar_block_stat = ();
			$block_stat{'bread/s'} =~ s/,$//;
			$block_stat{'bwrtn/s'} =~ s/,$//;
			print $FH &jqplot_linegraph_array($IDX++, 'system-block', $data_info, '', $block_stat{'bread/s'}, $block_stat{'bwrtn/s'});
		} elsif ($data_info->{name} eq 'system-tps') {
			$block_stat{'tps'} =~ s/,$//;
			$block_stat{'rtps'} =~ s/,$//;
			$block_stat{'wtps'} =~ s/,$//;
			print $FH &jqplot_linegraph_array($IDX++, 'system-tps', $data_info, '', $block_stat{'tps'}, $block_stat{'rtps'}, $block_stat{'wtps'});
		}
	}
}

sub compute_pidstatio_stat
{
	foreach my $l (@_)
	{
		my ($t, $sample, $pos, $end, $rd, $wr, $ccwr, $iodelay) = &split_pidstat_line($l);

		# Skip unwanted lines
		next if ($BEGIN && ($t < $BEGIN_STAT));
		next if ($END   && ($t > $END_STAT));

		my $s = &pidstat_sample_stats(\%pidstat_io_stat, 'pio', $t, $sample, $pos, $end) or next;
		# -1 is reported for the processes whose statistics can not be read
		$s->{'kB_rd/s'}   += $rd if (($rd||0) > 0);
		$s->{'kB_wr/s'}   += $wr if (($wr||0) > 0);
		$s->{'kB_ccwr/s'} += $ccwr if (($ccwr||0) > 0);
		$s->{$_} //= 0 foreach ('kB_rd/s', 'kB_wr/s', 'kB_ccwr/s');
		# iodelay is reported since sysstat 10.0.1
		if (defined $iodelay) {
			$s->{'iodelay'} += ($iodelay > 0) ? $iodelay : 0;
		}
	}
}

sub compute_pidstatio_report
{
	my $data_info = shift();

	my %lpidstatio_stat = ();
	foreach my $t (sort {$a <=> $b} keys %pidstat_io_stat)
	{
		$lpidstatio_stat{'kB_rd/s'} .= '[' . $t . ',' . ($pidstat_io_stat{$t}{'kB_rd/s'}||0) . '],';
		$lpidstatio_stat{'kB_wr/s'} .= '[' . $t . ',' . ($pidstat_io_stat{$t}{'kB_wr/s'}||0) . '],';
		$lpidstatio_stat{'kB_ccwr/s'} .= '[' . $t . ',' . ($pidstat_io_stat{$t}{'kB_ccwr/s'}||0) . '],';
		$lpidstatio_stat{'iodelay'} .= '[' . $t . ',' . ($pidstat_io_stat{$t}{'iodelay'}||0) . '],';
	}

	if (scalar keys %lpidstatio_stat > 0)
	{
		if ($data_info->{name} eq 'postgres-io')
		{
			$lpidstatio_stat{'kB_rd/s'} =~ s/,$//;
			$lpidstatio_stat{'kB_wr/s'} =~ s/,$//;
			$lpidstatio_stat{'kB_ccwr/s'} =~ s/,$//;
			print $FH &jqplot_linegraph_array($IDX++, 'postgres-io', $data_info, '', $lpidstatio_stat{'kB_rd/s'}, $lpidstatio_stat{'kB_wr/s'}, $lpidstatio_stat{'kB_ccwr/s'});
		}
		elsif ($data_info->{name} eq 'postgres-iodelay')
		{
			$lpidstatio_stat{'iodelay'} =~ s/,$//;
			print $FH &jqplot_linegraph_array($IDX++, 'postgres-iodelay', $data_info, '', $lpidstatio_stat{'iodelay'});
			%pidstat_io_stat = ();
		}
	}
}

sub compute_srvtime_stat
{
	for (my $i = 0; $i <= $#_; $i++)
	{
	    # See compute_rw_device_stat for explanation of columns of $data,
	    # and sar_stats.dat examples in load_sarfile_stats

	    my @data = split(/;/, $_[$i]);
		# print ("DEBUG : CC, data2 = $data[2] ; data3 = $data[3] ; data9 = $data[9] \n");
		next if ($data[2] !~ /^\d+/);

		# Skip unwanted lines
		next if ($BEGIN && ($data[2] < $BEGIN_STAT));
		next if ($END   && ($data[2] > $END_STAT));
		my $device = $data[3 + (8 * $SAR_UPPER_12_3_9)] ;
		next if (!&device_in_report($device));

		map { s/,/\./ } @data ;

		if ($SAR_UPPER_12_3_9) {
			$sar_srvtime_stat{$data[2]}{$device}{'await'} = ($data[9]||0);
		} elsif ($SAR_UPPER_12_1_1) {
			# sar > 12.1.1 and sar < 12.4.0
			$sar_srvtime_stat{$data[2]}{$device}{'await'} = ($data[10]||0);
		} else {     # sar < 12.1.2
			$sar_srvtime_stat{$data[2]}{$device}{'await'} = ($data[9]||0);
			$sar_srvtime_stat{$data[2]}{$device}{'svctm'} = ($data[10]||0);
		}
	}
}

sub compute_srvtime_report
{
	my $data_info = shift();
	my $src_base = shift();

	my %srvtime_stat = ();
	foreach my $t (sort {$a <=> $b} keys %sar_srvtime_stat)
	{
		foreach my $dev (sort keys %{$sar_srvtime_stat{$t}})
		{
			if ($SAR_UPPER_12_1_1)
			{
				if (!exists $OVERALL_STATS{'system'}{'await'} || ($OVERALL_STATS{'system'}{'await'}[1] < $sar_srvtime_stat{$t}{$dev}{'await'})) {
					@{$OVERALL_STATS{'system'}{'await'}} = ($t, $sar_srvtime_stat{$t}{$dev}{'await'}, $dev);
				}
				$srvtime_stat{$dev}{'await'} .= '[' . $t . ',' . $sar_srvtime_stat{$t}{$dev}{'await'} . '],';
			}
			else
			{
				if (!exists $OVERALL_STATS{'system'}{'svctm'} || ($OVERALL_STATS{'system'}{'svctm'}[1] < $sar_srvtime_stat{$t}{$dev}{'svctm'})) {
					@{$OVERALL_STATS{'system'}{'svctm'}} = ($t, $sar_srvtime_stat{$t}{$dev}{'svctm'}, $dev);
				}
				$srvtime_stat{$dev}{'await'} .= '[' . $t . ',' . $sar_srvtime_stat{$t}{$dev}{'await'} . '],';
				$srvtime_stat{$dev}{'svctm'} .= '[' . $t . ',' . $sar_srvtime_stat{$t}{$dev}{'svctm'} . '],';
			}
		}
	}
	%sar_srvtime_stat = ();
	if (scalar keys %srvtime_stat > 0)
	{
		foreach my $n (sort { $a cmp $b } keys %srvtime_stat)
		{
			next if ($n =~ /^loop\d+/);
			push(@DEVICE_LIST, $n) if (!grep(/^$n$/, @DEVICE_LIST));
			$srvtime_stat{$n}{'await'} =~ s/,$//;
			if (exists $srvtime_stat{$n}{'svctm'}) {
				$srvtime_stat{$n}{'svctm'} =~ s/,$//;
			}
			# Open a filehandle for each database
			my $fh = IO::File->new("$OUTPUT_DIR/$data_info->{name}-$n.html", 'w');
			if (not defined $fh) {
				die "FATAL: can't write to $OUTPUT_DIR/$data_info->{name}-$n.html, $!\n";
			}
			&html_header($fh, $src_base);
			$fh->print("<ul id=\"slides\">\n");
			if (exists $srvtime_stat{$n}{'svctm'}) {
				$fh->print( &jqplot_linegraph_array($IDX++, 'device-service_time', $data_info, $n, $srvtime_stat{$n}{'await'}, $srvtime_stat{$n}{'svctm'}) );
			} else {
				$fh->print( &jqplot_linegraph_array($IDX++, 'device-await_time', $data_info, $n, $srvtime_stat{$n}{'await'}) );
			}
                        $fh->print("</ul>\n");
                        &html_footer($fh, $n);
                        $fh->close;
		}
	}
}

sub compute_rw_device_stat
{
	for (my $i = 0; $i <= $#_; $i++) {

		# See function load_sarfile_stats for explanations of sar -dp output
		#
		# timestamp        : data[2]
		# device           : data[3] (sar < 12.4.0)  or   data [11] (sar >=12.4.0)
		# tps              : data[4]
		# rd_sec/s (rkB/s) : data[5]
		# wr_sec/s (wkB/s) : data[6]
		# await            : data[9]   (except sar > 12.1.1 and sar < 12.4.0 : data[10] )
		# %util            : data[10]  (          "                 "        : data[11] )

		my @data = split(/;/, $_[$i]);
		next if ($data[2] !~ /^\d+/);

		# Skip unwanted lines
		next if ($BEGIN && ($data[2] < $BEGIN_STAT));
		next if ($END   && ($data[2] > $END_STAT));

		my $device = $data[3 + (8 * $SAR_UPPER_12_3_9)] ;  # 3 or 11
		next if (!&device_in_report($device));

		map { s/,/\./ } @data ;
		my $sector = 512;
		$sector = 1024 if ($SAR_UPPER_11_5_6);
		$sar_rw_devices_stat{$data[2]}{$device}{'rd_sec/s'} = ($data[5]*$sector);
		$sar_rw_devices_stat{$data[2]}{$device}{'wr_sec/s'} = ($data[6]*$sector);
		$sar_rw_devices_stat{$data[2]}{$device}{'tps'}      = ($data[4]||0);
	}
}

sub compute_rw_device_report
{
	my $data_info = shift();
	my $src_base = shift();

	my %devices_stat = ();

	# for each timestamp
	foreach my $t (sort {$a <=> $b} keys %sar_rw_devices_stat) {

		# for each device
		foreach my $dev (keys %{$sar_rw_devices_stat{$t}}) {

			if ($data_info->{name} eq 'system-device') {
				$OVERALL_STATS{'system'}{'devices'}{$dev}{read} += $sar_rw_devices_stat{$t}{$dev}{'rd_sec/s'};
				$OVERALL_STATS{'system'}{'devices'}{$dev}{write} += $sar_rw_devices_stat{$t}{$dev}{'wr_sec/s'};
				$devices_stat{$dev}{'rd_sec/s'} .= '[' . $t . ',' . $sar_rw_devices_stat{$t}{$dev}{'rd_sec/s'} . '],';
				$devices_stat{$dev}{'wr_sec/s'} .= '[' . $t . ',' . $sar_rw_devices_stat{$t}{$dev}{'wr_sec/s'} . '],';
			} elsif ($data_info->{name} eq 'system-tpsdevice') {
				$devices_stat{$dev}{'tps'}      .= '[' . $t . ',' . $sar_rw_devices_stat{$t}{$dev}{'tps'} . '],';
				$OVERALL_STATS{'system'}{'devices'}{$dev}{tps} = $sar_rw_devices_stat{$t}{$dev}{'tps'} if (!$OVERALL_STATS{'system'}{'devices'}{$dev}{tps} || ($OVERALL_STATS{'system'}{'devices'}{$dev}{tps} < $sar_rw_devices_stat{$t}{$dev}{'tps'}));
			}
		}
	}

	if (scalar keys %devices_stat > 0) {
		foreach my $n (sort { $a cmp $b } keys %devices_stat) {
			next if ($n =~ /^loop\d+/);

			push(@DEVICE_LIST, $n) if (!grep(/^$n$/, @DEVICE_LIST));

			# Open a filehandle for each database
			my $fh = IO::File->new("$OUTPUT_DIR/$data_info->{name}-$n.html", 'w');
			if (not defined $fh) {
				die "FATAL: can't write to $OUTPUT_DIR/$data_info->{name}-$n.html, $!\n";
			}
			&html_header($fh, $src_base);
			$fh->print("<ul id=\"slides\">\n");
			if ($data_info->{name} eq 'system-device') {
				$devices_stat{$n}{'rd_sec/s'} =~ s/,$//;
				$devices_stat{$n}{'wr_sec/s'} =~ s/,$//;
				$fh->print( &jqplot_linegraph_array($IDX++, 'device-read_write', $data_info, $n, $devices_stat{$n}{'rd_sec/s'}, $devices_stat{$n}{'wr_sec/s'}) );
			} elsif ($data_info->{name} eq 'system-tpsdevice') {
				$devices_stat{$n}{'tps'} =~ s/,$//;
				$fh->print( &jqplot_linegraph_array($IDX++, 'device-tps', $data_info, $n, $devices_stat{$n}{'tps'}) );
			}
                        $fh->print("</ul>\n");
                        &html_footer($fh, $n);
                        $fh->close;
		}
	}
	@DEVICE_LIST = sort @DEVICE_LIST
}

sub compute_space_device_stat
{
	my %devices = ();
	for (my $i = 0; $i <= $#_; $i++) {
		# hostname;interval;timestamp;MBfsfree;MBfsused;%fsused;%ufsused;Ifree;Iused;%Iused;FILESYSTEM
		my @data = split(/;/, $_[$i]);
		next if ($data[2] !~ /^\d+/);
		$data[10] =~ s/.*\///;
		next if ($data[10] =~ /^(loop|tmpfs|udev)/);

		# Skip unwanted lines
		next if ($BEGIN && ($data[2] < $BEGIN_STAT));
		next if ($END   && ($data[2] > $END_STAT));
		next if (!&device_in_report($data[10]));
		$sar_space_devices_stat{$data[2]}{$data[10]}{'%fsused'} = $data[5];
		$sar_space_devices_stat{$data[2]}{$data[10]}{'%iused'} = $data[9];
		$devices{$data[10]} = 1;
	}
	foreach my $k (keys %devices) {
		if (!grep(/^$k$/, @DEVICE_SPACE_LIST)) {
			push(@DEVICE_SPACE_LIST, $k) if (!grep(/^$k$/, @DEVICE_SPACE_LIST));
		}
	}
}

sub compute_space_device_report
{
	my $data_info = shift();
	my $src_base = shift();

	my %devices_stat = ();
	foreach my $t (sort {$a <=> $b} keys %sar_space_devices_stat) {
		foreach my $dev (keys %{$sar_space_devices_stat{$t}}) {
			if ($data_info->{name} eq 'system-space') {
				$OVERALL_STATS{'system'}{'space'}{$dev}{'fsused'} = $sar_space_devices_stat{$t}{$dev}{'%fsused'} if (!exists $OVERALL_STATS{'system'}{'space'}{$dev}{'fsused'} || $sar_space_devices_stat{$t}{$dev}{'%fsused'} > $OVERALL_STATS{'system'}{'space'}{$dev}{'fsused'});
				$OVERALL_STATS{'system'}{'space'}{$dev}{'iused'} = $sar_space_devices_stat{$t}{$dev}{'%iused'} if (!exists $OVERALL_STATS{'system'}{'space'}{$dev}{'iused'} || $sar_space_devices_stat{$t}{$dev}{'%iused'} > $OVERALL_STATS{'system'}{'space'}{$dev}{'iused'});
				$devices_stat{$dev}{'%fsused'} .= '[' . $t . ',' . $sar_space_devices_stat{$t}{$dev}{'%fsused'} . '],';
				$devices_stat{$dev}{'%iused'} .= '[' . $t . ',' . $sar_space_devices_stat{$t}{$dev}{'%iused'} . '],';
			}
		}
	}

	if (scalar keys %devices_stat > 0) {
		foreach my $n (sort { $a cmp $b } keys %devices_stat) {
			next if ($n =~ /^loop\d+/);
			if (!grep(/^$n$/, @DEVICE_SPACE_LIST)) {
				push(@DEVICE_SPACE_LIST, $n);
			}
			# Open a filehandle for each database
			my $fh = IO::File->new("$OUTPUT_DIR/system-space-$n.html", 'w');
			if (not defined $fh) {
				die "FATAL: can't write to $OUTPUT_DIR/system-space-$n.html, $!\n";
			}
			&html_header($fh, $src_base);
			$fh->print("<ul id=\"slides\">\n");
			if ($data_info->{name} eq 'system-space') {
				$devices_stat{$n}{'%fsused'} =~ s/,$//;
				$devices_stat{$n}{'%iused'} =~ s/,$//;
				$fh->print( &jqplot_linegraph_array($IDX++, 'device-space', $data_info, $n, $devices_stat{$n}{'%fsused'}, $devices_stat{$n}{'%iused'}) );

			}
			$fh->print("</ul>\n");
			&html_footer($fh, $n);
			$fh->close;
		}
	}
}

sub compute_util_device_stat
{
	# See function compute_rw_device_stat for explanation of columns of $data
	# and function load_sarfile_stats for examples of sar_stats.dat

	my %devices = ();

	for (my $i = 0; $i <= $#_; $i++) {

		my @data = split(/;/, $_[$i]);
		next if ($data[2] !~ /^\d+/);

		# Skip unwanted lines
		next if ($BEGIN && ($data[2] < $BEGIN_STAT));
		next if ($END   && ($data[2] > $END_STAT));
		my $device = $data[3 + (8 * $SAR_UPPER_12_3_9)] ;
		next if (!&device_in_report($device));

		map { s/,/\./ } @data ;
		# %util is stored in data[10], except for sar > 12.1.1 and sar < 12.4.0, where it is data[11]
		$sar_util_devices_stat{$data[2]}{$device}{'%util'} = ($data[10 + $SAR_UPPER_12_1_1 - $SAR_UPPER_12_3_9 ]||0);
		$devices{$device} = 1;
	}
	foreach my $k (keys %devices) {
		push(@DEVICE_LIST, $k) if (!grep(/^$k$/, @DEVICE_LIST));
	}
}

sub compute_util_device_report
{
	my $data_info = shift();
	my $src_base = shift();

	my %devices_stat = ();
	foreach my $t (sort {$a <=> $b} keys %sar_util_devices_stat) {
		foreach my $dev (keys %{$sar_util_devices_stat{$t}}) {
			$devices_stat{$dev}{'%util'} .= '[' . $t . ',' . $sar_util_devices_stat{$t}{$dev}{'%util'} . '],';
		}
	}
	%sar_util_devices_stat = ();
	if (scalar keys %devices_stat > 0) {
		foreach my $n (sort { $a cmp $b } keys %devices_stat) {
			next if ($n =~ /^loop\d+/);

			push(@DEVICE_LIST, $n) if (!grep(/^$n$/, @DEVICE_LIST));

			# Open a filehandle for each database
			my $fh = IO::File->new("$OUTPUT_DIR/$data_info->{name}-$n.html", 'w');
			if (not defined $fh) {
				die "FATAL: can't write to $OUTPUT_DIR/$data_info->{name}-$n.html, $!\n";
			}
			&html_header($fh, $src_base);
			$fh->print("<ul id=\"slides\">\n");
			$devices_stat{$n}{'%util'} =~ s/,$//;
			$fh->print( &jqplot_linegraph_array($IDX++, 'device-cpu', $data_info, $n, $devices_stat{$n}{'%util'}) );
                        $fh->print("</ul>\n");
                        &html_footer($fh, $n);
                        $fh->close;
		}
	}
}

sub compute_network_stat
{
	my %devices = ();

	for (my $i = 0; $i <= $#_; $i++) {
		# hostname;interval;timestamp;IFACE;rxpck/s;txpck/s;rxkB/s;txkB/s;rxcmp/s;txcmp/s;rxmcst/s
		my @data = split(/;/, $_[$i]);
		next if ($data[2] !~ /^\d+/);

		# Skip unwanted lines
		next if ($BEGIN && ($data[2] < $BEGIN_STAT));
		next if ($END   && ($data[2] > $END_STAT));
		next if (!&interface_in_report($data[3]));

		map { s/,/\./ } @data ;
		$sar_networks_stat{$data[2]}{$data[3]}{'rxkB/s'} = ($data[6]*1024);
		$sar_networks_stat{$data[2]}{$data[3]}{'txkB/s'} = ($data[7]*1024);
		$devices{$data[3]} = 1;
	}
	foreach my $k (keys %devices) {
		push(@IFACE_LIST, $k) if (!grep(/^$k$/, @IFACE_LIST));
	}
}

sub compute_network_report
{
	my $data_info = shift();
	my $src_base = shift();

	my %networks_stat = ();
	foreach my $t (sort {$a <=> $b} keys %sar_networks_stat) {
		foreach my $dev (keys %{$sar_networks_stat{$t}}) {
			$networks_stat{$dev}{'rxkB/s'} .= '[' . $t . ',' . $sar_networks_stat{$t}{$dev}{'rxkB/s'} . '],';
			$networks_stat{$dev}{'txkB/s'} .= '[' . $t . ',' . $sar_networks_stat{$t}{$dev}{'txkB/s'} . '],';
		}
	}
	%sar_networks_stat = ();

	if (scalar keys %networks_stat > 0) {
		foreach my $n (sort { $a cmp $b } keys %networks_stat) {

			push(@IFACE_LIST, $n) if (!grep(/^$n$/, @IFACE_LIST));

			# Open a filehandle for each database
			my $fh = IO::File->new("$OUTPUT_DIR/$data_info->{name}-$n.html", 'w');
			if (not defined $fh) {
				die "FATAL: can't write to $OUTPUT_DIR/$data_info->{name}-$n.html, $!\n";
			}
			&html_header($fh, $src_base);
			$fh->print("<ul id=\"slides\">\n");
			$networks_stat{$n}{'rxkB/s'} =~ s/,$//;
			$networks_stat{$n}{'txkB/s'} =~ s/,$//;
			$fh->print( &jqplot_linegraph_array($IDX++, 'network-utilization', $data_info, $n, $networks_stat{$n}{'rxkB/s'}, $networks_stat{$n}{'txkB/s'}) );
                        $fh->print("</ul>\n");
                        &html_footer($fh, $n);
                        $fh->close;
		}
	}
}

sub compute_network_error_stat
{
	for (my $i = 0; $i <= $#_; $i++) {
		# hostname;interval;timestamp;IFACE;rxerr/s;txerr/s;coll/s;rxdrop/s;txdrop/s;txcarr/s;rxfram/s;rxfifo/s;txfifo/s
		my @data = split(/;/, $_[$i]);
		next if ($data[2] !~ /^\d+/);

		# Skip unwanted lines
		next if ($BEGIN && ($data[2] < $BEGIN_STAT));
		next if ($END   && ($data[2] > $END_STAT));
		next if (!&interface_in_report($data[3]));

		map { s/,/\./ } @data ;
		$sar_neterror_stat{$data[2]}{$data[3]}{'rxerr/s'} = $data[4] || 0;
		$sar_neterror_stat{$data[2]}{$data[3]}{'txerr/s'} = $data[5] || 0;
		$sar_neterror_stat{$data[2]}{$data[3]}{'coll/s'}  = $data[6] || 0;
	}
}

sub compute_network_error_report
{
	my $data_info = shift();
	my $src_base = shift();

	my %errors_stat = ();
	foreach my $t (sort {$a <=> $b} keys %sar_neterror_stat) {
		foreach my $dev (keys %{$sar_neterror_stat{$t}}) {
			$errors_stat{$dev}{'rxerr/s'} .= '[' . $t . ',' . $sar_neterror_stat{$t}{$dev}{'rxerr/s'} . '],';
			$errors_stat{$dev}{'txerr/s'} .= '[' . $t . ',' . $sar_neterror_stat{$t}{$dev}{'txerr/s'} . '],';
			$errors_stat{$dev}{'coll/s'}  .= '[' . $t . ',' . $sar_neterror_stat{$t}{$dev}{'coll/s'} . '],';
		}
	}
	if (scalar keys %errors_stat > 0) {
		foreach my $n (sort { $a cmp $b } keys %errors_stat) {
			push(@IFACE_LIST, $n) if (!grep(/^$n$/, @IFACE_LIST));

			# Open a filehandle for each interface
			my $fh = IO::File->new("$OUTPUT_DIR/$data_info->{name}-$n.html", 'w');
			if (not defined $fh) {
				die "FATAL: can't write to $OUTPUT_DIR/$data_info->{name}-$n.html, $!\n";
			}
			&html_header($fh, $src_base);
			$fh->print("<ul id=\"slides\">\n");
			$errors_stat{$n}{'rxerr/s'} =~ s/,$//;
			$errors_stat{$n}{'txerr/s'} =~ s/,$//;
			$errors_stat{$n}{'coll/s'} =~ s/,$//;
			$fh->print( &jqplot_linegraph_array($IDX++, 'network-error', $data_info, $n, $errors_stat{$n}{'rxerr/s'}, $errors_stat{$n}{'txerr/s'}, $errors_stat{$n}{'coll/s'}) );
			$fh->print("</ul>\n");
			&html_footer($fh, $n);
			$fh->close;
		}
	}
}

# Network / TCP / Utilization
sub compute_network_util_tcp_stat
{
    print "DEBUG: computing TCP utilization \n" if ($DEBUG);
	for (my $i = 0; $i <= $#_; $i++) {
        # 17:16:39     active/s passive/s    iseg/s    oseg/s
        # 17:16:40         0.00      0.00      6.00      9.00
		my @data = split(/;/, $_[$i]);
		# print ("DEBUG: TCP util:  $data[2] - $data[3] - $data[4] - $data[5] - $data[6] \n") if ($DEBUG) ;
		next if ($data[2] !~ /^\d+/);

		# Skip unwanted lines
		next if ($BEGIN && ($data[2] < $BEGIN_STAT));
		next if ($END   && ($data[2] > $END_STAT));

		map { s/,/\./ } @data ;
		$sar_tcputil_stat{$data[2]}{'active/s'}  = $data[3] || 0;
		$sar_tcputil_stat{$data[2]}{'passive/s'}  = $data[4] || 0;
		$sar_tcputil_stat{$data[2]}{'iseg/s'} = $data[5] || 0;
		$sar_tcputil_stat{$data[2]}{'oseg/s'} = $data[6] || 0;
	}
}

# Network / TCP / Utilization
sub compute_network_util_tcp_report
{
	my $data_info = shift();
	my $src_base = shift();
	my %util_stat = ();
    print "DEBUG: building TCP utilization report \n" if ($DEBUG);
	foreach my $t (sort {$a <=> $b} keys %sar_tcputil_stat) {
		$util_stat{'active/s'}  .= '[' . $t . ',' . $sar_tcputil_stat{$t}{'active/s'}  . '],';
		$util_stat{'passive/s'} .= '[' . $t . ',' . $sar_tcputil_stat{$t}{'passive/s'} . '],';
		$util_stat{'iseg/s'}    .= '[' . $t . ',' . $sar_tcputil_stat{$t}{'iseg/s'}    . '],';
		$util_stat{'oseg/s'}    .= '[' . $t . ',' . $sar_tcputil_stat{$t}{'oseg/s'} . '],';
	}
	if (scalar keys %util_stat > 0) {
			print "DEBUG: Writing data into $OUTPUT_DIR/$data_info->{name}.html \n" if ($DEBUG);
			$util_stat{'active/s'} =~ s/,$//;
			$util_stat{'passive/s'} =~ s/,$//;
			$util_stat{'iseg/s'} =~ s/,$//;
			$util_stat{'oseg/s'} =~ s/,$//;
			print $FH &jqplot_linegraph_array($IDX++, 'network-error-tcp', $data_info, '', $util_stat{'active/s'}, $util_stat{'passive/s'}, $util_stat{'iseg/s'}, $util_stat{'oseg/s'});
	}
}

# Network / TCP / Errrors
sub compute_network_error_tcp_stat
{
    print "DEBUG: computing TCP errors \n" if ($DEBUG);
	for (my $i = 0; $i <= $#_; $i++) {
        # sysstat >= 12.7.6 => 12:27:43     atmptf/s  estres/s **retrseg**/s isegerr/s   orsts/s
        # 12:27:43     atmptf/s  estres/s retrans/s isegerr/s   orsts/s
        # 12:27:44         0,00      0,00      0,00      0,00      0,00
		my @data = split(/;/, $_[$i]);
		next if ($data[2] !~ /^\d+/);

		# Skip unwanted lines
		next if ($BEGIN && ($data[2] < $BEGIN_STAT));
		next if ($END   && ($data[2] > $END_STAT));

		map { s/,/\./ } @data ;
		$sar_tcperror_stat{$data[2]}{'atmptf/s'}  = $data[3] || 0;
		$sar_tcperror_stat{$data[2]}{'estres/s'}  = $data[4] || 0;
		$sar_tcperror_stat{$data[2]}{'retrans/s'} = $data[5] || 0;
		$sar_tcperror_stat{$data[2]}{'isegerr/s'} = $data[6] || 0;
		$sar_tcperror_stat{$data[2]}{'orsts/s'}   = $data[7] || 0;
	}
}

# Network / TCP / Errrors
sub compute_network_error_tcp_report
{
	my $data_info = shift();
	my $src_base = shift();
	my %errors_stat = ();
    print "DEBUG: building TCP errors report \n" if ($DEBUG);
	foreach my $t (sort {$a <=> $b} keys %sar_tcperror_stat) {
		$errors_stat{'atmptf/s'}  .= '[' . $t . ',' . $sar_tcperror_stat{$t}{'atmptf/s'}  . '],';
		$errors_stat{'estres/s'}  .= '[' . $t . ',' . $sar_tcperror_stat{$t}{'estres/s'}  . '],';
		$errors_stat{'retrans/s'} .= '[' . $t . ',' . $sar_tcperror_stat{$t}{'retrans/s'} . '],';
		$errors_stat{'isegerr/s'} .= '[' . $t . ',' . $sar_tcperror_stat{$t}{'isegerr/s'} . '],';
		$errors_stat{'orsts/s'}   .= '[' . $t . ',' . $sar_tcperror_stat{$t}{'orsts/s'}   . '],';
	}
	if (scalar keys %errors_stat > 0) {
			print "DEBUG: Writing data into $OUTPUT_DIR/$data_info->{name}.html \n" if ($DEBUG);
			$errors_stat{'atmptf/s'} =~ s/,$//;
			$errors_stat{'estres/s'} =~ s/,$//;
			$errors_stat{'retrans/s'} =~ s/,$//;
			$errors_stat{'isegerr/s'} =~ s/,$//;
			$errors_stat{'orsts/s'} =~ s/,$//;
			print $FH &jqplot_linegraph_array($IDX++, 'network-error-tcp', $data_info, '', $errors_stat{'atmptf/s'}, $errors_stat{'estres/s'}, $errors_stat{'retrans/s'}, $errors_stat{'isegerr/s'}, $errors_stat{'orsts/s'} );
	}
}

sub compute_sarstat_stats
{
	my ($file, %data_info) = @_;

	####
	# Get CPU utilization
	####
	if ($data_info{name} eq 'system-cpu') {
		my $command = "$SADF_PROG -t -P ALL -d $file";
		print "DEBUG: running $command'\n" if ($DEBUG);
		# Load data from file
		my $fh = IO::File->new("$command", '-|');
		if (defined $fh) {
			die "FATAL: can't read output from command ($command): $!\n";
		}
		my @content = <$fh>;
		close($fh);
		chomp(@content);

		# Compute cpu statistics
		&compute_cpu_stat(@content);
	}

	####
	# Get load average
	####
	if ($data_info{name} eq 'system-load') {
		my $command = "$SADF_PROG -t -d $file -- -q";
		print "DEBUG: running $command'\n" if ($DEBUG);
		# Load data from file
		my $fh = IO::File->new("$command", '-|');
		if (defined $fh) {
			die "FATAL: can't read output from command ($command): $!\n";
		}
		my @content = <$fh>;
		close($fh);
		chomp(@content);

		# Compute load statistics
		&compute_load_stat(@content);
	}

	####
	# Get process number
	####
	if ($data_info{name} eq 'system-process') {
		my $command = "$SADF_PROG -t -d $file -- -q";
		print "DEBUG: running $command'\n" if ($DEBUG);
		# Load data from file
		my $fh = IO::File->new("$command", '-|');
		if (defined $fh) {
			die "FATAL: can't read output from command ($command): $!\n";
		}
		my @content = <$fh>;
		close($fh);
		chomp(@content);

		# Compute process statistics
		&compute_process_stat(@content);
	}

	####
	# Get run queue length
	####
	if ($data_info{name} eq 'system-runqueue') {
		my $command = "$SADF_PROG -t -d $file -- -q";
		print "DEBUG: running $command'\n" if ($DEBUG);
		# Load data from file
		my $fh = IO::File->new("$command", '-|');
		if (defined $fh) {
			die "FATAL: can't read output from command ($command): $!\n";
		}
		my @content = <$fh>;
		close($fh);
		chomp(@content);

		# Compute runqueue statistics
		&compute_process_stat(@content);
	}

	####
	# Get context swiches
	####
	if ($data_info{name} eq 'system-cswch') {
		my $command = "$SADF_PROG -t -d $file -- -w";
		print "DEBUG: running $command'\n" if ($DEBUG);
		# Load data from file
		my $fh = IO::File->new("$command", '-|');
		if (defined $fh) {
			die "FATAL: can't read output from command ($command): $!\n";
		}
		my @content = <$fh>;
		close($fh);
		chomp(@content);

		# Compute context switches statistics
		&compute_context_stat(@content);
	}

	####
	# Get tasks created per second
	####
	if ($data_info{name} eq 'system-pcrea') {
		my $command = "$SADF_PROG -t -d $file -- -w";
		print "DEBUG: running $command'\n" if ($DEBUG);
		# Load data from file
		my $fh = IO::File->new("$command", '-|');
		if (defined $fh) {
			die "FATAL: can't read output from command ($command): $!\n";
		}
		my @content = <$fh>;
		close($fh);
		chomp(@content);

		# Compute process creation statistics
		&compute_context_stat(@content);
	}

	####
	# Get memory utilization
	####
	if ($data_info{name} eq 'system-memory') {
		my $command = "$SADF_PROG -t -d $file -- -r";
		print "DEBUG: running $command'\n" if ($DEBUG);
		# Load data from file
		my $fh = IO::File->new("$command", '-|');
		if (defined $fh) {
			die "FATAL: can't read output from command ($command): $!\n";
		}
		my @content = <$fh>;
		close($fh);
		chomp(@content);

		# Compute graphs for memory statistics
		&compute_memory_stat(@content);
	}

	####
	# Get dirty memory utilization
	####
	if ($data_info{name} eq 'system-dirty') {
		my $command = "$SADF_PROG -t -d $file -- -r";
		print "DEBUG: running $command'\n" if ($DEBUG);
		# Load data from file
		my $fh = IO::File->new("$command", '-|');
		if (defined $fh) {
			die "FATAL: can't read output from command ($command): $!\n";
		}
		my @content = <$fh>;
		close($fh);
		chomp(@content);

		# Compute graphs for memory statistics
		&compute_dirty_stat(@content);
	}

	####
	# Get swap utilization
	####
	if ($data_info{name} eq 'system-swap') {
		my $command = "$SADF_PROG -t -d $file -- -W";
		print "DEBUG: running $command'\n" if ($DEBUG);
		# Load data from file
		my $fh = IO::File->new("$command", '-|');
		if (defined $fh) {
			die "FATAL: can't read output from command ($command): $!\n";
		}
		my @content = <$fh>;
		close($fh);
		chomp(@content);

		# Compute swap statistics
		&compute_swap_stat(@content);
	}

	####
	# Get page utilization
	####
	if ($data_info{name} eq 'system-page') {
		my $command = "$SADF_PROG -t -d $file -- -B";
		print "DEBUG: running $command'\n" if ($DEBUG);
		# Load data from file
		my $fh = IO::File->new("$command", '-|');
		if (defined $fh) {
			die "FATAL: can't read output from command ($command): $!\n";
		}
		my @content = <$fh>;
		close($fh);
		chomp(@content);

		# Compute page swap statistics
		&compute_page_stat(@content);
	}
	if ($data_info{name} eq 'system-fault') {
		# already done above
	}
	if ($data_info{name} eq 'system-scanpage') {
		# already done above
	}

	####
	# Get block in/out
	####
	if ($data_info{name} eq 'system-block') {
		my $command = "$SADF_PROG -t -d $file -- -b";
		print "DEBUG: running $command'\n" if ($DEBUG);
		# Load data from file
		my $fh = IO::File->new("$command", '-|');
		if (defined $fh) {
			die "FATAL: can't read output from command ($command): $!\n";
		}
		my @content = <$fh>;
		close($fh);
		chomp(@content);

		# Compute block statistics
		&compute_block_stat(@content);
	}

	####
	# Get TPS
	####
	if ($data_info{name} eq 'system-tps') {
		my $command = "$SADF_PROG -t -d $file -- -b";
		print "DEBUG: running $command'\n" if ($DEBUG);
		# Load data from file
		my $fh = IO::File->new("$command", '-|');
		if (defined $fh) {
			die "FATAL: can't read output from command ($command): $!\n";
		}
		my @content = <$fh>;
		close($fh);
		chomp(@content);

		# Compute block statistics
		&compute_block_stat(@content);
	}

	####
	# Get Device space utilization
	####
	if ($data_info{name} eq 'system-space') {
		my $command = "$SADF_PROG -t -P ALL -d $file -- -F -p";
		print "DEBUG: running $command'\n" if ($DEBUG);
		# Load data from file
		my $fh = IO::File->new("$command", '-|');
		if (defined $fh) {
			die "FATAL: can't read output from command ($command): $!\n";
		}
		my @content = <$fh>;
		close($fh);
		chomp(@content);

		# Compute disk space use per devices statistics
		&compute_space_device_stat(@content);
	}

	####
	# Get per device TPS utilization
	####
	if ($data_info{name} eq 'system-tpsdevice' && scalar keys %sar_rw_devices_stat == 0) {
		my $command = "$SADF_PROG -t -P ALL -d $file -- -d -p";
		print "DEBUG: running $command'\n" if ($DEBUG);
		# Load data from file
		my $fh = IO::File->new("$command", '-|');
		if (defined $fh) {
			die "FATAL: can't read output from command ($command): $!\n";
		}
		my @content = <$fh>;
		close($fh);
		chomp(@content);

		# Compute I/O per devices statistics
		&compute_rw_device_stat(@content);
	}

	####
	# Get Device service time
	####
	if ($data_info{name} eq 'system-srvtime') {
		my $command = "$SADF_PROG -t -P ALL -d $file -- -d -p";
		print "DEBUG: running $command'\n" if ($DEBUG);
		# Load data from file
		my $fh = IO::File->new("$command", '-|');
		if (defined $fh) {
			die "FATAL: can't read output from command ($command): $!\n";
		}
		my @content = <$fh>;
		close($fh);
		chomp(@content);

		# Compute service time per devices statistics
		&compute_srvtime_stat(@content);
	}

	####
	# Get Device block read/write utilization
	####
	if ($data_info{name} eq 'system-device') {
		my $command = "$SADF_PROG -t -P ALL -d $file -- -d -p";
		print "DEBUG: running $command'\n" if ($DEBUG);
		# Load data from file
		my $fh = IO::File->new("$command", '-|');
		if (defined $fh) {
			die "FATAL: can't read output from command ($command): $!\n";
		}
		my @content = <$fh>;
		close($fh);
		chomp(@content);

		# Compute I/O per devices statistics
		&compute_rw_device_stat(@content);
	}


	####
	# Get Device utilization
	####
	if ($data_info{name} eq 'system-cpudevice') {
		my $command = "$SADF_PROG -t -P ALL -d $file -- -d -p";
		print "DEBUG: running $command'\n" if ($DEBUG);
		# Load data from file
		my $fh = IO::File->new("$command", '-|');
		if (defined $fh) {
			die "FATAL: can't read output from command ($command): $!\n";
		}
		my @content = <$fh>;
		close($fh);
		chomp(@content);

		# Compute cpu utilization per devices statistics
		&compute_util_device_stat(@content);
	}


	####
	# Get network interface utilization
	####
	if ($data_info{name} eq 'network-utilization') {
		my $command = "$SADF_PROG -t -P ALL -d $file -- -n DEV";
		print "DEBUG: running $command'\n" if ($DEBUG);
		# Load data from file
		my $fh = IO::File->new("$command", '-|');
		if (defined $fh) {
			die "FATAL: can't read output from command ($command): $!\n";
		}
		my @content = <$fh>;
		close($fh);
		chomp(@content);

		# Compute network statistics
		&compute_network_stat(@content);
	}

	####
	# Get network errors utilization
	####
	if ($data_info{name} eq 'network-error') {
		my $command = "$SADF_PROG -t -P ALL -d $file -- -n EDEV";
		print "DEBUG: running $command'\n" if ($DEBUG);
		# Load data from file
		my $fh = IO::File->new("$command", '-|');
		if (defined $fh) {
			die "FATAL: can't read output from command ($command): $!\n";
		}
		my @content = <$fh>;
		close($fh);
		chomp(@content);

		# Compute network errors statistics
		&compute_network_error_stat(@content);
	}

	####
	# Get TCP utilization
	####
	if ($data_info{name} eq 'network-utilization-tcp') {
		my $command = "$SADF_PROG -t -P ALL -d $file -- -n TCP";
		print "DEBUG: TCP utilization : running $command'\n" if ($DEBUG);
		# Load data from file
		my $fh = IO::File->new("$command", '-|');
		if (defined $fh) {
			die "FATAL: can't read output from command ($command): $!\n";
		}
		my @content = <$fh>;
		close($fh);
		chomp(@content);

		# Compute network errors statistics
		&compute_network_util_tcp_stat(@content);
	}

    ####
	# Get TCP errors
	####
	if ($data_info{name} eq 'network-error-tcp') {
		my $command = "$SADF_PROG -t -P ALL -d $file -- -n ETCP";
		print "DEBUG: TCP errors : running $command'\n" if ($DEBUG);
		# Load data from file
		my $fh = IO::File->new("$command", '-|');
		if (defined $fh) {
			die "FATAL: can't read output from command ($command): $!\n";
		}
		my @content = <$fh>;
		close($fh);
		chomp(@content);

		# Compute network errors statistics
		&compute_network_error_tcp_stat(@content);
	}
}

sub find_report_type
{
	my $data = shift;
	my $type = '';

	# print ("DEBUG: candidate data : $data \n") if ($DEBUG);
	if ($data =~ m#nvcswch/s#) {
		$type = 'pcswch';
	} elsif ($data =~ m#cswch/s#) {
		$type = 'cswch';
	} elsif ($data =~ m#proc/s#) {
		$type = 'pcrea';
	} elsif ($data =~ m#CPU\s+i\d+#) {
		$type = 'ncpu';
	} elsif ($data =~ m#CPU\s+M#) {
		$type = 'scpu';
	} elsif ($data =~ m#CPU\s+w#) {
		$type = 'wcpu';
	} elsif ($data =~ m#CPU\s+t#) {
		$type = 'tcpu';
	} elsif ($data =~ m#CPU\s+\%#) {
		$type = 'cpu';
	} elsif ($data =~ m#CPU\s+C#) {
		$type = 'pcpu';
	} elsif ($data =~ m#INTR\s+#) {
		$type = 'intr';
	} elsif ($data =~ m#VSZ\s+RSS#) {
		$type = 'pmem';
	} elsif ($data =~ m#pgpgin/s\s+#) {
		$type = 'page';
	} elsif ($data =~ m#pswpin/s\s+#) {
		$type = 'pswap';
	# sar -b (IO)
	} elsif ( ($data =~ m#tps\s+#) && ($data !~ m#DEV\s+#) && ($data !~ m#\s+DEV$#) ) {
		$type = 'io';
	} elsif ($data =~ m#kB_ccwr/s\s+#) {
		$type = 'pio';
	} elsif ($data =~ m#frmpg/s\s+#) {
		$type = 'mpage';
	} elsif ($data =~ m#TTY\s+#) {
		$type = 'tty';
	} elsif ($data =~ m#IFACE\s+rxpck/s\s+#) {
		$type = 'net';
	} elsif ($data =~ m#IFACE\s+rxerr/s\s+#) {
		$type = 'err';
	# devices (sar -dp) : from sar 12.4.0, DEV may be at the end
	} elsif ($data =~ m#DEV\s+# or $data =~ m#\s+DEV$#) {
		$type = 'dev';
	} elsif ($data =~ m#kbmemfree\s+#) {
		$type = 'mem';
	# New in sysstat 8.1.5
	} elsif ($data =~ m#kbswpfree\s+#) {
		$type = 'swap';
	} elsif ($data =~ m#dentunusd\s+#) {
		$type = 'file';
	} elsif ($data =~ m#totsck\s+#) {
		$type = 'sock';
	} elsif ($data =~ m#runq-sz\s+#) {
		$type = 'load';
	# New in 8.1.7
	} elsif ($data =~ m#active\/s\s+#) {   # sar -n TCP
		$type = 'tcp';
	} elsif ($data =~ m#atmptf\/s\s+#) {   # sar -n ETCP
		$type = 'tcperr';
	# Since 11.1.4
	} elsif ($data =~ m#\%ufsused#) {
		$type = 'space';
	}
	# print ("DEBUG : type = $type \n")  if ($DEBUG);
	return $type;
}

sub load_sarfile_stats
{
	my ($file) = @_;

	my $interval = 0;
	my $hostname = 'unknown';

	# Load data from file
	my @content = ();
	my $offset = 0;
	print ("DEBUG : loading sar file \n") if ($DEBUG) ;
	$offset = $global_infos{"$file"} if (exists $global_infos{"$file"});

	my $curfh = open_filehdl("$file");
	$curfh->seek($offset,0);
	while (my $l = <$curfh>)
	{
		$offset += length($l);
		chomp($l);
		$l =~ s/\r//;
		# Prevent non relevant lines from being loaded into memory
		if ( ($l eq '') || ($l =~ /^\d+:\d+:\d+/) || ($l =~ /\d+[\-\/]\d+[\-\/]\d+/)) {
			push(@content, $l);
		}

		# Detecting the sysstat version from the sar -dp output
		# (pgcluu_collectd does ask for -p)

		# sysstat 10.1.5 (eg CentOS 7) ; DEV always at the beginning (-p or not)
		#
		# 12:14:34          DEV       tps  rd_sec/s  wr_sec/s  avgrq-sz  avgqu-sz     await     svctm     %util
		# 12:14:34          vda      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
		# 12:14:34          vdb      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
		# 12:14:34          vdc      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00

		# systat 11.5.7:
		#   Replace "avgrq-sz" field (unit: sectors) with "areq-sz" (kilobytes)
		#   Rename "avgqu-sz" field to "aqu-sz"
		#   Replace "rd_sec/s" and "wr_sec/s" (sectors/s) with "rkB/s" and "wkB/s" (kilobytes/s)
		#   (to be consistent with iostat output)
		#
		# 18:43:05          DEV       tps     rkB/s     wkB/s   areq-sz    aqu-sz     await     svctm     %util
		# 18:43:06      nvme0n1      3.00      0.00     44.00     14.67      0.02      7.33      8.00      2.40

		# sysstat 11.7.3 (Rocky 8), sysstat 12.0.3 (Debian 10) : same as above
		#
		# 12:03:57          DEV       tps     rkB/s     wkB/s   areq-sz    aqu-sz     await     svctm     %util
		# 12:03:58          vda      1.00      0.00      4.00      4.00      0.02     28.00     24.00      2.40
		# 12:03:59          vda      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00

		# sysstat 12.1.2:
		#   Remove obsolete metric service time (svctime)
		#   Add discard metric (dkB/s)
		#
		# 15:14:59          DEV       tps     rkB/s     wkB/s     dkB/s   areq-sz    aqu-sz     await     %util
		# 15:15:00      nvme0n1      6.00      0.00     40.00      0.00      6.67      0.04      6.83      1.60

		# sysstat 12.4.0: DEV goes at the (with -p)
		#
		# 15:18:38          tps     rkB/s     wkB/s     dkB/s   areq-sz    aqu-sz     await     %util DEV
		# 15:18:39         3.00      0.00     40.00      0.00     13.33      0.01      3.67      1.20 nvme0n1
		# 15:18:39        11.00      0.00     40.00      0.00      3.64      0.07      6.55      1.20 nvme0n1p3_crypt

		# sysstat 12.5.2 (Ubuntu 22.04, Debian 11) , 12.5.4  (Rocky 9), 12.6.1 (Debian 12) : same as above
		#
		# 14:07:06          tps     rkB/s     wkB/s     dkB/s   areq-sz    aqu-sz     await     %util DEV
		# 14:07:07         0,00      0,00      0,00      0,00      0,00      0,00      0,00      0,00 nvme0n1
		# 14:07:07         0,00      0,00      0,00      0,00      0,00      0,00      0,00      0,00 nvme0n1p3_crypt

		if (!$SAR_UPPER_11_5_6 && $l =~ m#wkB/s#)
		{
			$SAR_UPPER_11_5_6 = 1;
		}
		if (!$SAR_UPPER_12_1_1 && $l =~ /await/ && $l !~ /(srvtime|svctm)/)
		{
			$SAR_UPPER_12_1_1 = 1;
			if (!$SAR_UPPER_12_3_9 && $l =~ /%util DEV$/)
			{
				$SAR_UPPER_12_3_9 = 1 ;
			}
		}
	}
	$curfh->close();
	$global_infos{"$file"} = $offset;

	my $type = '';
	my @headers = ();
	my $old_time = 0;
	my $orig_time = 0;

	for (my $i = 0; $i <= $#content; $i++)
	{
		# Empty line, maybe the end of a report
		if ($content[$i] eq '') {
			$type = '';
			@headers = ();
			$old_time = $orig_time if ($FROM_SA_FILE);
			next;
		}
		# look for kernel header to find the date
		if ( ($content[$i] !~ /^\d+:\d+:\d+/)
			&& ($content[$i] =~ /\s+(\d+)([\-\/])(\d+)[\-\/](\d+)\s+/) )
		{
			if ($2 eq '/') {
				$sar_month = $1;
				$sar_day = $3;
				$sar_year = $4;
			} else {
				$sar_month = $3;
				$sar_day = $4;
				$sar_year = $1;
			}
			if (length($sar_year) == 2) {
				$sar_year += 2000;
			}
			#  mm/dd/yy format in sar file instead of dd/mm/yy (see option -r)
			if ($REVERT_DATE || ($sar_month > 12)) {
				my $tmp = $sar_day;
				$sar_day = $sar_month;
				$sar_month = $tmp;
			}

			my $tz = ((0-$TIMEZONE)*3600);
			$orig_time = &timegm_nocheck(0, 0, 0, $sar_day, $sar_month - 1, $sar_year - 1900) + $tz;

			$type = '';
			@headers = ();
			next;
		}
		# Remove average/summary header if any
		if ( ($content[$i] !~ /^\d+:\d+:\d+/) && ($content[$i] =~ /^\D+:\s+/) )
		{
			$type = '';
			@headers = ();
			next;
		}

		if ($#headers == -1)
		{
			push(@headers, split(m#\s+#, $content[$i]));
			shift(@headers);
			# Try to find the kind of report
			$type = &find_report_type($content[$i]);
			if (!$type) {
				@headers = ();
			} else {
				#push(@{$fulldata{$type}}, "hostname;interval;timestamp;" . join(";", @headers));
			}
			next;
		}

		# Remove AM|PM timestamp information
		my $am_pm = '';
		if ($content[$i] =~ s/^(\d+:\d+:\d+)\s(AM|PM)/$1/)
		{
			$am_pm = $2;
			shift(@headers) if ($headers[0] =~ /^(AM|PM)$/);
		}

		# Get all values reported
		my @values = ();
		push(@values, split(m#\s+#, $content[$i]));
		# Extract the timestamp of the line
		my $timestamp = shift(@values);

		if ($#values != $#headers) {
			warn "ERROR: Parsing of sar output reports different values than headers allow. ($#values != $#headers)\n";
			warn "INFO: sar output file was $file\n";
			warn "INFO: Line was: $content[$i]\n";
			die "Header: " . join(';', @headers) . " | Values: " . join(';', @values) . "\n";
		}
		if ($timestamp =~ /(\d+:\d+:\d+)/)
		{
			$timestamp = &convert_sar_time($1, $old_time, $am_pm);
			$old_time = $timestamp;
		}
		if (!$timestamp) {
			print STDERR "ERROR: unkown time information from sar file.\n";
			print STDERR "HEADER: $timestamp ", join(" ", @headers), "\n";
			die "DATA: $content[$i]\n";
		}
		# Change decimal character to perl
		map { s/,/\./; } @values;
		push(@{$fulldata{$type}}, "$hostname;$interval;$timestamp;" . join(";", @values));
	}
}

sub load_pidstatfile_stats
{
	my ($file) = @_;

	# Load data from file
	my @content = ();
	my $offset = 0;
	$offset = $global_infos{"$file"} if (exists $global_infos{"$file"});

	my $curfh = open_filehdl("$file");
	$curfh->seek($offset,0);
	while (my $l = <$curfh>)
	{
		# A line not terminated is being written, it will be read next time
		last if ($l !~ /\n$/);
		my $pos = $offset;
		$offset += length($l);
		chomp($l);
		$l =~ s/\r//;
		# Prevent non relevant lines from being loaded into memory
		if ( ($l eq '') || ($l =~ /^\d+:\d+:\d+/) || ($l =~ /\d+[\-\/]\d+[\-\/]\d+/)) {
			push(@content, [ $l, $pos, $offset ]);
		}
	}
	$curfh->close();
	$global_infos{"$file"} = $offset;

	# The read can start in the middle of a sample or of a report: their
	# header was read the previous time and is stored with the cache.
	my $sample = -1;
	my $header = '';
	if (exists $pidstat_samples{'last'})
	{
		$sample = $pidstat_samples{'last'}{'sample'};
		$header = $pidstat_samples{'last'}{'header'};
		$pidstat_day = $pidstat_samples{'last'}{'day'};
		$pidstat_month = $pidstat_samples{'last'}{'month'};
		$pidstat_year = $pidstat_samples{'last'}{'year'};
	}
	my ($type, $ncol, @columns) = ('');
	($type, $ncol, @columns) = &parse_pidstat_header($header) if ($header);
	my $in_report = ($header) ? 1 : 0;

	my $old_time = 0;
	my $orig_time = 0;

	foreach my $c (@content)
	{
		my ($line, $pos, $end) = @$c;

		# Empty line, maybe the end of a report
		if ($line eq '')
		{
			$type = '';
			$in_report = 0;
			$header = '';
			$old_time = $orig_time if ($FROM_SA_FILE);
			next;
		}
		# look for kernel header to find the date, it starts a new sample
		if ( ($line !~ /^\d+:\d+:\d+/)
			&& ($line =~ /\s+(\d+)([\-\/])(\d+)[\-\/](\d+)\s+/) )
		{
			if ($2 eq '/') {
				$pidstat_month = $1;
				$pidstat_day = $3;
				$pidstat_year = $4;
			} else {
				$pidstat_month = $3;
				$pidstat_day = $4;
				$pidstat_year = $1;
			}
			if (length($pidstat_year) == 2) {
				$pidstat_year += 2000;
			}
			#  mm/dd/yy format in pidstat file instead of dd/mm/yy (see option -r)
			if ($REVERT_DATE || ($pidstat_month > 12)) {
				my $tmp = $pidstat_day;
				$pidstat_day = $pidstat_month;
				$pidstat_month = $tmp;
			}

			my $tz = ((0-$TIMEZONE)*3600);
			$orig_time = &timegm_nocheck(0, 0, 0, $pidstat_day, $pidstat_month - 1, $pidstat_year - 1900) + $tz;

			$sample = $pos;
			$type = '';
			$in_report = 0;
			$header = '';
			next;
		}
		# Remove average/summary header if any
		if ( ($line !~ /^\d+:\d+:\d+/) && ($line =~ /^\D+:\s+/) ) {
			$type = '';
			$in_report = 0;
			$header = '';
			next;
		}

		# First line of a report: the header
		if (!$in_report)
		{
			$in_report = 1;
			$header = $line;
			($type, $ncol, @columns) = &parse_pidstat_header($line);
			next;
		}
		next if (!$type);

		# Remove AM|PM timestamp information
		my $am_pm = '';
		if ($line =~ s/^(\d+:\d+:\d+)\s(AM|PM)/$1/) {
			$am_pm = $2;
		}

		# Get all values reported, the command is the last column and may
		# contain spaces.
		my @values = split(m#\s+#, $line, $ncol+1);
		# Extract the timestamp of the line
		my $timestamp = shift(@values);

		if ($#values != $ncol - 1)
		{
			warn "ERROR: Parsing of pidstat output reports different values than headers allow. ($#values != " . ($ncol - 1) . ")\n";
			warn "INFO: pidstat output file was $file\n";
			warn "INFO: Line was: $line\n";
			die "Header: $header\n";
		}
		if ($timestamp =~ /(\d+:\d+:\d+)/)
		{
			$timestamp = &convert_pidstat_time($1, $old_time, $am_pm);
			$old_time = $timestamp;
		}
		if (!$timestamp)
		{
			print STDERR "ERROR: unkown time information from pidstat file.\n";
			print STDERR "HEADER: $header\n";
			die "DATA: $line\n";
		}

		# Keep the columns used, change decimal character to perl
		my @kept = map { ($_ >= 0) ? $values[$_] : '' } @columns;
		map { s/,/\./; } @kept;
		push(@{$fullpidstatdata{$type}}, join(';', $timestamp, $sample, $pos, $end, @kept));
	}

	# Where the next read will start
	$pidstat_samples{'last'} = {
		'sample' => $sample,
		'header' => $header,
		'day' => $pidstat_day,
		'month' => $pidstat_month,
		'year' => $pidstat_year,
	};
}

sub load_fsuse_stats
{
	my ($in_dir, $file) = @_;

	my $interval = 0;
	my $hostname = 'unknown';
	my @fsdata = ();

	# Load data from file
	my $offset = (exists $global_infos{"$in_dir/$file"}) ? $global_infos{"$in_dir/$file"} : 0;
	my $curfh = open_filehdl("$in_dir/$file");
	print STDERR "DEBUG: Starting to read $in_dir/$file from offset $offset\n" if ($DEBUG);
	$curfh->seek($offset,0);
	my $first = 0;
	while (my $l = <$curfh>) {
		$offset += length($l);
		chomp($l);
		$l =~ s/\r//;
		$l =~ s/,/\./g;
		# Add the header
		push(@fsdata, "hostname;interval;timestamp;MBfsfree;MBfsused;%fsused;%ufsused;Ifree;Iused;%Iused;FILESYSTEM") if (!$first);
		push(@fsdata, $l);
		$first++;
	}
	$curfh->close();
	$global_infos{"$in_dir/$file"} = $offset;

	return @fsdata;
}

sub load_commit_memory_stats
{
	my ($in_dir, $file) = @_;

	my $interval = 0;
	my $hostname = 'unknown';
	my @fsdata = ();

	# Load data from file
	my $offset = (exists $global_infos{"$in_dir/$file"}) ? $global_infos{"$in_dir/$file"} : 0;
	my $curfh = open_filehdl("$in_dir/$file");
	print STDERR "DEBUG: Starting to read $in_dir/$file from offset $offset\n" if ($DEBUG);
	$curfh->seek($offset,0);
	my $first = 0;
	while (my $l = <$curfh>) {
		$offset += length($l);
		chomp($l);
		$l =~ s/\r//;
		$l =~ s/,/\./g;
		# Add the header
		push(@fsdata, "timestamp;CommitLimit;CommittedAs") if (!$first);
		push(@fsdata, $l);
		$first++;
	}
	$curfh->close();
	$global_infos{"$in_dir/$file"} = $offset;

	return @fsdata;
}


sub compute_commit_memory_stat
{
	for (my $i = 0; $i <= $#_; $i++) {
		# epoch;commitLimit;committed_As
		my @data = split(/;/, $_[$i]);
		next if ($data[0] !~ /^\d+/);

		# Skip unwanted lines
		next if ($BEGIN && ($data[0] < $BEGIN_STAT));
		next if ($END   && ($data[0] > $END_STAT));

		my $tz = ((0-$TIMEZONE)*3600);
		$data[0] -= $tz;
		map { s/,/\./ } @data ;
		$sar_commit_memory_stat{$data[0]}{'commit_limit'}  = ($data[1]||0)*1000;
		$sar_commit_memory_stat{$data[0]}{'committed_as'} = ($data[2]||0)*1000;
	}
}

sub compute_commit_memory_report
{
	my $data_info = shift();

	my %commit_memory_stat = ();
	foreach my $t (sort {$a <=> $b} keys %sar_commit_memory_stat) {
		if (!exists $OVERALL_STATS{'system'}{'committed_as'} || ($OVERALL_STATS{'system'}{'committed_as'}[1] < $sar_commit_memory_stat{$t}{'committed_as'})) {
			@{$OVERALL_STATS{'system'}{'committed_as'}} = ($t, $sar_commit_memory_stat{$t}{'committed_as'});
		}
		$commit_memory_stat{'commit_limit'}  .= '[' . $t . ',' . $sar_commit_memory_stat{$t}{'commit_limit'} . '],';
		$commit_memory_stat{'committed_as'} .= '[' . $t . ',' . $sar_commit_memory_stat{$t}{'committed_as'} . '],';
	}
	%sar_commit_memory_stat = ();
	if (scalar keys %commit_memory_stat > 0) {
		$commit_memory_stat{'commit_limit'} =~ s/,$//;
		$commit_memory_stat{'committed_as'} =~ s/,$//;
		print $FH &jqplot_linegraph_array($IDX++, 'system-commit_memory', $data_info, '', $commit_memory_stat{'commit_limit'}, $commit_memory_stat{'committed_as'});
	}
}

sub compute_sarfile_stats
{
	my ($file, $in_dir, %data_info) = @_;

    print "DEBUG: Computing sarfile stats: $data_info{name} \n" if ($DEBUG);
	# Load sar statistics from file if not already done
	load_sarfile_stats($file) if (scalar keys %fulldata == 0);

	# With old sar version there is no filesystem use stats
	# pgcluu_collectd may have save these stat in file fs_stat_use.csv
	if (-e "$in_dir/fs_stat_use.csv" && $data_info{name} eq 'system-space') {
		push(@{$fulldata{'system-space'}}, &load_fsuse_stats($in_dir, 'fs_stat_use.csv'));
	}

	####
	# Get Commit memory stats
	####
	if (-e "$in_dir/commit_memory.csv" && $data_info{name} eq 'system-commit_memory') {
		push(@{$fulldata{'system-commit_memory'}}, &load_commit_memory_stats($in_dir, 'commit_memory.csv'));
	}

	####
	# Set CPU utilization
	####
	if ($data_info{name} eq 'system-cpu')
	{
		# Compute cpu statistics
		&compute_cpu_stat(@{$fulldata{cpu}});
	}

	####
	# Set load average
	####
	if ($data_info{name} eq 'system-load')
	{
		# Compute load statistics
		&compute_load_stat(@{$fulldata{load}});
	}

	####
	# Set process number
	####
	if ($data_info{name} eq 'system-process')
	{
		# Compute process statistics
		&compute_process_stat(@{$fulldata{load}});
	}

	####
	# Set run queue length
	####
	if ($data_info{name} eq 'system-runqueue')
	{
		# Compute runqueue statistics
		&compute_process_stat(@{$fulldata{load}});
	}

	####
	# Set context switches
	####
	if ($data_info{name} eq 'system-cswch')
	{
		# Compute context switches statistics
		&compute_context_stat(@{$fulldata{cswch}});
	}

	####
	# Set process created per second
	####
	if ($data_info{name} eq 'system-pcrea')
	{
		# Compute process created per second statistics
		&compute_context_stat(@{$fulldata{cswch}});
	}

	####
	# Set memory utilization
	####
	if ($data_info{name} eq 'system-memory')
	{
		# Compute memory statistics
		&compute_memory_stat(@{$fulldata{mem}});
	}

	####
	# Set dirty memory utilization
	####
	if ($data_info{name} eq 'system-dirty')
	{
		# Compute memory statistics
		&compute_dirty_stat(@{$fulldata{mem}});
	}

	####
	# Set swap utilization
	####
	if ($data_info{name} eq 'system-swap')
	{
		# Compute swap statistics
		&compute_swap_stat(@{$fulldata{pswap}});
	}

	####
	# Set commit memory utilization
	####
	if ($data_info{name} eq 'system-commit_memory')
	{
		# Compute disk space use per devices statistics
		&compute_commit_memory_stat(@{$fulldata{'system-commit_memory'}});
	}

	####
	# Set page utilization
	####
	if ($data_info{name} eq 'system-page')
	{
		# Compute page swap statistics
		&compute_page_stat(@{$fulldata{page}});
	}

	####
	# Set block in/out
	####
	if ($data_info{name} eq 'system-block')
	{
		# Compute block statistics
		&compute_block_stat(@{$fulldata{io}});
	}

	####
	# Set TPS
	####
	if ($data_info{name} eq 'system-tps')
	{
		# Compute block statistics
		&compute_block_stat(@{$fulldata{io}});
	}

	####
	# Set Device disk space utilization
	####
	if ($data_info{name} eq 'system-space')
	{
		# Compute disk space use per devices statistics
		&compute_space_device_stat(@{$fulldata{space}});
	}

	####
	# Set Device service time
	####
	if ($data_info{name} eq 'system-srvtime')
	{
		# Compute service time per devices statistics
		&compute_srvtime_stat(@{$fulldata{dev}});
	}

	####
	# Set Device read/write utilization
	####
	if ($data_info{name} eq 'system-device')
	{
		# Compute I/O per devices statistics
		&compute_rw_device_stat(@{$fulldata{dev}});
	}

	####
	# Set Device read/write utilization
	####
	if ($data_info{name} eq 'system-tpsdevice'
		&& scalar keys %sar_rw_devices_stat == 0)
	{
		# Compute I/O per devices statistics
		&compute_rw_device_stat(@{$fulldata{dev}});
	}

	####
	# Set Device utilization
	####
	if ($data_info{name} eq 'system-cpudevice')
	{
		# Compute cpu utilization per devices statistics
		&compute_util_device_stat(@{$fulldata{dev}});
	}

	####
	# Set network utilization
	####
	if ($data_info{name} eq 'network-utilization')
	{
		# Compute block statistics
		&compute_network_stat(@{$fulldata{net}});
	}

	####
	# Set network error utilization
	####
	if ($data_info{name} eq 'network-error')
	{
		# Compute network error statistics
		&compute_network_error_stat(@{$fulldata{err}});
	}

	####
	# Set network TCP errors
	####
	if ($data_info{name} eq 'network-utilization-tcp')
	{
		# Compute network error statistics
		&compute_network_util_tcp_stat(@{$fulldata{tcp}});
	}

	####
	# Set network TCP errors
	####
	if ($data_info{name} eq 'network-error-tcp')
	{
		# Compute network error statistics
		&compute_network_error_tcp_stat(@{$fulldata{tcperr}});
	}

}

sub compute_sar_graph
{
	my ($src_base, %data_info) = @_;

    print "DEBUG: Computing sar data: $data_info{name} \n" if ($DEBUG);

	if (!grep(/^$data_info{name}$/,
			'system-await', 'system-device',
			'system-srvtime', 'system-device',
			'system-tpsdevice', 'system-cpudevice',
			'network-utilization', 'network-error'))
	{
		# Open global filehandle
		print ("DEBUG: opening $data_info{name} \n") if ($DEBUG) ;
		$FH = IO::File->new("$OUTPUT_DIR/$data_info{name}.html", 'w');
		if (not defined $FH) {
			die "FATAL: can't write to $OUTPUT_DIR/$data_info{name}.html, $!\n";
		}
		# Generate the html header for each sar devices statistics report
		&html_header($FH, $src_base);
		print $FH "<ul id=\"slides\">\n";
	}

	####
	# Show CPU utilization
	####
	if ($data_info{name} eq 'system-cpu')
	{
		# Compute graphs for cpu statistics
		&compute_cpu_report(\%data_info);
	}

	####
	# Show load average
	####
	if ($data_info{name} eq 'system-load')
	{
		# Compute graphs for load statistics
		&compute_load_report(\%data_info);
	}

	####
	# Show process number
	####
	if ($data_info{name} eq 'system-process')
	{
		# Compute graphs for process statistics
		&compute_process_report(\%data_info);
	}

	####
	# Show run queue length
	####
	if ($data_info{name} eq 'system-runqueue')
	{
		# Compute graphs for runqueue statistics
		&compute_process_report(\%data_info);
	}

	####
	# Show context switches
	####
	if ($data_info{name} eq 'system-cswch')
	{
		# Compute graphs for context switches statistics
		&compute_context_report(\%data_info);
	}

	####
	# Show process created per second
	####
	if ($data_info{name} eq 'system-pcrea')
	{
		# Compute graphs for number of process created per second statistics
		&compute_context_report(\%data_info);
	}

	####
	# Show memory utilization
	####
	if ($data_info{name} eq 'system-memory')
	{
		# Compute graphs for memory statistics
		&compute_memory_report(\%data_info);
	}

	####
	# Show dirty memory utilization
	####
	if ($data_info{name} eq 'system-dirty')
	{
		# Compute graphs for dirty memory statistics
		&compute_dirty_report(\%data_info);
	}

	####
	# Show swap utilization
	####
	if ($data_info{name} eq 'system-swap')
	{
		# Compute graphs for swap statistics
		&compute_swap_report(\%data_info);
	}

	####
	# Show commit memory utilization
	####
	if ($data_info{name} eq 'system-commit_memory')
	{
		# Compute graphs for I/O per devices statistics
		&compute_commit_memory_report(\%data_info, $src_base);
	}

	####
	# Show page utilization
	####
	if ($data_info{name} eq 'system-page')
	{
		# Compute graphs for page swap statistics
		&compute_page_report(\%data_info);
	}
	if ($data_info{name} eq 'system-fault')
	{
		# Compute graphs for page swap statistics
		&compute_fault_report(\%data_info);
	}
	if ($data_info{name} eq 'system-scanpage')
	{
		# Compute graphs for page swap statistics
		&compute_scanpage_report(\%data_info);
	}

	####
	# Show block in/out
	####
	if ($data_info{name} eq 'system-block')
	{
		# Compute graphs for block statistics
		&compute_block_report(\%data_info);
	}

	####
	# Show TPS
	####
	if ($data_info{name} eq 'system-tps')
	{
		# Compute graphs for block statistics
		&compute_block_report(\%data_info);
	}

	####
	# Show per device TPS utilization
	####
	if ($data_info{name} eq 'system-tpsdevice')
	{
		# Compute graphs for I/O per devices statistics
		&compute_rw_device_report(\%data_info, $src_base);
	}

	####
	# Show Device space utilization
	####
	if ($data_info{name} eq 'system-space')
	{
		# Compute graphs for I/O per devices statistics
		&compute_space_device_report(\%data_info, $src_base);
	}

	if (!$SAR_UPPER_12_1_1)
	{
		####
		# Show Device service time (old sar versions)
		####
		if ($data_info{name} eq 'system-srvtime')
		{
			# Compute graphs for service time per device statistics
			&compute_srvtime_report(\%data_info, $src_base);
		}
	}
	else
	{
		####
		# Show Device await time
		####
		if ($data_info{name} eq 'system-await')
		{
			# Compute graphs for service time per device statistics
			&compute_srvtime_report(\%data_info, $src_base);
		}
	}

	####
	# Show Device read/write utilization
	####
	if ($data_info{name} eq 'system-device')
	{
		# Compute graphs for I/O per devices statistics
		&compute_rw_device_report(\%data_info, $src_base);
	}


	####
	# Show Device utilization
	####
	if ($data_info{name} eq 'system-cpudevice')
	{
		# Compute graphs for cpu utilization per devices statistics
		&compute_util_device_report(\%data_info, $src_base);
	}

	####
	# Show network utilization
	####
	if ($data_info{name} eq 'network-utilization')
	{
		# Compute graphs for network utilization statistics
		&compute_network_report(\%data_info, $src_base);
	}

	####
	# Show network error utilization
	####
	if ($data_info{name} eq 'network-error')
	{
		# Compute graphs for network errors statistics
		&compute_network_error_report(\%data_info, $src_base);
	}

	####
	# Show TCP utilization
	####
	if ($data_info{name} eq 'network-utilization-tcp')
	{
		# Compute graphs for network errors statistics
		&compute_network_util_tcp_report(\%data_info, $src_base);
	}

	####
	# Show TCP errors
	####
	if ($data_info{name} eq 'network-error-tcp')
	{
		# Compute graphs for network errors statistics
		&compute_network_error_tcp_report(\%data_info, $src_base);
	}

	if (!grep(/^$data_info{name}$/, 'system-await', 'system-srvtime', 'system-device', 'system-tpsdevice', 'system-cpudevice', 'network-utilization', 'network-error'))
	{
		# Write html footer in all reports
		print $FH "</ul>\n";
		&html_footer($FH);
		$FH->close;
	}
}

sub compute_pidstatfile_stats
{
	my ($file, $in_dir, %data_info) = @_;

	$SAR_UPPER_11_5_6 = 0;

	# Load sar statistics from file if not already done
	load_pidstatfile_stats($file) if (scalar keys %fullpidstatdata == 0);

	####
	# Set CPU utilization
	####
	if ($data_info{name} eq 'postgres-cpu')
	{
		# Compute cpu statistics
		&compute_pidstatcpu_stat(@{$fullpidstatdata{pcpu}});
	}

	####
	# Set context switches
	####
	if ($data_info{name} eq 'postgres-cswch')
	{
		# Compute context switches statistics
		&compute_pidstatcontext_stat(@{$fullpidstatdata{pcswch}});
	}

	####
	# Set memory utilization
	####
	if ($data_info{name} eq 'postgres-memory')
	{
		# Compute memory statistics
		&compute_pidstatmemory_stat(@{$fullpidstatdata{pmem}});
	}

	if ($data_info{name} eq 'postgres-fault')
	{
		# Done above
	}

	####
	# Set Kb in/out
	####
	if ($data_info{name} eq 'postgres-io')
	{
		# Compute block statistics
		&compute_pidstatio_stat(@{$fullpidstatdata{pio}});
	}
}

sub compute_pidstat_graph
{
	my ($src_base, %data_info) = @_;

	# Open global filehandle
	$FH = IO::File->new("$OUTPUT_DIR/pidstat-$data_info{name}.html", 'w');
	if (not defined $FH) {
		die "FATAL: can't write to $OUTPUT_DIR/pidstat-$data_info{name}.html, $!\n";
	}
	# Generate the html header for each sar devices statistics report
	&html_header($FH, $src_base);
	print $FH "<ul id=\"slides\">\n";

	####
	# Show CPU utilization
	####
	if ($data_info{name} eq 'postgres-cpu')
	{
		# Compute graphs for cpu statistics
		&compute_pidstatcpu_report(\%data_info);
	}

	####
	# Show context switches
	####
	if ($data_info{name} eq 'postgres-cswch')
	{
		# Compute graphs for context switches statistics
		&compute_pidstatcontext_report(\%data_info);
	}

	####
	# Show memory utilization
	####
	if ($data_info{name} eq 'postgres-memory')
	{
		# Compute graphs for memory statistics
		&compute_pidstatmemory_report(\%data_info);
	}
	if ($data_info{name} eq 'postgres-mempercent')
	{
		# Compute graphs for memory statistics
		&compute_pidstatmemory_report(\%data_info);
	}

	####
	# Show page utilization
	####
	if ($data_info{name} eq 'postgres-fault')
	{
		# Compute graphs for page swap statistics
		&compute_pidstatfault_report(\%data_info);
	}

	####
	# Show in/out
	####
	if ($data_info{name} eq 'postgres-io')
	{
		# Compute graphs for block statistics
		&compute_pidstatio_report(\%data_info);
	}
	if ($data_info{name} eq 'postgres-iodelay')
	{
		# Compute graphs for block statistics
		&compute_pidstatio_report(\%data_info);
	}


	# Write html footer in all reports
	print $FH "</ul>\n";
	&html_footer($FH);
	$FH->close;
}

sub convert_time
{
	my $str = shift;

	# 2012-07-16 12:35:29+02
	if ($str =~ /(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+)/) {
		return &timegm_nocheck($6, $5, $4, $3, $2 - 1, $1 - 1900) * 1000;
	} elsif ($str =~ /(\d+)-(\d+)-(\d+) (\d+):(\d+)/) {
		return &timegm_nocheck(0, $5, $4, $3, $2 - 1, $1 - 1900) * 1000;
	} elsif ($str =~ /(\d+):(\d+):(\d+)/) {
		return &timegm_nocheck($3, $2, $1, $o_day, $o_month - 1, $o_year - 1900) * 1000;
	} elsif ($str !~ /\D/) {
		return $str * 1000;
	}

	return $str;
}

sub convert_sar_time
{
	my ($str, $old_timestamp, $am_pm) = @_;

	my $curdate = '';

	$old_timestamp ||= 0;
	$sar_day ||= $o_day;
	$sar_month ||= $o_month;
	$sar_year ||= $o_year;

	if ($str =~ /(\d+):(\d+):(\d+)/) {
		my $h = $1;
		my $m = $2;
		my $s = $3;
		if ($am_pm && ($am_pm eq 'AM')) {
			$h = 0 if ($h == 12);
		} elsif ($am_pm && ($am_pm eq 'PM')) {
			$h += 12 if ($h < 12);
		}

		my $time = ($h*3600)+($m*60)+$s;

		my $tz = ((0-$TIMEZONE)*3600);
		$curdate = &timegm_nocheck(0, 0, 0, $sar_day, $sar_month - 1, $sar_year - 1900) + $tz;
		if (!$FROM_SA_FILE) {
			while ($old_timestamp > (($curdate+$time) * 1000)) {
				$curdate += 86399;
				my @tinf = gmtime($curdate - $tz);
				$sar_month = $tinf[4]+1;
				$sar_day = $tinf[3];
				$sar_year = $tinf[5]+1900;
			}
		}

		return ($curdate + $time) * 1000;
	}

	return 0;
}

sub convert_pidstat_time
{
	my ($str, $old_timestamp, $am_pm) = @_;

	my $curdate = '';

	$old_timestamp ||= 0;
	$pidstat_day ||= $o_day;
	$pidstat_month ||= $o_month;
	$pidstat_year ||= $o_year;

	if ($str =~ /(\d+):(\d+):(\d+)/) {
		my $h = $1;
		my $m = $2;
		my $s = $3;
		if ($am_pm && ($am_pm eq 'AM')) {
			$h = 0 if ($h == 12);
		} elsif ($am_pm && ($am_pm eq 'PM')) {
			$h += 12 if ($h < 12);
		}

		my $time = ($h*3600)+($m*60)+$s;

		my $tz = ((0-$TIMEZONE)*3600);
		$curdate = &timegm_nocheck(0, 0, 0, $pidstat_day, $pidstat_month - 1, $pidstat_year - 1900) + $tz;
		if (!$FROM_SA_FILE) {
			while ($old_timestamp > (($curdate+$time) * 1000)) {
				$curdate += 86399;
				my @tinf = gmtime($curdate - $tz);
				$pidstat_month = $tinf[4]+1;
				$pidstat_day = $tinf[3];
				$pidstat_year = $tinf[5]+1900;
			}
		}

		return ($curdate + $time) * 1000;
	}

	return 0;
}

sub jqplot_linegraph_array
{
	my ($buttonid, $divid, $infos, $title, @data) = @_;

	my @legend = ();
	my $description = $infos->{description} || '';

	for (my $i = 0; $i <= $#data; $i++) {
		push(@legend, $infos->{legends}[$i] || '');
	}
	if ($title eq 'all') {
		$title = $infos->{all_title};
		$description = $infos->{all_description};
	}
	elsif ($title ne '') {
		$title = sprintf($infos->{title}, $title);
	} else {
		$title = $infos->{title};
	}
	return &jqplot_linegraph($buttonid, $divid, $infos, $title, $description, \@data, \@legend);
}

sub jqplot_linegraph_hash
{
	my ($buttonid, $divid, $infos, $title, %data_h) = @_;

	my @legend = ();
	my @data = ();
	my $i = 1;
	my $description = $infos->{description} || '';
	my $print_after = $infos->{print_after} || '';

	foreach my $id (sort keys %data_h) {
		$data_h{$id} ||= '';
		push(@data, $data_h{$id});
		push(@legend, $id);
		$i++;
	}
	if ($title ne '') {
		$title = sprintf($infos->{title}, $title);
	} else {
		$title = $infos->{title};
	}

	return &jqplot_linegraph($buttonid, $divid, $infos, $title, $description, \@data, \@legend, $print_after);
}

sub jqplot_linegraph
{
	my ($buttonid, $divid, $infos, $title, $description, $data, $legend, $print_after) = @_;

	my $ylabel = $infos->{ylabel} || '';
	$print_after ||= '';
	my $str = '';
	if (($divid !~ /\+$/) && ($divid !~ /^statio-/)) {
		$str = qq{
<li class="slide active-slide" id="$divid-slide">
      <div id="$divid"><br/><br/><br/><br/></div>
};
	} else {
		$divid =~ s/\+$//;
	}
	$str .= qq{
      <div class="row">
            <div class="col-md-12">
              <div class="panel panel-default">
              <div class="panel-heading">
              <h2>$title</h2>
		<p>$description</p>
              </div>
              <div class="panel-body">
};
	my $y2label = $infos->{y2label} || '';

	my $dateTracker_dataopts = '';
        my $options_series = '';
	my $has_data = 0;
	if ($#{$data} >= 0) {
		for (my $i = 0; $i <= $#{$legend}; $i++) {
			next if (!$legend->[$i]);
			if ($legend->[$i] =~ /label: "([^"]+)"/) {
				if (($i == $#{$legend}) && $infos->{y2label}) {
					$options_series .= "{ label: \"$1\", yaxis: 'y2axis' },";
				} else {
					$options_series .= "{ label: \"$1\" },";
				}
			} else {
				if (($i == $#{$legend}) && $infos->{y2label}) {
					$options_series .= "{ label: \"$legend->[$i]\", yaxis: 'y2axis' },";
				} else {
					$options_series .= "{ label: \"$legend->[$i]\" },";
				}
			}
		}
		$options_series =~ s/,$//;

		for (my $i = 0; $i <= $#{$data}; $i++) {
			next if (!$data->[$i]);
			$data->[$i] = "var graph_${buttonid}_d$i = [$data->[$i]];\n";
			$dateTracker_dataopts .= "graph_${buttonid}_d$i,";
			$has_data = 1;
		}
		$dateTracker_dataopts =~ s/,$//;
		$dateTracker_dataopts = "[$dateTracker_dataopts]";
	}

	my $cssgraph = 'linegraph';
	if ($divid =~ /^table-/) {
		$cssgraph = 'smallgraph';
	}
	if ($has_data) {
		$str .= <<EOF;
<div id="$divid$buttonid" class="jqplot-graph $cssgraph"></div>
<script type="text/javascript">
/* <![CDATA[ */
@$data
var series_arr_$buttonid = [ $options_series ];

create_download_button($buttonid, 'btn');
var graph_${buttonid} = create_linegraph('$divid$buttonid', '$title', '$ylabel', series_arr_$buttonid, $dateTracker_dataopts, '$y2label');
add_download_button_event($buttonid, '$divid$buttonid', graph_${buttonid});
/* ]]> */
</script>
              </div>
              </div>
            </div>
      </div>
      $print_after
  </li>
EOF
	}

	return $str;
}

sub jqplot_piegraph
{
	my ($buttonid, $divid, $infos, $title, %data) = @_;

        my $datadef = '';
        foreach my $k (sort keys %data) {
                $datadef .= "['$k', $data{$k}],";
        }
	if ($title ne '') {
		$title = sprintf($infos->{title}, $title);
	} else {
		$title = $infos->{title};
	}
	my $description = $infos->{description} || '';
	my $str = qq{
<li class="slide active-slide" id="$divid-slide">
      <div id="$divid"><br/><br/><br/><br/></div>
      <div class="row">
            <div class="col-md-12">
              <div class="panel panel-default">
              <div class="panel-heading">
              <h2>$title</h2>
		<p>$description</p>
              </div>
              <div class="panel-body">

};

	if ($datadef) {
		$str .= <<EOF;
<div id="$divid$buttonid" class="jqplot-graph piegraph"></div>
<script type="text/javascript">
/* <![CDATA[ */
var data_${buttonid} = [ $datadef ];

create_download_button($buttonid, 'btn');
var graph_$buttonid = create_piechart('$divid$buttonid', '$title', data_${buttonid});
add_download_button_event($buttonid, '$divid$buttonid', graph_${buttonid});
/* ]]> */
</script>
EOF
	} else {
		$str .= '<div class="jqplot-graph piegraph"><blockquote><b>NO DATASET</b></blockquote></div>';
	}
	$str .= qq{
              </div>
              </div>
            </div><!--/span-->
      </div>
</li>
};

	return $str;
}

sub getNumericalOffset
{
	my $stringofs = shift;

	return 0 if (!$stringofs);

	my @pieces = split /\//, $stringofs;
	die "Invalid offset: $stringofs" unless ($#pieces == 1);


	# First part is logid, second part is record offset
	return (hex("ffffffff") * hex($pieces[0])) + hex($pieces[1]);
}

sub read_sysinfo
{
        my $in_dir = shift;

	my @toclear = qw/DF MOUNT PROCESS PCI CRONTAB INSTALLATION EXTENSION SCHEMA JSON PGDATA POSTMASTER/;
	foreach my $s (@toclear) {
		delete $sysinfo{$s};
	}

        print STDERR "DEBUG: Looking for system information in directory $in_dir\n" if ($DEBUG);
        if (-e "$in_dir/sys_cache.bin") {
                print STDERR "DEBUG: Loading system information from cache file $in_dir/sys_cache.bin\n" if ($DEBUG);
                &load_sysinfo_binary($in_dir, "sys_cache.bin");
        } elsif (-e "$in_dir/sysinfo.txt") {
                print STDERR "DEBUG: Loading system information from file $in_dir/sysinfo.txt\n" if ($DEBUG);
                %sysinfo = &read_sysinfo_file("$in_dir/sysinfo.txt");
                $sysinfo{RELEASE}{'name'} ||= 'unknown';
        } elsif (-e "$in_dir/sysinfo.txt.gz") {
                print STDERR "DEBUG: Loading system information from file $in_dir/sysinfo.txt.gz\n" if ($DEBUG);
                %sysinfo = &read_sysinfo_file("$in_dir/sysinfo.txt.gz");
                $sysinfo{RELEASE}{'name'} ||= 'unknown';
        }

	# In capture mode there is no sar statistics
	$DISABLE_SAR = 1 if ($sysinfo{CONFIGURATION}{'capture'});
}

sub read_sysinfo_file
{
	my $file = shift;

	# Fix weird case of empty file
	return if (-z $file);

	my $fh = open_filehdl($file);
	my %sysinfo = ();
	my $section = '';
	my $current_device = '';
	while (my $l = <$fh>)
	{
		chomp($l);
		$l =~ s/\r//;
		if ($l =~ /^\[(.*)\]$/)
		{
			$section = $1;
			next;
		}
		if ($section eq 'CPU')
		{
			my ($key, $val) = split(/\s+:\s+/, $l);
			if ($key eq 'processor') {
				$sysinfo{$section}{$key} = $val + 1;
			} elsif ($key eq 'model name') {
				$val =~ s/\s+\@\s+(.*)$//;
				$sysinfo{$section}{'cpu MHz'} = $1;
				$sysinfo{$section}{$key} = $val;
			} else {
				$sysinfo{$section}{$key} = $val;
			}
		}
		elsif ($section eq 'KERNEL')
		{
			my @kinf = split(/\s+/, $l);
			$sysinfo{$section}{'hostname'} = $kinf[1];
			$sysinfo{$section}{'kernel'} = "$kinf[0] $kinf[2] $kinf[3] $kinf[4]";
			$sysinfo{$section}{'arch'} = "$kinf[-2] $kinf[-1]";
		}
		elsif ($section eq 'UPTIME')
		{
			$sysinfo{$section}{'all'} = $l;
			if ($l =~ /\s*([^,]+), (.*)/) {
				$sysinfo{$section}{'uptime'} = $1;
				$sysinfo{$section}{'infos'} = $2;
			}
		}
		elsif ($section eq 'RELEASE')
		{
			my ($key, $val) = split(/=/, $l);
			if ($val) {
				$val =~ s/"//g;
				$sysinfo{$section}{lc($key)} = $val;
			} else {
				$sysinfo{RELEASE}{'name'} = $key;
				$sysinfo{RELEASE}{'version'} = '';
			}
		}
		elsif ($section eq 'MEMORY')
		{
			my ($key, $val) = split(/:\s+/, $l);
			if ($val =~ s/ kB//) {
				$sysinfo{$section}{lc($key)} = &pretty_print_size($val*1000);
			} else {
				$sysinfo{$section}{lc($key)} = $val;
			}
		}
		elsif ($section eq 'DF')
		{
			next if ($l !~ /^[\s\/]/);
			if ($l =~ s/^\s+//) {
				$sysinfo{$section}[-1] =~ s/<\/tr>$/<td>/;
				$sysinfo{$section}[-1] .= join('</td><td>', split(/\s+/, $l)) . "</td></tr>";
				next;
			}
			push(@{$sysinfo{$section}}, '<tr><td>' . join('</td><td>', split(/\s+/, $l)) . "</td></tr>");
		}
		elsif ($section eq 'MOUNT')
		{
			push(@{$sysinfo{$section}}, '<tr><td>' . join('</td><td>', split(/\s+on\s+|\s+type\s+|\s+/, $l)) . '</td></tr>');
		}
		elsif ($section eq 'SYSTEM')
		{
			my ($key, $val) = split(/\s*[=:]\s+/, $l);
			 $sysinfo{$section}{$key} = $val if ($key && defined $val);
		}
		elsif ($section eq 'POSTMASTER')
		{
			# Limits of the postmaster process, ordered list of key: value
			my ($key, $val) = split(/:\s+/, $l, 2);
			push(@{$sysinfo{$section}}, [ $key, $val ]) if ($key && defined $val);
		}
		elsif ($section eq 'PGVERSION')
		{
			$sysinfo{$section}{full_version} = $l;
			if ($l =~ /^PostgreSQL (\d+)\.(\d+)\.(\d+)/) {
				$sysinfo{$section}{major} = "$1.$2";
				$sysinfo{$section}{minor} = "$1.$2.$3";
			} elsif ($l =~ /^PostgreSQL (\d+)\.(\d+)/) {
				$sysinfo{$section}{major} = "$1.$2";
				$sysinfo{$section}{minor} = "$1.$2.0";
			} elsif ($l =~ /^PostgreSQL (\d+)(devel|alpha|beta|rc)/) {
				# Development and pre-release versions, ex: PostgreSQL 19beta4
				$sysinfo{$section}{major} = "$1.0";
				$sysinfo{$section}{minor} = "$1.0.0";
			} elsif ($l =~ /^EnterpriseDB (\d+)\.(\d+)\.(\d+)/) {
				$sysinfo{$section}{major} = "$1.$2";
				$sysinfo{$section}{minor} = "$1.$2.$3";
			} elsif ($l =~ /(\d+)\.(\d+)\.(\d+)/) {
				$sysinfo{$section}{major} = "$1.$2";
				$sysinfo{$section}{minor} = "$1.$2.$3";
			} else {
				$sysinfo{$section}{major} = '';
				$sysinfo{$section}{minor} = '';
			}
		}
		elsif ($section eq 'PGUPTIME')
		{
			$sysinfo{PGVERSION}{uptime} = $l;
		}
		elsif ($section eq 'EXTENSION')
		{
			my ($db, @vals) = split(/[=,]+/, $l);
			foreach my $e (@vals) {
				push(@{$sysinfo{$section}{$db}}, $e) if (!grep(/^$e$/, @{$sysinfo{$section}{$db}}));
				push(@{$OVERALL_STATS{'cluster'}{'extensions'}}, $e) if (!grep(/^$e$/, @{$OVERALL_STATS{'cluster'}{'extensions'}}));
			}
		}
		elsif ($section eq 'SCHEMA')
		{
			my ($db, @vals) = split(/[=,]+/, $l);
			foreach my $s (@vals) {
				push(@{$sysinfo{$section}{$db}}, $s) if (!grep(/^$s$/, @{$sysinfo{$section}{$db}}));
			}
		}
		elsif ($section eq 'JSON')
		{
			my ($db, @vals) = split(/[=,]+/, $l);
			foreach my $s (@vals) {
				push(@{$sysinfo{$section}{$db}}, $s) if (!grep(/^$s$/, @{$sysinfo{$section}{$db}}));
			}
		}
		elsif ($section eq 'PROCEDURE')
		{
			if ($l =~ /^([^=]+)=(\d+)$/) {
				$sysinfo{$section}{$1} = $2;
			} else {
				# Backward compatibility with version 2.4
				my ($db, @vals) = split(/[=,]+/, $l);
				$sysinfo{$section}{$db} = $#vals + 1;
			}
		}
		elsif ($section eq 'TRIGGER')
		{
			my ($db, $val) = split(/[=]+/, $l);
			$sysinfo{$section}{$db} = $val;
		}
		elsif ($section eq 'PROCESS')
		{
			my ($USER,$PID,$CPU,$MEM,$VSZ,$RSS,$TTY,$STAT,$START,$TIME,$COMMAND) = split(/\s+/, $l, 11);
			push(@{$sysinfo{$section}}, '<tr><td>' . join('</td><td>', $USER,$PID,$CPU,$MEM,$VSZ,$RSS,$TTY,$STAT,$START,$TIME,$COMMAND) . '</td></tr>') if ($l !~/^USER/);
		}
		elsif ($section eq 'PARTITIONNED_TABLE')
		{
			# limit split to 2 fields, check constraint can contains "="
			my ($db, $csv) = split(/[=]/, $l, 2);

			if ($csv && $csv ne ';') {
				my ($oid, $parent, $child, $constraint, $kind, $nparts ) = split(/;/, $csv);
				$sysinfo{$section}{$db}{$oid}{child}{$child} = $constraint;
				$sysinfo{$section}{$db}{$oid}{kind} = $kind;
				$sysinfo{$section}{$db}{$oid}{nparts} = $nparts;
				$sysinfo{$section}{$db}{$oid}{name} = $parent;
				push(@{$OVERALL_STATS{'cluster'}{'partitionned_tables'}}, "$db.$parent") if (!grep(/^$db.$parent/, @{$OVERALL_STATS{'cluster'}{'partitionned_tables'}}));
			}
		}
		elsif ($section =~ /PARTITION_IMPL (.*) (\d+)/)
		{
			$sysinfo{PARTITIONNED_TABLE}{$1}{$2}{implementation} .= "$l\n";
		}
		elsif ($section eq 'CONFIGURATION')
		{
			my ($name, $val) = split(/[=]+/, $l);
			$sysinfo{$section}{$name} = $val;
		}
		elsif ($section =~ /^(PCI|CRONTAB|INSTALLATION|PGDATA)$/)
		{
			push(@{$sysinfo{$section}}, "$l\n");
		}
		elsif ($section eq 'DEVICES')
		{
			if ($l =~ /^Device : (.*)/) {
				$current_device = $1;
			} else {
				push(@{$sysinfo{$section}{$current_device}}, "$l\n");
			}
		}
	}
	close($fh);

	return %sysinfo;
}

sub write_resources
{
	# Write resource file to report directory
	my $rscfh;
	while (my $l = <DATA>) {
		if ($l =~ /^WRFILE: (.*)/) {
			$rscfh->close() if (defined $rscfh);
			if (!-e "$OUTPUT_DIR/$1" || $OVERRIDE) {
				$rscfh = IO::File->new("$OUTPUT_DIR/$1", 'w');
				die "FATAL: can't write file $1\n" if (not defined $rscfh);
			}
			next;
		}
		$rscfh->print($l) if (defined $rscfh);
	}
	$rscfh->close() if (defined $rscfh);
}

# Format duration
sub format_duration
{
	my $time = shift;

	return '0s' if (!$time);

	my $days = int($time / 86400000);
	$time -= ($days * 86400000);
	my $hours = int($time / 3600000);
	$time -= ($hours * 3600000);
	my $minutes = int($time / 60000);
	$time -= ($minutes * 60000);
	my $seconds = sprintf("%0.3f", $time / 1000);

	$days    = $days < 1    ? '' : $days . 'd';
	$hours   = $hours < 1   ? '' : $hours . 'h';
	$minutes = $minutes < 1 ? '' : $minutes . 'm';
	$seconds =~ s/\.\d+$// if ($minutes);
	$time    = $days . $hours . $minutes . $seconds . 's';

	return $time;
}

sub get_data_directories
{
	my @work_dirs = ();

	# Lookup for daily or hourly sub directories to scan
	# Search years / months / days / hours directories
	if (not opendir(DIR, "$INPUT_DIR")) {
		die "FATAL: Can't open directory $INPUT_DIR: $!\n";
	}
	my @years = grep { /^\d+$/ && -d "$INPUT_DIR/$_" } readdir(DIR);
	closedir(DIR);
	if ($#years >= 0) {
		$have_incremental_dir = 1;
		foreach  my $y (sort { $a <=> $b } @years) {
			if (not opendir(DIR, "$INPUT_DIR/$y")) {
				die "FATAL: Can't open directory $INPUT_DIR/$y: $!\n";
			}
			my @months = grep { /^\d+$/ && -d "$INPUT_DIR/$y/$_" } readdir(DIR);
			closedir(DIR);
			foreach  my $m (sort { $a <=> $b } @months) {
				if (not opendir(DIR, "$INPUT_DIR/$y/$m")) {
					die "FATAL: Can't open directory $INPUT_DIR/$y/$m: $!\n";
				}
				my @days = grep { /^\d+$/ && -d "$INPUT_DIR/$y/$m/$_" } readdir(DIR);
				closedir(DIR);
				foreach  my $d (sort { $a <=> $b } @days) {
					if (not opendir(DIR, "$INPUT_DIR/$y/$m/$d")) {
						die "FATAL: Can't open directory $INPUT_DIR/$y/$m/$d: $!\n";
					}
					my @hours = grep { /^\d+$/ && -d "$INPUT_DIR/$y/$m/$d/$_" } readdir(DIR);
					closedir(DIR);
					if ($#hours == -1) {
						push(@work_dirs, "$y/$m/$d");
					} else {
						foreach  my $h (sort { $a <=> $b } @hours) {
							push(@work_dirs, "$y/$m/$d/$h");
							$have_hourly_dir = 1;
						}
					}
				}
			}
		}

	} else {
		# we are not in incremental mode only first level directory will be proceed
		push(@work_dirs, '.');
	}

	return @work_dirs;
}

# Initialise global variables storing PostgreSQL statistics
sub clear_db_stats
{
	print "DEBUG: Cleaning memory from PostgreSQL statistics storages\n" if ($DEBUG);

	foreach my $name (@pg_to_be_stored) {
		if (grep(/^$name$/, 'global_databases', 'global_tbspnames', )) {
			@{$name} = ();
		} else {
			%{$name} = ();
		}
	}
}


# Initialise global variables storing statistics
sub clear_stats
{
	# Clean PostgreSQL statistics
	&clear_db_stats();

	print "DEBUG: Cleaning memory from all statistics storages\n" if ($DEBUG);
	%OVERALL_STATS = ();
	%sysinfo = ();
	foreach my $name (@sar_to_be_stored) {
		%{$name} = ();
	}
	# The offsets of the samples are related to the pidstat file of the
	# directory, statistics of an other directory must not be kept.
	foreach my $name (@pidstat_to_be_stored) {
		%{$name} = ();
	}

}

####
# Lock the cache files of a directory. pgcluu takes an exclusive lock to
# replace them (commit_cache_files), the readers take a shared lock to load
# a set of files: the offsets in the csv files (global_infos.bin) must come
# from the same run than the statistics loaded with them, otherwise lines
# are read twice or lost. Returns the file handle holding the lock, closing
# it releases the lock. A reader that can not open the lock file (no write
# permission and file not created yet) reads the cache without lock.
####
sub lock_cache_dir
{
	my ($dir, $mode) = @_;

	my $file = "$dir/$CACHE_DIR_LOCK_FILE";
	my $fh;
	if (!open($fh, '>>', $file) && !open($fh, '<', $file))
	{
		die "FATAL: can't open lock file $file, $!\n" if ($mode == LOCK_EX);
		return undef;
	}
	flock($fh, $mode) or die "FATAL: can't lock $file, $!\n";

	return $fh;
}

####
# Cache files are written in a temporary file, they replace the current
# cache files when commit_cache_files() is called.
####
sub cache_tmp_file
{
	my ($dir, $file) = @_;

	push(@{$PENDING_CACHE_FILES{$dir}}, $file) if (!grep { $_ eq $file } @{$PENDING_CACHE_FILES{$dir}});

	return "$dir/$file.tmp";
}

####
# Replace the cache files of a directory by the temporary files written
# since the last call. The renames are done under an exclusive lock so a
# reader never loads a mix of old and new files of the same set.
####
sub commit_cache_files
{
	my $dir = shift;

	return if (!exists $PENDING_CACHE_FILES{$dir});

	my $lock = &lock_cache_dir($dir, LOCK_EX);
	foreach my $f (@{$PENDING_CACHE_FILES{$dir}}) {
		rename("$dir/$f.tmp", "$dir/$f") or die "FATAL: can't rename $dir/$f.tmp into $dir/$f, $!\n";
	}
	close($lock);
	delete $PENDING_CACHE_FILES{$dir};
}

# Dump relevant memory to file for incremental use
sub dump_pg_binary
{
        my ($in_dir, $outfile) = @_;

	foreach my $name (@pg_to_be_stored) {
		my $lfh = IO::File->new(&cache_tmp_file($in_dir, "$name.bin"), 'w');
		if (not defined $lfh) {
			die "FATAL: can't write to $in_dir/$name.bin.tmp, $!\n";
		}
		if (grep(/^$name$/, 'global_databases', 'global_tbspnames')) {
			store_fd({ $name => \@{$name} }, $lfh) || die ("Couldn't save binary data to \"$in_dir/$name.bin\"!\n");
		} else {
			store_fd({ $name => \%{$name} }, $lfh) || die ("Couldn't save binary data to \"$in_dir/$name.bin\"!\n");
		}
		$lfh->close;
	}
}

# Dump memory from sar statistics to file for incremental use
sub dump_sar_binary
{
        my ($in_dir, $outfile) = @_;

	foreach my $name (@sar_to_be_stored) {
		my $lfh = IO::File->new(&cache_tmp_file($in_dir, "$name.bin"), 'w');
		if (not defined $lfh) {
			die "FATAL: can't write to $in_dir/$name.bin.tmp, $!\n";
		}
		store_fd({ $name => \%{$name} }, $lfh) || die ("Couldn't save binary data to \"$in_dir/$name.bin\"!\n");
		$lfh->close;
	}
}

# Dump memory from system information to file for incremental use
sub dump_sys_binary
{
        my ($in_dir, $outfile) = @_;

	my $lfh = IO::File->new(&cache_tmp_file($in_dir, $outfile), 'w');
	if (not defined $lfh) {
		die "FATAL: can't write to $in_dir/$outfile.tmp, $!\n";
	}
        store_fd({
		'sysinfo' => \%sysinfo,
        }, $lfh) || die ("Couldn't save binary data to «$in_dir/$outfile»!\n");
	$lfh->close;
}

# Dump memory from pidstat statistics to file for incremental use
sub dump_pidstat_binary
{
        my ($in_dir, $outfile) = @_;

	foreach my $name (@pidstat_to_be_stored) {
		my $lfh = IO::File->new(&cache_tmp_file($in_dir, "$name.bin"), 'w');
		if (not defined $lfh) {
			die "FATAL: can't write to $in_dir/$name.bin.tmp, $!\n";
		}
		store_fd({ $name => \%{$name} }, $lfh) || die ("Couldn't save binary data to \"$in_dir/$name.bin\"!\n");
		$lfh->close;
	}
}

# Load statistics from pg cache into memory
sub load_pg_binary
{
        my ($in_dir) = @_;

	# Load a consistent set of files, see lock_cache_dir()
	my $lock = &lock_cache_dir($in_dir, LOCK_SH);

	foreach my $name (@pg_to_be_stored) {

		next if (!-e "$in_dir/$name.bin");

		my $lfh = IO::File->new("$in_dir/$name.bin", 'r');
		if (not defined $lfh) {
			die "FATAL: can't read from $in_dir/$name.bin, $!\n";
		}
		my %stats = %{ fd_retrieve($lfh) };
		$lfh->close();

		# Setting global information
		if ($name eq 'global_infos') {

			my %_global_infos = %{$stats{global_infos}} ;
			foreach my $inf (keys %_global_infos) {
				$_global_infos{$inf} //= 0;
				if ($_global_infos{$inf} =~ /ARRAY/) {
					push(@{$global_infos{$inf}}, @{$_global_infos{$inf}});
				} else {
					$global_infos{$inf} = $_global_infos{$inf};
				}
			}
			delete $stats{global_infos};

		} elsif (grep(/^$name$/, 'global_databases', 'global_tbspnames', )) {

			# Look for database and tablespace
			foreach my $d (@{$stats{$name}}) {
				push(@{$name}, $d) if (!grep(/^$d$/, @{$name}));
			}
			delete $stats{$name};

		} else {

			# Load other storages
			foreach my $m (keys %stats) {
				foreach my $t (keys %{$stats{$m}}) {
					if ($stats{$m}{$t} =~ /HASH/) {
						foreach my $d (keys %{$stats{$m}{$t}}) {
							if ($stats{$m}{$t}{$d} =~ /HASH/) {
								foreach my $k (keys %{$stats{$m}{$t}{$d}}) {
									${$m}{$t}{$d}{$k} = $stats{$m}{$t}{$d}{$k};
								}
							} elsif ($stats{$m}{$t}{$d} =~ /ARRAY/) {
								push(@{${$m}{$t}{$d}}, @{$stats{$m}{$t}{$d}});
							} else {
								${$m}{$t}{$d} = $stats{$m}{$t}{$d};
							}
						}
					} elsif ($stats{$m}{$t} =~ /ARRAY/) {
						push(@{${$m}{$t}}, @{$stats{$m}{$t}});
					} else {
						${$m}{$t} = $stats{$m}{$t};
					}
				}
			}
		}
	}

	# Preserve backward compatibility with renaming of variable all_statio_all_indexes
	if (-e "$in_dir/all_statio_all_indexes.bin") {

		my $lfh = IO::File->new("$in_dir/all_statio_all_indexes.bin", 'r');
		if (not defined $lfh) {
			die "FATAL: can't read from $in_dir/all_statio_all_indexes.bin, $!\n";
		}
		my %stats = %{ fd_retrieve($lfh) };
		$lfh->close();

		foreach my $a (keys %{$stats{'all_statio_all_indexes'}}) {
			foreach my $b (keys %{$stats{'all_statio_all_indexes'}{$a}}) {
				foreach my $c (keys %{$stats{'all_statio_all_indexes'}{$a}{$b}}) {
					foreach my $k (keys %{$stats{'all_statio_all_indexes'}{$a}{$b}{$c}}) {
						$all_statio_user_indexes{$a}{$b}{$c}{$k} = $stats{'all_statio_all_indexes'}{$a}{$b}{$c}{$k};
					}
				}
			}
		}
	}
}

# Load statistics from sar cache into memory
sub load_sar_binary
{
        my ($in_dir) = @_;

	foreach my $name (@sar_to_be_stored) {

		my $lfh = IO::File->new("$in_dir/$name.bin", 'r');
		if (not defined $lfh) {
			die "FATAL: can't write to $in_dir/$name.bin, $!\n";
		}
		my %stats = %{ fd_retrieve($lfh) };
		$lfh->close();
		# Setting global information
		if ($name eq 'global_infos') {

			# Setting global information
			my %_global_infos = %{$stats{global_infos}} ;
			foreach my $inf (keys %_global_infos) {
				$_global_infos{$inf} //= 0;
				if ($_global_infos{$inf} =~ /ARRAY/) {
					push(@{$global_infos{$inf}}, @{$_global_infos{$inf}});
				} else {
					$global_infos{$inf} = $_global_infos{$inf};
				}
			}
			delete $stats{global_infos};

		} else {

			# Load other sar storages
			foreach my $m (keys %stats) {
				foreach my $t (keys %{$stats{$m}}) {
					foreach my $d (keys %{$stats{$m}{$t}}) {
						if ($stats{$m}{$t}{$d} =~ /HASH/) {
							foreach my $k (keys %{$stats{$m}{$t}{$d}}) {
								${$m}{$t}{$d}{$k} = $stats{$m}{$t}{$d}{$k};
							}
						} else {
							${$m}{$t}{$d} = $stats{$m}{$t}{$d};
						}
					}
				}
			}
		}
	}
}

# Load statistics from pidstat cache into memory
sub load_pidstat_binary
{
        my ($in_dir) = @_;

	foreach my $name (@pidstat_to_be_stored) {

		# Cache built by an older version
		next if (!-e "$in_dir/$name.bin");

		my $lfh = IO::File->new("$in_dir/$name.bin", 'r');
		if (not defined $lfh) {
			die "FATAL: can't read $in_dir/$name.bin, $!\n";
		}
		my %stats = %{ fd_retrieve($lfh) };
		$lfh->close();
		# Load pidstat storages
		foreach my $m (keys %stats) {
			foreach my $t (keys %{$stats{$m}}) {
				foreach my $d (keys %{$stats{$m}{$t}}) {
					if ($stats{$m}{$t}{$d} =~ /HASH/) {
						foreach my $k (keys %{$stats{$m}{$t}{$d}}) {
							${$m}{$t}{$d}{$k} = $stats{$m}{$t}{$d}{$k};
						}
					} else {
						${$m}{$t}{$d} = $stats{$m}{$t}{$d};
					}
				}
			}
		}
	}
}

# Load statistics from sysinfo cache into memory
sub load_sysinfo_binary
{
        my ($in_dir, $infile) = @_;

	# Fix weird case of empty file
	return if (-z "$in_dir/$infile");

	my $lfh = IO::File->new("$in_dir/$infile", 'r');
	if (not defined $lfh) {
		die "FATAL: can't read file $in_dir/$infile, $!\n";
	}
	my %stats = %{ fd_retrieve($lfh) };
	$lfh->close();
	my %_sysinfo = %{$stats{sysinfo}};

	# Empty arrays before filling them
	my @toclear = qw/DF MOUNT PROCESS PCI CRONTAB INSTALLATION EXTENSION SCHEMA JSON PGDATA POSTMASTER/;
	foreach my $s (@toclear) {
		delete $sysinfo{$s};
	}

	# Load sysinfo storages
	foreach my $s (keys %_sysinfo) {
		if ($_sysinfo{$s} =~ /^HASH/) {
			foreach my $n (keys %{$_sysinfo{$s}}) {
				if ($_sysinfo{$s}{$n} =~ /^HASH/) {
					foreach my $k (keys %{$_sysinfo{$s}{$n}}) {
						if ($_sysinfo{$s}{$n}{$k} =~ /^HASH/) {
							foreach my $j (keys %{$_sysinfo{$s}{$n}{$k}}) {
								if ($_sysinfo{$s}{$n}{$k}{$j} =~ /^HASH/) {
									foreach my $i (keys %{$_sysinfo{$s}{$n}{$k}{$j}}) {
										$sysinfo{$s}{$n}{$k}{$j}{$i} = $_sysinfo{$s}{$n}{$k}{$j}{$i};
									}
								} else {
									$sysinfo{$s}{$n}{$k}{$j} = $_sysinfo{$s}{$n}{$k}{$j};
								}
							}
						} else {
							$sysinfo{$s}{$n}{$k} = $_sysinfo{$s}{$n}{$k};
						}
					}
				} elsif ($_sysinfo{$s}{$n} =~ /^ARRAY/) {
					push(@{$sysinfo{$s}{$n}}, @{$_sysinfo{$s}{$n}});
				} else {
					$sysinfo{$s}{$n} = $_sysinfo{$s}{$n};
				}
			}
		} elsif ($_sysinfo{$s} =~ /^ARRAY/) {
			push(@{$sysinfo{$s}}, @{$_sysinfo{$s}});
		}
	}
	foreach my $db (keys %{$sysinfo{EXTENSION}}) {
		foreach my $e (@{$sysinfo{EXTENSION}{$db}}) {
			push(@{$OVERALL_STATS{'cluster'}{'extensions'}}, $e) if (!grep(/^$e$/, @{$OVERALL_STATS{'cluster'}{'extensions'}}));
		}
	}
	foreach my $db (keys %{$sysinfo{PARTITIONNED_TABLE}}) {
		foreach my $oid (keys %{$sysinfo{PARTITIONNED_TABLE}{$db}}) {
			push(@{$OVERALL_STATS{'cluster'}{'partitionned_tables'}}, "$db.$sysinfo{PARTITIONNED_TABLE}{$db}{$oid}{name}") if (!grep(/^$db.$sysinfo{PARTITIONNED_TABLE}{$db}{$oid}{name}/, @{$OVERALL_STATS{'cluster'}{'partitionned_tables'}}));
		}
	}
}

# Compare given version numbers to the server's version
sub backend_minimum_version
{
	my ($numver) = @_;

	return 0 if (!$numver);

	return 1 if (!exists $sysinfo{PGVERSION}{'major'} || ($sysinfo{PGVERSION}{'major'} >= $numver));

	return 0;
}

sub build_incremental_index
{
	my $outdir = shift;

	print "DEBUG: generating global index to access incremental reports...\n" if ($DEBUG);

	my $fh = IO::File->new("$outdir/index.html", 'w');
	if (not defined $fh) {
		die "FATAL: can't write to $outdir/index.html, $!\n";
	}
	print $fh &build_head('Global Index on incremental reports');
	print $fh qq{
<body>

<div id="navigation">

    <div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
      <div class="container mainmenu">
        <a class="navbar-brand" href="http://pgcluu.darold.net/">
        <img src="$pgcluu_logo" title="$PROGRAM"></a>
        <div class="navbar-header">
          <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
        </div>
        <div class="navbar-collapse collapse">
          <ul class="nav navbar-nav">
              <!-- li id="menu-home" class="dropdown"><a href="index.html#home">Home</a></li -->
              <!--li id="menu-about" class="dropdown"><a href="index.html#about">About</a></li -->
          </ul>
        </div><!--/.nav-collapse -->
      </div>
    </div>
</div>
<div class="container" id="main-container">
};

	# get year directories
	unless(opendir(DIR, "$outdir")) {
		localdie("Error: can't opendir $outdir: $!");
	}
	my @dyears = grep { !/^\./ && /^\d{4}$/ } readdir(DIR);
	closedir DIR;
	foreach my $y (sort { $b <=> $a } @dyears) {
		print $fh qq{
	<h1>Year $y</h1>
        <table class="table table-condensed"><tr>
};
		# foreach year directory look for week directories
		unless(opendir(DIR, "$outdir/$y")) {
			localdie("Error: can't opendir $outdir/$y: $!");
		}

		my @ymonths = grep { /^\d{2}$/ } readdir(DIR);
		closedir DIR;
		my $i = 1;
		foreach my $m (sort {$a <=> $b } @ymonths) {
			print $fh "<td><span>", &get_calendar($y, $m, $outdir), "</span></td>\n";
			print $fh "</tr>\n<tr>\n" if ( ($i%4) == 0 );
			$i++;
		}
		print $fh qq{
        </tr></table>
};
	}
	print $fh qq{
	$COPYRIGHT
</div><!--/.container-->
  </body>
</html>
};
	$fh->close;
}

sub IsLeapYear
{
	return ((($_[0] & 3) == 0) && (($_[0] % 100 != 0) || ($_[0] % 400 == 0)));
}

sub get_calendar
{
	my ($year, $month, $outdir) = @_;

	my $str = "<table class=\"table table-striped table-hover table-condensed\">\n";
	my @wday = qw(Su Mo Tu We Th Fr Sa);
	my @std_day = qw(Su Mo Tu We Th Fr Sa);
	if ($week_start_monday) {
		@wday = qw(Mo Tu We Th Fr Sa Su);
		@std_day = qw(Mo Tu We Th Fr Sa Su);
	}
	my %day_lbl = ();
	for (my $i = 0; $i <= $#wday; $i++) {
		$day_lbl{$wday[$i]} = $wday[$i];
	}
	$str .= "<thead><tr><td>&nbsp;</td>";
	map { $str .= '<th>' . $day_lbl{$_} . '</th>'; } @wday;
	$str .= "</tr></thead>\n<tbody>\n";
	my @currow = ('','','','','','','');
	my $wd = 0;
	my $wn = 0;
	my $week = '';
	my @report_hour_done = ();
	my @report_day_done = ();
	my @report_week_done = ();
	for my $d ("01" .. "31")
	{
		last if (($d == 31) && grep(/^$month$/, '04','06','09','11'));
		last if (($d == 30) && ($month eq '02'));
		last if (($d == 29) && ($month eq '02') && !IsLeapYear($year));
		$wd = &get_day_of_week($year,$month,$d);
		$wn =  &get_week_number($year,$month,$d);
		next if ($wn == -1);
		if ( !-d "$outdir/$year/$month/$d" ) {
			$currow[$wd] = "<td>$d</td>";
		} else {
			if ( !-e "$outdir/$year/$month/$d/done" ) {
				opendir(HDIR, "$outdir/$year/$month/$d") || die "FATAL: can't opendir $outdir/$year/$month/$d: $!";
				my @hours = grep { /^\d+$/ && -d "$outdir/$year/$month/$d/$_" } readdir(HDIR);
				closedir(HDIR);
				if ($#hours >= 0) {
					push(@report_hour_done, &build_hour_index("$outdir/$year/$month/$d"));
				}
				push(@report_day_done, "$year/$month/$d");
			}
			$currow[$wd] = "<td><a href=\"$year/$month/$d/index.html\" target=\"new\">$d</a></td>";
		}
		if ($wd == 6) {
			$week = sprintf("%02d", $wn);
			if (-d "$outdir/$year/week-$week") {
				push(@report_hour_done, "$outdir/$year/week-$week");
				$week = "<th><a href=\"$year/week-$week/index.html\" target=\"new\">$week</a>&nbsp;</th>";
			} else {
				$week = "<th>$week</th>";
			}
			map { $_ = "<td>&nbsp;</td>" if ($_ eq ''); } @currow;
			$str .= "<tr>$week" . join('', @currow) . "</tr>\n";
			@currow = ('','','','','','','');
		}
	}
	if ( ($wd != 6) || ($currow[0] ne '') ) {
		$week = sprintf("%02d", $wn);
		if (-d "$outdir/$year/week-$week") {
			push(@report_hour_done, "$outdir/$year/week-$week");
			$week = "<th><a href=\"$year/week-$week/index.html\" target=\"new\">$week</a>&nbsp;</th>";
		} else {
			$week = "<th>$week</th>";
		}
		map { $_ = "<td>&nbsp;</td>" if ($_ eq ''); } @currow;
		$str .= "<tr>$week" . join('', @currow) . "</tr>\n";
		@currow = ('','','','','','','');
	}
	$str .=  "</tbody>\n</table>\n";

	# Mark the repository as already fully processed
	pop(@report_hour_done);
	foreach my $path (@report_hour_done) {
		next if (-e "$outdir/$path/done");
		my $fh = IO::File->new("$outdir/$path/done", 'w');
		if (defined $fh) {
			close($fh);
			print "DEBUG: marking directory $outdir/$path/ has been done...\n" if ($DEBUG);
		}
	}
	pop(@report_day_done);
	foreach my $path (@report_day_done) {
		next if (-e "$path/done");
		my $fh = IO::File->new("$outdir/$path/done", 'w');
		if (defined $fh) {
			close($fh);
			print "DEBUG: marking directory $outdir/$path/ has been done...\n" if ($DEBUG);
		}
	}

	my %month_name = (
		'01' => 'January', '02' => 'February', '03' => 'March', '04' => 'April',
		'05' => 'May', '06' => 'June', '07' => 'July', '08' => 'August',
		'09' => 'September', '10' => 'October', '11' => 'November', '12' => 'December'
	);
	return qq{
	      <div class="panel panel-default">
		<div class="panel-heading">
		<h2>$month_name{$month}</h2>
		</div>
		<div class="panel-body">
		$str
		</div>
	      </div>
};
}

sub build_head
{
	my ($local_title, $base) = @_;

	$base ||= '.';
	my $date = localtime(time);

	return qq{<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="Content-Type" content="text/html; charset=$charset" />
<meta name="robots" content="noindex,nofollow">
<meta http-equiv="Expires" content="$date">
<meta http-equiv="Generator" content="pgCluu v$VERSION">
<meta http-equiv="Date" content="$date">
<meta name="description" content="">
<meta name="author" content="">
<link rel="shortcut icon" href="$pgcluu_ico" />
<title>pgCluu :: $local_title</title>

 <link href="$base/jquery.jqplot.min.css" rel="stylesheet">
 <script type="text/javascript" src="$base/jquery.min.js"></script>
 <script type="text/javascript" src="$base/jquery.jqplot.min.js"></script>
 <script type="text/javascript" src="$base/jqplot.pieRenderer.min.js"></script>
 <script type="text/javascript" src="$base/jqplot.barRenderer.min.js"></script>
 <script type="text/javascript" src="$base/jqplot.dateAxisRenderer.min.js"></script>
 <script type="text/javascript" src="$base/jqplot.canvasTextRenderer.min.js"></script>
 <script type="text/javascript" src="$base/jqplot.categoryAxisRenderer.min.js"></script>
 <script type="text/javascript" src="$base/jqplot.canvasAxisTickRenderer.min.js"></script>
 <script type="text/javascript" src="$base/jqplot.canvasAxisLabelRenderer.min.js"></script>
 <script type="text/javascript" src="$base/jqplot.highlighter.min.js"></script>
 <script type="text/javascript" src="$base/jqplot.highlighter.min.js"></script>
 <script type="text/javascript" src="$base/jqplot.cursor.min.js"></script>
 <script type="text/javascript" src="$base/jqplot.pointLabels.min.js"></script>
 <script type="text/javascript" src="$base/bean.min.js"></script>
 <script type="text/javascript" src="$base/underscore.min.js"></script>
 <link href="$base/bootstrap.min.css" rel="stylesheet">
 <link href="$base/fontawesome.min.css" rel="stylesheet">
 <script type="text/javascript" src="$base/bootstrap.min.js"></script>
 <link href="$base/pgcluu.min.css" rel="stylesheet">
 <link href="$base/bootstrap-datetimepicker.min.css" rel="stylesheet">
 <script src="$base/pgcluu.min.js"></script>
 <script src="$base/pgcluu_slide.min.js"></script>
 <script src="$base/sorttable.min.js"></script>
 <script src="$base/bootstrap-datetimepicker.min.js"></script>
 <script src="$base/w3.min.js"></script>

</head>
};

}

sub build_hour_index
{
	my $outdir = shift;

	print "DEBUG: generating index to access hourly reports...\n" if ($DEBUG);

	my @done = ();
	my $fh = IO::File->new("$outdir/index.html", 'w');
	if (not defined $fh) {
		die "FATAL: can't write to $outdir/index.html, $!\n";
	}
	print $fh &build_head('Hourly Index on incremental reports', '../../..');
	print $fh qq{
<body>

<div id="navigation">

    <div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
      <div class="container mainmenu">
        <a class="navbar-brand" href="http://pgcluu.darold.net/">
        <img src="$pgcluu_logo" title="$PROGRAM"></a>
        <div class="navbar-header">
          <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
        </div>
        <div class="navbar-collapse collapse">
          <ul class="nav navbar-nav">
              <!-- li id="menu-home" class="dropdown"><a href="index.html#home">Home</a></li -->
              <!--li id="menu-about" class="dropdown"><a href="index.html#about">About</a></li -->
          </ul>
        </div><!--/.nav-collapse -->
      </div>
    </div>
</div>
<div class="container" id="main-container">
};

	my $date = $outdir;
	$date =~ s/^.*(\d{4})\/(\d{2})\/(\d{2}).*/$1-$2-$3/;
	print $fh qq{
	<h1>Hourly reports</h1>
	<table class="table table-striped table-hover table-condensed"><tr><td>
	<div class="panel panel-default">
	<div class="panel-heading">
	<h2>Day $date</h2>
	<div class="panel-body">
};
        print $fh "<table width='20%'><thead><tr><th colspan=4>Hours</th></tr></thead><tbody><tr>";
	foreach my $h ('00' .. '23') {
		print $fh "</tr><tr>" if ( ($h%4) == 0 && $h ne '00');
		if (-e "$outdir/$h/index.html") {
			push(@done, "$outdir/$h");
			print $fh "<td><a href=\"$h/index.html\" target=\"new\">$h:00</a></td>";
		} else {
			print $fh "<td>$h:00</td>";
		}
	}
	print $fh qq{</tr></tbody></table>
                </div>
              </div>
        </td></tr></table>
	$COPYRIGHT
</div><!--/.container-->
  </body>
</html>
};
	$fh->close;

	return @done;
}


# Returns day number of the week of a given days
sub get_day_of_week
{
	my ($year, $month, $day) = @_;

#       %w     The day of the week as a decimal, range 0 to 6, Sunday being 0.
	my $weekDay = '';
	if (!$week_start_monday) {
		# Start on sunday = 0
		$weekDay = POSIX::strftime("%w", 1,1,1,$day,--$month,$year-1900);
	} else {
		# Start on monday = 1
		$weekDay = POSIX::strftime("%u", 1,1,1,$day,--$month,$year-1900);
		$weekDay--;
	}

	return $weekDay;
}

# Return the week number of the year for a given date
sub get_week_number
{
	my ($year, $month, $day) = @_;

#       %U     The week number of the current year as a decimal number, range 00 to 53, starting with the first
#              Sunday as the first day of week 01.
#       %V     The ISO 8601 week number (see NOTES) of the current year as a decimal number, range 01 to 53,
#              where week 1 is the first week that has at least 4 days in the new year.
#       %W     The week number of the current year as a decimal number, range 00 to 53, starting with the first
#              Monday as the first day of week 01.

	# Check if the date is valid first
	my $datefmt = POSIX::strftime("%Y-%m-%d", 1, 1, 1, $day, $month - 1, $year - 1900);
	if ($datefmt ne "$year-$month-$day") {
		return -1;
	}
	my $weekNumber = '';
	if (!$week_start_monday) {
		$weekNumber = POSIX::strftime("%U", 1, 1, 1, $day, $month - 1, $year - 1900);
	} else {
		$weekNumber = POSIX::strftime("%W", 1, 1, 1, $day, $month - 1, $year - 1900);
	}
	return sprintf("%02d", $weekNumber+1);
}

sub build_daily_binary
{
	my $old_day = '';
	my $day_dir = '';
	foreach (my $dx = 0; $dx <= $#WORK_DIRS; $dx++) {

		next if ($WORK_DIRS[$dx] !~ /\d{4}\/\d{2}\/(\d{2})\/\d{2}/);
		my $curday = $1;
		my $in_dir = "$INPUT_DIR/$WORK_DIRS[$dx]";

		if ($old_day ne $curday) {
			$day_dir = "$INPUT_DIR/$WORK_DIRS[$dx]";
			$day_dir =~ s/\/\d{2}$//;
			# Save binary files for the previous day
			&dump_sys_binary($day_dir, "sys_cache.bin");
			&dump_pg_binary($day_dir);
			&dump_sar_binary($day_dir);
			&dump_pidstat_binary($day_dir);
			&commit_cache_files($day_dir);

			# Reset global variables before processing a new work dir
			&clear_stats();
			@DEVICE_LIST = ();
			@DEVICE_SPACE_LIST = ();
			@IFACE_LIST = ();

			# Switch to next day
			$old_day = $curday;
		}

		$OUTPUT_DIR = "$ORIG_OUTPUT_DIR/$WORK_DIRS[$dx]";

		# Check if we have binary file in the directory
		my @binfiles = ();
		if (-d "$in_dir") {
			opendir(IDIR, "$in_dir") || die "FATAL: can't opendir $in_dir: $!";
			@binfiles = grep { /^all_.*\.bin$/ } readdir(IDIR);
			closedir(IDIR);
		}

		# Look at system information
		&read_sysinfo($in_dir);

		if ($#binfiles > 0) {
			# Load statistics from cache files
			print "DEBUG: Loading PostgreSQL statistics from cache files $in_dir/*.bin\n" if ($DEBUG);
			&load_pg_binary($in_dir);
			if (($TIMEZONE eq '00') && $global_infos{timezone}) {
				$TIMEZONE = $global_infos{timezone};
			}
			if (($STATS_TIMEZONE eq '00') && $global_infos{stats_timezone}) {
				$STATS_TIMEZONE = $global_infos{stats_timezone};
			}
			if (!$DISABLE_SAR) {
				print "DEBUG: Loading Sar statistics from cache files $in_dir/*.bin\n" if ($DEBUG);
				# sar and pidstat files are written together, see lock_cache_dir()
				my $lock = &lock_cache_dir($in_dir, LOCK_SH);
				&load_sar_binary($in_dir);
				&load_pidstat_binary($in_dir);
				close($lock) if ($lock);
			}
		}
	}

	# Save binary files for the last day
	$day_dir = "$INPUT_DIR/$WORK_DIRS[-1]";
	$day_dir =~ s/\/\d{2}$//;
	$global_infos{'in_dir'} = $day_dir;
	# Save binary files for the last day
	&dump_sys_binary($day_dir, "sys_cache.bin");
	&dump_pg_binary($day_dir);
	&dump_sar_binary($day_dir);
	&dump_pidstat_binary($day_dir);
	&commit_cache_files($day_dir);
}

sub read_conf
{
	# We don't need a configuration file but if any check the
	# configuration directives related to pgcluu only.
	my $fh = IO::File->new($CONFIG_FILE, 'r');
	if (defined $fh)
	{
		print STDERR "DEBUG: Reading configuration file $CONFIG_FILE\n" if ($DEBUG);
		while (my $l = <$fh>)
		{
			chomp($l);
			$l =~ s/\r//gs;
			next if (!$l);

			my ($var, @vals) = split(/[\s]+/, $l);
			if ($var eq 'STATS_REPORT_RETENTION')
			{
				$vals[0] = int($vals[0]);
				if ($RETENTION != $vals[0])
				{
					$RETENTION = $vals[0];
					print STDERR "LOG: Setting retention from configuration file to $RETENTION\n";
				}
			}
			elsif ($var eq 'STATS_REPORT_CACHING')
			{
				my $tmp_outdir = '';
				for (my $i = 0; $i <= $#ARGV; $i++) {
					$tmp_outdir = $ARGV[$i+1], last if ($ARGV[$i] =~ /^(-o|--output)$/);
				}
				if (is_interactive_mode() and !$CACHE and $tmp_outdir and $vals[0]) {
					# The user might don't want to use cache mode, do nothing
					$CACHE = 0;
				} else {
					$CACHE = $vals[0];
				}
			}
			elsif ($var eq 'STATS_REPORT_OUTDIR')
			{
				$OUTPUT_DIR = $vals[0];
				print STDERR "LOG: Setting output dir from configuration file to $OUTPUT_DIR\n";
			}
		}
		close($fh);
	}
}

__DATA__

WRFILE: jquery.jqplot.min.css

.jqplot-target{position:relative;color:#666;font-family:"Trebuchet MS",Arial,Helvetica,sans-serif;font-size:1em}.jqplot-axis{font-size:.75em}.jqplot-xaxis{margin-top:10px}.jqplot-x2axis{margin-bottom:10px}.jqplot-yaxis{margin-right:10px}.jqplot-y2axis,.jqplot-y3axis,.jqplot-y4axis,.jqplot-y5axis,.jqplot-y6axis,.jqplot-y7axis,.jqplot-y8axis,.jqplot-y9axis,.jqplot-yMidAxis{margin-left:10px;margin-right:10px}.jqplot-axis-tick,.jqplot-xaxis-tick,.jqplot-yaxis-tick,.jqplot-x2axis-tick,.jqplot-y2axis-tick,.jqplot-y3axis-tick,.jqplot-y4axis-tick,.jqplot-y5axis-tick,.jqplot-y6axis-tick,.jqplot-y7axis-tick,.jqplot-y8axis-tick,.jqplot-y9axis-tick,.jqplot-yMidAxis-tick{position:absolute;white-space:pre}.jqplot-xaxis-tick{top:0;left:15px;vertical-align:top}.jqplot-x2axis-tick{bottom:0;left:15px;vertical-align:bottom}.jqplot-yaxis-tick{right:0;top:15px;text-align:right}.jqplot-yaxis-tick.jqplot-breakTick{right:-20px;margin-right:0;padding:1px 5px 1px 5px;z-index:2;font-size:1.5em}.jqplot-y2axis-tick,.jqplot-y3axis-tick,.jqplot-y4axis-tick,.jqplot-y5axis-tick,.jqplot-y6axis-tick,.jqplot-y7axis-tick,.jqplot-y8axis-tick,.jqplot-y9axis-tick{left:0;top:15px;text-align:left}.jqplot-yMidAxis-tick{text-align:center;white-space:nowrap}.jqplot-xaxis-label{margin-top:10px;font-size:11pt;position:absolute}.jqplot-x2axis-label{margin-bottom:10px;font-size:11pt;position:absolute}.jqplot-yaxis-label{margin-right:10px;font-size:11pt;position:absolute}.jqplot-yMidAxis-label{font-size:11pt;position:absolute}.jqplot-y2axis-label,.jqplot-y3axis-label,.jqplot-y4axis-label,.jqplot-y5axis-label,.jqplot-y6axis-label,.jqplot-y7axis-label,.jqplot-y8axis-label,.jqplot-y9axis-label{font-size:11pt;margin-left:10px;position:absolute}.jqplot-meterGauge-tick{font-size:.75em;color:#999}.jqplot-meterGauge-label{font-size:1em;color:#999}table.jqplot-table-legend{margin-top:12px;margin-bottom:12px;margin-left:12px;margin-right:12px}table.jqplot-table-legend,table.jqplot-cursor-legend{background-color:rgba(255,255,255,0.6);border:1px solid #ccc;position:absolute;font-size:.75em}td.jqplot-table-legend{vertical-align:middle}td.jqplot-seriesToggle:hover,td.jqplot-seriesToggle:active{cursor:pointer}.jqplot-table-legend .jqplot-series-hidden{text-decoration:line-through}div.jqplot-table-legend-swatch-outline{border:1px solid #ccc;padding:1px}div.jqplot-table-legend-swatch{width:0;height:0;border-top-width:5px;border-bottom-width:5px;border-left-width:6px;border-right-width:6px;border-top-style:solid;border-bottom-style:solid;border-left-style:solid;border-right-style:solid}.jqplot-title{top:0;left:0;padding-bottom:.5em;font-size:1.2em}table.jqplot-cursor-tooltip{border:1px solid #ccc;font-size:.75em}.jqplot-cursor-tooltip{border:1px solid #ccc;font-size:.75em;white-space:nowrap;background:rgba(208,208,208,0.5);padding:1px}.jqplot-highlighter-tooltip,.jqplot-canvasOverlay-tooltip{border:1px solid #ccc;font-size:.75em;white-space:nowrap;background:rgba(208,208,208,0.5);padding:1px}.jqplot-point-label{font-size:.75em;z-index:2}td.jqplot-cursor-legend-swatch{vertical-align:middle;text-align:center}div.jqplot-cursor-legend-swatch{width:1.2em;height:.7em}.jqplot-error{text-align:center}.jqplot-error-message{position:relative;top:46%;display:inline-block}div.jqplot-bubble-label{font-size:.8em;padding-left:2px;padding-right:2px;color:rgb(20%,20%,20%)}div.jqplot-bubble-label.jqplot-bubble-label-highlight{background:rgba(90%,90%,90%,0.7)}div.jqplot-noData-container{text-align:center;background-color:rgba(96%,96%,96%,0.3)}
WRFILE: jquery.min.js

/*!
 * jQuery JavaScript Library v1.9.1
 * http://jquery.com/
 *
 * Includes Sizzle.js
 * http://sizzlejs.com/
 *
 * Copyright 2005, 2012 jQuery Foundation, Inc. and other contributors
 * Released under the MIT license
 * http://jquery.org/license
 *
 * Date: 2013-2-4
 */
(function(a2,aG){var ai,w,aC=typeof aG,l=a2.document,aL=a2.location,bi=a2.jQuery,H=a2.$,aa={},a6=[],s="1.9.1",aI=a6.concat,ao=a6.push,a4=a6.slice,aM=a6.indexOf,z=aa.toString,V=aa.hasOwnProperty,aQ=s.trim,bJ=function(e,b3){return new bJ.fn.init(e,b3,w)},bA=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,ac=/\S+/g,C=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,br=/^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/,a=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,bh=/^[\],:{}\s]*$/,bk=/(?:^|:|,)(?:\s*\[)+/g,bG=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,aZ=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,bS=/^-ms-/,aV=/-([\da-z])/gi,M=function(e,b3){return b3.toUpperCase()},bW=function(e){if(l.addEventListener||e.type==="load"||l.readyState==="complete"){bl();bJ.ready()}},bl=function(){if(l.addEventListener){l.removeEventListener("DOMContentLoaded",bW,false);a2.removeEventListener("load",bW,false)}else{l.detachEvent("onreadystatechange",bW);a2.detachEvent("onload",bW)}};bJ.fn=bJ.prototype={jquery:s,constructor:bJ,init:function(e,b5,b4){var b3,b6;if(!e){return this}if(typeof e==="string"){if(e.charAt(0)==="<"&&e.charAt(e.length-1)===">"&&e.length>=3){b3=[null,e,null]}else{b3=br.exec(e)}if(b3&&(b3[1]||!b5)){if(b3[1]){b5=b5 instanceof bJ?b5[0]:b5;bJ.merge(this,bJ.parseHTML(b3[1],b5&&b5.nodeType?b5.ownerDocument||b5:l,true));if(a.test(b3[1])&&bJ.isPlainObject(b5)){for(b3 in b5){if(bJ.isFunction(this[b3])){this[b3](b5[b3])}else{this.attr(b3,b5[b3])}}}return this}else{b6=l.getElementById(b3[2]);if(b6&&b6.parentNode){if(b6.id!==b3[2]){return b4.find(e)}this.length=1;this[0]=b6}this.context=l;this.selector=e;return this}}else{if(!b5||b5.jquery){return(b5||b4).find(e)}else{return this.constructor(b5).find(e)}}}else{if(e.nodeType){this.context=this[0]=e;this.length=1;return this}else{if(bJ.isFunction(e)){return b4.ready(e)}}}if(e.selector!==aG){this.selector=e.selector;this.context=e.context}return bJ.makeArray(e,this)},selector:"",length:0,size:function(){return this.length},toArray:function(){return a4.call(this)},get:function(e){return e==null?this.toArray():(e<0?this[this.length+e]:this[e])},pushStack:function(e){var b3=bJ.merge(this.constructor(),e);b3.prevObject=this;b3.context=this.context;return b3},each:function(b3,e){return bJ.each(this,b3,e)},ready:function(e){bJ.ready.promise().done(e);return this},slice:function(){return this.pushStack(a4.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(b4){var e=this.length,b3=+b4+(b4<0?e:0);return this.pushStack(b3>=0&&b3<e?[this[b3]]:[])},map:function(e){return this.pushStack(bJ.map(this,function(b4,b3){return e.call(b4,b3,b4)}))},end:function(){return this.prevObject||this.constructor(null)},push:ao,sort:[].sort,splice:[].splice};bJ.fn.init.prototype=bJ.fn;bJ.extend=bJ.fn.extend=function(){var e,b8,b3,b4,cb,b9,b7=arguments[0]||{},b6=1,b5=arguments.length,ca=false;if(typeof b7==="boolean"){ca=b7;b7=arguments[1]||{};b6=2}if(typeof b7!=="object"&&!bJ.isFunction(b7)){b7={}}if(b5===b6){b7=this;--b6}for(;b6<b5;b6++){if((cb=arguments[b6])!=null){for(b4 in cb){e=b7[b4];b3=cb[b4];if(b7===b3){continue}if(ca&&b3&&(bJ.isPlainObject(b3)||(b8=bJ.isArray(b3)))){if(b8){b8=false;b9=e&&bJ.isArray(e)?e:[]}else{b9=e&&bJ.isPlainObject(e)?e:{}}b7[b4]=bJ.extend(ca,b9,b3)}else{if(b3!==aG){b7[b4]=b3}}}}}return b7};bJ.extend({noConflict:function(e){if(a2.$===bJ){a2.$=H}if(e&&a2.jQuery===bJ){a2.jQuery=bi}return bJ},isReady:false,readyWait:1,holdReady:function(e){if(e){bJ.readyWait++}else{bJ.ready(true)}},ready:function(e){if(e===true?--bJ.readyWait:bJ.isReady){return}if(!l.body){return setTimeout(bJ.ready)}bJ.isReady=true;if(e!==true&&--bJ.readyWait>0){return}ai.resolveWith(l,[bJ]);if(bJ.fn.trigger){bJ(l).trigger("ready").off("ready")}},isFunction:function(e){return bJ.type(e)==="function"},isArray:Array.isArray||function(e){return bJ.type(e)==="array"},isWindow:function(e){return e!=null&&e==e.window},isNumeric:function(e){return !isNaN(parseFloat(e))&&isFinite(e)},type:function(e){if(e==null){return String(e)}return typeof e==="object"||typeof e==="function"?aa[z.call(e)]||"object":typeof e},isPlainObject:function(b5){if(!b5||bJ.type(b5)!=="object"||b5.nodeType||bJ.isWindow(b5)){return false}try{if(b5.constructor&&!V.call(b5,"constructor")&&!V.call(b5.constructor.prototype,"isPrototypeOf")){return false}}catch(b4){return false}var b3;for(b3 in b5){}return b3===aG||V.call(b5,b3)},isEmptyObject:function(b3){var e;for(e in b3){return false}return true},error:function(e){throw new Error(e)},parseHTML:function(b6,b4,b5){if(!b6||typeof b6!=="string"){return null}if(typeof b4==="boolean"){b5=b4;b4=false}b4=b4||l;var b3=a.exec(b6),e=!b5&&[];if(b3){return[b4.createElement(b3[1])]}b3=bJ.buildFragment([b6],b4,e);if(e){bJ(e).remove()}return bJ.merge([],b3.childNodes)},parseJSON:function(e){if(a2.JSON&&a2.JSON.parse){return a2.JSON.parse(e)}if(e===null){return e}if(typeof e==="string"){e=bJ.trim(e);if(e){if(bh.test(e.replace(bG,"@").replace(aZ,"]").replace(bk,""))){return(new Function("return "+e))()}}}bJ.error("Invalid JSON: "+e)},parseXML:function(b5){var b3,b4;if(!b5||typeof b5!=="string"){return null}try{if(a2.DOMParser){b4=new DOMParser();b3=b4.parseFromString(b5,"text/xml")}else{b3=new ActiveXObject("Microsoft.XMLDOM");b3.async="false";b3.loadXML(b5)}}catch(b6){b3=aG}if(!b3||!b3.documentElement||b3.getElementsByTagName("parsererror").length){bJ.error("Invalid XML: "+b5)}return b3},noop:function(){},globalEval:function(e){if(e&&bJ.trim(e)){(a2.execScript||function(b3){a2["eval"].call(a2,b3)})(e)}},camelCase:function(e){return e.replace(bS,"ms-").replace(aV,M)},nodeName:function(b3,e){return b3.nodeName&&b3.nodeName.toLowerCase()===e.toLowerCase()},each:function(b7,b8,b3){var b6,b4=0,b5=b7.length,e=ab(b7);if(b3){if(e){for(;b4<b5;b4++){b6=b8.apply(b7[b4],b3);if(b6===false){break}}}else{for(b4 in b7){b6=b8.apply(b7[b4],b3);if(b6===false){break}}}}else{if(e){for(;b4<b5;b4++){b6=b8.call(b7[b4],b4,b7[b4]);if(b6===false){break}}}else{for(b4 in b7){b6=b8.call(b7[b4],b4,b7[b4]);if(b6===false){break}}}}return b7},trim:aQ&&!aQ.call("\uFEFF\xA0")?function(e){return e==null?"":aQ.call(e)}:function(e){return e==null?"":(e+"").replace(C,"")},makeArray:function(e,b4){var b3=b4||[];if(e!=null){if(ab(Object(e))){bJ.merge(b3,typeof e==="string"?[e]:e)}else{ao.call(b3,e)}}return b3},inArray:function(b5,b3,b4){var e;if(b3){if(aM){return aM.call(b3,b5,b4)}e=b3.length;b4=b4?b4<0?Math.max(0,e+b4):b4:0;for(;b4<e;b4++){if(b4 in b3&&b3[b4]===b5){return b4}}}return -1},merge:function(b6,b4){var e=b4.length,b5=b6.length,b3=0;if(typeof e==="number"){for(;b3<e;b3++){b6[b5++]=b4[b3]}}else{while(b4[b3]!==aG){b6[b5++]=b4[b3++]}}b6.length=b5;return b6},grep:function(b3,b8,e){var b7,b4=[],b5=0,b6=b3.length;e=!!e;for(;b5<b6;b5++){b7=!!b8(b3[b5],b5);if(e!==b7){b4.push(b3[b5])}}return b4},map:function(b4,b9,e){var b8,b6=0,b7=b4.length,b3=ab(b4),b5=[];if(b3){for(;b6<b7;b6++){b8=b9(b4[b6],b6,e);if(b8!=null){b5[b5.length]=b8}}}else{for(b6 in b4){b8=b9(b4[b6],b6,e);if(b8!=null){b5[b5.length]=b8}}}return aI.apply([],b5)},guid:1,proxy:function(b6,b5){var e,b4,b3;if(typeof b5==="string"){b3=b6[b5];b5=b6;b6=b3}if(!bJ.isFunction(b6)){return aG}e=a4.call(arguments,2);b4=function(){return b6.apply(b5||this,e.concat(a4.call(arguments)))};b4.guid=b6.guid=b6.guid||bJ.guid++;return b4},access:function(e,b7,b9,b8,b5,cb,ca){var b4=0,b3=e.length,b6=b9==null;if(bJ.type(b9)==="object"){b5=true;for(b4 in b9){bJ.access(e,b7,b4,b9[b4],true,cb,ca)}}else{if(b8!==aG){b5=true;if(!bJ.isFunction(b8)){ca=true}if(b6){if(ca){b7.call(e,b8);b7=null}else{b6=b7;b7=function(cd,cc,ce){return b6.call(bJ(cd),ce)}}}if(b7){for(;b4<b3;b4++){b7(e[b4],b9,ca?b8:b8.call(e[b4],b4,b7(e[b4],b9)))}}}}return b5?e:b6?b7.call(e):b3?b7(e[0],b9):cb},now:function(){return(new Date()).getTime()}});bJ.ready.promise=function(b6){if(!ai){ai=bJ.Deferred();if(l.readyState==="complete"){setTimeout(bJ.ready)}else{if(l.addEventListener){l.addEventListener("DOMContentLoaded",bW,false);a2.addEventListener("load",bW,false)}else{l.attachEvent("onreadystatechange",bW);a2.attachEvent("onload",bW);var b5=false;try{b5=a2.frameElement==null&&l.documentElement}catch(b4){}if(b5&&b5.doScroll){(function b3(){if(!bJ.isReady){try{b5.doScroll("left")}catch(b7){return setTimeout(b3,50)}bl();bJ.ready()}})()}}}}return ai.promise(b6)};bJ.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(b3,e){aa["[object "+e+"]"]=e.toLowerCase()});function ab(b4){var b3=b4.length,e=bJ.type(b4);if(bJ.isWindow(b4)){return false}if(b4.nodeType===1&&b3){return true}return e==="array"||e!=="function"&&(b3===0||typeof b3==="number"&&b3>0&&(b3-1) in b4)}w=bJ(l);var bY={};function ae(b3){var e=bY[b3]={};bJ.each(b3.match(ac)||[],function(b5,b4){e[b4]=true});return e}bJ.Callbacks=function(cc){cc=typeof cc==="string"?(bY[cc]||ae(cc)):bJ.extend({},cc);var b6,b5,e,b7,b8,b4,b9=[],ca=!cc.once&&[],b3=function(cd){b5=cc.memory&&cd;e=true;b8=b4||0;b4=0;b7=b9.length;b6=true;for(;b9&&b8<b7;b8++){if(b9[b8].apply(cd[0],cd[1])===false&&cc.stopOnFalse){b5=false;break}}b6=false;if(b9){if(ca){if(ca.length){b3(ca.shift())}}else{if(b5){b9=[]}else{cb.disable()}}}},cb={add:function(){if(b9){var ce=b9.length;(function cd(cf){bJ.each(cf,function(ch,cg){var ci=bJ.type(cg);if(ci==="function"){if(!cc.unique||!cb.has(cg)){b9.push(cg)}}else{if(cg&&cg.length&&ci!=="string"){cd(cg)}}})})(arguments);if(b6){b7=b9.length}else{if(b5){b4=ce;b3(b5)}}}return this},remove:function(){if(b9){bJ.each(arguments,function(cf,cd){var ce;while((ce=bJ.inArray(cd,b9,ce))>-1){b9.splice(ce,1);if(b6){if(ce<=b7){b7--}if(ce<=b8){b8--}}}})}return this},has:function(cd){return cd?bJ.inArray(cd,b9)>-1:!!(b9&&b9.length)},empty:function(){b9=[];return this},disable:function(){b9=ca=b5=aG;return this},disabled:function(){return !b9},lock:function(){ca=aG;if(!b5){cb.disable()}return this},locked:function(){return !ca},fireWith:function(ce,cd){cd=cd||[];cd=[ce,cd.slice?cd.slice():cd];if(b9&&(!e||ca)){if(b6){ca.push(cd)}else{b3(cd)}}return this},fire:function(){cb.fireWith(this,arguments);return this},fired:function(){return !!e}};return cb};bJ.extend({Deferred:function(b4){var b3=[["resolve","done",bJ.Callbacks("once memory"),"resolved"],["reject","fail",bJ.Callbacks("once memory"),"rejected"],["notify","progress",bJ.Callbacks("memory")]],b5="pending",b6={state:function(){return b5},always:function(){e.done(arguments).fail(arguments);return this},then:function(){var b7=arguments;return bJ.Deferred(function(b8){bJ.each(b3,function(ca,b9){var cc=b9[0],cb=bJ.isFunction(b7[ca])&&b7[ca];e[b9[1]](function(){var cd=cb&&cb.apply(this,arguments);if(cd&&bJ.isFunction(cd.promise)){cd.promise().done(b8.resolve).fail(b8.reject).progress(b8.notify)}else{b8[cc+"With"](this===b6?b8.promise():this,cb?[cd]:arguments)}})});b7=null}).promise()},promise:function(b7){return b7!=null?bJ.extend(b7,b6):b6}},e={};b6.pipe=b6.then;bJ.each(b3,function(b8,b7){var ca=b7[2],b9=b7[3];b6[b7[1]]=ca.add;if(b9){ca.add(function(){b5=b9},b3[b8^1][2].disable,b3[2][2].lock)}e[b7[0]]=function(){e[b7[0]+"With"](this===e?b6:this,arguments);return this};e[b7[0]+"With"]=ca.fireWith});b6.promise(e);if(b4){b4.call(e,e)}return e},when:function(b6){var b4=0,b8=a4.call(arguments),e=b8.length,b3=e!==1||(b6&&bJ.isFunction(b6.promise))?e:0,cb=b3===1?b6:bJ.Deferred(),b5=function(cd,ce,cc){return function(cf){ce[cd]=this;cc[cd]=arguments.length>1?a4.call(arguments):cf;if(cc===ca){cb.notifyWith(ce,cc)}else{if(!(--b3)){cb.resolveWith(ce,cc)}}}},ca,b7,b9;if(e>1){ca=new Array(e);b7=new Array(e);b9=new Array(e);for(;b4<e;b4++){if(b8[b4]&&bJ.isFunction(b8[b4].promise)){b8[b4].promise().done(b5(b4,b9,b8)).fail(cb.reject).progress(b5(b4,b7,ca))}else{--b3}}}if(!b3){cb.resolveWith(b9,b8)}return cb.promise()}});bJ.support=(function(){var ce,cd,cb,ca,cc,b9,b5,b7,b4,b6,b3=l.createElement("div");b3.setAttribute("className","t");b3.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";cd=b3.getElementsByTagName("*");cb=b3.getElementsByTagName("a")[0];if(!cd||!cb||!cd.length){return{}}cc=l.createElement("select");b5=cc.appendChild(l.createElement("option"));ca=b3.getElementsByTagName("input")[0];cb.style.cssText="top:1px;float:left;opacity:.5";ce={getSetAttribute:b3.className!=="t",leadingWhitespace:b3.firstChild.nodeType===3,tbody:!b3.getElementsByTagName("tbody").length,htmlSerialize:!!b3.getElementsByTagName("link").length,style:/top/.test(cb.getAttribute("style")),hrefNormalized:cb.getAttribute("href")==="/a",opacity:/^0.5/.test(cb.style.opacity),cssFloat:!!cb.style.cssFloat,checkOn:!!ca.value,optSelected:b5.selected,enctype:!!l.createElement("form").enctype,html5Clone:l.createElement("nav").cloneNode(true).outerHTML!=="<:nav></:nav>",boxModel:l.compatMode==="CSS1Compat",deleteExpando:true,noCloneEvent:true,inlineBlockNeedsLayout:false,shrinkWrapBlocks:false,reliableMarginRight:true,boxSizingReliable:true,pixelPosition:false};ca.checked=true;ce.noCloneChecked=ca.cloneNode(true).checked;cc.disabled=true;ce.optDisabled=!b5.disabled;try{delete b3.test}catch(b8){ce.deleteExpando=false}ca=l.createElement("input");ca.setAttribute("value","");ce.input=ca.getAttribute("value")==="";ca.value="t";ca.setAttribute("type","radio");ce.radioValue=ca.value==="t";ca.setAttribute("checked","t");ca.setAttribute("name","t");b9=l.createDocumentFragment();b9.appendChild(ca);ce.appendChecked=ca.checked;ce.checkClone=b9.cloneNode(true).cloneNode(true).lastChild.checked;if(b3.attachEvent){b3.attachEvent("onclick",function(){ce.noCloneEvent=false});b3.cloneNode(true).click()}for(b6 in {submit:true,change:true,focusin:true}){b3.setAttribute(b7="on"+b6,"t");ce[b6+"Bubbles"]=b7 in a2||b3.attributes[b7].expando===false}b3.style.backgroundClip="content-box";b3.cloneNode(true).style.backgroundClip="";ce.clearCloneStyle=b3.style.backgroundClip==="content-box";bJ(function(){var cf,ci,ch,cg="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",e=l.getElementsByTagName("body")[0];if(!e){return}cf=l.createElement("div");cf.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px";e.appendChild(cf).appendChild(b3);b3.innerHTML="<table><tr><td></td><td>t</td></tr></table>";ch=b3.getElementsByTagName("td");ch[0].style.cssText="padding:0;margin:0;border:0;display:none";b4=(ch[0].offsetHeight===0);ch[0].style.display="";ch[1].style.display="none";ce.reliableHiddenOffsets=b4&&(ch[0].offsetHeight===0);b3.innerHTML="";b3.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;";ce.boxSizing=(b3.offsetWidth===4);ce.doesNotIncludeMarginInBodyOffset=(e.offsetTop!==1);if(a2.getComputedStyle){ce.pixelPosition=(a2.getComputedStyle(b3,null)||{}).top!=="1%";ce.boxSizingReliable=(a2.getComputedStyle(b3,null)||{width:"4px"}).width==="4px";ci=b3.appendChild(l.createElement("div"));ci.style.cssText=b3.style.cssText=cg;ci.style.marginRight=ci.style.width="0";b3.style.width="1px";ce.reliableMarginRight=!parseFloat((a2.getComputedStyle(ci,null)||{}).marginRight)}if(typeof b3.style.zoom!==aC){b3.innerHTML="";b3.style.cssText=cg+"width:1px;padding:1px;display:inline;zoom:1";ce.inlineBlockNeedsLayout=(b3.offsetWidth===3);b3.style.display="block";b3.innerHTML="<div></div>";b3.firstChild.style.width="5px";ce.shrinkWrapBlocks=(b3.offsetWidth!==3);if(ce.inlineBlockNeedsLayout){e.style.zoom=1}}e.removeChild(cf);cf=b3=ch=ci=null});cd=cc=b9=b5=cb=ca=null;return ce})();var bw=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,aN=/([A-Z])/g;function ba(b5,b3,b7,b6){if(!bJ.acceptData(b5)){return}var b8,ca,cb=bJ.expando,b9=typeof b3==="string",cc=b5.nodeType,e=cc?bJ.cache:b5,b4=cc?b5[cb]:b5[cb]&&cb;if((!b4||!e[b4]||(!b6&&!e[b4].data))&&b9&&b7===aG){return}if(!b4){if(cc){b5[cb]=b4=a6.pop()||bJ.guid++}else{b4=cb}}if(!e[b4]){e[b4]={};if(!cc){e[b4].toJSON=bJ.noop}}if(typeof b3==="object"||typeof b3==="function"){if(b6){e[b4]=bJ.extend(e[b4],b3)}else{e[b4].data=bJ.extend(e[b4].data,b3)}}b8=e[b4];if(!b6){if(!b8.data){b8.data={}}b8=b8.data}if(b7!==aG){b8[bJ.camelCase(b3)]=b7}if(b9){ca=b8[b3];if(ca==null){ca=b8[bJ.camelCase(b3)]}}else{ca=b8}return ca}function Z(b5,b3,b6){if(!bJ.acceptData(b5)){return}var b8,b7,b9,ca=b5.nodeType,e=ca?bJ.cache:b5,b4=ca?b5[bJ.expando]:bJ.expando;if(!e[b4]){return}if(b3){b9=b6?e[b4]:e[b4].data;if(b9){if(!bJ.isArray(b3)){if(b3 in b9){b3=[b3]}else{b3=bJ.camelCase(b3);if(b3 in b9){b3=[b3]}else{b3=b3.split(" ")}}}else{b3=b3.concat(bJ.map(b3,bJ.camelCase))}for(b8=0,b7=b3.length;b8<b7;b8++){delete b9[b3[b8]]}if(!(b6?N:bJ.isEmptyObject)(b9)){return}}}if(!b6){delete e[b4].data;if(!N(e[b4])){return}}if(ca){bJ.cleanData([b5],true)}else{if(bJ.support.deleteExpando||e!=e.window){delete e[b4]}else{e[b4]=null}}}bJ.extend({cache:{},expando:"jQuery"+(s+Math.random()).replace(/\D/g,""),noData:{embed:true,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:true},hasData:function(e){e=e.nodeType?bJ.cache[e[bJ.expando]]:e[bJ.expando];return !!e&&!N(e)},data:function(b3,e,b4){return ba(b3,e,b4)},removeData:function(b3,e){return Z(b3,e)},_data:function(b3,e,b4){return ba(b3,e,b4,true)},_removeData:function(b3,e){return Z(b3,e,true)},acceptData:function(b3){if(b3.nodeType&&b3.nodeType!==1&&b3.nodeType!==9){return false}var e=b3.nodeName&&bJ.noData[b3.nodeName.toLowerCase()];return !e||e!==true&&b3.getAttribute("classid")===e}});bJ.fn.extend({data:function(b5,b8){var b3,e,b6=this[0],b4=0,b7=null;if(b5===aG){if(this.length){b7=bJ.data(b6);if(b6.nodeType===1&&!bJ._data(b6,"parsedAttrs")){b3=b6.attributes;for(;b4<b3.length;b4++){e=b3[b4].name;if(!e.indexOf("data-")){e=bJ.camelCase(e.slice(5));by(b6,e,b7[e])}}bJ._data(b6,"parsedAttrs",true)}}return b7}if(typeof b5==="object"){return this.each(function(){bJ.data(this,b5)})}return bJ.access(this,function(b9){if(b9===aG){return b6?by(b6,b5,bJ.data(b6,b5)):null}this.each(function(){bJ.data(this,b5,b9)})},null,b8,arguments.length>1,null,true)},removeData:function(e){return this.each(function(){bJ.removeData(this,e)})}});function by(b5,b4,b6){if(b6===aG&&b5.nodeType===1){var b3="data-"+b4.replace(aN,"-$1").toLowerCase();b6=b5.getAttribute(b3);if(typeof b6==="string"){try{b6=b6==="true"?true:b6==="false"?false:b6==="null"?null:+b6+""===b6?+b6:bw.test(b6)?bJ.parseJSON(b6):b6}catch(b7){}bJ.data(b5,b4,b6)}else{b6=aG}}return b6}function N(b3){var e;for(e in b3){if(e==="data"&&bJ.isEmptyObject(b3[e])){continue}if(e!=="toJSON"){return false}}return true}bJ.extend({queue:function(b4,b3,b5){var e;if(b4){b3=(b3||"fx")+"queue";e=bJ._data(b4,b3);if(b5){if(!e||bJ.isArray(b5)){e=bJ._data(b4,b3,bJ.makeArray(b5))}else{e.push(b5)}}return e||[]}},dequeue:function(b7,b6){b6=b6||"fx";var b3=bJ.queue(b7,b6),b8=b3.length,b5=b3.shift(),e=bJ._queueHooks(b7,b6),b4=function(){bJ.dequeue(b7,b6)};if(b5==="inprogress"){b5=b3.shift();b8--}e.cur=b5;if(b5){if(b6==="fx"){b3.unshift("inprogress")}delete e.stop;b5.call(b7,b4,e)}if(!b8&&e){e.empty.fire()}},_queueHooks:function(b4,b3){var e=b3+"queueHooks";return bJ._data(b4,e)||bJ._data(b4,e,{empty:bJ.Callbacks("once memory").add(function(){bJ._removeData(b4,b3+"queue");bJ._removeData(b4,e)})})}});bJ.fn.extend({queue:function(e,b3){var b4=2;if(typeof e!=="string"){b3=e;e="fx";b4--}if(arguments.length<b4){return bJ.queue(this[0],e)}return b3===aG?this:this.each(function(){var b5=bJ.queue(this,e,b3);bJ._queueHooks(this,e);if(e==="fx"&&b5[0]!=="inprogress"){bJ.dequeue(this,e)}})},dequeue:function(e){return this.each(function(){bJ.dequeue(this,e)})},delay:function(b3,e){b3=bJ.fx?bJ.fx.speeds[b3]||b3:b3;e=e||"fx";return this.queue(e,function(b5,b4){var b6=setTimeout(b5,b3);b4.stop=function(){clearTimeout(b6)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(b4,b8){var b3,b5=1,b9=bJ.Deferred(),b7=this,e=this.length,b6=function(){if(!(--b5)){b9.resolveWith(b7,[b7])}};if(typeof b4!=="string"){b8=b4;b4=aG}b4=b4||"fx";while(e--){b3=bJ._data(b7[e],b4+"queueHooks");if(b3&&b3.empty){b5++;b3.empty.add(b6)}}b6();return b9.promise(b8)}});var a8,bZ,bM=/[\t\r\n]/g,ak=/\r/g,aF=/^(?:input|select|textarea|button|object)$/i,D=/^(?:a|area)$/i,L=/^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/i,aq=/^(?:checked|selected)$/i,bP=bJ.support.getSetAttribute,bF=bJ.support.input;bJ.fn.extend({attr:function(e,b3){return bJ.access(this,bJ.attr,e,b3,arguments.length>1)},removeAttr:function(e){return this.each(function(){bJ.removeAttr(this,e)})},prop:function(e,b3){return bJ.access(this,bJ.prop,e,b3,arguments.length>1)},removeProp:function(e){e=bJ.propFix[e]||e;return this.each(function(){try{this[e]=aG;delete this[e]}catch(b3){}})},addClass:function(b9){var b3,e,ca,b6,b4,b5=0,b7=this.length,b8=typeof b9==="string"&&b9;if(bJ.isFunction(b9)){return this.each(function(cb){bJ(this).addClass(b9.call(this,cb,this.className))})}if(b8){b3=(b9||"").match(ac)||[];for(;b5<b7;b5++){e=this[b5];ca=e.nodeType===1&&(e.className?(" "+e.className+" ").replace(bM," "):" ");if(ca){b4=0;while((b6=b3[b4++])){if(ca.indexOf(" "+b6+" ")<0){ca+=b6+" "}}e.className=bJ.trim(ca)}}}return this},removeClass:function(b9){var b3,e,ca,b6,b4,b5=0,b7=this.length,b8=arguments.length===0||typeof b9==="string"&&b9;if(bJ.isFunction(b9)){return this.each(function(cb){bJ(this).removeClass(b9.call(this,cb,this.className))})}if(b8){b3=(b9||"").match(ac)||[];for(;b5<b7;b5++){e=this[b5];ca=e.nodeType===1&&(e.className?(" "+e.className+" ").replace(bM," "):"");if(ca){b4=0;while((b6=b3[b4++])){while(ca.indexOf(" "+b6+" ")>=0){ca=ca.replace(" "+b6+" "," ")}}e.className=b9?bJ.trim(ca):""}}}return this},toggleClass:function(b5,b3){var b4=typeof b5,e=typeof b3==="boolean";if(bJ.isFunction(b5)){return this.each(function(b6){bJ(this).toggleClass(b5.call(this,b6,this.className,b3),b3)})}return this.each(function(){if(b4==="string"){var b8,b7=0,b6=bJ(this),b9=b3,ca=b5.match(ac)||[];while((b8=ca[b7++])){b9=e?b9:!b6.hasClass(b8);b6[b9?"addClass":"removeClass"](b8)}}else{if(b4===aC||b4==="boolean"){if(this.className){bJ._data(this,"__className__",this.className)}this.className=this.className||b5===false?"":bJ._data(this,"__className__")||""}}})},hasClass:function(e){var b5=" "+e+" ",b4=0,b3=this.length;for(;b4<b3;b4++){if(this[b4].nodeType===1&&(" "+this[b4].className+" ").replace(bM," ").indexOf(b5)>=0){return true}}return false},val:function(b5){var b3,e,b6,b4=this[0];if(!arguments.length){if(b4){e=bJ.valHooks[b4.type]||bJ.valHooks[b4.nodeName.toLowerCase()];if(e&&"get" in e&&(b3=e.get(b4,"value"))!==aG){return b3}b3=b4.value;return typeof b3==="string"?b3.replace(ak,""):b3==null?"":b3}return}b6=bJ.isFunction(b5);return this.each(function(b8){var b9,b7=bJ(this);if(this.nodeType!==1){return}if(b6){b9=b5.call(this,b8,b7.val())}else{b9=b5}if(b9==null){b9=""}else{if(typeof b9==="number"){b9+=""}else{if(bJ.isArray(b9)){b9=bJ.map(b9,function(ca){return ca==null?"":ca+""})}}}e=bJ.valHooks[this.type]||bJ.valHooks[this.nodeName.toLowerCase()];if(!e||!("set" in e)||e.set(this,b9,"value")===aG){this.value=b9}})}});bJ.extend({valHooks:{option:{get:function(e){var b3=e.attributes.value;return !b3||b3.specified?e.value:e.text}},select:{get:function(e){var b8,b4,ca=e.options,b6=e.selectedIndex,b5=e.type==="select-one"||b6<0,b9=b5?null:[],b7=b5?b6+1:ca.length,b3=b6<0?b7:b5?b6:0;for(;b3<b7;b3++){b4=ca[b3];if((b4.selected||b3===b6)&&(bJ.support.optDisabled?!b4.disabled:b4.getAttribute("disabled")===null)&&(!b4.parentNode.disabled||!bJ.nodeName(b4.parentNode,"optgroup"))){b8=bJ(b4).val();if(b5){return b8}b9.push(b8)}}return b9},set:function(b3,b4){var e=bJ.makeArray(b4);bJ(b3).find("option").each(function(){this.selected=bJ.inArray(bJ(this).val(),e)>=0});if(!e.length){b3.selectedIndex=-1}return e}}},attr:function(b7,b5,b8){var e,b6,b4,b3=b7.nodeType;if(!b7||b3===3||b3===8||b3===2){return}if(typeof b7.getAttribute===aC){return bJ.prop(b7,b5,b8)}b6=b3!==1||!bJ.isXMLDoc(b7);if(b6){b5=b5.toLowerCase();e=bJ.attrHooks[b5]||(L.test(b5)?bZ:a8)}if(b8!==aG){if(b8===null){bJ.removeAttr(b7,b5)}else{if(e&&b6&&"set" in e&&(b4=e.set(b7,b8,b5))!==aG){return b4}else{b7.setAttribute(b5,b8+"");return b8}}}else{if(e&&b6&&"get" in e&&(b4=e.get(b7,b5))!==null){return b4}else{if(typeof b7.getAttribute!==aC){b4=b7.getAttribute(b5)}return b4==null?aG:b4}}},removeAttr:function(b4,b6){var e,b5,b3=0,b7=b6&&b6.match(ac);if(b7&&b4.nodeType===1){while((e=b7[b3++])){b5=bJ.propFix[e]||e;if(L.test(e)){if(!bP&&aq.test(e)){b4[bJ.camelCase("default-"+e)]=b4[b5]=false}else{b4[b5]=false}}else{bJ.attr(b4,e,"")}b4.removeAttribute(bP?e:b5)}}},attrHooks:{type:{set:function(e,b3){if(!bJ.support.radioValue&&b3==="radio"&&bJ.nodeName(e,"input")){var b4=e.value;e.setAttribute("type",b3);if(b4){e.value=b4}return b3}}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(b7,b5,b8){var b4,e,b6,b3=b7.nodeType;if(!b7||b3===3||b3===8||b3===2){return}b6=b3!==1||!bJ.isXMLDoc(b7);if(b6){b5=bJ.propFix[b5]||b5;e=bJ.propHooks[b5]}if(b8!==aG){if(e&&"set" in e&&(b4=e.set(b7,b8,b5))!==aG){return b4}else{return(b7[b5]=b8)}}else{if(e&&"get" in e&&(b4=e.get(b7,b5))!==null){return b4}else{return b7[b5]}}},propHooks:{tabIndex:{get:function(b3){var e=b3.getAttributeNode("tabindex");return e&&e.specified?parseInt(e.value,10):aF.test(b3.nodeName)||D.test(b3.nodeName)&&b3.href?0:aG}}}});bZ={get:function(b5,b3){var b6=bJ.prop(b5,b3),e=typeof b6==="boolean"&&b5.getAttribute(b3),b4=typeof b6==="boolean"?bF&&bP?e!=null:aq.test(b3)?b5[bJ.camelCase("default-"+b3)]:!!e:b5.getAttributeNode(b3);return b4&&b4.value!==false?b3.toLowerCase():aG},set:function(b3,b4,e){if(b4===false){bJ.removeAttr(b3,e)}else{if(bF&&bP||!aq.test(e)){b3.setAttribute(!bP&&bJ.propFix[e]||e,e)}else{b3[bJ.camelCase("default-"+e)]=b3[e]=true}}return e}};if(!bF||!bP){bJ.attrHooks.value={get:function(b4,b3){var e=b4.getAttributeNode(b3);return bJ.nodeName(b4,"input")?b4.defaultValue:e&&e.specified?e.value:aG},set:function(b3,b4,e){if(bJ.nodeName(b3,"input")){b3.defaultValue=b4}else{return a8&&a8.set(b3,b4,e)}}}}if(!bP){a8=bJ.valHooks.button={get:function(b4,b3){var e=b4.getAttributeNode(b3);return e&&(b3==="id"||b3==="name"||b3==="coords"?e.value!=="":e.specified)?e.value:aG},set:function(b4,b5,b3){var e=b4.getAttributeNode(b3);if(!e){b4.setAttributeNode((e=b4.ownerDocument.createAttribute(b3)))}e.value=b5+="";return b3==="value"||b5===b4.getAttribute(b3)?b5:aG}};bJ.attrHooks.contenteditable={get:a8.get,set:function(b3,b4,e){a8.set(b3,b4===""?false:b4,e)}};bJ.each(["width","height"],function(b3,e){bJ.attrHooks[e]=bJ.extend(bJ.attrHooks[e],{set:function(b4,b5){if(b5===""){b4.setAttribute(e,"auto");return b5}}})})}if(!bJ.support.hrefNormalized){bJ.each(["href","src","width","height"],function(b3,e){bJ.attrHooks[e]=bJ.extend(bJ.attrHooks[e],{get:function(b5){var b4=b5.getAttribute(e,2);return b4==null?aG:b4}})});bJ.each(["href","src"],function(b3,e){bJ.propHooks[e]={get:function(b4){return b4.getAttribute(e,4)}}})}if(!bJ.support.style){bJ.attrHooks.style={get:function(e){return e.style.cssText||aG},set:function(e,b3){return(e.style.cssText=b3+"")}}}if(!bJ.support.optSelected){bJ.propHooks.selected=bJ.extend(bJ.propHooks.selected,{get:function(b3){var e=b3.parentNode;if(e){e.selectedIndex;if(e.parentNode){e.parentNode.selectedIndex}}return null}})}if(!bJ.support.enctype){bJ.propFix.enctype="encoding"}if(!bJ.support.checkOn){bJ.each(["radio","checkbox"],function(){bJ.valHooks[this]={get:function(e){return e.getAttribute("value")===null?"on":e.value}}})}bJ.each(["radio","checkbox"],function(){bJ.valHooks[this]=bJ.extend(bJ.valHooks[this],{set:function(e,b3){if(bJ.isArray(b3)){return(e.checked=bJ.inArray(bJ(e).val(),b3)>=0)}}})});var bH=/^(?:input|select|textarea)$/i,a3=/^key/,bN=/^(?:mouse|contextmenu)|click/,bB=/^(?:focusinfocus|focusoutblur)$/,bu=/^([^.]*)(?:\.(.+)|)$/;function R(){return true}function X(){return false}bJ.event={global:{},add:function(b6,cb,cg,b8,b7){var b9,ch,ci,b4,cd,ca,cf,b5,ce,e,b3,cc=bJ._data(b6);if(!cc){return}if(cg.handler){b4=cg;cg=b4.handler;b7=b4.selector}if(!cg.guid){cg.guid=bJ.guid++}if(!(ch=cc.events)){ch=cc.events={}}if(!(ca=cc.handle)){ca=cc.handle=function(cj){return typeof bJ!==aC&&(!cj||bJ.event.triggered!==cj.type)?bJ.event.dispatch.apply(ca.elem,arguments):aG};ca.elem=b6}cb=(cb||"").match(ac)||[""];ci=cb.length;while(ci--){b9=bu.exec(cb[ci])||[];ce=b3=b9[1];e=(b9[2]||"").split(".").sort();cd=bJ.event.special[ce]||{};ce=(b7?cd.delegateType:cd.bindType)||ce;cd=bJ.event.special[ce]||{};cf=bJ.extend({type:ce,origType:b3,data:b8,handler:cg,guid:cg.guid,selector:b7,needsContext:b7&&bJ.expr.match.needsContext.test(b7),namespace:e.join(".")},b4);if(!(b5=ch[ce])){b5=ch[ce]=[];b5.delegateCount=0;if(!cd.setup||cd.setup.call(b6,b8,e,ca)===false){if(b6.addEventListener){b6.addEventListener(ce,ca,false)}else{if(b6.attachEvent){b6.attachEvent("on"+ce,ca)}}}}if(cd.add){cd.add.call(b6,cf);if(!cf.handler.guid){cf.handler.guid=cg.guid}}if(b7){b5.splice(b5.delegateCount++,0,cf)}else{b5.push(cf)}bJ.event.global[ce]=true}b6=null},remove:function(b5,cb,ci,b6,ca){var b8,cf,b9,b7,ch,cg,cd,b4,ce,e,b3,cc=bJ.hasData(b5)&&bJ._data(b5);if(!cc||!(cg=cc.events)){return}cb=(cb||"").match(ac)||[""];ch=cb.length;while(ch--){b9=bu.exec(cb[ch])||[];ce=b3=b9[1];e=(b9[2]||"").split(".").sort();if(!ce){for(ce in cg){bJ.event.remove(b5,ce+cb[ch],ci,b6,true)}continue}cd=bJ.event.special[ce]||{};ce=(b6?cd.delegateType:cd.bindType)||ce;b4=cg[ce]||[];b9=b9[2]&&new RegExp("(^|\\.)"+e.join("\\.(?:.*\\.|)")+"(\\.|$)");b7=b8=b4.length;while(b8--){cf=b4[b8];if((ca||b3===cf.origType)&&(!ci||ci.guid===cf.guid)&&(!b9||b9.test(cf.namespace))&&(!b6||b6===cf.selector||b6==="**"&&cf.selector)){b4.splice(b8,1);if(cf.selector){b4.delegateCount--}if(cd.remove){cd.remove.call(b5,cf)}}}if(b7&&!b4.length){if(!cd.teardown||cd.teardown.call(b5,e,cc.handle)===false){bJ.removeEvent(b5,ce,cc.handle)}delete cg[ce]}}if(bJ.isEmptyObject(cg)){delete cc.handle;bJ._removeData(b5,"events")}},trigger:function(b3,ca,b6,ch){var cb,b5,cf,cg,cd,b9,b8,b7=[b6||l],ce=V.call(b3,"type")?b3.type:b3,b4=V.call(b3,"namespace")?b3.namespace.split("."):[];cf=b9=b6=b6||l;if(b6.nodeType===3||b6.nodeType===8){return}if(bB.test(ce+bJ.event.triggered)){return}if(ce.indexOf(".")>=0){b4=ce.split(".");ce=b4.shift();b4.sort()}b5=ce.indexOf(":")<0&&"on"+ce;b3=b3[bJ.expando]?b3:new bJ.Event(ce,typeof b3==="object"&&b3);b3.isTrigger=true;b3.namespace=b4.join(".");b3.namespace_re=b3.namespace?new RegExp("(^|\\.)"+b4.join("\\.(?:.*\\.|)")+"(\\.|$)"):null;b3.result=aG;if(!b3.target){b3.target=b6}ca=ca==null?[b3]:bJ.makeArray(ca,[b3]);cd=bJ.event.special[ce]||{};if(!ch&&cd.trigger&&cd.trigger.apply(b6,ca)===false){return}if(!ch&&!cd.noBubble&&!bJ.isWindow(b6)){cg=cd.delegateType||ce;if(!bB.test(cg+ce)){cf=cf.parentNode}for(;cf;cf=cf.parentNode){b7.push(cf);b9=cf}if(b9===(b6.ownerDocument||l)){b7.push(b9.defaultView||b9.parentWindow||a2)}}b8=0;while((cf=b7[b8++])&&!b3.isPropagationStopped()){b3.type=b8>1?cg:cd.bindType||ce;cb=(bJ._data(cf,"events")||{})[b3.type]&&bJ._data(cf,"handle");if(cb){cb.apply(cf,ca)}cb=b5&&cf[b5];if(cb&&bJ.acceptData(cf)&&cb.apply&&cb.apply(cf,ca)===false){b3.preventDefault()}}b3.type=ce;if(!ch&&!b3.isDefaultPrevented()){if((!cd._default||cd._default.apply(b6.ownerDocument,ca)===false)&&!(ce==="click"&&bJ.nodeName(b6,"a"))&&bJ.acceptData(b6)){if(b5&&b6[ce]&&!bJ.isWindow(b6)){b9=b6[b5];if(b9){b6[b5]=null}bJ.event.triggered=ce;try{b6[ce]()}catch(cc){}bJ.event.triggered=aG;if(b9){b6[b5]=b9}}}}return b3.result},dispatch:function(e){e=bJ.event.fix(e);var b6,b7,cb,b3,b5,ca=[],b9=a4.call(arguments),b4=(bJ._data(this,"events")||{})[e.type]||[],b8=bJ.event.special[e.type]||{};b9[0]=e;e.delegateTarget=this;if(b8.preDispatch&&b8.preDispatch.call(this,e)===false){return}ca=bJ.event.handlers.call(this,e,b4);b6=0;while((b3=ca[b6++])&&!e.isPropagationStopped()){e.currentTarget=b3.elem;b5=0;while((cb=b3.handlers[b5++])&&!e.isImmediatePropagationStopped()){if(!e.namespace_re||e.namespace_re.test(cb.namespace)){e.handleObj=cb;e.data=cb.data;b7=((bJ.event.special[cb.origType]||{}).handle||cb.handler).apply(b3.elem,b9);if(b7!==aG){if((e.result=b7)===false){e.preventDefault();e.stopPropagation()}}}}}if(b8.postDispatch){b8.postDispatch.call(this,e)}return e.result},handlers:function(e,b4){var b3,b9,b7,b6,b8=[],b5=b4.delegateCount,ca=e.target;if(b5&&ca.nodeType&&(!e.button||e.type!=="click")){for(;ca!=this;ca=ca.parentNode||this){if(ca.nodeType===1&&(ca.disabled!==true||e.type!=="click")){b7=[];for(b6=0;b6<b5;b6++){b9=b4[b6];b3=b9.selector+" ";if(b7[b3]===aG){b7[b3]=b9.needsContext?bJ(b3,this).index(ca)>=0:bJ.find(b3,this,null,[ca]).length}if(b7[b3]){b7.push(b9)}}if(b7.length){b8.push({elem:ca,handlers:b7})}}}}if(b5<b4.length){b8.push({elem:this,handlers:b4.slice(b5)})}return b8},fix:function(b5){if(b5[bJ.expando]){return b5}var b3,b8,b7,b4=b5.type,e=b5,b6=this.fixHooks[b4];if(!b6){this.fixHooks[b4]=b6=bN.test(b4)?this.mouseHooks:a3.test(b4)?this.keyHooks:{}}b7=b6.props?this.props.concat(b6.props):this.props;b5=new bJ.Event(e);b3=b7.length;while(b3--){b8=b7[b3];b5[b8]=e[b8]}if(!b5.target){b5.target=e.srcElement||l}if(b5.target.nodeType===3){b5.target=b5.target.parentNode}b5.metaKey=!!b5.metaKey;return b6.filter?b6.filter(b5,e):b5},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(b3,e){if(b3.which==null){b3.which=e.charCode!=null?e.charCode:e.keyCode}return b3}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(b5,b4){var e,b6,b7,b3=b4.button,b8=b4.fromElement;if(b5.pageX==null&&b4.clientX!=null){b6=b5.target.ownerDocument||l;b7=b6.documentElement;e=b6.body;b5.pageX=b4.clientX+(b7&&b7.scrollLeft||e&&e.scrollLeft||0)-(b7&&b7.clientLeft||e&&e.clientLeft||0);b5.pageY=b4.clientY+(b7&&b7.scrollTop||e&&e.scrollTop||0)-(b7&&b7.clientTop||e&&e.clientTop||0)}if(!b5.relatedTarget&&b8){b5.relatedTarget=b8===b5.target?b4.toElement:b8}if(!b5.which&&b3!==aG){b5.which=(b3&1?1:(b3&2?3:(b3&4?2:0)))}return b5}},special:{load:{noBubble:true},click:{trigger:function(){if(bJ.nodeName(this,"input")&&this.type==="checkbox"&&this.click){this.click();return false}}},focus:{trigger:function(){if(this!==l.activeElement&&this.focus){try{this.focus();return false}catch(b3){}}},delegateType:"focusin"},blur:{trigger:function(){if(this===l.activeElement&&this.blur){this.blur();return false}},delegateType:"focusout"},beforeunload:{postDispatch:function(e){if(e.result!==aG){e.originalEvent.returnValue=e.result}}}},simulate:function(b4,b6,b5,b3){var b7=bJ.extend(new bJ.Event(),b5,{type:b4,isSimulated:true,originalEvent:{}});if(b3){bJ.event.trigger(b7,null,b6)}else{bJ.event.dispatch.call(b6,b7)}if(b7.isDefaultPrevented()){b5.preventDefault()}}};bJ.removeEvent=l.removeEventListener?function(b3,e,b4){if(b3.removeEventListener){b3.removeEventListener(e,b4,false)}}:function(b4,b3,b5){var e="on"+b3;if(b4.detachEvent){if(typeof b4[e]===aC){b4[e]=null}b4.detachEvent(e,b5)}};bJ.Event=function(b3,e){if(!(this instanceof bJ.Event)){return new bJ.Event(b3,e)}if(b3&&b3.type){this.originalEvent=b3;this.type=b3.type;this.isDefaultPrevented=(b3.defaultPrevented||b3.returnValue===false||b3.getPreventDefault&&b3.getPreventDefault())?R:X}else{this.type=b3}if(e){bJ.extend(this,e)}this.timeStamp=b3&&b3.timeStamp||bJ.now();this[bJ.expando]=true};bJ.Event.prototype={isDefaultPrevented:X,isPropagationStopped:X,isImmediatePropagationStopped:X,preventDefault:function(){var b3=this.originalEvent;this.isDefaultPrevented=R;if(!b3){return}if(b3.preventDefault){b3.preventDefault()}else{b3.returnValue=false}},stopPropagation:function(){var b3=this.originalEvent;this.isPropagationStopped=R;if(!b3){return}if(b3.stopPropagation){b3.stopPropagation()}b3.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=R;this.stopPropagation()}};bJ.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(b3,e){bJ.event.special[b3]={delegateType:e,bindType:e,handle:function(b6){var b4,b8=this,b7=b6.relatedTarget,b5=b6.handleObj;if(!b7||(b7!==b8&&!bJ.contains(b8,b7))){b6.type=b5.origType;b4=b5.handler.apply(this,arguments);b6.type=e}return b4}}});if(!bJ.support.submitBubbles){bJ.event.special.submit={setup:function(){if(bJ.nodeName(this,"form")){return false}bJ.event.add(this,"click._submit keypress._submit",function(b5){var b4=b5.target,b3=bJ.nodeName(b4,"input")||bJ.nodeName(b4,"button")?b4.form:aG;if(b3&&!bJ._data(b3,"submitBubbles")){bJ.event.add(b3,"submit._submit",function(e){e._submit_bubble=true});bJ._data(b3,"submitBubbles",true)}})},postDispatch:function(e){if(e._submit_bubble){delete e._submit_bubble;if(this.parentNode&&!e.isTrigger){bJ.event.simulate("submit",this.parentNode,e,true)}}},teardown:function(){if(bJ.nodeName(this,"form")){return false}bJ.event.remove(this,"._submit")}}}if(!bJ.support.changeBubbles){bJ.event.special.change={setup:function(){if(bH.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio"){bJ.event.add(this,"propertychange._change",function(e){if(e.originalEvent.propertyName==="checked"){this._just_changed=true}});bJ.event.add(this,"click._change",function(e){if(this._just_changed&&!e.isTrigger){this._just_changed=false}bJ.event.simulate("change",this,e,true)})}return false}bJ.event.add(this,"beforeactivate._change",function(b4){var b3=b4.target;if(bH.test(b3.nodeName)&&!bJ._data(b3,"changeBubbles")){bJ.event.add(b3,"change._change",function(e){if(this.parentNode&&!e.isSimulated&&!e.isTrigger){bJ.event.simulate("change",this.parentNode,e,true)}});bJ._data(b3,"changeBubbles",true)}})},handle:function(b3){var e=b3.target;if(this!==e||b3.isSimulated||b3.isTrigger||(e.type!=="radio"&&e.type!=="checkbox")){return b3.handleObj.handler.apply(this,arguments)}},teardown:function(){bJ.event.remove(this,"._change");return !bH.test(this.nodeName)}}}if(!bJ.support.focusinBubbles){bJ.each({focus:"focusin",blur:"focusout"},function(b5,e){var b3=0,b4=function(b6){bJ.event.simulate(e,b6.target,bJ.event.fix(b6),true)};bJ.event.special[e]={setup:function(){if(b3++===0){l.addEventListener(b5,b4,true)}},teardown:function(){if(--b3===0){l.removeEventListener(b5,b4,true)}}}})}bJ.fn.extend({on:function(b4,e,b7,b6,b3){var b5,b8;if(typeof b4==="object"){if(typeof e!=="string"){b7=b7||e;e=aG}for(b5 in b4){this.on(b5,e,b7,b4[b5],b3)}return this}if(b7==null&&b6==null){b6=e;b7=e=aG}else{if(b6==null){if(typeof e==="string"){b6=b7;b7=aG}else{b6=b7;b7=e;e=aG}}}if(b6===false){b6=X}else{if(!b6){return this}}if(b3===1){b8=b6;b6=function(b9){bJ().off(b9);return b8.apply(this,arguments)};b6.guid=b8.guid||(b8.guid=bJ.guid++)}return this.each(function(){bJ.event.add(this,b4,b6,b7,e)})},one:function(b3,e,b5,b4){return this.on(b3,e,b5,b4,1)},off:function(b4,e,b6){var b3,b5;if(b4&&b4.preventDefault&&b4.handleObj){b3=b4.handleObj;bJ(b4.delegateTarget).off(b3.namespace?b3.origType+"."+b3.namespace:b3.origType,b3.selector,b3.handler);return this}if(typeof b4==="object"){for(b5 in b4){this.off(b5,e,b4[b5])}return this}if(e===false||typeof e==="function"){b6=e;e=aG}if(b6===false){b6=X}return this.each(function(){bJ.event.remove(this,b4,b6,e)})},bind:function(e,b4,b3){return this.on(e,null,b4,b3)},unbind:function(e,b3){return this.off(e,null,b3)},delegate:function(e,b3,b5,b4){return this.on(b3,e,b5,b4)},undelegate:function(e,b3,b4){return arguments.length===1?this.off(e,"**"):this.off(b3,e||"**",b4)},trigger:function(e,b3){return this.each(function(){bJ.event.trigger(e,b3,this)})},triggerHandler:function(e,b4){var b3=this[0];if(b3){return bJ.event.trigger(e,b4,b3,true)}}});
/*!
 * Sizzle CSS Selector Engine
 * Copyright 2012 jQuery Foundation and other contributors
 * Released under the MIT license
 * http://sizzlejs.com/
 */
(function(da,ch){var cx,cb,cn,cH,cJ,cS,cT,dg,cV,cB,co,cd,cZ,db,ca,cF,cD,c5="sizzle"+-(new Date()),cI=da.document,dd={},de=0,c0=0,b5=cz(),c4=cz(),cG=cz(),c9=typeof ch,cN=1<<31,c7=[],c8=c7.pop,b4=c7.push,cm=c7.slice,b9=c7.indexOf||function(di){var dh=0,e=this.length;for(;dh<e;dh++){if(this[dh]===di){return dh}}return -1},cp="[\\x20\\t\\r\\n\\f]",b3="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",cK=b3.replace("w","w#"),ci="([*^$|!~]?=)",c2="\\["+cp+"*("+b3+")"+cp+"*(?:"+ci+cp+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+cK+")|)|)"+cp+"*\\]",ck=":("+b3+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+c2.replace(3,8)+")*)|.*)\\)|)",cr=new RegExp("^"+cp+"+|((?:^|[^\\\\])(?:\\\\.)*)"+cp+"+$","g"),cu=new RegExp("^"+cp+"*,"+cp+"*"),cA=new RegExp("^"+cp+"*([\\x20\\t\\r\\n\\f>+~])"+cp+"*"),cP=new RegExp(ck),cQ=new RegExp("^"+cK+"$"),cY={ID:new RegExp("^#("+b3+")"),CLASS:new RegExp("^\\.("+b3+")"),NAME:new RegExp("^\\[name=['\"]?("+b3+")['\"]?\\]"),TAG:new RegExp("^("+b3.replace("w","w*")+")"),ATTR:new RegExp("^"+c2),PSEUDO:new RegExp("^"+ck),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+cp+"*(even|odd|(([+-]|)(\\d*)n|)"+cp+"*(?:([+-]|)"+cp+"*(\\d+)|))"+cp+"*\\)|)","i"),needsContext:new RegExp("^"+cp+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+cp+"*((?:-\\d)?\\d*)"+cp+"*\\)|)(?=[^-]|$)","i")},cW=/[\x20\t\r\n\f]*[+~]/,cM=/^[^{]+\{\s*\[native code/,cO=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,b8=/^(?:input|select|textarea|button)$/i,cl=/^h\d$/i,cL=/'|\\/g,ct=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,cs=/\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g,c1=function(e,di){var dh="0x"+di-65536;return dh!==dh?di:dh<0?String.fromCharCode(dh+65536):String.fromCharCode(dh>>10|55296,dh&1023|56320)};try{cm.call(cI.documentElement.childNodes,0)[0].nodeType}catch(cC){cm=function(dh){var di,e=[];while((di=this[dh++])){e.push(di)}return e}}function cE(e){return cM.test(e+"")}function cz(){var e,dh=[];return(e=function(di,dj){if(dh.push(di+=" ")>cn.cacheLength){delete e[dh.shift()]}return(e[di]=dj)})}function cj(e){e[c5]=true;return e}function cc(dh){var dj=cB.createElement("div");try{return dh(dj)}catch(di){return false}finally{dj=null}}function cv(dp,dh,dt,dv){var du,dl,dm,dr,ds,dk,dj,e,di,dq;if((dh?dh.ownerDocument||dh:cI)!==cB){cV(dh)}dh=dh||cB;dt=dt||[];if(!dp||typeof dp!=="string"){return dt}if((dr=dh.nodeType)!==1&&dr!==9){return[]}if(!cd&&!dv){if((du=cO.exec(dp))){if((dm=du[1])){if(dr===9){dl=dh.getElementById(dm);if(dl&&dl.parentNode){if(dl.id===dm){dt.push(dl);return dt}}else{return dt}}else{if(dh.ownerDocument&&(dl=dh.ownerDocument.getElementById(dm))&&cF(dh,dl)&&dl.id===dm){dt.push(dl);return dt}}}else{if(du[2]){b4.apply(dt,cm.call(dh.getElementsByTagName(dp),0));return dt}else{if((dm=du[3])&&dd.getByClassName&&dh.getElementsByClassName){b4.apply(dt,cm.call(dh.getElementsByClassName(dm),0));return dt}}}}if(dd.qsa&&!cZ.test(dp)){dj=true;e=c5;di=dh;dq=dr===9&&dp;if(dr===1&&dh.nodeName.toLowerCase()!=="object"){dk=cf(dp);if((dj=dh.getAttribute("id"))){e=dj.replace(cL,"\\$&")}else{dh.setAttribute("id",e)}e="[id='"+e+"'] ";ds=dk.length;while(ds--){dk[ds]=e+cg(dk[ds])}di=cW.test(dp)&&dh.parentNode||dh;dq=dk.join(",")}if(dq){try{b4.apply(dt,cm.call(di.querySelectorAll(dq),0));return dt}catch(dn){}finally{if(!dj){dh.removeAttribute("id")}}}}}return dc(dp.replace(cr,"$1"),dh,dt,dv)}cJ=cv.isXML=function(e){var dh=e&&(e.ownerDocument||e).documentElement;return dh?dh.nodeName!=="HTML":false};cV=cv.setDocument=function(e){var dh=e?e.ownerDocument||e:cI;if(dh===cB||dh.nodeType!==9||!dh.documentElement){return cB}cB=dh;co=dh.documentElement;cd=cJ(dh);dd.tagNameNoComments=cc(function(di){di.appendChild(dh.createComment(""));return !di.getElementsByTagName("*").length});dd.attributes=cc(function(dj){dj.innerHTML="<select></select>";var di=typeof dj.lastChild.getAttribute("multiple");return di!=="boolean"&&di!=="string"});dd.getByClassName=cc(function(di){di.innerHTML="<div class='hidden e'></div><div class='hidden'></div>";if(!di.getElementsByClassName||!di.getElementsByClassName("e").length){return false}di.lastChild.className="e";return di.getElementsByClassName("e").length===2});dd.getByName=cc(function(dj){dj.id=c5+0;dj.innerHTML="<a name='"+c5+"'></a><div name='"+c5+"'></div>";co.insertBefore(dj,co.firstChild);var di=dh.getElementsByName&&dh.getElementsByName(c5).length===2+dh.getElementsByName(c5+0).length;dd.getIdNotName=!dh.getElementById(c5);co.removeChild(dj);return di});cn.attrHandle=cc(function(di){di.innerHTML="<a href='#'></a>";return di.firstChild&&typeof di.firstChild.getAttribute!==c9&&di.firstChild.getAttribute("href")==="#"})?{}:{href:function(di){return di.getAttribute("href",2)},type:function(di){return di.getAttribute("type")}};if(dd.getIdNotName){cn.find.ID=function(dk,dj){if(typeof dj.getElementById!==c9&&!cd){var di=dj.getElementById(dk);return di&&di.parentNode?[di]:[]}};cn.filter.ID=function(dj){var di=dj.replace(cs,c1);return function(dk){return dk.getAttribute("id")===di}}}else{cn.find.ID=function(dk,dj){if(typeof dj.getElementById!==c9&&!cd){var di=dj.getElementById(dk);return di?di.id===dk||typeof di.getAttributeNode!==c9&&di.getAttributeNode("id").value===dk?[di]:ch:[]}};cn.filter.ID=function(dj){var di=dj.replace(cs,c1);return function(dl){var dk=typeof dl.getAttributeNode!==c9&&dl.getAttributeNode("id");return dk&&dk.value===di}}}cn.find.TAG=dd.tagNameNoComments?function(di,dj){if(typeof dj.getElementsByTagName!==c9){return dj.getElementsByTagName(di)}}:function(di,dm){var dn,dl=[],dk=0,dj=dm.getElementsByTagName(di);if(di==="*"){while((dn=dj[dk++])){if(dn.nodeType===1){dl.push(dn)}}return dl}return dj};cn.find.NAME=dd.getByName&&function(di,dj){if(typeof dj.getElementsByName!==c9){return dj.getElementsByName(name)}};cn.find.CLASS=dd.getByClassName&&function(dj,di){if(typeof di.getElementsByClassName!==c9&&!cd){return di.getElementsByClassName(dj)}};db=[];cZ=[":focus"];if((dd.qsa=cE(dh.querySelectorAll))){cc(function(di){di.innerHTML="<select><option selected=''></option></select>";if(!di.querySelectorAll("[selected]").length){cZ.push("\\["+cp+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)")}if(!di.querySelectorAll(":checked").length){cZ.push(":checked")}});cc(function(di){di.innerHTML="<input type='hidden' i=''/>";if(di.querySelectorAll("[i^='']").length){cZ.push("[*^$]="+cp+"*(?:\"\"|'')")}if(!di.querySelectorAll(":enabled").length){cZ.push(":enabled",":disabled")}di.querySelectorAll("*,:x");cZ.push(",.*:")})}if((dd.matchesSelector=cE((ca=co.matchesSelector||co.mozMatchesSelector||co.webkitMatchesSelector||co.oMatchesSelector||co.msMatchesSelector)))){cc(function(di){dd.disconnectedMatch=ca.call(di,"div");ca.call(di,"[s!='']:x");db.push("!=",ck)})}cZ=new RegExp(cZ.join("|"));db=new RegExp(db.join("|"));cF=cE(co.contains)||co.compareDocumentPosition?function(dj,di){var dl=dj.nodeType===9?dj.documentElement:dj,dk=di&&di.parentNode;return dj===dk||!!(dk&&dk.nodeType===1&&(dl.contains?dl.contains(dk):dj.compareDocumentPosition&&dj.compareDocumentPosition(dk)&16))}:function(dj,di){if(di){while((di=di.parentNode)){if(di===dj){return true}}}return false};cD=co.compareDocumentPosition?function(dj,di){var dk;if(dj===di){cT=true;return 0}if((dk=di.compareDocumentPosition&&dj.compareDocumentPosition&&dj.compareDocumentPosition(di))){if(dk&1||dj.parentNode&&dj.parentNode.nodeType===11){if(dj===dh||cF(cI,dj)){return -1}if(di===dh||cF(cI,di)){return 1}return 0}return dk&4?-1:1}return dj.compareDocumentPosition?-1:1}:function(dj,di){var dq,dm=0,dp=dj.parentNode,dl=di.parentNode,dk=[dj],dn=[di];if(dj===di){cT=true;return 0}else{if(!dp||!dl){return dj===dh?-1:di===dh?1:dp?-1:dl?1:0}else{if(dp===dl){return b6(dj,di)}}}dq=dj;while((dq=dq.parentNode)){dk.unshift(dq)}dq=di;while((dq=dq.parentNode)){dn.unshift(dq)}while(dk[dm]===dn[dm]){dm++}return dm?b6(dk[dm],dn[dm]):dk[dm]===cI?-1:dn[dm]===cI?1:0};cT=false;[0,0].sort(cD);dd.detectDuplicates=cT;return cB};cv.matches=function(dh,e){return cv(dh,null,null,e)};cv.matchesSelector=function(di,dk){if((di.ownerDocument||di)!==cB){cV(di)}dk=dk.replace(ct,"='$1']");if(dd.matchesSelector&&!cd&&(!db||!db.test(dk))&&!cZ.test(dk)){try{var dh=ca.call(di,dk);if(dh||dd.disconnectedMatch||di.document&&di.document.nodeType!==11){return dh}}catch(dj){}}return cv(dk,cB,null,[di]).length>0};cv.contains=function(e,dh){if((e.ownerDocument||e)!==cB){cV(e)}return cF(e,dh)};cv.attr=function(dh,e){var di;if((dh.ownerDocument||dh)!==cB){cV(dh)}if(!cd){e=e.toLowerCase()}if((di=cn.attrHandle[e])){return di(dh)}if(cd||dd.attributes){return dh.getAttribute(e)}return((di=dh.getAttributeNode(e))||dh.getAttribute(e))&&dh[e]===true?e:di&&di.specified?di.value:null};cv.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)};cv.uniqueSort=function(di){var dj,dk=[],dh=1,e=0;cT=!dd.detectDuplicates;di.sort(cD);if(cT){for(;(dj=di[dh]);dh++){if(dj===di[dh-1]){e=dk.push(dh)}}while(e--){di.splice(dk[e],1)}}return di};function b6(dh,e){var dj=e&&dh,di=dj&&(~e.sourceIndex||cN)-(~dh.sourceIndex||cN);if(di){return di}if(dj){while((dj=dj.nextSibling)){if(dj===e){return -1}}}return dh?1:-1}function cw(e){return function(di){var dh=di.nodeName.toLowerCase();return dh==="input"&&di.type===e}}function b7(e){return function(di){var dh=di.nodeName.toLowerCase();return(dh==="input"||dh==="button")&&di.type===e}}function c3(e){return cj(function(dh){dh=+dh;return cj(function(di,dm){var dk,dj=e([],di.length,dh),dl=dj.length;while(dl--){if(di[(dk=dj[dl])]){di[dk]=!(dm[dk]=di[dk])}}})})}cH=cv.getText=function(dk){var dj,dh="",di=0,e=dk.nodeType;if(!e){for(;(dj=dk[di]);di++){dh+=cH(dj)}}else{if(e===1||e===9||e===11){if(typeof dk.textContent==="string"){return dk.textContent}else{for(dk=dk.firstChild;dk;dk=dk.nextSibling){dh+=cH(dk)}}}else{if(e===3||e===4){return dk.nodeValue}}}return dh};cn=cv.selectors={cacheLength:50,createPseudo:cj,match:cY,find:{},relative:{">":{dir:"parentNode",first:true}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:true},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){e[1]=e[1].replace(cs,c1);e[3]=(e[4]||e[5]||"").replace(cs,c1);if(e[2]==="~="){e[3]=" "+e[3]+" "}return e.slice(0,4)},CHILD:function(e){e[1]=e[1].toLowerCase();if(e[1].slice(0,3)==="nth"){if(!e[3]){cv.error(e[0])}e[4]=+(e[4]?e[5]+(e[6]||1):2*(e[3]==="even"||e[3]==="odd"));e[5]=+((e[7]+e[8])||e[3]==="odd")}else{if(e[3]){cv.error(e[0])}}return e},PSEUDO:function(dh){var e,di=!dh[5]&&dh[2];if(cY.CHILD.test(dh[0])){return null}if(dh[4]){dh[2]=dh[4]}else{if(di&&cP.test(di)&&(e=cf(di,true))&&(e=di.indexOf(")",di.length-e)-di.length)){dh[0]=dh[0].slice(0,e);dh[2]=di.slice(0,e)}}return dh.slice(0,3)}},filter:{TAG:function(e){if(e==="*"){return function(){return true}}e=e.replace(cs,c1).toLowerCase();return function(dh){return dh.nodeName&&dh.nodeName.toLowerCase()===e}},CLASS:function(e){var dh=b5[e+" "];return dh||(dh=new RegExp("(^|"+cp+")"+e+"("+cp+"|$)"))&&b5(e,function(di){return dh.test(di.className||(typeof di.getAttribute!==c9&&di.getAttribute("class"))||"")})},ATTR:function(di,dh,e){return function(dk){var dj=cv.attr(dk,di);if(dj==null){return dh==="!="}if(!dh){return true}dj+="";return dh==="="?dj===e:dh==="!="?dj!==e:dh==="^="?e&&dj.indexOf(e)===0:dh==="*="?e&&dj.indexOf(e)>-1:dh==="$="?e&&dj.slice(-e.length)===e:dh==="~="?(" "+dj+" ").indexOf(e)>-1:dh==="|="?dj===e||dj.slice(0,e.length+1)===e+"-":false}},CHILD:function(dh,dk,dj,dl,di){var dn=dh.slice(0,3)!=="nth",e=dh.slice(-4)!=="last",dm=dk==="of-type";return dl===1&&di===0?function(dp){return !!dp.parentNode}:function(dv,dt,dy){var dp,dB,dw,dA,dx,ds,du=dn!==e?"nextSibling":"previousSibling",dz=dv.parentNode,dr=dm&&dv.nodeName.toLowerCase(),dq=!dy&&!dm;if(dz){if(dn){while(du){dw=dv;while((dw=dw[du])){if(dm?dw.nodeName.toLowerCase()===dr:dw.nodeType===1){return false}}ds=du=dh==="only"&&!ds&&"nextSibling"}return true}ds=[e?dz.firstChild:dz.lastChild];if(e&&dq){dB=dz[c5]||(dz[c5]={});dp=dB[dh]||[];dx=dp[0]===de&&dp[1];dA=dp[0]===de&&dp[2];dw=dx&&dz.childNodes[dx];while((dw=++dx&&dw&&dw[du]||(dA=dx=0)||ds.pop())){if(dw.nodeType===1&&++dA&&dw===dv){dB[dh]=[de,dx,dA];break}}}else{if(dq&&(dp=(dv[c5]||(dv[c5]={}))[dh])&&dp[0]===de){dA=dp[1]}else{while((dw=++dx&&dw&&dw[du]||(dA=dx=0)||ds.pop())){if((dm?dw.nodeName.toLowerCase()===dr:dw.nodeType===1)&&++dA){if(dq){(dw[c5]||(dw[c5]={}))[dh]=[de,dA]}if(dw===dv){break}}}}}dA-=di;return dA===dl||(dA%dl===0&&dA/dl>=0)}}},PSEUDO:function(dj,di){var e,dh=cn.pseudos[dj]||cn.setFilters[dj.toLowerCase()]||cv.error("unsupported pseudo: "+dj);if(dh[c5]){return dh(di)}if(dh.length>1){e=[dj,dj,"",di];return cn.setFilters.hasOwnProperty(dj.toLowerCase())?cj(function(dm,dp){var dl,dk=dh(dm,di),dn=dk.length;while(dn--){dl=b9.call(dm,dk[dn]);dm[dl]=!(dp[dl]=dk[dn])}}):function(dk){return dh(dk,0,e)}}return dh}},pseudos:{not:cj(function(e){var dh=[],di=[],dj=cS(e.replace(cr,"$1"));return dj[c5]?cj(function(dl,dr,dp,dm){var dq,dk=dj(dl,null,dm,[]),dn=dl.length;while(dn--){if((dq=dk[dn])){dl[dn]=!(dr[dn]=dq)}}}):function(dm,dl,dk){dh[0]=dm;dj(dh,null,dk,di);return !di.pop()}}),has:cj(function(e){return function(dh){return cv(e,dh).length>0}}),contains:cj(function(e){return function(dh){return(dh.textContent||dh.innerText||cH(dh)).indexOf(e)>-1}}),lang:cj(function(e){if(!cQ.test(e||"")){cv.error("unsupported lang: "+e)}e=e.replace(cs,c1).toLowerCase();return function(di){var dh;do{if((dh=cd?di.getAttribute("xml:lang")||di.getAttribute("lang"):di.lang)){dh=dh.toLowerCase();return dh===e||dh.indexOf(e+"-")===0}}while((di=di.parentNode)&&di.nodeType===1);return false}}),target:function(e){var dh=da.location&&da.location.hash;return dh&&dh.slice(1)===e.id},root:function(e){return e===co},focus:function(e){return e===cB.activeElement&&(!cB.hasFocus||cB.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===false},disabled:function(e){return e.disabled===true},checked:function(e){var dh=e.nodeName.toLowerCase();return(dh==="input"&&!!e.checked)||(dh==="option"&&!!e.selected)},selected:function(e){if(e.parentNode){e.parentNode.selectedIndex}return e.selected===true},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling){if(e.nodeName>"@"||e.nodeType===3||e.nodeType===4){return false}}return true},parent:function(e){return !cn.pseudos.empty(e)},header:function(e){return cl.test(e.nodeName)},input:function(e){return b8.test(e.nodeName)},button:function(dh){var e=dh.nodeName.toLowerCase();return e==="input"&&dh.type==="button"||e==="button"},text:function(dh){var e;return dh.nodeName.toLowerCase()==="input"&&dh.type==="text"&&((e=dh.getAttribute("type"))==null||e.toLowerCase()===dh.type)},first:c3(function(){return[0]}),last:c3(function(e,dh){return[dh-1]}),eq:c3(function(e,di,dh){return[dh<0?dh+di:dh]}),even:c3(function(e,di){var dh=0;for(;dh<di;dh+=2){e.push(dh)}return e}),odd:c3(function(e,di){var dh=1;for(;dh<di;dh+=2){e.push(dh)}return e}),lt:c3(function(e,dj,di){var dh=di<0?di+dj:di;for(;--dh>=0;){e.push(dh)}return e}),gt:c3(function(e,dj,di){var dh=di<0?di+dj:di;for(;++dh<dj;){e.push(dh)}return e})}};for(cx in {radio:true,checkbox:true,file:true,password:true,image:true}){cn.pseudos[cx]=cw(cx)}for(cx in {submit:true,reset:true}){cn.pseudos[cx]=b7(cx)}function cf(dk,dq){var dh,dl,dn,dp,dm,di,e,dj=c4[dk+" "];if(dj){return dq?0:dj.slice(0)}dm=dk;di=[];e=cn.preFilter;while(dm){if(!dh||(dl=cu.exec(dm))){if(dl){dm=dm.slice(dl[0].length)||dm}di.push(dn=[])}dh=false;if((dl=cA.exec(dm))){dh=dl.shift();dn.push({value:dh,type:dl[0].replace(cr," ")});dm=dm.slice(dh.length)}for(dp in cn.filter){if((dl=cY[dp].exec(dm))&&(!e[dp]||(dl=e[dp](dl)))){dh=dl.shift();dn.push({value:dh,type:dp,matches:dl});dm=dm.slice(dh.length)}}if(!dh){break}}return dq?dm.length:dm?cv.error(dk):c4(dk,di).slice(0)}function cg(dj){var di=0,dh=dj.length,e="";for(;di<dh;di++){e+=dj[di].value}return e}function cq(dk,di,dj){var e=di.dir,dl=dj&&e==="parentNode",dh=c0++;return di.first?function(dp,dn,dm){while((dp=dp[e])){if(dp.nodeType===1||dl){return dk(dp,dn,dm)}}}:function(dr,dp,dn){var dt,dm,dq,ds=de+" "+dh;if(dn){while((dr=dr[e])){if(dr.nodeType===1||dl){if(dk(dr,dp,dn)){return true}}}}else{while((dr=dr[e])){if(dr.nodeType===1||dl){dq=dr[c5]||(dr[c5]={});if((dm=dq[e])&&dm[0]===ds){if((dt=dm[1])===true||dt===cb){return dt===true}}else{dm=dq[e]=[ds];dm[1]=dk(dr,dp,dn)||cb;if(dm[1]===true){return true}}}}}}}function df(e){return e.length>1?function(dk,dj,dh){var di=e.length;while(di--){if(!e[di](dk,dj,dh)){return false}}return true}:e[0]}function cX(e,dh,di,dj,dm){var dk,dq=[],dl=0,dn=e.length,dp=dh!=null;for(;dl<dn;dl++){if((dk=e[dl])){if(!di||di(dk,dj,dm)){dq.push(dk);if(dp){dh.push(dl)}}}}return dq}function ce(di,dh,dk,dj,dl,e){if(dj&&!dj[c5]){dj=ce(dj)}if(dl&&!dl[c5]){dl=ce(dl,e)}return cj(function(dx,du,dp,dw){var dz,dv,dr,dq=[],dy=[],dn=du.length,dm=dx||cy(dh||"*",dp.nodeType?[dp]:dp,[]),ds=di&&(dx||!dh)?cX(dm,dq,di,dp,dw):dm,dt=dk?dl||(dx?di:dn||dj)?[]:du:ds;if(dk){dk(ds,dt,dp,dw)}if(dj){dz=cX(dt,dy);dj(dz,[],dp,dw);dv=dz.length;while(dv--){if((dr=dz[dv])){dt[dy[dv]]=!(ds[dy[dv]]=dr)}}}if(dx){if(dl||di){if(dl){dz=[];dv=dt.length;while(dv--){if((dr=dt[dv])){dz.push((ds[dv]=dr))}}dl(null,(dt=[]),dz,dw)}dv=dt.length;while(dv--){if((dr=dt[dv])&&(dz=dl?b9.call(dx,dr):dq[dv])>-1){dx[dz]=!(du[dz]=dr)}}}}else{dt=cX(dt===du?dt.splice(dn,dt.length):dt);if(dl){dl(null,du,dt,dw)}else{b4.apply(du,dt)}}})}function c6(dm){var dh,dk,di,dl=dm.length,dq=cn.relative[dm[0].type],dr=dq||cn.relative[" "],dj=dq?1:0,dn=cq(function(ds){return ds===dh},dr,true),dp=cq(function(ds){return b9.call(dh,ds)>-1},dr,true),e=[function(du,dt,ds){return(!dq&&(ds||dt!==dg))||((dh=dt).nodeType?dn(du,dt,ds):dp(du,dt,ds))}];for(;dj<dl;dj++){if((dk=cn.relative[dm[dj].type])){e=[cq(df(e),dk)]}else{dk=cn.filter[dm[dj].type].apply(null,dm[dj].matches);if(dk[c5]){di=++dj;for(;di<dl;di++){if(cn.relative[dm[di].type]){break}}return ce(dj>1&&df(e),dj>1&&cg(dm.slice(0,dj-1)).replace(cr,"$1"),dk,dj<di&&c6(dm.slice(dj,di)),di<dl&&c6((dm=dm.slice(di))),di<dl&&cg(dm))}e.push(dk)}}return df(e)}function cU(dj,di){var dl=0,e=di.length>0,dk=dj.length>0,dh=function(dw,dq,dv,du,dC){var dr,ds,dx,dB=[],dA=0,dt="0",dm=dw&&[],dy=dC!=null,dz=dg,dp=dw||dk&&cn.find.TAG("*",dC&&dq.parentNode||dq),dn=(de+=dz==null?1:Math.random()||0.1);if(dy){dg=dq!==cB&&dq;cb=dl}for(;(dr=dp[dt])!=null;dt++){if(dk&&dr){ds=0;while((dx=dj[ds++])){if(dx(dr,dq,dv)){du.push(dr);break}}if(dy){de=dn;cb=++dl}}if(e){if((dr=!dx&&dr)){dA--}if(dw){dm.push(dr)}}}dA+=dt;if(e&&dt!==dA){ds=0;while((dx=di[ds++])){dx(dm,dB,dq,dv)}if(dw){if(dA>0){while(dt--){if(!(dm[dt]||dB[dt])){dB[dt]=c8.call(du)}}}dB=cX(dB)}b4.apply(du,dB);if(dy&&!dw&&dB.length>0&&(dA+di.length)>1){cv.uniqueSort(du)}}if(dy){de=dn;dg=dz}return dm};return e?cj(dh):dh}cS=cv.compile=function(e,dl){var di,dh=[],dk=[],dj=cG[e+" "];if(!dj){if(!dl){dl=cf(e)}di=dl.length;while(di--){dj=c6(dl[di]);if(dj[c5]){dh.push(dj)}else{dk.push(dj)}}dj=cG(e,cU(dk,dh))}return dj};function cy(dh,dk,dj){var di=0,e=dk.length;for(;di<e;di++){cv(dh,dk[di],dj)}return dj}function dc(di,e,dj,dm){var dk,dp,dh,dq,dn,dl=cf(di);if(!dm){if(dl.length===1){dp=dl[0]=dl[0].slice(0);if(dp.length>2&&(dh=dp[0]).type==="ID"&&e.nodeType===9&&!cd&&cn.relative[dp[1].type]){e=cn.find.ID(dh.matches[0].replace(cs,c1),e)[0];if(!e){return dj}di=di.slice(dp.shift().value.length)}dk=cY.needsContext.test(di)?0:dp.length;while(dk--){dh=dp[dk];if(cn.relative[(dq=dh.type)]){break}if((dn=cn.find[dq])){if((dm=dn(dh.matches[0].replace(cs,c1),cW.test(dp[0].type)&&e.parentNode||e))){dp.splice(dk,1);di=dm.length&&cg(dp);if(!di){b4.apply(dj,cm.call(dm,0));return dj}break}}}}}cS(di,dl)(dm,e,cd,dj,cW.test(di));return dj}cn.pseudos.nth=cn.pseudos.eq;function cR(){}cn.filters=cR.prototype=cn.pseudos;cn.setFilters=new cR();cV();cv.attr=bJ.attr;bJ.find=cv;bJ.expr=cv.selectors;bJ.expr[":"]=bJ.expr.pseudos;bJ.unique=cv.uniqueSort;bJ.text=cv.getText;bJ.isXMLDoc=cv.isXML;bJ.contains=cv.contains})(a2);var aj=/Until$/,bt=/^(?:parents|prev(?:Until|All))/,an=/^.[^:#\[\.,]*$/,y=bJ.expr.match.needsContext,bx={children:true,contents:true,next:true,prev:true};bJ.fn.extend({find:function(b3){var b6,b5,b4,e=this.length;if(typeof b3!=="string"){b4=this;return this.pushStack(bJ(b3).filter(function(){for(b6=0;b6<e;b6++){if(bJ.contains(b4[b6],this)){return true}}}))}b5=[];for(b6=0;b6<e;b6++){bJ.find(b3,this[b6],b5)}b5=this.pushStack(e>1?bJ.unique(b5):b5);b5.selector=(this.selector?this.selector+" ":"")+b3;return b5},has:function(b5){var b4,b3=bJ(b5,this),e=b3.length;return this.filter(function(){for(b4=0;b4<e;b4++){if(bJ.contains(this,b3[b4])){return true}}})},not:function(e){return this.pushStack(aO(this,e,false))},filter:function(e){return this.pushStack(aO(this,e,true))},is:function(e){return !!e&&(typeof e==="string"?y.test(e)?bJ(e,this.context).index(this[0])>=0:bJ.filter(e,this).length>0:this.filter(e).length>0)},closest:function(b6,b5){var b7,b4=0,e=this.length,b3=[],b8=y.test(b6)||typeof b6!=="string"?bJ(b6,b5||this.context):0;for(;b4<e;b4++){b7=this[b4];while(b7&&b7.ownerDocument&&b7!==b5&&b7.nodeType!==11){if(b8?b8.index(b7)>-1:bJ.find.matchesSelector(b7,b6)){b3.push(b7);break}b7=b7.parentNode}}return this.pushStack(b3.length>1?bJ.unique(b3):b3)},index:function(e){if(!e){return(this[0]&&this[0].parentNode)?this.first().prevAll().length:-1}if(typeof e==="string"){return bJ.inArray(this[0],bJ(e))}return bJ.inArray(e.jquery?e[0]:e,this)},add:function(e,b3){var b5=typeof e==="string"?bJ(e,b3):bJ.makeArray(e&&e.nodeType?[e]:e),b4=bJ.merge(this.get(),b5);return this.pushStack(bJ.unique(b4))},addBack:function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}});bJ.fn.andSelf=bJ.fn.addBack;function aX(b3,e){do{b3=b3[e]}while(b3&&b3.nodeType!==1);return b3}bJ.each({parent:function(b3){var e=b3.parentNode;return e&&e.nodeType!==11?e:null},parents:function(e){return bJ.dir(e,"parentNode")},parentsUntil:function(b3,e,b4){return bJ.dir(b3,"parentNode",b4)},next:function(e){return aX(e,"nextSibling")},prev:function(e){return aX(e,"previousSibling")},nextAll:function(e){return bJ.dir(e,"nextSibling")},prevAll:function(e){return bJ.dir(e,"previousSibling")},nextUntil:function(b3,e,b4){return bJ.dir(b3,"nextSibling",b4)},prevUntil:function(b3,e,b4){return bJ.dir(b3,"previousSibling",b4)},siblings:function(e){return bJ.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return bJ.sibling(e.firstChild)},contents:function(e){return bJ.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:bJ.merge([],e.childNodes)}},function(e,b3){bJ.fn[e]=function(b6,b4){var b5=bJ.map(this,b3,b6);if(!aj.test(e)){b4=b6}if(b4&&typeof b4==="string"){b5=bJ.filter(b4,b5)}b5=this.length>1&&!bx[e]?bJ.unique(b5):b5;if(this.length>1&&bt.test(e)){b5=b5.reverse()}return this.pushStack(b5)}});bJ.extend({filter:function(b4,e,b3){if(b3){b4=":not("+b4+")"}return e.length===1?bJ.find.matchesSelector(e[0],b4)?[e[0]]:[]:bJ.find.matches(b4,e)},dir:function(b4,b3,b6){var e=[],b5=b4[b3];while(b5&&b5.nodeType!==9&&(b6===aG||b5.nodeType!==1||!bJ(b5).is(b6))){if(b5.nodeType===1){e.push(b5)}b5=b5[b3]}return e},sibling:function(b4,b3){var e=[];for(;b4;b4=b4.nextSibling){if(b4.nodeType===1&&b4!==b3){e.push(b4)}}return e}});function aO(b5,b4,e){b4=b4||0;if(bJ.isFunction(b4)){return bJ.grep(b5,function(b7,b6){var b8=!!b4.call(b7,b6,b7);return b8===e})}else{if(b4.nodeType){return bJ.grep(b5,function(b6){return(b6===b4)===e})}else{if(typeof b4==="string"){var b3=bJ.grep(b5,function(b6){return b6.nodeType===1});if(an.test(b4)){return bJ.filter(b4,b3,!e)}else{b4=bJ.filter(b4,b3)}}}}return bJ.grep(b5,function(b6){return(bJ.inArray(b6,b4)>=0)===e})}function A(e){var b4=d.split("|"),b3=e.createDocumentFragment();if(b3.createElement){while(b4.length){b3.createElement(b4.pop())}}return b3}var d="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",aA=/ jQuery\d+="(?:null|\d+)"/g,J=new RegExp("<(?:"+d+")[\\s/>]","i"),b2=/^\s+/,aD=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,m=/<([\w:]+)/,bX=/<tbody/i,I=/<|&#?\w+;/,al=/<(?:script|style|link)/i,q=/^(?:checkbox|radio)$/i,bU=/checked\s*(?:[^=]|=\s*.checked.)/i,bz=/^$|\/(?:java|ecma)script/i,ar=/^true\/(.*)/,aK=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,T={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:bJ.support.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},aS=A(l),j=aS.appendChild(l.createElement("div"));T.optgroup=T.option;T.tbody=T.tfoot=T.colgroup=T.caption=T.thead;T.th=T.td;bJ.fn.extend({text:function(e){return bJ.access(this,function(b3){return b3===aG?bJ.text(this):this.empty().append((this[0]&&this[0].ownerDocument||l).createTextNode(b3))},null,e,arguments.length)},wrapAll:function(e){if(bJ.isFunction(e)){return this.each(function(b4){bJ(this).wrapAll(e.call(this,b4))})}if(this[0]){var b3=bJ(e,this[0].ownerDocument).eq(0).clone(true);if(this[0].parentNode){b3.insertBefore(this[0])}b3.map(function(){var b4=this;while(b4.firstChild&&b4.firstChild.nodeType===1){b4=b4.firstChild}return b4}).append(this)}return this},wrapInner:function(e){if(bJ.isFunction(e)){return this.each(function(b3){bJ(this).wrapInner(e.call(this,b3))})}return this.each(function(){var b3=bJ(this),b4=b3.contents();if(b4.length){b4.wrapAll(e)}else{b3.append(e)}})},wrap:function(e){var b3=bJ.isFunction(e);return this.each(function(b4){bJ(this).wrapAll(b3?e.call(this,b4):e)})},unwrap:function(){return this.parent().each(function(){if(!bJ.nodeName(this,"body")){bJ(this).replaceWith(this.childNodes)}}).end()},append:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1||this.nodeType===11||this.nodeType===9){this.appendChild(e)}})},prepend:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1||this.nodeType===11||this.nodeType===9){this.insertBefore(e,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(e){if(this.parentNode){this.parentNode.insertBefore(e,this)}})},after:function(){return this.domManip(arguments,false,function(e){if(this.parentNode){this.parentNode.insertBefore(e,this.nextSibling)}})},remove:function(e,b5){var b4,b3=0;for(;(b4=this[b3])!=null;b3++){if(!e||bJ.filter(e,[b4]).length>0){if(!b5&&b4.nodeType===1){bJ.cleanData(k(b4))}if(b4.parentNode){if(b5&&bJ.contains(b4.ownerDocument,b4)){bs(k(b4,"script"))}b4.parentNode.removeChild(b4)}}}return this},empty:function(){var b3,e=0;for(;(b3=this[e])!=null;e++){if(b3.nodeType===1){bJ.cleanData(k(b3,false))}while(b3.firstChild){b3.removeChild(b3.firstChild)}if(b3.options&&bJ.nodeName(b3,"select")){b3.options.length=0}}return this},clone:function(b3,e){b3=b3==null?false:b3;e=e==null?b3:e;return this.map(function(){return bJ.clone(this,b3,e)})},html:function(e){return bJ.access(this,function(b6){var b5=this[0]||{},b4=0,b3=this.length;if(b6===aG){return b5.nodeType===1?b5.innerHTML.replace(aA,""):aG}if(typeof b6==="string"&&!al.test(b6)&&(bJ.support.htmlSerialize||!J.test(b6))&&(bJ.support.leadingWhitespace||!b2.test(b6))&&!T[(m.exec(b6)||["",""])[1].toLowerCase()]){b6=b6.replace(aD,"<$1></$2>");try{for(;b4<b3;b4++){b5=this[b4]||{};if(b5.nodeType===1){bJ.cleanData(k(b5,false));b5.innerHTML=b6}}b5=0}catch(b7){}}if(b5){this.empty().append(b6)}},null,e,arguments.length)},replaceWith:function(b3){var e=bJ.isFunction(b3);if(!e&&typeof b3!=="string"){b3=bJ(b3).not(this).detach()}return this.domManip([b3],true,function(b6){var b5=this.nextSibling,b4=this.parentNode;if(b4){bJ(this).remove();b4.insertBefore(b6,b5)}})},detach:function(e){return this.remove(e,true)},domManip:function(ca,cg,cf){ca=aI.apply([],ca);var b8,b4,e,b6,cd,b9,b7=0,b5=this.length,cc=this,ce=b5-1,cb=ca[0],b3=bJ.isFunction(cb);if(b3||!(b5<=1||typeof cb!=="string"||bJ.support.checkClone||!bU.test(cb))){return this.each(function(ci){var ch=cc.eq(ci);if(b3){ca[0]=cb.call(this,ci,cg?ch.html():aG)}ch.domManip(ca,cg,cf)})}if(b5){b9=bJ.buildFragment(ca,this[0].ownerDocument,false,this);b8=b9.firstChild;if(b9.childNodes.length===1){b9=b8}if(b8){cg=cg&&bJ.nodeName(b8,"tr");b6=bJ.map(k(b9,"script"),t);e=b6.length;for(;b7<b5;b7++){b4=b9;if(b7!==ce){b4=bJ.clone(b4,true,true);if(e){bJ.merge(b6,k(b4,"script"))}}cf.call(cg&&bJ.nodeName(this[b7],"table")?x(this[b7],"tbody"):this[b7],b4,b7)}if(e){cd=b6[b6.length-1].ownerDocument;bJ.map(b6,bc);for(b7=0;b7<e;b7++){b4=b6[b7];if(bz.test(b4.type||"")&&!bJ._data(b4,"globalEval")&&bJ.contains(cd,b4)){if(b4.src){bJ.ajax({url:b4.src,type:"GET",dataType:"script",async:false,global:false,"throws":true})}else{bJ.globalEval((b4.text||b4.textContent||b4.innerHTML||"").replace(aK,""))}}}}b9=b8=null}}return this}});function x(b3,e){return b3.getElementsByTagName(e)[0]||b3.appendChild(b3.ownerDocument.createElement(e))}function t(b3){var e=b3.getAttributeNode("type");b3.type=(e&&e.specified)+"/"+b3.type;return b3}function bc(b3){var e=ar.exec(b3.type);if(e){b3.type=e[1]}else{b3.removeAttribute("type")}return b3}function bs(e,b4){var b5,b3=0;for(;(b5=e[b3])!=null;b3++){bJ._data(b5,"globalEval",!b4||bJ._data(b4[b3],"globalEval"))}}function at(b9,b3){if(b3.nodeType!==1||!bJ.hasData(b9)){return}var b6,b5,e,b8=bJ._data(b9),b7=bJ._data(b3,b8),b4=b8.events;if(b4){delete b7.handle;b7.events={};for(b6 in b4){for(b5=0,e=b4[b6].length;b5<e;b5++){bJ.event.add(b3,b6,b4[b6][b5])}}}if(b7.data){b7.data=bJ.extend({},b7.data)}}function Q(b6,b3){var b7,b5,b4;if(b3.nodeType!==1){return}b7=b3.nodeName.toLowerCase();if(!bJ.support.noCloneEvent&&b3[bJ.expando]){b4=bJ._data(b3);for(b5 in b4.events){bJ.removeEvent(b3,b5,b4.handle)}b3.removeAttribute(bJ.expando)}if(b7==="script"&&b3.text!==b6.text){t(b3).text=b6.text;bc(b3)}else{if(b7==="object"){if(b3.parentNode){b3.outerHTML=b6.outerHTML}if(bJ.support.html5Clone&&(b6.innerHTML&&!bJ.trim(b3.innerHTML))){b3.innerHTML=b6.innerHTML}}else{if(b7==="input"&&q.test(b6.type)){b3.defaultChecked=b3.checked=b6.checked;if(b3.value!==b6.value){b3.value=b6.value}}else{if(b7==="option"){b3.defaultSelected=b3.selected=b6.defaultSelected}else{if(b7==="input"||b7==="textarea"){b3.defaultValue=b6.defaultValue}}}}}}bJ.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,b3){bJ.fn[e]=function(b4){var b5,b7=0,b6=[],b9=bJ(b4),b8=b9.length-1;for(;b7<=b8;b7++){b5=b7===b8?this:this.clone(true);bJ(b9[b7])[b3](b5);ao.apply(b6,b5.get())}return this.pushStack(b6)}});function k(b5,e){var b3,b6,b4=0,b7=typeof b5.getElementsByTagName!==aC?b5.getElementsByTagName(e||"*"):typeof b5.querySelectorAll!==aC?b5.querySelectorAll(e||"*"):aG;if(!b7){for(b7=[],b3=b5.childNodes||b5;(b6=b3[b4])!=null;b4++){if(!e||bJ.nodeName(b6,e)){b7.push(b6)}else{bJ.merge(b7,k(b6,e))}}}return e===aG||e&&bJ.nodeName(b5,e)?bJ.merge([b5],b7):b7}function bV(e){if(q.test(e.type)){e.defaultChecked=e.checked}}bJ.extend({clone:function(b3,b5,e){var b7,b4,ca,b6,b8,b9=bJ.contains(b3.ownerDocument,b3);if(bJ.support.html5Clone||bJ.isXMLDoc(b3)||!J.test("<"+b3.nodeName+">")){ca=b3.cloneNode(true)}else{j.innerHTML=b3.outerHTML;j.removeChild(ca=j.firstChild)}if((!bJ.support.noCloneEvent||!bJ.support.noCloneChecked)&&(b3.nodeType===1||b3.nodeType===11)&&!bJ.isXMLDoc(b3)){b7=k(ca);b8=k(b3);for(b6=0;(b4=b8[b6])!=null;++b6){if(b7[b6]){Q(b4,b7[b6])}}}if(b5){if(e){b8=b8||k(b3);b7=b7||k(ca);for(b6=0;(b4=b8[b6])!=null;b6++){at(b4,b7[b6])}}else{at(b3,ca)}}b7=k(ca,"script");if(b7.length>0){bs(b7,!b9&&k(b3,"script"))}b7=b8=b4=null;return ca},buildFragment:function(b3,b5,ca,cf){var cb,b7,b9,ce,cg,cd,b4,b8=b3.length,b6=A(b5),e=[],cc=0;for(;cc<b8;cc++){b7=b3[cc];if(b7||b7===0){if(bJ.type(b7)==="object"){bJ.merge(e,b7.nodeType?[b7]:b7)}else{if(!I.test(b7)){e.push(b5.createTextNode(b7))}else{ce=ce||b6.appendChild(b5.createElement("div"));cg=(m.exec(b7)||["",""])[1].toLowerCase();b4=T[cg]||T._default;ce.innerHTML=b4[1]+b7.replace(aD,"<$1></$2>")+b4[2];cb=b4[0];while(cb--){ce=ce.lastChild}if(!bJ.support.leadingWhitespace&&b2.test(b7)){e.push(b5.createTextNode(b2.exec(b7)[0]))}if(!bJ.support.tbody){b7=cg==="table"&&!bX.test(b7)?ce.firstChild:b4[1]==="<table>"&&!bX.test(b7)?ce:0;cb=b7&&b7.childNodes.length;while(cb--){if(bJ.nodeName((cd=b7.childNodes[cb]),"tbody")&&!cd.childNodes.length){b7.removeChild(cd)}}}bJ.merge(e,ce.childNodes);ce.textContent="";while(ce.firstChild){ce.removeChild(ce.firstChild)}ce=b6.lastChild}}}}if(ce){b6.removeChild(ce)}if(!bJ.support.appendChecked){bJ.grep(k(e,"input"),bV)}cc=0;while((b7=e[cc++])){if(cf&&bJ.inArray(b7,cf)!==-1){continue}b9=bJ.contains(b7.ownerDocument,b7);ce=k(b6.appendChild(b7),"script");if(b9){bs(ce)}if(ca){cb=0;while((b7=ce[cb++])){if(bz.test(b7.type||"")){ca.push(b7)}}}}ce=null;return b6},cleanData:function(b3,cb){var b5,ca,b4,b6,b7=0,cc=bJ.expando,e=bJ.cache,b8=bJ.support.deleteExpando,b9=bJ.event.special;for(;(b5=b3[b7])!=null;b7++){if(cb||bJ.acceptData(b5)){b4=b5[cc];b6=b4&&e[b4];if(b6){if(b6.events){for(ca in b6.events){if(b9[ca]){bJ.event.remove(b5,ca)}else{bJ.removeEvent(b5,ca,b6.handle)}}}if(e[b4]){delete e[b4];if(b8){delete b5[cc]}else{if(typeof b5.removeAttribute!==aC){b5.removeAttribute(cc)}else{b5[cc]=null}}a6.push(b4)}}}}}});var aE,bo,E,bg=/alpha\([^)]*\)/i,aT=/opacity\s*=\s*([^)]*)/,bn=/^(top|right|bottom|left)$/,F=/^(none|table(?!-c[ea]).+)/,aY=/^margin/,a9=new RegExp("^("+bA+")(.*)$","i"),W=new RegExp("^("+bA+")(?!px)[a-z%]+$","i"),S=new RegExp("^([+-])=("+bA+")","i"),bj={BODY:"block"},bb={position:"absolute",visibility:"hidden",display:"block"},bC={letterSpacing:0,fontWeight:400},bT=["Top","Right","Bottom","Left"],av=["Webkit","O","Moz","ms"];function b(b5,b3){if(b3 in b5){return b3}var b6=b3.charAt(0).toUpperCase()+b3.slice(1),e=b3,b4=av.length;while(b4--){b3=av[b4]+b6;if(b3 in b5){return b3}}return e}function P(b3,e){b3=e||b3;return bJ.css(b3,"display")==="none"||!bJ.contains(b3.ownerDocument,b3)}function p(b8,e){var b9,b6,b7,b3=[],b4=0,b5=b8.length;for(;b4<b5;b4++){b6=b8[b4];if(!b6.style){continue}b3[b4]=bJ._data(b6,"olddisplay");b9=b6.style.display;if(e){if(!b3[b4]&&b9==="none"){b6.style.display=""}if(b6.style.display===""&&P(b6)){b3[b4]=bJ._data(b6,"olddisplay",bE(b6.nodeName))}}else{if(!b3[b4]){b7=P(b6);if(b9&&b9!=="none"||!b7){bJ._data(b6,"olddisplay",b7?b9:bJ.css(b6,"display"))}}}}for(b4=0;b4<b5;b4++){b6=b8[b4];if(!b6.style){continue}if(!e||b6.style.display==="none"||b6.style.display===""){b6.style.display=e?b3[b4]||"":"none"}}return b8}bJ.fn.extend({css:function(e,b3){return bJ.access(this,function(b8,b5,b9){var b4,b7,ca={},b6=0;if(bJ.isArray(b5)){b7=bo(b8);b4=b5.length;for(;b6<b4;b6++){ca[b5[b6]]=bJ.css(b8,b5[b6],false,b7)}return ca}return b9!==aG?bJ.style(b8,b5,b9):bJ.css(b8,b5)},e,b3,arguments.length>1)},show:function(){return p(this,true)},hide:function(){return p(this)},toggle:function(b3){var e=typeof b3==="boolean";return this.each(function(){if(e?b3:P(this)){bJ(this).show()}else{bJ(this).hide()}})}});bJ.extend({cssHooks:{opacity:{get:function(b4,b3){if(b3){var e=E(b4,"opacity");return e===""?"1":e}}}},cssNumber:{columnCount:true,fillOpacity:true,fontWeight:true,lineHeight:true,opacity:true,orphans:true,widows:true,zIndex:true,zoom:true},cssProps:{"float":bJ.support.cssFloat?"cssFloat":"styleFloat"},style:function(b5,b4,cb,b6){if(!b5||b5.nodeType===3||b5.nodeType===8||!b5.style){return}var b9,ca,cc,b7=bJ.camelCase(b4),b3=b5.style;b4=bJ.cssProps[b7]||(bJ.cssProps[b7]=b(b3,b7));cc=bJ.cssHooks[b4]||bJ.cssHooks[b7];if(cb!==aG){ca=typeof cb;if(ca==="string"&&(b9=S.exec(cb))){cb=(b9[1]+1)*b9[2]+parseFloat(bJ.css(b5,b4));ca="number"}if(cb==null||ca==="number"&&isNaN(cb)){return}if(ca==="number"&&!bJ.cssNumber[b7]){cb+="px"}if(!bJ.support.clearCloneStyle&&cb===""&&b4.indexOf("background")===0){b3[b4]="inherit"}if(!cc||!("set" in cc)||(cb=cc.set(b5,cb,b6))!==aG){try{b3[b4]=cb}catch(b8){}}}else{if(cc&&"get" in cc&&(b9=cc.get(b5,false,b6))!==aG){return b9}return b3[b4]}},css:function(b8,b6,b3,b7){var b5,b9,e,b4=bJ.camelCase(b6);b6=bJ.cssProps[b4]||(bJ.cssProps[b4]=b(b8.style,b4));e=bJ.cssHooks[b6]||bJ.cssHooks[b4];if(e&&"get" in e){b9=e.get(b8,true,b3)}if(b9===aG){b9=E(b8,b6,b7)}if(b9==="normal"&&b6 in bC){b9=bC[b6]}if(b3===""||b3){b5=parseFloat(b9);return b3===true||bJ.isNumeric(b5)?b5||0:b9}return b9},swap:function(b7,b6,b8,b5){var b4,b3,e={};for(b3 in b6){e[b3]=b7.style[b3];b7.style[b3]=b6[b3]}b4=b8.apply(b7,b5||[]);for(b3 in b6){b7.style[b3]=e[b3]}return b4}});if(a2.getComputedStyle){bo=function(e){return a2.getComputedStyle(e,null)};E=function(b6,b4,b8){var b5,b3,ca,b7=b8||bo(b6),b9=b7?b7.getPropertyValue(b4)||b7[b4]:aG,e=b6.style;if(b7){if(b9===""&&!bJ.contains(b6.ownerDocument,b6)){b9=bJ.style(b6,b4)}if(W.test(b9)&&aY.test(b4)){b5=e.width;b3=e.minWidth;ca=e.maxWidth;e.minWidth=e.maxWidth=e.width=b9;b9=b7.width;e.width=b5;e.minWidth=b3;e.maxWidth=ca}}return b9}}else{if(l.documentElement.currentStyle){bo=function(e){return e.currentStyle};E=function(b5,b3,b8){var b4,b7,b9,b6=b8||bo(b5),ca=b6?b6[b3]:aG,e=b5.style;if(ca==null&&e&&e[b3]){ca=e[b3]}if(W.test(ca)&&!bn.test(b3)){b4=e.left;b7=b5.runtimeStyle;b9=b7&&b7.left;if(b9){b7.left=b5.currentStyle.left}e.left=b3==="fontSize"?"1em":ca;ca=e.pixelLeft+"px";e.left=b4;if(b9){b7.left=b9}}return ca===""?"auto":ca}}}function aJ(e,b4,b5){var b3=a9.exec(b4);return b3?Math.max(0,b3[1]-(b5||0))+(b3[2]||"px"):b4}function aw(b6,b3,e,b8,b5){var b4=e===(b8?"border":"content")?4:b3==="width"?1:0,b7=0;for(;b4<4;b4+=2){if(e==="margin"){b7+=bJ.css(b6,e+bT[b4],true,b5)}if(b8){if(e==="content"){b7-=bJ.css(b6,"padding"+bT[b4],true,b5)}if(e!=="margin"){b7-=bJ.css(b6,"border"+bT[b4]+"Width",true,b5)}}else{b7+=bJ.css(b6,"padding"+bT[b4],true,b5);if(e!=="padding"){b7+=bJ.css(b6,"border"+bT[b4]+"Width",true,b5)}}}return b7}function u(b6,b3,e){var b5=true,b7=b3==="width"?b6.offsetWidth:b6.offsetHeight,b4=bo(b6),b8=bJ.support.boxSizing&&bJ.css(b6,"boxSizing",false,b4)==="border-box";if(b7<=0||b7==null){b7=E(b6,b3,b4);if(b7<0||b7==null){b7=b6.style[b3]}if(W.test(b7)){return b7}b5=b8&&(bJ.support.boxSizingReliable||b7===b6.style[b3]);b7=parseFloat(b7)||0}return(b7+aw(b6,b3,e||(b8?"border":"content"),b5,b4))+"px"}function bE(b4){var b3=l,e=bj[b4];if(!e){e=a1(b4,b3);if(e==="none"||!e){aE=(aE||bJ("<iframe frameborder='0' width='0' height='0'/>").css("cssText","display:block !important")).appendTo(b3.documentElement);b3=(aE[0].contentWindow||aE[0].contentDocument).document;b3.write("<!doctype html><html><body>");b3.close();e=a1(b4,b3);aE.detach()}bj[b4]=e}return e}function a1(e,b5){var b3=bJ(b5.createElement(e)).appendTo(b5.body),b4=bJ.css(b3[0],"display");b3.remove();return b4}bJ.each(["height","width"],function(b3,e){bJ.cssHooks[e]={get:function(b6,b5,b4){if(b5){return b6.offsetWidth===0&&F.test(bJ.css(b6,"display"))?bJ.swap(b6,bb,function(){return u(b6,e,b4)}):u(b6,e,b4)}},set:function(b6,b7,b4){var b5=b4&&bo(b6);return aJ(b6,b7,b4?aw(b6,e,b4,bJ.support.boxSizing&&bJ.css(b6,"boxSizing",false,b5)==="border-box",b5):0)}}});if(!bJ.support.opacity){bJ.cssHooks.opacity={get:function(b3,e){return aT.test((e&&b3.currentStyle?b3.currentStyle.filter:b3.style.filter)||"")?(0.01*parseFloat(RegExp.$1))+"":e?"1":""},set:function(b6,b7){var b5=b6.style,b3=b6.currentStyle,e=bJ.isNumeric(b7)?"alpha(opacity="+b7*100+")":"",b4=b3&&b3.filter||b5.filter||"";b5.zoom=1;if((b7>=1||b7==="")&&bJ.trim(b4.replace(bg,""))===""&&b5.removeAttribute){b5.removeAttribute("filter");if(b7===""||b3&&!b3.filter){return}}b5.filter=bg.test(b4)?b4.replace(bg,e):b4+" "+e}}}bJ(function(){if(!bJ.support.reliableMarginRight){bJ.cssHooks.marginRight={get:function(b3,e){if(e){return bJ.swap(b3,{display:"inline-block"},E,[b3,"marginRight"])}}}}if(!bJ.support.pixelPosition&&bJ.fn.position){bJ.each(["top","left"],function(e,b3){bJ.cssHooks[b3]={get:function(b5,b4){if(b4){b4=E(b5,b3);return W.test(b4)?bJ(b5).position()[b3]+"px":b4}}}})}});if(bJ.expr&&bJ.expr.filters){bJ.expr.filters.hidden=function(e){return e.offsetWidth<=0&&e.offsetHeight<=0||(!bJ.support.reliableHiddenOffsets&&((e.style&&e.style.display)||bJ.css(e,"display"))==="none")};bJ.expr.filters.visible=function(e){return !bJ.expr.filters.hidden(e)}}bJ.each({margin:"",padding:"",border:"Width"},function(e,b3){bJ.cssHooks[e+b3]={expand:function(b6){var b5=0,b4={},b7=typeof b6==="string"?b6.split(" "):[b6];for(;b5<4;b5++){b4[e+bT[b5]+b3]=b7[b5]||b7[b5-2]||b7[0]}return b4}};if(!aY.test(e)){bJ.cssHooks[e+b3].set=aJ}});var bv=/%20/g,aR=/\[\]$/,U=/\r?\n/g,c=/^(?:submit|button|image|reset|file)$/i,au=/^(?:input|select|textarea|keygen)/i;bJ.fn.extend({serialize:function(){return bJ.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=bJ.prop(this,"elements");return e?bJ.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!bJ(this).is(":disabled")&&au.test(this.nodeName)&&!c.test(e)&&(this.checked||!q.test(e))}).map(function(e,b3){var b4=bJ(this).val();return b4==null?null:bJ.isArray(b4)?bJ.map(b4,function(b5){return{name:b3.name,value:b5.replace(U,"\r\n")}}):{name:b3.name,value:b4.replace(U,"\r\n")}}).get()}});bJ.param=function(e,b4){var b5,b3=[],b6=function(b7,b8){b8=bJ.isFunction(b8)?b8():(b8==null?"":b8);b3[b3.length]=encodeURIComponent(b7)+"="+encodeURIComponent(b8)};if(b4===aG){b4=bJ.ajaxSettings&&bJ.ajaxSettings.traditional}if(bJ.isArray(e)||(e.jquery&&!bJ.isPlainObject(e))){bJ.each(e,function(){b6(this.name,this.value)})}else{for(b5 in e){i(b5,e[b5],b4,b6)}}return b3.join("&").replace(bv,"+")};function i(b4,b6,b3,b5){var e;if(bJ.isArray(b6)){bJ.each(b6,function(b8,b7){if(b3||aR.test(b4)){b5(b4,b7)}else{i(b4+"["+(typeof b7==="object"?b8:"")+"]",b7,b3,b5)}})}else{if(!b3&&bJ.type(b6)==="object"){for(e in b6){i(b4+"["+e+"]",b6[e],b3,b5)}}else{b5(b4,b6)}}}bJ.each(("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu").split(" "),function(b3,e){bJ.fn[e]=function(b5,b4){return arguments.length>0?this.on(e,null,b5,b4):this.trigger(e)}});bJ.fn.hover=function(e,b3){return this.mouseenter(e).mouseleave(b3||e)};var b1,Y,bO=bJ.now(),az=/\?/,ap=/#.*$/,O=/([?&])_=[^&]*/,ag=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,B=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,o=/^(?:GET|HEAD)$/,aH=/^\/\//,aU=/^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,b0=bJ.fn.load,v={},a7={},aW="*/".concat("*");try{Y=aL.href}catch(bf){Y=l.createElement("a");Y.href="";Y=Y.href}b1=aU.exec(Y.toLowerCase())||[];function bL(e){return function(b6,b7){if(typeof b6!=="string"){b7=b6;b6="*"}var b3,b4=0,b5=b6.toLowerCase().match(ac)||[];if(bJ.isFunction(b7)){while((b3=b5[b4++])){if(b3[0]==="+"){b3=b3.slice(1)||"*";(e[b3]=e[b3]||[]).unshift(b7)}else{(e[b3]=e[b3]||[]).push(b7)}}}}}function n(e,b4,b8,b5){var b3={},b6=(e===a7);function b7(b9){var ca;b3[b9]=true;bJ.each(e[b9]||[],function(cc,cb){var cd=cb(b4,b8,b5);if(typeof cd==="string"&&!b6&&!b3[cd]){b4.dataTypes.unshift(cd);b7(cd);return false}else{if(b6){return !(ca=cd)}}});return ca}return b7(b4.dataTypes[0])||!b3["*"]&&b7("*")}function r(b4,b5){var e,b3,b6=bJ.ajaxSettings.flatOptions||{};for(b3 in b5){if(b5[b3]!==aG){(b6[b3]?b4:(e||(e={})))[b3]=b5[b3]}}if(e){bJ.extend(true,b4,e)}return b4}bJ.fn.load=function(b5,b8,b9){if(typeof b5!=="string"&&b0){return b0.apply(this,arguments)}var e,b4,b6,b3=this,b7=b5.indexOf(" ");if(b7>=0){e=b5.slice(b7,b5.length);b5=b5.slice(0,b7)}if(bJ.isFunction(b8)){b9=b8;b8=aG}else{if(b8&&typeof b8==="object"){b6="POST"}}if(b3.length>0){bJ.ajax({url:b5,type:b6,dataType:"html",data:b8}).done(function(ca){b4=arguments;b3.html(e?bJ("<div>").append(bJ.parseHTML(ca)).find(e):ca)}).complete(b9&&function(cb,ca){b3.each(b9,b4||[cb.responseText,ca,cb])})}return this};bJ.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,b3){bJ.fn[b3]=function(b4){return this.on(b3,b4)}});bJ.each(["get","post"],function(e,b3){bJ[b3]=function(b4,b6,b7,b5){if(bJ.isFunction(b6)){b5=b5||b7;b7=b6;b6=aG}return bJ.ajax({url:b4,type:b3,dataType:b5,data:b6,success:b7})}});bJ.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Y,type:"GET",isLocal:B.test(b1[1]),global:true,processData:true,async:true,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":aW,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a2.String,"text html":true,"text json":bJ.parseJSON,"text xml":bJ.parseXML},flatOptions:{url:true,context:true}},ajaxSetup:function(b3,e){return e?r(r(b3,bJ.ajaxSettings),e):r(bJ.ajaxSettings,b3)},ajaxPrefilter:bL(v),ajaxTransport:bL(a7),ajax:function(b7,b4){if(typeof b7==="object"){b4=b7;b7=aG}b4=b4||{};var cg,ci,b8,cn,cc,b3,cj,b5,cb=bJ.ajaxSetup({},b4),cp=cb.context||cb,ce=cb.context&&(cp.nodeType||cp.jquery)?bJ(cp):bJ.event,co=bJ.Deferred(),cl=bJ.Callbacks("once memory"),b9=cb.statusCode||{},cf={},cm={},b6=0,ca="canceled",ch={readyState:0,getResponseHeader:function(cq){var e;if(b6===2){if(!b5){b5={};while((e=ag.exec(cn))){b5[e[1].toLowerCase()]=e[2]}}e=b5[cq.toLowerCase()]}return e==null?null:e},getAllResponseHeaders:function(){return b6===2?cn:null},setRequestHeader:function(cq,cr){var e=cq.toLowerCase();if(!b6){cq=cm[e]=cm[e]||cq;cf[cq]=cr}return this},overrideMimeType:function(e){if(!b6){cb.mimeType=e}return this},statusCode:function(cq){var e;if(cq){if(b6<2){for(e in cq){b9[e]=[b9[e],cq[e]]}}else{ch.always(cq[ch.status])}}return this},abort:function(cq){var e=cq||ca;if(cj){cj.abort(e)}cd(0,e);return this}};co.promise(ch).complete=cl.add;ch.success=ch.done;ch.error=ch.fail;cb.url=((b7||cb.url||Y)+"").replace(ap,"").replace(aH,b1[1]+"//");cb.type=b4.method||b4.type||cb.method||cb.type;cb.dataTypes=bJ.trim(cb.dataType||"*").toLowerCase().match(ac)||[""];if(cb.crossDomain==null){cg=aU.exec(cb.url.toLowerCase());cb.crossDomain=!!(cg&&(cg[1]!==b1[1]||cg[2]!==b1[2]||(cg[3]||(cg[1]==="http:"?80:443))!=(b1[3]||(b1[1]==="http:"?80:443))))}if(cb.data&&cb.processData&&typeof cb.data!=="string"){cb.data=bJ.param(cb.data,cb.traditional)}n(v,cb,b4,ch);if(b6===2){return ch}b3=cb.global;if(b3&&bJ.active++===0){bJ.event.trigger("ajaxStart")}cb.type=cb.type.toUpperCase();cb.hasContent=!o.test(cb.type);b8=cb.url;if(!cb.hasContent){if(cb.data){b8=(cb.url+=(az.test(b8)?"&":"?")+cb.data);delete cb.data}if(cb.cache===false){cb.url=O.test(b8)?b8.replace(O,"$1_="+bO++):b8+(az.test(b8)?"&":"?")+"_="+bO++}}if(cb.ifModified){if(bJ.lastModified[b8]){ch.setRequestHeader("If-Modified-Since",bJ.lastModified[b8])}if(bJ.etag[b8]){ch.setRequestHeader("If-None-Match",bJ.etag[b8])}}if(cb.data&&cb.hasContent&&cb.contentType!==false||b4.contentType){ch.setRequestHeader("Content-Type",cb.contentType)}ch.setRequestHeader("Accept",cb.dataTypes[0]&&cb.accepts[cb.dataTypes[0]]?cb.accepts[cb.dataTypes[0]]+(cb.dataTypes[0]!=="*"?", "+aW+"; q=0.01":""):cb.accepts["*"]);for(ci in cb.headers){ch.setRequestHeader(ci,cb.headers[ci])}if(cb.beforeSend&&(cb.beforeSend.call(cp,ch,cb)===false||b6===2)){return ch.abort()}ca="abort";for(ci in {success:1,error:1,complete:1}){ch[ci](cb[ci])}cj=n(a7,cb,b4,ch);if(!cj){cd(-1,"No Transport")}else{ch.readyState=1;if(b3){ce.trigger("ajaxSend",[ch,cb])}if(cb.async&&cb.timeout>0){cc=setTimeout(function(){ch.abort("timeout")},cb.timeout)}try{b6=1;cj.send(cf,cd)}catch(ck){if(b6<2){cd(-1,ck)}else{throw ck}}}function cd(cu,cq,cv,cs){var e,cy,cw,ct,cx,cr=cq;if(b6===2){return}b6=2;if(cc){clearTimeout(cc)}cj=aG;cn=cs||"";ch.readyState=cu>0?4:0;if(cv){ct=g(cb,ch,cv)}if(cu>=200&&cu<300||cu===304){if(cb.ifModified){cx=ch.getResponseHeader("Last-Modified");if(cx){bJ.lastModified[b8]=cx}cx=ch.getResponseHeader("etag");if(cx){bJ.etag[b8]=cx}}if(cu===204){e=true;cr="nocontent"}else{if(cu===304){e=true;cr="notmodified"}else{e=af(cb,ct);cr=e.state;cy=e.data;cw=e.error;e=!cw}}}else{cw=cr;if(cu||!cr){cr="error";if(cu<0){cu=0}}}ch.status=cu;ch.statusText=(cq||cr)+"";if(e){co.resolveWith(cp,[cy,cr,ch])}else{co.rejectWith(cp,[ch,cr,cw])}ch.statusCode(b9);b9=aG;if(b3){ce.trigger(e?"ajaxSuccess":"ajaxError",[ch,cb,e?cy:cw])}cl.fireWith(cp,[ch,cr]);if(b3){ce.trigger("ajaxComplete",[ch,cb]);if(!(--bJ.active)){bJ.event.trigger("ajaxStop")}}}return ch},getScript:function(e,b3){return bJ.get(e,aG,b3,"script")},getJSON:function(e,b3,b4){return bJ.get(e,b3,b4,"json")}});function g(cb,ca,b7){var e,b6,b5,b8,b3=cb.contents,b9=cb.dataTypes,b4=cb.responseFields;for(b8 in b4){if(b8 in b7){ca[b4[b8]]=b7[b8]}}while(b9[0]==="*"){b9.shift();if(b6===aG){b6=cb.mimeType||ca.getResponseHeader("Content-Type")}}if(b6){for(b8 in b3){if(b3[b8]&&b3[b8].test(b6)){b9.unshift(b8);break}}}if(b9[0] in b7){b5=b9[0]}else{for(b8 in b7){if(!b9[0]||cb.converters[b8+" "+b9[0]]){b5=b8;break}if(!e){e=b8}}b5=b5||e}if(b5){if(b5!==b9[0]){b9.unshift(b5)}return b7[b5]}}function af(cd,b5){var b3,b9,cb,b6,cc={},b7=0,ca=cd.dataTypes.slice(),b4=ca[0];if(cd.dataFilter){b5=cd.dataFilter(b5,cd.dataType)}if(ca[1]){for(cb in cd.converters){cc[cb.toLowerCase()]=cd.converters[cb]}}for(;(b9=ca[++b7]);){if(b9!=="*"){if(b4!=="*"&&b4!==b9){cb=cc[b4+" "+b9]||cc["* "+b9];if(!cb){for(b3 in cc){b6=b3.split(" ");if(b6[1]===b9){cb=cc[b4+" "+b6[0]]||cc["* "+b6[0]];if(cb){if(cb===true){cb=cc[b3]}else{if(cc[b3]!==true){b9=b6[0];ca.splice(b7--,0,b9)}}break}}}}if(cb!==true){if(cb&&cd["throws"]){b5=cb(b5)}else{try{b5=cb(b5)}catch(b8){return{state:"parsererror",error:cb?b8:"No conversion from "+b4+" to "+b9}}}}}b4=b9}}return{state:"success",data:b5}}bJ.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){bJ.globalEval(e);return e}}});bJ.ajaxPrefilter("script",function(e){if(e.cache===aG){e.cache=false}if(e.crossDomain){e.type="GET";e.global=false}});bJ.ajaxTransport("script",function(b4){if(b4.crossDomain){var e,b3=l.head||bJ("head")[0]||l.documentElement;return{send:function(b5,b6){e=l.createElement("script");e.async=true;if(b4.scriptCharset){e.charset=b4.scriptCharset}e.src=b4.url;e.onload=e.onreadystatechange=function(b8,b7){if(b7||!e.readyState||/loaded|complete/.test(e.readyState)){e.onload=e.onreadystatechange=null;if(e.parentNode){e.parentNode.removeChild(e)}e=null;if(!b7){b6(200,"success")}}};b3.insertBefore(e,b3.firstChild)},abort:function(){if(e){e.onload(aG,true)}}}}});var bq=[],a5=/(=)\?(?=&|$)|\?\?/;bJ.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=bq.pop()||(bJ.expando+"_"+(bO++));this[e]=true;return e}});bJ.ajaxPrefilter("json jsonp",function(b5,e,b6){var b8,b3,b4,b7=b5.jsonp!==false&&(a5.test(b5.url)?"url":typeof b5.data==="string"&&!(b5.contentType||"").indexOf("application/x-www-form-urlencoded")&&a5.test(b5.data)&&"data");if(b7||b5.dataTypes[0]==="jsonp"){b8=b5.jsonpCallback=bJ.isFunction(b5.jsonpCallback)?b5.jsonpCallback():b5.jsonpCallback;if(b7){b5[b7]=b5[b7].replace(a5,"$1"+b8)}else{if(b5.jsonp!==false){b5.url+=(az.test(b5.url)?"&":"?")+b5.jsonp+"="+b8}}b5.converters["script json"]=function(){if(!b4){bJ.error(b8+" was not called")}return b4[0]};b5.dataTypes[0]="json";b3=a2[b8];a2[b8]=function(){b4=arguments};b6.always(function(){a2[b8]=b3;if(b5[b8]){b5.jsonpCallback=e.jsonpCallback;bq.push(b8)}if(b4&&bJ.isFunction(b3)){b3(b4[0])}b4=b3=aG});return"script"}});var ah,ax,ay=0,aP=a2.ActiveXObject&&function(){var e;for(e in ah){ah[e](aG,true)}};function bD(){try{return new a2.XMLHttpRequest()}catch(b3){}}function bd(){try{return new a2.ActiveXObject("Microsoft.XMLHTTP")}catch(b3){}}bJ.ajaxSettings.xhr=a2.ActiveXObject?function(){return !this.isLocal&&bD()||bd()}:bD;ax=bJ.ajaxSettings.xhr();bJ.support.cors=!!ax&&("withCredentials" in ax);ax=bJ.support.ajax=!!ax;if(ax){bJ.ajaxTransport(function(e){if(!e.crossDomain||bJ.support.cors){var b3;return{send:function(b9,b4){var b7,b5,b8=e.xhr();if(e.username){b8.open(e.type,e.url,e.async,e.username,e.password)}else{b8.open(e.type,e.url,e.async)}if(e.xhrFields){for(b5 in e.xhrFields){b8[b5]=e.xhrFields[b5]}}if(e.mimeType&&b8.overrideMimeType){b8.overrideMimeType(e.mimeType)}if(!e.crossDomain&&!b9["X-Requested-With"]){b9["X-Requested-With"]="XMLHttpRequest"}try{for(b5 in b9){b8.setRequestHeader(b5,b9[b5])}}catch(b6){}b8.send((e.hasContent&&e.data)||null);b3=function(cc,cb){var ca,cd,cg,ce;try{if(b3&&(cb||b8.readyState===4)){b3=aG;if(b7){b8.onreadystatechange=bJ.noop;if(aP){delete ah[b7]}}if(cb){if(b8.readyState!==4){b8.abort()}}else{ce={};ca=b8.status;cd=b8.getAllResponseHeaders();if(typeof b8.responseText==="string"){ce.text=b8.responseText}try{cg=b8.statusText}catch(cf){cg=""}if(!ca&&e.isLocal&&!e.crossDomain){ca=ce.text?200:404}else{if(ca===1223){ca=204}}}}}catch(ch){if(!cb){b4(-1,ch)}}if(ce){b4(ca,cg,ce,cd)}};if(!e.async){b3()}else{if(b8.readyState===4){setTimeout(b3)}else{b7=++ay;if(aP){if(!ah){ah={};bJ(a2).unload(aP)}ah[b7]=b3}b8.onreadystatechange=b3}}},abort:function(){if(b3){b3(aG,true)}}}}})}var K,ad,bR=/^(?:toggle|show|hide)$/,bK=new RegExp("^(?:([+-])=|)("+bA+")([a-z%]*)$","i"),bQ=/queueHooks$/,aB=[h],a0={"*":[function(e,b9){var b5,ca,cb=this.createTween(e,b9),b6=bK.exec(b9),b7=cb.cur(),b3=+b7||0,b4=1,b8=20;if(b6){b5=+b6[2];ca=b6[3]||(bJ.cssNumber[e]?"":"px");if(ca!=="px"&&b3){b3=bJ.css(cb.elem,e,true)||b5||1;do{b4=b4||".5";b3=b3/b4;bJ.style(cb.elem,e,b3+ca)}while(b4!==(b4=cb.cur()/b7)&&b4!==1&&--b8)}cb.unit=ca;cb.start=b3;cb.end=b6[1]?b3+(b6[1]+1)*b5:b5}return cb}]};function bm(){setTimeout(function(){K=aG});return(K=bJ.now())}function be(b3,e){bJ.each(e,function(b8,b6){var b7=(a0[b8]||[]).concat(a0["*"]),b4=0,b5=b7.length;for(;b4<b5;b4++){if(b7[b4].call(b3,b8,b6)){return}}})}function f(b4,b8,cb){var cc,e,b7=0,b3=aB.length,ca=bJ.Deferred().always(function(){delete b6.elem}),b6=function(){if(e){return false}var ci=K||bm(),cf=Math.max(0,b5.startTime+b5.duration-ci),cd=cf/b5.duration||0,ch=1-cd,ce=0,cg=b5.tweens.length;for(;ce<cg;ce++){b5.tweens[ce].run(ch)}ca.notifyWith(b4,[b5,ch,cf]);if(ch<1&&cg){return cf}else{ca.resolveWith(b4,[b5]);return false}},b5=ca.promise({elem:b4,props:bJ.extend({},b8),opts:bJ.extend(true,{specialEasing:{}},cb),originalProperties:b8,originalOptions:cb,startTime:K||bm(),duration:cb.duration,tweens:[],createTween:function(cf,cd){var ce=bJ.Tween(b4,b5.opts,cf,cd,b5.opts.specialEasing[cf]||b5.opts.easing);b5.tweens.push(ce);return ce},stop:function(ce){var cd=0,cf=ce?b5.tweens.length:0;if(e){return this}e=true;for(;cd<cf;cd++){b5.tweens[cd].run(1)}if(ce){ca.resolveWith(b4,[b5,ce])}else{ca.rejectWith(b4,[b5,ce])}return this}}),b9=b5.props;am(b9,b5.opts.specialEasing);for(;b7<b3;b7++){cc=aB[b7].call(b5,b4,b9,b5.opts);if(cc){return cc}}be(b5,b9);if(bJ.isFunction(b5.opts.start)){b5.opts.start.call(b4,b5)}bJ.fx.timer(bJ.extend(b6,{elem:b4,anim:b5,queue:b5.opts.queue}));return b5.progress(b5.opts.progress).done(b5.opts.done,b5.opts.complete).fail(b5.opts.fail).always(b5.opts.always)}function am(b5,b7){var b6,b4,b3,b8,e;for(b3 in b5){b4=bJ.camelCase(b3);b8=b7[b4];b6=b5[b3];if(bJ.isArray(b6)){b8=b6[1];b6=b5[b3]=b6[0]}if(b3!==b4){b5[b4]=b6;delete b5[b3]}e=bJ.cssHooks[b4];if(e&&"expand" in e){b6=e.expand(b6);delete b5[b4];for(b3 in b6){if(!(b3 in b5)){b5[b3]=b6[b3];b7[b3]=b8}}}else{b7[b4]=b8}}}bJ.Animation=bJ.extend(f,{tweener:function(b3,b6){if(bJ.isFunction(b3)){b6=b3;b3=["*"]}else{b3=b3.split(" ")}var b5,e=0,b4=b3.length;for(;e<b4;e++){b5=b3[e];a0[b5]=a0[b5]||[];a0[b5].unshift(b6)}},prefilter:function(b3,e){if(e){aB.unshift(b3)}else{aB.push(b3)}}});function h(b6,cc,e){var b4,cb,b5,ce,ci,b8,ch,cg,cf,b7=this,b3=b6.style,cd={},ca=[],b9=b6.nodeType&&P(b6);if(!e.queue){cg=bJ._queueHooks(b6,"fx");if(cg.unqueued==null){cg.unqueued=0;cf=cg.empty.fire;cg.empty.fire=function(){if(!cg.unqueued){cf()}}}cg.unqueued++;b7.always(function(){b7.always(function(){cg.unqueued--;if(!bJ.queue(b6,"fx").length){cg.empty.fire()}})})}if(b6.nodeType===1&&("height" in cc||"width" in cc)){e.overflow=[b3.overflow,b3.overflowX,b3.overflowY];if(bJ.css(b6,"display")==="inline"&&bJ.css(b6,"float")==="none"){if(!bJ.support.inlineBlockNeedsLayout||bE(b6.nodeName)==="inline"){b3.display="inline-block"}else{b3.zoom=1}}}if(e.overflow){b3.overflow="hidden";if(!bJ.support.shrinkWrapBlocks){b7.always(function(){b3.overflow=e.overflow[0];b3.overflowX=e.overflow[1];b3.overflowY=e.overflow[2]})}}for(cb in cc){ce=cc[cb];if(bR.exec(ce)){delete cc[cb];b8=b8||ce==="toggle";if(ce===(b9?"hide":"show")){continue}ca.push(cb)}}b5=ca.length;if(b5){ci=bJ._data(b6,"fxshow")||bJ._data(b6,"fxshow",{});if("hidden" in ci){b9=ci.hidden}if(b8){ci.hidden=!b9}if(b9){bJ(b6).show()}else{b7.done(function(){bJ(b6).hide()})}b7.done(function(){var cj;bJ._removeData(b6,"fxshow");for(cj in cd){bJ.style(b6,cj,cd[cj])}});for(cb=0;cb<b5;cb++){b4=ca[cb];ch=b7.createTween(b4,b9?ci[b4]:0);cd[b4]=ci[b4]||bJ.style(b6,b4);if(!(b4 in ci)){ci[b4]=ch.start;if(b9){ch.end=ch.start;ch.start=b4==="width"||b4==="height"?1:0}}}}}function G(b4,b3,b6,e,b5){return new G.prototype.init(b4,b3,b6,e,b5)}bJ.Tween=G;G.prototype={constructor:G,init:function(b5,b3,b7,e,b6,b4){this.elem=b5;this.prop=b7;this.easing=b6||"swing";this.options=b3;this.start=this.now=this.cur();this.end=e;this.unit=b4||(bJ.cssNumber[b7]?"":"px")},cur:function(){var e=G.propHooks[this.prop];return e&&e.get?e.get(this):G.propHooks._default.get(this)},run:function(b4){var b3,e=G.propHooks[this.prop];if(this.options.duration){this.pos=b3=bJ.easing[this.easing](b4,this.options.duration*b4,0,1,this.options.duration)}else{this.pos=b3=b4}this.now=(this.end-this.start)*b3+this.start;if(this.options.step){this.options.step.call(this.elem,this.now,this)}if(e&&e.set){e.set(this)}else{G.propHooks._default.set(this)}return this}};G.prototype.init.prototype=G.prototype;G.propHooks={_default:{get:function(b3){var e;if(b3.elem[b3.prop]!=null&&(!b3.elem.style||b3.elem.style[b3.prop]==null)){return b3.elem[b3.prop]}e=bJ.css(b3.elem,b3.prop,"");return !e||e==="auto"?0:e},set:function(e){if(bJ.fx.step[e.prop]){bJ.fx.step[e.prop](e)}else{if(e.elem.style&&(e.elem.style[bJ.cssProps[e.prop]]!=null||bJ.cssHooks[e.prop])){bJ.style(e.elem,e.prop,e.now+e.unit)}else{e.elem[e.prop]=e.now}}}}};G.propHooks.scrollTop=G.propHooks.scrollLeft={set:function(e){if(e.elem.nodeType&&e.elem.parentNode){e.elem[e.prop]=e.now}}};bJ.each(["toggle","show","hide"],function(b3,e){var b4=bJ.fn[e];bJ.fn[e]=function(b5,b7,b6){return b5==null||typeof b5==="boolean"?b4.apply(this,arguments):this.animate(bI(e,true),b5,b7,b6)}});bJ.fn.extend({fadeTo:function(e,b5,b4,b3){return this.filter(P).css("opacity",0).show().end().animate({opacity:b5},e,b4,b3)},animate:function(b8,b5,b7,b6){var b4=bJ.isEmptyObject(b8),e=bJ.speed(b5,b7,b6),b3=function(){var b9=f(this,bJ.extend({},b8),e);b3.finish=function(){b9.stop(true)};if(b4||bJ._data(this,"finish")){b9.stop(true)}};b3.finish=b3;return b4||e.queue===false?this.each(b3):this.queue(e.queue,b3)},stop:function(b4,b3,e){var b5=function(b6){var b7=b6.stop;delete b6.stop;b7(e)};if(typeof b4!=="string"){e=b3;b3=b4;b4=aG}if(b3&&b4!==false){this.queue(b4||"fx",[])}return this.each(function(){var b9=true,b6=b4!=null&&b4+"queueHooks",b8=bJ.timers,b7=bJ._data(this);if(b6){if(b7[b6]&&b7[b6].stop){b5(b7[b6])}}else{for(b6 in b7){if(b7[b6]&&b7[b6].stop&&bQ.test(b6)){b5(b7[b6])}}}for(b6=b8.length;b6--;){if(b8[b6].elem===this&&(b4==null||b8[b6].queue===b4)){b8[b6].anim.stop(e);b9=false;b8.splice(b6,1)}}if(b9||!e){bJ.dequeue(this,b4)}})},finish:function(e){if(e!==false){e=e||"fx"}return this.each(function(){var b5,b8=bJ._data(this),b4=b8[e+"queue"],b3=b8[e+"queueHooks"],b7=bJ.timers,b6=b4?b4.length:0;b8.finish=true;bJ.queue(this,e,[]);if(b3&&b3.cur&&b3.cur.finish){b3.cur.finish.call(this)}for(b5=b7.length;b5--;){if(b7[b5].elem===this&&b7[b5].queue===e){b7[b5].anim.stop(true);b7.splice(b5,1)}}for(b5=0;b5<b6;b5++){if(b4[b5]&&b4[b5].finish){b4[b5].finish.call(this)}}delete b8.finish})}});function bI(b4,b6){var b5,e={height:b4},b3=0;b6=b6?1:0;for(;b3<4;b3+=2-b6){b5=bT[b3];e["margin"+b5]=e["padding"+b5]=b4}if(b6){e.opacity=e.width=b4}return e}bJ.each({slideDown:bI("show"),slideUp:bI("hide"),slideToggle:bI("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,b3){bJ.fn[e]=function(b4,b6,b5){return this.animate(b3,b4,b6,b5)}});bJ.speed=function(b4,b5,b3){var e=b4&&typeof b4==="object"?bJ.extend({},b4):{complete:b3||!b3&&b5||bJ.isFunction(b4)&&b4,duration:b4,easing:b3&&b5||b5&&!bJ.isFunction(b5)&&b5};e.duration=bJ.fx.off?0:typeof e.duration==="number"?e.duration:e.duration in bJ.fx.speeds?bJ.fx.speeds[e.duration]:bJ.fx.speeds._default;if(e.queue==null||e.queue===true){e.queue="fx"}e.old=e.complete;e.complete=function(){if(bJ.isFunction(e.old)){e.old.call(this)}if(e.queue){bJ.dequeue(this,e.queue)}};return e};bJ.easing={linear:function(e){return e},swing:function(e){return 0.5-Math.cos(e*Math.PI)/2}};bJ.timers=[];bJ.fx=G.prototype.init;bJ.fx.tick=function(){var b4,b3=bJ.timers,e=0;K=bJ.now();for(;e<b3.length;e++){b4=b3[e];if(!b4()&&b3[e]===b4){b3.splice(e--,1)}}if(!b3.length){bJ.fx.stop()}K=aG};bJ.fx.timer=function(e){if(e()&&bJ.timers.push(e)){bJ.fx.start()}};bJ.fx.interval=13;bJ.fx.start=function(){if(!ad){ad=setInterval(bJ.fx.tick,bJ.fx.interval)}};bJ.fx.stop=function(){clearInterval(ad);ad=null};bJ.fx.speeds={slow:600,fast:200,_default:400};bJ.fx.step={};if(bJ.expr&&bJ.expr.filters){bJ.expr.filters.animated=function(e){return bJ.grep(bJ.timers,function(b3){return e===b3.elem}).length}}bJ.fn.offset=function(b3){if(arguments.length){return b3===aG?this:this.each(function(b8){bJ.offset.setOffset(this,b3,b8)})}var e,b7,b5={top:0,left:0},b4=this[0],b6=b4&&b4.ownerDocument;if(!b6){return}e=b6.documentElement;if(!bJ.contains(e,b4)){return b5}if(typeof b4.getBoundingClientRect!==aC){b5=b4.getBoundingClientRect()}b7=bp(b6);return{top:b5.top+(b7.pageYOffset||e.scrollTop)-(e.clientTop||0),left:b5.left+(b7.pageXOffset||e.scrollLeft)-(e.clientLeft||0)}};bJ.offset={setOffset:function(b5,ce,b8){var b9=bJ.css(b5,"position");if(b9==="static"){b5.style.position="relative"}var b7=bJ(b5),b3=b7.offset(),e=bJ.css(b5,"top"),cc=bJ.css(b5,"left"),cd=(b9==="absolute"||b9==="fixed")&&bJ.inArray("auto",[e,cc])>-1,cb={},ca={},b4,b6;if(cd){ca=b7.position();b4=ca.top;b6=ca.left}else{b4=parseFloat(e)||0;b6=parseFloat(cc)||0}if(bJ.isFunction(ce)){ce=ce.call(b5,b8,b3)}if(ce.top!=null){cb.top=(ce.top-b3.top)+b4}if(ce.left!=null){cb.left=(ce.left-b3.left)+b6}if("using" in ce){ce.using.call(b5,cb)}else{b7.css(cb)}}};bJ.fn.extend({position:function(){if(!this[0]){return}var b4,b5,e={top:0,left:0},b3=this[0];if(bJ.css(b3,"position")==="fixed"){b5=b3.getBoundingClientRect()}else{b4=this.offsetParent();b5=this.offset();if(!bJ.nodeName(b4[0],"html")){e=b4.offset()}e.top+=bJ.css(b4[0],"borderTopWidth",true);e.left+=bJ.css(b4[0],"borderLeftWidth",true)}return{top:b5.top-e.top-bJ.css(b3,"marginTop",true),left:b5.left-e.left-bJ.css(b3,"marginLeft",true)}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||l.documentElement;while(e&&(!bJ.nodeName(e,"html")&&bJ.css(e,"position")==="static")){e=e.offsetParent}return e||l.documentElement})}});bJ.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(b4,b3){var e=/Y/.test(b3);bJ.fn[b4]=function(b5){return bJ.access(this,function(b6,b9,b8){var b7=bp(b6);if(b8===aG){return b7?(b3 in b7)?b7[b3]:b7.document.documentElement[b9]:b6[b9]}if(b7){b7.scrollTo(!e?b8:bJ(b7).scrollLeft(),e?b8:bJ(b7).scrollTop())}else{b6[b9]=b8}},b4,b5,arguments.length,null)}});function bp(e){return bJ.isWindow(e)?e:e.nodeType===9?e.defaultView||e.parentWindow:false}bJ.each({Height:"height",Width:"width"},function(e,b3){bJ.each({padding:"inner"+e,content:b3,"":"outer"+e},function(b4,b5){bJ.fn[b5]=function(b9,b8){var b7=arguments.length&&(b4||typeof b9!=="boolean"),b6=b4||(b9===true||b8===true?"margin":"border");return bJ.access(this,function(cb,ca,cc){var cd;if(bJ.isWindow(cb)){return cb.document.documentElement["client"+e]}if(cb.nodeType===9){cd=cb.documentElement;return Math.max(cb.body["scroll"+e],cd["scroll"+e],cb.body["offset"+e],cd["offset"+e],cd["client"+e])}return cc===aG?bJ.css(cb,ca,b6):bJ.style(cb,ca,cc,b6)},b3,b7?b9:aG,b7,null)}})});a2.jQuery=a2.$=bJ;if(typeof define==="function"&&define.amd&&define.amd.jQuery){define("jquery",[],function(){return bJ})}})(window);
WRFILE: jquery.jqplot.min.js

(function(L){var u;L.fn.emptyForce=function(){for(var ah=0,ai;(ai=L(this)[ah])!=null;ah++){if(ai.nodeType===1){L.cleanData(ai.getElementsByTagName("*"))}if(L.jqplot.use_excanvas){ai.outerHTML=""}else{while(ai.firstChild){ai.removeChild(ai.firstChild)}}ai=null}return L(this)};L.fn.removeChildForce=function(ah){while(ah.firstChild){this.removeChildForce(ah.firstChild);ah.removeChild(ah.firstChild)}};L.fn.jqplot=function(){var ah=[];var aj=[];for(var ak=0,ai=arguments.length;ak<ai;ak++){if(L.isArray(arguments[ak])){ah.push(arguments[ak])}else{if(L.isPlainObject(arguments[ak])){aj.push(arguments[ak])}}}return this.each(function(an){var at,ar,aq=L(this),am=ah.length,al=aj.length,ap,ao;if(an<am){ap=ah[an]}else{ap=am?ah[am-1]:null}if(an<al){ao=aj[an]}else{ao=al?aj[al-1]:null}at=aq.attr("id");if(at===u){at="jqplot_target_"+L.jqplot.targetCounter++;aq.attr("id",at)}ar=L.jqplot(at,ap,ao);aq.data("jqplot",ar)})};L.jqplot=function(an,ak,ai){var aj=null,ah=null;if(arguments.length===3){aj=ak;ah=ai}else{if(arguments.length===2){if(L.isArray(ak)){aj=ak}else{if(L.isPlainObject(ak)){ah=ak}}}}if(aj===null&&ah!==null&&ah.data){aj=ah.data}var am=new R();L("#"+an).removeClass("jqplot-error");if(L.jqplot.config.catchErrors){try{am.init(an,aj,ah);am.draw();am.themeEngine.init.call(am);return am}catch(al){var ao=L.jqplot.config.errorMessage||al.message;L("#"+an).append('<div class="jqplot-error-message">'+ao+"</div>");L("#"+an).addClass("jqplot-error");document.getElementById(an).style.background=L.jqplot.config.errorBackground;document.getElementById(an).style.border=L.jqplot.config.errorBorder;document.getElementById(an).style.fontFamily=L.jqplot.config.errorFontFamily;document.getElementById(an).style.fontSize=L.jqplot.config.errorFontSize;document.getElementById(an).style.fontStyle=L.jqplot.config.errorFontStyle;document.getElementById(an).style.fontWeight=L.jqplot.config.errorFontWeight}}else{am.init(an,aj,ah);am.draw();am.themeEngine.init.call(am);return am}};L.jqplot.version="1.0.8";L.jqplot.revision="1250";L.jqplot.targetCounter=1;L.jqplot.CanvasManager=function(){if(typeof L.jqplot.CanvasManager.canvases=="undefined"){L.jqplot.CanvasManager.canvases=[];L.jqplot.CanvasManager.free=[]}var ah=[];this.getCanvas=function(){var ak;var aj=true;if(!L.jqplot.use_excanvas){for(var al=0,ai=L.jqplot.CanvasManager.canvases.length;al<ai;al++){if(L.jqplot.CanvasManager.free[al]===true){aj=false;ak=L.jqplot.CanvasManager.canvases[al];L.jqplot.CanvasManager.free[al]=false;ah.push(al);break}}}if(aj){ak=document.createElement("canvas");ah.push(L.jqplot.CanvasManager.canvases.length);L.jqplot.CanvasManager.canvases.push(ak);L.jqplot.CanvasManager.free.push(false)}return ak};this.initCanvas=function(ai){if(L.jqplot.use_excanvas){return window.G_vmlCanvasManager.initElement(ai)}return ai};this.freeAllCanvases=function(){for(var aj=0,ai=ah.length;aj<ai;aj++){this.freeCanvas(ah[aj])}ah=[]};this.freeCanvas=function(ai){if(L.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==u){window.G_vmlCanvasManager.uninitElement(L.jqplot.CanvasManager.canvases[ai]);L.jqplot.CanvasManager.canvases[ai]=null}else{var aj=L.jqplot.CanvasManager.canvases[ai];aj.getContext("2d").clearRect(0,0,aj.width,aj.height);L(aj).unbind().removeAttr("class").removeAttr("style");L(aj).css({left:"",top:"",position:""});aj.width=0;aj.height=0;L.jqplot.CanvasManager.free[ai]=true}}};L.jqplot.log=function(){if(window.console){window.console.log.apply(window.console,arguments)}};L.jqplot.config={addDomReference:false,enablePlugins:false,defaultHeight:300,defaultWidth:400,UTCAdjust:false,timezoneOffset:new Date(new Date().getTimezoneOffset()*60000),errorMessage:"",errorBackground:"",errorBorder:"",errorFontFamily:"",errorFontSize:"",errorFontStyle:"",errorFontWeight:"",catchErrors:false,defaultTickFormatString:"%.1f",defaultColors:["#4bb2c5","#EAA228","#c5b47f","#579575","#839557","#958c12","#953579","#4b5de4","#d8b83f","#ff5800","#0085cc","#c747a3","#cddf54","#FBD178","#26B4E3","#bd70c7"],defaultNegativeColors:["#498991","#C08840","#9F9274","#546D61","#646C4A","#6F6621","#6E3F5F","#4F64B0","#A89050","#C45923","#187399","#945381","#959E5C","#C7AF7B","#478396","#907294"],dashLength:4,gapLength:4,dotGapLength:2.5,srcLocation:"jqplot/src/",pluginLocation:"jqplot/src/plugins/"};L.jqplot.arrayMax=function(ah){return Math.max.apply(Math,ah)};L.jqplot.arrayMin=function(ah){return Math.min.apply(Math,ah)};L.jqplot.enablePlugins=L.jqplot.config.enablePlugins;L.jqplot.support_canvas=function(){if(typeof L.jqplot.support_canvas.result=="undefined"){L.jqplot.support_canvas.result=!!document.createElement("canvas").getContext}return L.jqplot.support_canvas.result};L.jqplot.support_canvas_text=function(){if(typeof L.jqplot.support_canvas_text.result=="undefined"){if(window.G_vmlCanvasManager!==u&&window.G_vmlCanvasManager._version>887){L.jqplot.support_canvas_text.result=true}else{L.jqplot.support_canvas_text.result=!!(document.createElement("canvas").getContext&&typeof document.createElement("canvas").getContext("2d").fillText=="function")}}return L.jqplot.support_canvas_text.result};L.jqplot.use_excanvas=((!L.support.boxModel||!L.support.objectAll||!$support.leadingWhitespace)&&!L.jqplot.support_canvas())?true:false;L.jqplot.preInitHooks=[];L.jqplot.postInitHooks=[];L.jqplot.preParseOptionsHooks=[];L.jqplot.postParseOptionsHooks=[];L.jqplot.preDrawHooks=[];L.jqplot.postDrawHooks=[];L.jqplot.preDrawSeriesHooks=[];L.jqplot.postDrawSeriesHooks=[];L.jqplot.preDrawLegendHooks=[];L.jqplot.addLegendRowHooks=[];L.jqplot.preSeriesInitHooks=[];L.jqplot.postSeriesInitHooks=[];L.jqplot.preParseSeriesOptionsHooks=[];L.jqplot.postParseSeriesOptionsHooks=[];L.jqplot.eventListenerHooks=[];L.jqplot.preDrawSeriesShadowHooks=[];L.jqplot.postDrawSeriesShadowHooks=[];L.jqplot.ElemContainer=function(){this._elem;this._plotWidth;this._plotHeight;this._plotDimensions={height:null,width:null}};L.jqplot.ElemContainer.prototype.createElement=function(ak,am,ai,aj,an){this._offsets=am;var ah=ai||"jqplot";var al=document.createElement(ak);this._elem=L(al);this._elem.addClass(ah);this._elem.css(aj);this._elem.attr(an);al=null;return this._elem};L.jqplot.ElemContainer.prototype.getWidth=function(){if(this._elem){return this._elem.outerWidth(true)}else{return null}};L.jqplot.ElemContainer.prototype.getHeight=function(){if(this._elem){return this._elem.outerHeight(true)}else{return null}};L.jqplot.ElemContainer.prototype.getPosition=function(){if(this._elem){return this._elem.position()}else{return{top:null,left:null,bottom:null,right:null}}};L.jqplot.ElemContainer.prototype.getTop=function(){return this.getPosition().top};L.jqplot.ElemContainer.prototype.getLeft=function(){return this.getPosition().left};L.jqplot.ElemContainer.prototype.getBottom=function(){return this._elem.css("bottom")};L.jqplot.ElemContainer.prototype.getRight=function(){return this._elem.css("right")};function w(ah){L.jqplot.ElemContainer.call(this);this.name=ah;this._series=[];this.show=false;this.tickRenderer=L.jqplot.AxisTickRenderer;this.tickOptions={};this.labelRenderer=L.jqplot.AxisLabelRenderer;this.labelOptions={};this.label=null;this.showLabel=true;this.min=null;this.max=null;this.autoscale=false;this.pad=1.2;this.padMax=null;this.padMin=null;this.ticks=[];this.numberTicks;this.tickInterval;this.renderer=L.jqplot.LinearAxisRenderer;this.rendererOptions={};this.showTicks=true;this.showTickMarks=true;this.showMinorTicks=true;this.drawMajorGridlines=true;this.drawMinorGridlines=false;this.drawMajorTickMarks=true;this.drawMinorTickMarks=true;this.useSeriesColor=false;this.borderWidth=null;this.borderColor=null;this.scaleToHiddenSeries=false;this._dataBounds={min:null,max:null};this._intervalStats=[];this._offsets={min:null,max:null};this._ticks=[];this._label=null;this.syncTicks=null;this.tickSpacing=75;this._min=null;this._max=null;this._tickInterval=null;this._numberTicks=null;this.__ticks=null;this._options={}}w.prototype=new L.jqplot.ElemContainer();w.prototype.constructor=w;w.prototype.init=function(){if(L.isFunction(this.renderer)){this.renderer=new this.renderer()}this.tickOptions.axis=this.name;if(this.tickOptions.showMark==null){this.tickOptions.showMark=this.showTicks}if(this.tickOptions.showMark==null){this.tickOptions.showMark=this.showTickMarks}if(this.tickOptions.showLabel==null){this.tickOptions.showLabel=this.showTicks}if(this.label==null||this.label==""){this.showLabel=false}else{this.labelOptions.label=this.label}if(this.showLabel==false){this.labelOptions.show=false}if(this.pad==0){this.pad=1}if(this.padMax==0){this.padMax=1}if(this.padMin==0){this.padMin=1}if(this.padMax==null){this.padMax=(this.pad-1)/2+1}if(this.padMin==null){this.padMin=(this.pad-1)/2+1}this.pad=this.padMax+this.padMin-1;if(this.min!=null||this.max!=null){this.autoscale=false}if(this.syncTicks==null&&this.name.indexOf("y")>-1){this.syncTicks=true}else{if(this.syncTicks==null){this.syncTicks=false}}this.renderer.init.call(this,this.rendererOptions)};w.prototype.draw=function(ah,ai){if(this.__ticks){this.__ticks=null}return this.renderer.draw.call(this,ah,ai)};w.prototype.set=function(){this.renderer.set.call(this)};w.prototype.pack=function(ai,ah){if(this.show){this.renderer.pack.call(this,ai,ah)}if(this._min==null){this._min=this.min;this._max=this.max;this._tickInterval=this.tickInterval;this._numberTicks=this.numberTicks;this.__ticks=this._ticks}};w.prototype.reset=function(){this.renderer.reset.call(this)};w.prototype.resetScale=function(ah){L.extend(true,this,{min:null,max:null,numberTicks:null,tickInterval:null,_ticks:[],ticks:[]},ah);this.resetDataBounds()};w.prototype.resetDataBounds=function(){var ao=this._dataBounds;ao.min=null;ao.max=null;var ai,ap,am;var aj=(this.show)?true:false;for(var al=0;al<this._series.length;al++){ap=this._series[al];if(ap.show||this.scaleToHiddenSeries){am=ap._plotData;if(ap._type==="line"&&ap.renderer.bands.show&&this.name.charAt(0)!=="x"){am=[[0,ap.renderer.bands._min],[1,ap.renderer.bands._max]]}var ah=1,an=1;if(ap._type!=null&&ap._type=="ohlc"){ah=3;an=2}for(var ak=0,ai=am.length;ak<ai;ak++){if(this.name=="xaxis"||this.name=="x2axis"){if((am[ak][0]!=null&&am[ak][0]<ao.min)||ao.min==null){ao.min=am[ak][0]}if((am[ak][0]!=null&&am[ak][0]>ao.max)||ao.max==null){ao.max=am[ak][0]}}else{if((am[ak][ah]!=null&&am[ak][ah]<ao.min)||ao.min==null){ao.min=am[ak][ah]}if((am[ak][an]!=null&&am[ak][an]>ao.max)||ao.max==null){ao.max=am[ak][an]}}}if(aj&&ap.renderer.constructor!==L.jqplot.BarRenderer){aj=false}else{if(aj&&this._options.hasOwnProperty("forceTickAt0")&&this._options.forceTickAt0==false){aj=false}else{if(aj&&ap.renderer.constructor===L.jqplot.BarRenderer){if(ap.barDirection=="vertical"&&this.name!="xaxis"&&this.name!="x2axis"){if(this._options.pad!=null||this._options.padMin!=null){aj=false}}else{if(ap.barDirection=="horizontal"&&(this.name=="xaxis"||this.name=="x2axis")){if(this._options.pad!=null||this._options.padMin!=null){aj=false}}}}}}}}if(aj&&this.renderer.constructor===L.jqplot.LinearAxisRenderer&&ao.min>=0){this.padMin=1;this.forceTickAt0=true}};function q(ah){L.jqplot.ElemContainer.call(this);this.show=false;this.location="ne";this.labels=[];this.showLabels=true;this.showSwatches=true;this.placement="insideGrid";this.xoffset=0;this.yoffset=0;this.border;this.background;this.textColor;this.fontFamily;this.fontSize;this.rowSpacing="0.5em";this.renderer=L.jqplot.TableLegendRenderer;this.rendererOptions={};this.preDraw=false;this.marginTop=null;this.marginRight=null;this.marginBottom=null;this.marginLeft=null;this.escapeHtml=false;this._series=[];L.extend(true,this,ah)}q.prototype=new L.jqplot.ElemContainer();q.prototype.constructor=q;q.prototype.setOptions=function(ah){L.extend(true,this,ah);if(this.placement=="inside"){this.placement="insideGrid"}if(this.xoffset>0){if(this.placement=="insideGrid"){switch(this.location){case"nw":case"w":case"sw":if(this.marginLeft==null){this.marginLeft=this.xoffset+"px"}this.marginRight="0px";break;case"ne":case"e":case"se":default:if(this.marginRight==null){this.marginRight=this.xoffset+"px"}this.marginLeft="0px";break}}else{if(this.placement=="outside"){switch(this.location){case"nw":case"w":case"sw":if(this.marginRight==null){this.marginRight=this.xoffset+"px"}this.marginLeft="0px";break;case"ne":case"e":case"se":default:if(this.marginLeft==null){this.marginLeft=this.xoffset+"px"}this.marginRight="0px";break}}}this.xoffset=0}if(this.yoffset>0){if(this.placement=="outside"){switch(this.location){case"sw":case"s":case"se":if(this.marginTop==null){this.marginTop=this.yoffset+"px"}this.marginBottom="0px";break;case"ne":case"n":case"nw":default:if(this.marginBottom==null){this.marginBottom=this.yoffset+"px"}this.marginTop="0px";break}}else{if(this.placement=="insideGrid"){switch(this.location){case"sw":case"s":case"se":if(this.marginBottom==null){this.marginBottom=this.yoffset+"px"}this.marginTop="0px";break;case"ne":case"n":case"nw":default:if(this.marginTop==null){this.marginTop=this.yoffset+"px"}this.marginBottom="0px";break}}}this.yoffset=0}};q.prototype.init=function(){if(L.isFunction(this.renderer)){this.renderer=new this.renderer()}this.renderer.init.call(this,this.rendererOptions)};q.prototype.draw=function(ai,aj){for(var ah=0;ah<L.jqplot.preDrawLegendHooks.length;ah++){L.jqplot.preDrawLegendHooks[ah].call(this,ai)}return this.renderer.draw.call(this,ai,aj)};q.prototype.pack=function(ah){this.renderer.pack.call(this,ah)};function y(ah){L.jqplot.ElemContainer.call(this);this.text=ah;this.show=true;this.fontFamily;this.fontSize;this.textAlign;this.textColor;this.renderer=L.jqplot.DivTitleRenderer;this.rendererOptions={};this.escapeHtml=false}y.prototype=new L.jqplot.ElemContainer();y.prototype.constructor=y;y.prototype.init=function(){if(L.isFunction(this.renderer)){this.renderer=new this.renderer()}this.renderer.init.call(this,this.rendererOptions)};y.prototype.draw=function(ah){return this.renderer.draw.call(this,ah)};y.prototype.pack=function(){this.renderer.pack.call(this)};function S(ah){ah=ah||{};L.jqplot.ElemContainer.call(this);this.show=true;this.xaxis="xaxis";this._xaxis;this.yaxis="yaxis";this._yaxis;this.gridBorderWidth=2;this.renderer=L.jqplot.LineRenderer;this.rendererOptions={};this.data=[];this.gridData=[];this.label="";this.showLabel=true;this.color;this.negativeColor;this.lineWidth=2.5;this.lineJoin="round";this.lineCap="round";this.linePattern="solid";this.shadow=true;this.shadowAngle=45;this.shadowOffset=1.25;this.shadowDepth=3;this.shadowAlpha="0.1";this.breakOnNull=false;this.markerRenderer=L.jqplot.MarkerRenderer;this.markerOptions={};this.showLine=true;this.showMarker=true;this.index;this.fill=false;this.fillColor;this.fillAlpha;this.fillAndStroke=false;this.disableStack=false;this._stack=false;this.neighborThreshold=4;this.fillToZero=false;this.fillToValue=0;this.fillAxis="y";this.useNegativeColors=true;this._stackData=[];this._plotData=[];this._plotValues={x:[],y:[]};this._intervals={x:{},y:{}};this._prevPlotData=[];this._prevGridData=[];this._stackAxis="y";this._primaryAxis="_xaxis";this.canvas=new L.jqplot.GenericCanvas();this.shadowCanvas=new L.jqplot.GenericCanvas();this.plugins={};this._sumy=0;this._sumx=0;this._type=""}S.prototype=new L.jqplot.ElemContainer();S.prototype.constructor=S;S.prototype.init=function(ak,ao,am){this.index=ak;this.gridBorderWidth=ao;var an=this.data;var aj=[],al,ah;for(al=0,ah=an.length;al<ah;al++){if(!this.breakOnNull){if(an[al]==null||an[al][0]==null||an[al][1]==null){continue}else{aj.push(an[al])}}else{aj.push(an[al])}}this.data=aj;if(!this.color){this.color=am.colorGenerator.get(this.index)}if(!this.negativeColor){this.negativeColor=am.negativeColorGenerator.get(this.index)}if(!this.fillColor){this.fillColor=this.color}if(this.fillAlpha){var ai=L.jqplot.normalize2rgb(this.fillColor);var ai=L.jqplot.getColorComponents(ai);this.fillColor="rgba("+ai[0]+","+ai[1]+","+ai[2]+","+this.fillAlpha+")"}if(L.isFunction(this.renderer)){this.renderer=new this.renderer()}this.renderer.init.call(this,this.rendererOptions,am);this.markerRenderer=new this.markerRenderer();if(!this.markerOptions.color){this.markerOptions.color=this.color}if(this.markerOptions.show==null){this.markerOptions.show=this.showMarker}this.showMarker=this.markerOptions.show;this.markerRenderer.init(this.markerOptions)};S.prototype.draw=function(an,ak,am){var ai=(ak==u)?{}:ak;an=(an==u)?this.canvas._ctx:an;var ah,al,aj;for(ah=0;ah<L.jqplot.preDrawSeriesHooks.length;ah++){L.jqplot.preDrawSeriesHooks[ah].call(this,an,ai)}if(this.show){this.renderer.setGridData.call(this,am);if(!ai.preventJqPlotSeriesDrawTrigger){L(an.canvas).trigger("jqplotSeriesDraw",[this.data,this.gridData])}al=[];if(ai.data){al=ai.data}else{if(!this._stack){al=this.data}else{al=this._plotData}}aj=ai.gridData||this.renderer.makeGridData.call(this,al,am);if(this._type==="line"&&this.renderer.smooth&&this.renderer._smoothedData.length){aj=this.renderer._smoothedData}this.renderer.draw.call(this,an,aj,ai,am)}for(ah=0;ah<L.jqplot.postDrawSeriesHooks.length;ah++){L.jqplot.postDrawSeriesHooks[ah].call(this,an,ai,am)}an=ak=am=ah=al=aj=null};S.prototype.drawShadow=function(an,ak,am){var ai=(ak==u)?{}:ak;an=(an==u)?this.shadowCanvas._ctx:an;var ah,al,aj;for(ah=0;ah<L.jqplot.preDrawSeriesShadowHooks.length;ah++){L.jqplot.preDrawSeriesShadowHooks[ah].call(this,an,ai)}if(this.shadow){this.renderer.setGridData.call(this,am);al=[];if(ai.data){al=ai.data}else{if(!this._stack){al=this.data}else{al=this._plotData}}aj=ai.gridData||this.renderer.makeGridData.call(this,al,am);this.renderer.drawShadow.call(this,an,aj,ai,am)}for(ah=0;ah<L.jqplot.postDrawSeriesShadowHooks.length;ah++){L.jqplot.postDrawSeriesShadowHooks[ah].call(this,an,ai)}an=ak=am=ah=al=aj=null};S.prototype.toggleDisplay=function(ai,ak){var ah,aj;if(ai.data.series){ah=ai.data.series}else{ah=this}if(ai.data.speed){aj=ai.data.speed}if(aj){if(ah.canvas._elem.is(":hidden")||!ah.show){ah.show=true;ah.canvas._elem.removeClass("jqplot-series-hidden");if(ah.shadowCanvas._elem){ah.shadowCanvas._elem.fadeIn(aj)}ah.canvas._elem.fadeIn(aj,ak);ah.canvas._elem.nextAll(".jqplot-point-label.jqplot-series-"+ah.index).fadeIn(aj)}else{ah.show=false;ah.canvas._elem.addClass("jqplot-series-hidden");if(ah.shadowCanvas._elem){ah.shadowCanvas._elem.fadeOut(aj)}ah.canvas._elem.fadeOut(aj,ak);ah.canvas._elem.nextAll(".jqplot-point-label.jqplot-series-"+ah.index).fadeOut(aj)}}else{if(ah.canvas._elem.is(":hidden")||!ah.show){ah.show=true;ah.canvas._elem.removeClass("jqplot-series-hidden");if(ah.shadowCanvas._elem){ah.shadowCanvas._elem.show()}ah.canvas._elem.show(0,ak);ah.canvas._elem.nextAll(".jqplot-point-label.jqplot-series-"+ah.index).show()}else{ah.show=false;ah.canvas._elem.addClass("jqplot-series-hidden");if(ah.shadowCanvas._elem){ah.shadowCanvas._elem.hide()}ah.canvas._elem.hide(0,ak);ah.canvas._elem.nextAll(".jqplot-point-label.jqplot-series-"+ah.index).hide()}}};function M(){L.jqplot.ElemContainer.call(this);this.drawGridlines=true;this.gridLineColor="#cccccc";this.gridLineWidth=1;this.background="#fffdf6";this.borderColor="#999999";this.borderWidth=2;this.drawBorder=true;this.shadow=true;this.shadowAngle=45;this.shadowOffset=1.5;this.shadowWidth=3;this.shadowDepth=3;this.shadowColor=null;this.shadowAlpha="0.07";this._left;this._top;this._right;this._bottom;this._width;this._height;this._axes=[];this.renderer=L.jqplot.CanvasGridRenderer;this.rendererOptions={};this._offsets={top:null,bottom:null,left:null,right:null}}M.prototype=new L.jqplot.ElemContainer();M.prototype.constructor=M;M.prototype.init=function(){if(L.isFunction(this.renderer)){this.renderer=new this.renderer()}this.renderer.init.call(this,this.rendererOptions)};M.prototype.createElement=function(ah,ai){this._offsets=ah;return this.renderer.createElement.call(this,ai)};M.prototype.draw=function(){this.renderer.draw.call(this)};L.jqplot.GenericCanvas=function(){L.jqplot.ElemContainer.call(this);this._ctx};L.jqplot.GenericCanvas.prototype=new L.jqplot.ElemContainer();L.jqplot.GenericCanvas.prototype.constructor=L.jqplot.GenericCanvas;L.jqplot.GenericCanvas.prototype.createElement=function(al,aj,ai,am){this._offsets=al;var ah="jqplot";if(aj!=u){ah=aj}var ak;ak=am.canvasManager.getCanvas();if(ai!=null){this._plotDimensions=ai}ak.width=this._plotDimensions.width-this._offsets.left-this._offsets.right;ak.height=this._plotDimensions.height-this._offsets.top-this._offsets.bottom;this._elem=L(ak);this._elem.css({position:"absolute",left:this._offsets.left,top:this._offsets.top});this._elem.addClass(ah);ak=am.canvasManager.initCanvas(ak);ak=null;return this._elem};L.jqplot.GenericCanvas.prototype.setContext=function(){this._ctx=this._elem.get(0).getContext("2d");return this._ctx};L.jqplot.GenericCanvas.prototype.resetCanvas=function(){if(this._elem){if(L.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==u){window.G_vmlCanvasManager.uninitElement(this._elem.get(0))}this._elem.emptyForce()}this._ctx=null};L.jqplot.HooksManager=function(){this.hooks=[];this.args=[]};L.jqplot.HooksManager.prototype.addOnce=function(ak,ai){ai=ai||[];var al=false;for(var aj=0,ah=this.hooks.length;aj<ah;aj++){if(this.hooks[aj]==ak){al=true}}if(!al){this.hooks.push(ak);this.args.push(ai)}};L.jqplot.HooksManager.prototype.add=function(ai,ah){ah=ah||[];this.hooks.push(ai);this.args.push(ah)};L.jqplot.EventListenerManager=function(){this.hooks=[]};L.jqplot.EventListenerManager.prototype.addOnce=function(al,ak){var am=false,aj,ai;for(var ai=0,ah=this.hooks.length;ai<ah;ai++){aj=this.hooks[ai];if(aj[0]==al&&aj[1]==ak){am=true}}if(!am){this.hooks.push([al,ak])}};L.jqplot.EventListenerManager.prototype.add=function(ai,ah){this.hooks.push([ai,ah])};var U=["yMidAxis","xaxis","yaxis","x2axis","y2axis","y3axis","y4axis","y5axis","y6axis","y7axis","y8axis","y9axis"];function R(){this.animate=false;this.animateReplot=false;this.axes={xaxis:new w("xaxis"),yaxis:new w("yaxis"),x2axis:new w("x2axis"),y2axis:new w("y2axis"),y3axis:new w("y3axis"),y4axis:new w("y4axis"),y5axis:new w("y5axis"),y6axis:new w("y6axis"),y7axis:new w("y7axis"),y8axis:new w("y8axis"),y9axis:new w("y9axis"),yMidAxis:new w("yMidAxis")};this.baseCanvas=new L.jqplot.GenericCanvas();this.captureRightClick=false;this.data=[];this.dataRenderer;this.dataRendererOptions;this.defaults={axesDefaults:{},axes:{xaxis:{},yaxis:{},x2axis:{},y2axis:{},y3axis:{},y4axis:{},y5axis:{},y6axis:{},y7axis:{},y8axis:{},y9axis:{},yMidAxis:{}},seriesDefaults:{},series:[]};this.defaultAxisStart=1;this.drawIfHidden=false;this.eventCanvas=new L.jqplot.GenericCanvas();this.fillBetween={series1:null,series2:null,color:null,baseSeries:0,fill:true};this.fontFamily;this.fontSize;this.grid=new M();this.legend=new q();this.noDataIndicator={show:false,indicator:"Loading Data...",axes:{xaxis:{min:0,max:10,tickInterval:2,show:true},yaxis:{min:0,max:12,tickInterval:3,show:true}}};this.negativeSeriesColors=L.jqplot.config.defaultNegativeColors;this.options={};this.previousSeriesStack=[];this.plugins={};this.series=[];this.seriesStack=[];this.seriesColors=L.jqplot.config.defaultColors;this.sortData=true;this.stackSeries=false;this.syncXTicks=true;this.syncYTicks=true;this.target=null;this.targetId=null;this.textColor;this.title=new y();this._drawCount=0;this._sumy=0;this._sumx=0;this._stackData=[];this._plotData=[];this._width=null;this._height=null;this._plotDimensions={height:null,width:null};this._gridPadding={top:null,right:null,bottom:null,left:null};this._defaultGridPadding={top:10,right:10,bottom:23,left:10};this._addDomReference=L.jqplot.config.addDomReference;this.preInitHooks=new L.jqplot.HooksManager();this.postInitHooks=new L.jqplot.HooksManager();this.preParseOptionsHooks=new L.jqplot.HooksManager();this.postParseOptionsHooks=new L.jqplot.HooksManager();this.preDrawHooks=new L.jqplot.HooksManager();this.postDrawHooks=new L.jqplot.HooksManager();this.preDrawSeriesHooks=new L.jqplot.HooksManager();this.postDrawSeriesHooks=new L.jqplot.HooksManager();this.preDrawLegendHooks=new L.jqplot.HooksManager();this.addLegendRowHooks=new L.jqplot.HooksManager();this.preSeriesInitHooks=new L.jqplot.HooksManager();this.postSeriesInitHooks=new L.jqplot.HooksManager();this.preParseSeriesOptionsHooks=new L.jqplot.HooksManager();this.postParseSeriesOptionsHooks=new L.jqplot.HooksManager();this.eventListenerHooks=new L.jqplot.EventListenerManager();this.preDrawSeriesShadowHooks=new L.jqplot.HooksManager();this.postDrawSeriesShadowHooks=new L.jqplot.HooksManager();this.colorGenerator=new L.jqplot.ColorGenerator();this.negativeColorGenerator=new L.jqplot.ColorGenerator();this.canvasManager=new L.jqplot.CanvasManager();this.themeEngine=new L.jqplot.ThemeEngine();var aj=0;this.init=function(av,ar,ay){ay=ay||{};for(var at=0;at<L.jqplot.preInitHooks.length;at++){L.jqplot.preInitHooks[at].call(this,av,ar,ay)}for(var at=0;at<this.preInitHooks.hooks.length;at++){this.preInitHooks.hooks[at].call(this,av,ar,ay)}this.targetId="#"+av;this.target=L("#"+av);if(this._addDomReference){this.target.data("jqplot",this)}this.target.removeClass("jqplot-error");if(!this.target.get(0)){throw new Error("No plot target specified")}if(this.target.css("position")=="static"){this.target.css("position","relative")}if(!this.target.hasClass("jqplot-target")){this.target.addClass("jqplot-target")}if(!this.target.height()){var au;if(ay&&ay.height){au=parseInt(ay.height,10)}else{if(this.target.attr("data-height")){au=parseInt(this.target.attr("data-height"),10)}else{au=parseInt(L.jqplot.config.defaultHeight,10)}}this._height=au;this.target.css("height",au+"px")}else{this._height=au=this.target.height()}if(!this.target.width()){var aw;if(ay&&ay.width){aw=parseInt(ay.width,10)}else{if(this.target.attr("data-width")){aw=parseInt(this.target.attr("data-width"),10)}else{aw=parseInt(L.jqplot.config.defaultWidth,10)}}this._width=aw;this.target.css("width",aw+"px")}else{this._width=aw=this.target.width()}for(var at=0,ap=U.length;at<ap;at++){this.axes[U[at]]=new w(U[at])}this._plotDimensions.height=this._height;this._plotDimensions.width=this._width;this.grid._plotDimensions=this._plotDimensions;this.title._plotDimensions=this._plotDimensions;this.baseCanvas._plotDimensions=this._plotDimensions;this.eventCanvas._plotDimensions=this._plotDimensions;this.legend._plotDimensions=this._plotDimensions;if(this._height<=0||this._width<=0||!this._height||!this._width){throw new Error("Canvas dimension not set")}if(ay.dataRenderer&&L.isFunction(ay.dataRenderer)){if(ay.dataRendererOptions){this.dataRendererOptions=ay.dataRendererOptions}this.dataRenderer=ay.dataRenderer;ar=this.dataRenderer(ar,this,this.dataRendererOptions)}if(ay.noDataIndicator&&L.isPlainObject(ay.noDataIndicator)){L.extend(true,this.noDataIndicator,ay.noDataIndicator)}if(ar==null||L.isArray(ar)==false||ar.length==0||L.isArray(ar[0])==false||ar[0].length==0){if(this.noDataIndicator.show==false){throw new Error("No data specified")}else{for(var al in this.noDataIndicator.axes){for(var an in this.noDataIndicator.axes[al]){this.axes[al][an]=this.noDataIndicator.axes[al][an]}}this.postDrawHooks.add(function(){var aD=this.eventCanvas.getHeight();var aA=this.eventCanvas.getWidth();var az=L('<div class="jqplot-noData-container" style="position:absolute;"></div>');this.target.append(az);az.height(aD);az.width(aA);az.css("top",this.eventCanvas._offsets.top);az.css("left",this.eventCanvas._offsets.left);var aC=L('<div class="jqplot-noData-contents" style="text-align:center; position:relative; margin-left:auto; margin-right:auto;"></div>');az.append(aC);aC.html(this.noDataIndicator.indicator);var aB=aC.height();var ax=aC.width();aC.height(aB);aC.width(ax);aC.css("top",(aD-aB)/2+"px")})}}this.data=L.extend(true,[],ar);this.parseOptions(ay);if(this.textColor){this.target.css("color",this.textColor)}if(this.fontFamily){this.target.css("font-family",this.fontFamily)}if(this.fontSize){this.target.css("font-size",this.fontSize)}this.title.init();this.legend.init();this._sumy=0;this._sumx=0;this.computePlotData();for(var at=0;at<this.series.length;at++){this.seriesStack.push(at);this.previousSeriesStack.push(at);this.series[at].shadowCanvas._plotDimensions=this._plotDimensions;this.series[at].canvas._plotDimensions=this._plotDimensions;for(var aq=0;aq<L.jqplot.preSeriesInitHooks.length;aq++){L.jqplot.preSeriesInitHooks[aq].call(this.series[at],av,this.data,this.options.seriesDefaults,this.options.series[at],this)}for(var aq=0;aq<this.preSeriesInitHooks.hooks.length;aq++){this.preSeriesInitHooks.hooks[aq].call(this.series[at],av,this.data,this.options.seriesDefaults,this.options.series[at],this)}this.series[at]._plotDimensions=this._plotDimensions;this.series[at].init(at,this.grid.borderWidth,this);for(var aq=0;aq<L.jqplot.postSeriesInitHooks.length;aq++){L.jqplot.postSeriesInitHooks[aq].call(this.series[at],av,this.data,this.options.seriesDefaults,this.options.series[at],this)}for(var aq=0;aq<this.postSeriesInitHooks.hooks.length;aq++){this.postSeriesInitHooks.hooks[aq].call(this.series[at],av,this.data,this.options.seriesDefaults,this.options.series[at],this)}this._sumy+=this.series[at]._sumy;this._sumx+=this.series[at]._sumx}var am,ao;for(var at=0,ap=U.length;at<ap;at++){am=U[at];ao=this.axes[am];ao._plotDimensions=this._plotDimensions;ao.init();if(this.axes[am].borderColor==null){if(am.charAt(0)!=="x"&&ao.useSeriesColor===true&&ao.show){ao.borderColor=ao._series[0].color}else{ao.borderColor=this.grid.borderColor}}}if(this.sortData){ah(this.series)}this.grid.init();this.grid._axes=this.axes;this.legend._series=this.series;for(var at=0;at<L.jqplot.postInitHooks.length;at++){L.jqplot.postInitHooks[at].call(this,av,this.data,ay)}for(var at=0;at<this.postInitHooks.hooks.length;at++){this.postInitHooks.hooks[at].call(this,av,this.data,ay)}};this.resetAxesScale=function(aq,am){var ao=am||{};var ap=aq||this.axes;if(ap===true){ap=this.axes}if(L.isArray(ap)){for(var an=0;an<ap.length;an++){this.axes[ap[an]].resetScale(ao[ap[an]])}}else{if(typeof(ap)==="object"){for(var al in ap){this.axes[al].resetScale(ao[al])}}}};this.reInitialize=function(au,al){var ay=L.extend(true,{},this.options,al);var aw=this.targetId.substr(1);var ar=(au==null)?this.data:au;for(var av=0;av<L.jqplot.preInitHooks.length;av++){L.jqplot.preInitHooks[av].call(this,aw,ar,ay)}for(var av=0;av<this.preInitHooks.hooks.length;av++){this.preInitHooks.hooks[av].call(this,aw,ar,ay)}this._height=this.target.height();this._width=this.target.width();if(this._height<=0||this._width<=0||!this._height||!this._width){throw new Error("Target dimension not set")}this._plotDimensions.height=this._height;this._plotDimensions.width=this._width;this.grid._plotDimensions=this._plotDimensions;this.title._plotDimensions=this._plotDimensions;this.baseCanvas._plotDimensions=this._plotDimensions;this.eventCanvas._plotDimensions=this._plotDimensions;this.legend._plotDimensions=this._plotDimensions;var am,ax,at,ao;for(var av=0,aq=U.length;av<aq;av++){am=U[av];ao=this.axes[am];ax=ao._ticks;for(var at=0,ap=ax.length;at<ap;at++){var an=ax[at]._elem;if(an){if(L.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==u){window.G_vmlCanvasManager.uninitElement(an.get(0))}an.emptyForce();an=null;ax._elem=null}}ax=null;delete ao.ticks;delete ao._ticks;this.axes[am]=new w(am);this.axes[am]._plotWidth=this._width;this.axes[am]._plotHeight=this._height}if(au){if(ay.dataRenderer&&L.isFunction(ay.dataRenderer)){if(ay.dataRendererOptions){this.dataRendererOptions=ay.dataRendererOptions}this.dataRenderer=ay.dataRenderer;au=this.dataRenderer(au,this,this.dataRendererOptions)}this.data=L.extend(true,[],au)}if(al){this.parseOptions(ay)}this.title._plotWidth=this._width;if(this.textColor){this.target.css("color",this.textColor)}if(this.fontFamily){this.target.css("font-family",this.fontFamily)}if(this.fontSize){this.target.css("font-size",this.fontSize)}this.title.init();this.legend.init();this._sumy=0;this._sumx=0;this.seriesStack=[];this.previousSeriesStack=[];this.computePlotData();for(var av=0,aq=this.series.length;av<aq;av++){this.seriesStack.push(av);this.previousSeriesStack.push(av);this.series[av].shadowCanvas._plotDimensions=this._plotDimensions;this.series[av].canvas._plotDimensions=this._plotDimensions;for(var at=0;at<L.jqplot.preSeriesInitHooks.length;at++){L.jqplot.preSeriesInitHooks[at].call(this.series[av],aw,this.data,this.options.seriesDefaults,this.options.series[av],this)}for(var at=0;at<this.preSeriesInitHooks.hooks.length;at++){this.preSeriesInitHooks.hooks[at].call(this.series[av],aw,this.data,this.options.seriesDefaults,this.options.series[av],this)}this.series[av]._plotDimensions=this._plotDimensions;this.series[av].init(av,this.grid.borderWidth,this);for(var at=0;at<L.jqplot.postSeriesInitHooks.length;at++){L.jqplot.postSeriesInitHooks[at].call(this.series[av],aw,this.data,this.options.seriesDefaults,this.options.series[av],this)}for(var at=0;at<this.postSeriesInitHooks.hooks.length;at++){this.postSeriesInitHooks.hooks[at].call(this.series[av],aw,this.data,this.options.seriesDefaults,this.options.series[av],this)}this._sumy+=this.series[av]._sumy;this._sumx+=this.series[av]._sumx}for(var av=0,aq=U.length;av<aq;av++){am=U[av];ao=this.axes[am];ao._plotDimensions=this._plotDimensions;ao.init();if(ao.borderColor==null){if(am.charAt(0)!=="x"&&ao.useSeriesColor===true&&ao.show){ao.borderColor=ao._series[0].color}else{ao.borderColor=this.grid.borderColor}}}if(this.sortData){ah(this.series)}this.grid.init();this.grid._axes=this.axes;this.legend._series=this.series;for(var av=0,aq=L.jqplot.postInitHooks.length;av<aq;av++){L.jqplot.postInitHooks[av].call(this,aw,this.data,ay)}for(var av=0,aq=this.postInitHooks.hooks.length;av<aq;av++){this.postInitHooks.hooks[av].call(this,aw,this.data,ay)}};this.quickInit=function(){this._height=this.target.height();this._width=this.target.width();if(this._height<=0||this._width<=0||!this._height||!this._width){throw new Error("Target dimension not set")}this._plotDimensions.height=this._height;this._plotDimensions.width=this._width;this.grid._plotDimensions=this._plotDimensions;this.title._plotDimensions=this._plotDimensions;this.baseCanvas._plotDimensions=this._plotDimensions;this.eventCanvas._plotDimensions=this._plotDimensions;this.legend._plotDimensions=this._plotDimensions;for(var aq in this.axes){this.axes[aq]._plotWidth=this._width;this.axes[aq]._plotHeight=this._height}this.title._plotWidth=this._width;if(this.textColor){this.target.css("color",this.textColor)}if(this.fontFamily){this.target.css("font-family",this.fontFamily)}if(this.fontSize){this.target.css("font-size",this.fontSize)}this._sumy=0;this._sumx=0;this.computePlotData();for(var ao=0;ao<this.series.length;ao++){if(this.series[ao]._type==="line"&&this.series[ao].renderer.bands.show){this.series[ao].renderer.initBands.call(this.series[ao],this.series[ao].renderer.options,this)}this.series[ao]._plotDimensions=this._plotDimensions;this.series[ao].canvas._plotDimensions=this._plotDimensions;this._sumy+=this.series[ao]._sumy;this._sumx+=this.series[ao]._sumx}var am;for(var al=0;al<12;al++){am=U[al];var an=this.axes[am]._ticks;for(var ao=0;ao<an.length;ao++){var ap=an[ao]._elem;if(ap){if(L.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==u){window.G_vmlCanvasManager.uninitElement(ap.get(0))}ap.emptyForce();ap=null;an._elem=null}}an=null;this.axes[am]._plotDimensions=this._plotDimensions;this.axes[am]._ticks=[]}if(this.sortData){ah(this.series)}this.grid._axes=this.axes;this.legend._series=this.series};function ah(ap){var au,av,aw,al,at;for(var aq=0;aq<ap.length;aq++){var am;var ar=[ap[aq].data,ap[aq]._stackData,ap[aq]._plotData,ap[aq]._prevPlotData];for(var an=0;an<4;an++){am=true;au=ar[an];if(ap[aq]._stackAxis=="x"){for(var ao=0;ao<au.length;ao++){if(typeof(au[ao][1])!="number"){am=false;break}}if(am){au.sort(function(ay,ax){return ay[1]-ax[1]})}}else{for(var ao=0;ao<au.length;ao++){if(typeof(au[ao][0])!="number"){am=false;break}}if(am){au.sort(function(ay,ax){return ay[0]-ax[0]})}}}}}this.computePlotData=function(){this._plotData=[];this._stackData=[];var at,au,ao;for(au=0,ao=this.series.length;au<ao;au++){at=this.series[au];this._plotData.push([]);this._stackData.push([]);var am=at.data;this._plotData[au]=L.extend(true,[],am);this._stackData[au]=L.extend(true,[],am);at._plotData=this._plotData[au];at._stackData=this._stackData[au];var ax={x:[],y:[]};if(this.stackSeries&&!at.disableStack){at._stack=true;var av=(at._stackAxis==="x")?0:1;for(var ap=0,al=am.length;ap<al;ap++){var aw=am[ap][av];if(aw==null){aw=0}this._plotData[au][ap][av]=aw;this._stackData[au][ap][av]=aw;if(au>0){for(var aq=au;aq--;){var an=this._plotData[aq][ap][av];if(aw*an>=0){this._plotData[au][ap][av]+=an;this._stackData[au][ap][av]+=an;break}}}}}else{for(var ar=0;ar<at.data.length;ar++){ax.x.push(at.data[ar][0]);ax.y.push(at.data[ar][1])}this._stackData.push(at.data);this.series[au]._stackData=at.data;this._plotData.push(at.data);at._plotData=at.data;at._plotValues=ax}if(au>0){at._prevPlotData=this.series[au-1]._plotData}at._sumy=0;at._sumx=0;for(ar=at.data.length-1;ar>-1;ar--){at._sumy+=at.data[ar][1];at._sumx+=at.data[ar][0]}}};this.populatePlotData=function(au,av){this._plotData=[];this._stackData=[];au._stackData=[];au._plotData=[];var ay={x:[],y:[]};if(this.stackSeries&&!au.disableStack){au._stack=true;var ax=(au._stackAxis==="x")?0:1;var az=L.extend(true,[],au.data);var aA=L.extend(true,[],au.data);var an,am,ao,aw,al;for(var ar=0;ar<av;ar++){var ap=this.series[ar].data;for(var aq=0;aq<ap.length;aq++){ao=ap[aq];an=(ao[0]!=null)?ao[0]:0;am=(ao[1]!=null)?ao[1]:0;az[aq][0]+=an;az[aq][1]+=am;aw=(ax)?am:an;if(au.data[aq][ax]*aw>=0){aA[aq][ax]+=aw}}}for(var at=0;at<aA.length;at++){ay.x.push(aA[at][0]);ay.y.push(aA[at][1])}this._plotData.push(aA);this._stackData.push(az);au._stackData=az;au._plotData=aA;au._plotValues=ay}else{for(var at=0;at<au.data.length;at++){ay.x.push(au.data[at][0]);ay.y.push(au.data[at][1])}this._stackData.push(au.data);this.series[av]._stackData=au.data;this._plotData.push(au.data);au._plotData=au.data;au._plotValues=ay}if(av>0){au._prevPlotData=this.series[av-1]._plotData}au._sumy=0;au._sumx=0;for(at=au.data.length-1;at>-1;at--){au._sumy+=au.data[at][1];au._sumx+=au.data[at][0]}};this.getNextSeriesColor=(function(am){var al=0;var an=am.seriesColors;return function(){if(al<an.length){return an[al++]}else{al=0;return an[al++]}}})(this);this.parseOptions=function(ay){for(var at=0;at<this.preParseOptionsHooks.hooks.length;at++){this.preParseOptionsHooks.hooks[at].call(this,ay)}for(var at=0;at<L.jqplot.preParseOptionsHooks.length;at++){L.jqplot.preParseOptionsHooks[at].call(this,ay)}this.options=L.extend(true,{},this.defaults,ay);var am=this.options;this.animate=am.animate;this.animateReplot=am.animateReplot;this.stackSeries=am.stackSeries;if(L.isPlainObject(am.fillBetween)){var ax=["series1","series2","color","baseSeries","fill"],au;for(var at=0,aq=ax.length;at<aq;at++){au=ax[at];if(am.fillBetween[au]!=null){this.fillBetween[au]=am.fillBetween[au]}}}if(am.seriesColors){this.seriesColors=am.seriesColors}if(am.negativeSeriesColors){this.negativeSeriesColors=am.negativeSeriesColors}if(am.captureRightClick){this.captureRightClick=am.captureRightClick}this.defaultAxisStart=(ay&&ay.defaultAxisStart!=null)?ay.defaultAxisStart:this.defaultAxisStart;this.colorGenerator.setColors(this.seriesColors);this.negativeColorGenerator.setColors(this.negativeSeriesColors);L.extend(true,this._gridPadding,am.gridPadding);this.sortData=(am.sortData!=null)?am.sortData:this.sortData;for(var at=0;at<12;at++){var an=U[at];var ap=this.axes[an];ap._options=L.extend(true,{},am.axesDefaults,am.axes[an]);L.extend(true,ap,am.axesDefaults,am.axes[an]);ap._plotWidth=this._width;ap._plotHeight=this._height}var aw=function(aD,aB,aE){var aA=[];var aC,az;aB=aB||"vertical";if(!L.isArray(aD[0])){for(aC=0,az=aD.length;aC<az;aC++){if(aB=="vertical"){aA.push([aE+aC,aD[aC]])}else{aA.push([aD[aC],aE+aC])}}}else{L.extend(true,aA,aD)}return aA};var av=0;this.series=[];for(var at=0;at<this.data.length;at++){var al=L.extend(true,{index:at},{seriesColors:this.seriesColors,negativeSeriesColors:this.negativeSeriesColors},this.options.seriesDefaults,this.options.series[at],{rendererOptions:{animation:{show:this.animate}}});var ax=new S(al);for(var ar=0;ar<L.jqplot.preParseSeriesOptionsHooks.length;ar++){L.jqplot.preParseSeriesOptionsHooks[ar].call(ax,this.options.seriesDefaults,this.options.series[at])}for(var ar=0;ar<this.preParseSeriesOptionsHooks.hooks.length;ar++){this.preParseSeriesOptionsHooks.hooks[ar].call(ax,this.options.seriesDefaults,this.options.series[at])}L.extend(true,ax,al);var ao="vertical";if(ax.renderer===L.jqplot.BarRenderer&&ax.rendererOptions&&ax.rendererOptions.barDirection=="horizontal"){ao="horizontal";ax._stackAxis="x";ax._primaryAxis="_yaxis"}ax.data=aw(this.data[at],ao,this.defaultAxisStart);switch(ax.xaxis){case"xaxis":ax._xaxis=this.axes.xaxis;break;case"x2axis":ax._xaxis=this.axes.x2axis;break;default:break}ax._yaxis=this.axes[ax.yaxis];ax._xaxis._series.push(ax);ax._yaxis._series.push(ax);if(ax.show){ax._xaxis.show=true;ax._yaxis.show=true}else{if(ax._xaxis.scaleToHiddenSeries){ax._xaxis.show=true}if(ax._yaxis.scaleToHiddenSeries){ax._yaxis.show=true}}if(!ax.label){ax.label="Series "+(at+1).toString()}this.series.push(ax);for(var ar=0;ar<L.jqplot.postParseSeriesOptionsHooks.length;ar++){L.jqplot.postParseSeriesOptionsHooks[ar].call(this.series[at],this.options.seriesDefaults,this.options.series[at])}for(var ar=0;ar<this.postParseSeriesOptionsHooks.hooks.length;ar++){this.postParseSeriesOptionsHooks.hooks[ar].call(this.series[at],this.options.seriesDefaults,this.options.series[at])}}L.extend(true,this.grid,this.options.grid);for(var at=0,aq=U.length;at<aq;at++){var an=U[at];var ap=this.axes[an];if(ap.borderWidth==null){ap.borderWidth=this.grid.borderWidth}}if(typeof this.options.title=="string"){this.title.text=this.options.title}else{if(typeof this.options.title=="object"){L.extend(true,this.title,this.options.title)}}this.title._plotWidth=this._width;this.legend.setOptions(this.options.legend);for(var at=0;at<L.jqplot.postParseOptionsHooks.length;at++){L.jqplot.postParseOptionsHooks[at].call(this,ay)}for(var at=0;at<this.postParseOptionsHooks.hooks.length;at++){this.postParseOptionsHooks.hooks[at].call(this,ay)}};this.destroy=function(){this.canvasManager.freeAllCanvases();if(this.eventCanvas&&this.eventCanvas._elem){this.eventCanvas._elem.unbind()}this.target.empty();this.target[0].innerHTML=""};this.replot=function(am){var an=am||{};var ap=an.data||null;var al=(an.clear===false)?false:true;var ao=an.resetAxes||false;delete an.data;delete an.clear;delete an.resetAxes;this.target.trigger("jqplotPreReplot");if(al){this.destroy()}if(ap||!L.isEmptyObject(an)){this.reInitialize(ap,an)}else{this.quickInit()}if(ao){this.resetAxesScale(ao,an.axes)}this.draw();this.target.trigger("jqplotPostReplot")};this.redraw=function(al){al=(al!=null)?al:true;this.target.trigger("jqplotPreRedraw");if(al){this.canvasManager.freeAllCanvases();this.eventCanvas._elem.unbind();this.target.empty()}for(var an in this.axes){this.axes[an]._ticks=[]}this.computePlotData();this._sumy=0;this._sumx=0;for(var am=0,ao=this.series.length;am<ao;am++){this._sumy+=this.series[am]._sumy;this._sumx+=this.series[am]._sumx}this.draw();this.target.trigger("jqplotPostRedraw")};this.draw=function(){if(this.drawIfHidden||this.target.is(":visible")){this.target.trigger("jqplotPreDraw");var aH,aF,aE,ao;for(aH=0,aE=L.jqplot.preDrawHooks.length;aH<aE;aH++){L.jqplot.preDrawHooks[aH].call(this)}for(aH=0,aE=this.preDrawHooks.hooks.length;aH<aE;aH++){this.preDrawHooks.hooks[aH].apply(this,this.preDrawSeriesHooks.args[aH])}this.target.append(this.baseCanvas.createElement({left:0,right:0,top:0,bottom:0},"jqplot-base-canvas",null,this));this.baseCanvas.setContext();this.target.append(this.title.draw());this.title.pack({top:0,left:0});var aL=this.legend.draw({},this);var al={top:0,left:0,bottom:0,right:0};if(this.legend.placement=="outsideGrid"){this.target.append(aL);switch(this.legend.location){case"n":al.top+=this.legend.getHeight();break;case"s":al.bottom+=this.legend.getHeight();break;case"ne":case"e":case"se":al.right+=this.legend.getWidth();break;case"nw":case"w":case"sw":al.left+=this.legend.getWidth();break;default:al.right+=this.legend.getWidth();break}aL=aL.detach()}var ar=this.axes;var aM;for(aH=0;aH<12;aH++){aM=U[aH];this.target.append(ar[aM].draw(this.baseCanvas._ctx,this));ar[aM].set()}if(ar.yaxis.show){al.left+=ar.yaxis.getWidth()}var aG=["y2axis","y3axis","y4axis","y5axis","y6axis","y7axis","y8axis","y9axis"];var az=[0,0,0,0,0,0,0,0];var aC=0;var aB;for(aB=0;aB<8;aB++){if(ar[aG[aB]].show){aC+=ar[aG[aB]].getWidth();az[aB]=aC}}al.right+=aC;if(ar.x2axis.show){al.top+=ar.x2axis.getHeight()}if(this.title.show){al.top+=this.title.getHeight()}if(ar.xaxis.show){al.bottom+=ar.xaxis.getHeight()}if(this.options.gridDimensions&&L.isPlainObject(this.options.gridDimensions)){var at=parseInt(this.options.gridDimensions.width,10)||0;var aI=parseInt(this.options.gridDimensions.height,10)||0;var an=(this._width-al.left-al.right-at)/2;var aK=(this._height-al.top-al.bottom-aI)/2;if(aK>=0&&an>=0){al.top+=aK;al.bottom+=aK;al.left+=an;al.right+=an}}var am=["top","bottom","left","right"];for(var aB in am){if(this._gridPadding[am[aB]]==null&&al[am[aB]]>0){this._gridPadding[am[aB]]=al[am[aB]]}else{if(this._gridPadding[am[aB]]==null){this._gridPadding[am[aB]]=this._defaultGridPadding[am[aB]]}}}var aA=this._gridPadding;if(this.legend.placement==="outsideGrid"){aA={top:this.title.getHeight(),left:0,right:0,bottom:0};if(this.legend.location==="s"){aA.left=this._gridPadding.left;aA.right=this._gridPadding.right}}ar.xaxis.pack({position:"absolute",bottom:this._gridPadding.bottom-ar.xaxis.getHeight(),left:0,width:this._width},{min:this._gridPadding.left,max:this._width-this._gridPadding.right});ar.yaxis.pack({position:"absolute",top:0,left:this._gridPadding.left-ar.yaxis.getWidth(),height:this._height},{min:this._height-this._gridPadding.bottom,max:this._gridPadding.top});ar.x2axis.pack({position:"absolute",top:this._gridPadding.top-ar.x2axis.getHeight(),left:0,width:this._width},{min:this._gridPadding.left,max:this._width-this._gridPadding.right});for(aH=8;aH>0;aH--){ar[aG[aH-1]].pack({position:"absolute",top:0,right:this._gridPadding.right-az[aH-1]},{min:this._height-this._gridPadding.bottom,max:this._gridPadding.top})}var au=(this._width-this._gridPadding.left-this._gridPadding.right)/2+this._gridPadding.left-ar.yMidAxis.getWidth()/2;ar.yMidAxis.pack({position:"absolute",top:0,left:au,zIndex:9,textAlign:"center"},{min:this._height-this._gridPadding.bottom,max:this._gridPadding.top});this.target.append(this.grid.createElement(this._gridPadding,this));this.grid.draw();var aq=this.series;var aJ=aq.length;for(aH=0,aE=aJ;aH<aE;aH++){aF=this.seriesStack[aH];this.target.append(aq[aF].shadowCanvas.createElement(this._gridPadding,"jqplot-series-shadowCanvas",null,this));aq[aF].shadowCanvas.setContext();aq[aF].shadowCanvas._elem.data("seriesIndex",aF)}for(aH=0,aE=aJ;aH<aE;aH++){aF=this.seriesStack[aH];this.target.append(aq[aF].canvas.createElement(this._gridPadding,"jqplot-series-canvas",null,this));aq[aF].canvas.setContext();aq[aF].canvas._elem.data("seriesIndex",aF)}this.target.append(this.eventCanvas.createElement(this._gridPadding,"jqplot-event-canvas",null,this));this.eventCanvas.setContext();this.eventCanvas._ctx.fillStyle="rgba(0,0,0,0)";this.eventCanvas._ctx.fillRect(0,0,this.eventCanvas._ctx.canvas.width,this.eventCanvas._ctx.canvas.height);this.bindCustomEvents();if(this.legend.preDraw){this.eventCanvas._elem.before(aL);this.legend.pack(aA);if(this.legend._elem){this.drawSeries({legendInfo:{location:this.legend.location,placement:this.legend.placement,width:this.legend.getWidth(),height:this.legend.getHeight(),xoffset:this.legend.xoffset,yoffset:this.legend.yoffset}})}else{this.drawSeries()}}else{this.drawSeries();if(aJ){L(aq[aJ-1].canvas._elem).after(aL)}this.legend.pack(aA)}for(var aH=0,aE=L.jqplot.eventListenerHooks.length;aH<aE;aH++){this.eventCanvas._elem.bind(L.jqplot.eventListenerHooks[aH][0],{plot:this},L.jqplot.eventListenerHooks[aH][1])}for(var aH=0,aE=this.eventListenerHooks.hooks.length;aH<aE;aH++){this.eventCanvas._elem.bind(this.eventListenerHooks.hooks[aH][0],{plot:this},this.eventListenerHooks.hooks[aH][1])}var ay=this.fillBetween;if(ay.fill&&ay.series1!==ay.series2&&ay.series1<aJ&&ay.series2<aJ&&aq[ay.series1]._type==="line"&&aq[ay.series2]._type==="line"){this.doFillBetweenLines()}for(var aH=0,aE=L.jqplot.postDrawHooks.length;aH<aE;aH++){L.jqplot.postDrawHooks[aH].call(this)}for(var aH=0,aE=this.postDrawHooks.hooks.length;aH<aE;aH++){this.postDrawHooks.hooks[aH].apply(this,this.postDrawHooks.args[aH])}if(this.target.is(":visible")){this._drawCount+=1}var av,aw,aD,ap;for(aH=0,aE=aJ;aH<aE;aH++){av=aq[aH];aw=av.renderer;aD=".jqplot-point-label.jqplot-series-"+aH;if(aw.animation&&aw.animation._supported&&aw.animation.show&&(this._drawCount<2||this.animateReplot)){ap=this.target.find(aD);ap.stop(true,true).hide();av.canvas._elem.stop(true,true).hide();av.shadowCanvas._elem.stop(true,true).hide();av.canvas._elem.jqplotEffect("blind",{mode:"show",direction:aw.animation.direction},aw.animation.speed);av.shadowCanvas._elem.jqplotEffect("blind",{mode:"show",direction:aw.animation.direction},aw.animation.speed);ap.fadeIn(aw.animation.speed*0.8)}}ap=null;this.target.trigger("jqplotPostDraw",[this])}};R.prototype.doFillBetweenLines=function(){var an=this.fillBetween;var ax=an.series1;var av=an.series2;var aw=(ax<av)?ax:av;var au=(av>ax)?av:ax;var ar=this.series[aw];var aq=this.series[au];if(aq.renderer.smooth){var ap=aq.renderer._smoothedData.slice(0).reverse()}else{var ap=aq.gridData.slice(0).reverse()}if(ar.renderer.smooth){var at=ar.renderer._smoothedData.concat(ap)}else{var at=ar.gridData.concat(ap)}var ao=(an.color!==null)?an.color:this.series[ax].fillColor;var ay=(an.baseSeries!==null)?an.baseSeries:aw;var am=this.series[ay].renderer.shapeRenderer;var al={fillStyle:ao,fill:true,closePath:true};am.draw(ar.shadowCanvas._ctx,at,al)};this.bindCustomEvents=function(){this.eventCanvas._elem.bind("click",{plot:this},this.onClick);this.eventCanvas._elem.bind("dblclick",{plot:this},this.onDblClick);this.eventCanvas._elem.bind("mousedown",{plot:this},this.onMouseDown);this.eventCanvas._elem.bind("mousemove",{plot:this},this.onMouseMove);this.eventCanvas._elem.bind("mouseenter",{plot:this},this.onMouseEnter);this.eventCanvas._elem.bind("mouseleave",{plot:this},this.onMouseLeave);if(this.captureRightClick){this.eventCanvas._elem.bind("mouseup",{plot:this},this.onRightClick);this.eventCanvas._elem.get(0).oncontextmenu=function(){return false}}else{this.eventCanvas._elem.bind("mouseup",{plot:this},this.onMouseUp)}};function ai(av){var au=av.data.plot;var ap=au.eventCanvas._elem.offset();var at={x:av.pageX-ap.left,y:av.pageY-ap.top};var aq={xaxis:null,yaxis:null,x2axis:null,y2axis:null,y3axis:null,y4axis:null,y5axis:null,y6axis:null,y7axis:null,y8axis:null,y9axis:null,yMidAxis:null};var ar=["xaxis","yaxis","x2axis","y2axis","y3axis","y4axis","y5axis","y6axis","y7axis","y8axis","y9axis","yMidAxis"];var al=au.axes;var am,ao;for(am=11;am>0;am--){ao=ar[am-1];if(al[ao].show){aq[ao]=al[ao].series_p2u(at[ao.charAt(0)])}}return{offsets:ap,gridPos:at,dataPos:aq}}function ak(al,am){var aq=am.series;var aW,aU,aT,aO,aP,aJ,aI,aw,au,az,aA,aK;var aS,aX,aQ,ar,aH,aM,aV;var an,aN;for(aT=am.seriesStack.length-1;aT>=0;aT--){aW=am.seriesStack[aT];aO=aq[aW];aV=aO._highlightThreshold;switch(aO.renderer.constructor){case L.jqplot.BarRenderer:aJ=al.x;aI=al.y;for(aU=0;aU<aO._barPoints.length;aU++){aH=aO._barPoints[aU];aQ=aO.gridData[aU];if(aJ>aH[0][0]&&aJ<aH[2][0]&&aI>aH[2][1]&&aI<aH[0][1]){return{seriesIndex:aO.index,pointIndex:aU,gridData:aQ,data:aO.data[aU],points:aO._barPoints[aU]}}}break;case L.jqplot.PyramidRenderer:aJ=al.x;aI=al.y;for(aU=0;aU<aO._barPoints.length;aU++){aH=aO._barPoints[aU];aQ=aO.gridData[aU];if(aJ>aH[0][0]+aV[0][0]&&aJ<aH[2][0]+aV[2][0]&&aI>aH[2][1]&&aI<aH[0][1]){return{seriesIndex:aO.index,pointIndex:aU,gridData:aQ,data:aO.data[aU],points:aO._barPoints[aU]}}}break;case L.jqplot.DonutRenderer:az=aO.startAngle/180*Math.PI;aJ=al.x-aO._center[0];aI=al.y-aO._center[1];aP=Math.sqrt(Math.pow(aJ,2)+Math.pow(aI,2));if(aJ>0&&-aI>=0){aw=2*Math.PI-Math.atan(-aI/aJ)}else{if(aJ>0&&-aI<0){aw=-Math.atan(-aI/aJ)}else{if(aJ<0){aw=Math.PI-Math.atan(-aI/aJ)}else{if(aJ==0&&-aI>0){aw=3*Math.PI/2}else{if(aJ==0&&-aI<0){aw=Math.PI/2}else{if(aJ==0&&aI==0){aw=0}}}}}}if(az){aw-=az;if(aw<0){aw+=2*Math.PI}else{if(aw>2*Math.PI){aw-=2*Math.PI}}}au=aO.sliceMargin/180*Math.PI;if(aP<aO._radius&&aP>aO._innerRadius){for(aU=0;aU<aO.gridData.length;aU++){aA=(aU>0)?aO.gridData[aU-1][1]+au:au;aK=aO.gridData[aU][1];if(aw>aA&&aw<aK){return{seriesIndex:aO.index,pointIndex:aU,gridData:[al.x,al.y],data:aO.data[aU]}}}}break;case L.jqplot.PieRenderer:az=aO.startAngle/180*Math.PI;aJ=al.x-aO._center[0];aI=al.y-aO._center[1];aP=Math.sqrt(Math.pow(aJ,2)+Math.pow(aI,2));if(aJ>0&&-aI>=0){aw=2*Math.PI-Math.atan(-aI/aJ)}else{if(aJ>0&&-aI<0){aw=-Math.atan(-aI/aJ)}else{if(aJ<0){aw=Math.PI-Math.atan(-aI/aJ)}else{if(aJ==0&&-aI>0){aw=3*Math.PI/2}else{if(aJ==0&&-aI<0){aw=Math.PI/2}else{if(aJ==0&&aI==0){aw=0}}}}}}if(az){aw-=az;if(aw<0){aw+=2*Math.PI}else{if(aw>2*Math.PI){aw-=2*Math.PI}}}au=aO.sliceMargin/180*Math.PI;if(aP<aO._radius){for(aU=0;aU<aO.gridData.length;aU++){aA=(aU>0)?aO.gridData[aU-1][1]+au:au;aK=aO.gridData[aU][1];if(aw>aA&&aw<aK){return{seriesIndex:aO.index,pointIndex:aU,gridData:[al.x,al.y],data:aO.data[aU]}}}}break;case L.jqplot.BubbleRenderer:aJ=al.x;aI=al.y;var aF=null;if(aO.show){for(var aU=0;aU<aO.gridData.length;aU++){aQ=aO.gridData[aU];aX=Math.sqrt((aJ-aQ[0])*(aJ-aQ[0])+(aI-aQ[1])*(aI-aQ[1]));if(aX<=aQ[2]&&(aX<=aS||aS==null)){aS=aX;aF={seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}if(aF!=null){return aF}}break;case L.jqplot.FunnelRenderer:aJ=al.x;aI=al.y;var aL=aO._vertices,ap=aL[0],ao=aL[aL.length-1],at,aE,ay;function aR(a0,a2,a1){var aZ=(a2[1]-a1[1])/(a2[0]-a1[0]);var aY=a2[1]-aZ*a2[0];var a3=a0+a2[1];return[(a3-aY)/aZ,a3]}at=aR(aI,ap[0],ao[3]);aE=aR(aI,ap[1],ao[2]);for(aU=0;aU<aL.length;aU++){ay=aL[aU];if(aI>=ay[0][1]&&aI<=ay[3][1]&&aJ>=at[0]&&aJ<=aE[0]){return{seriesIndex:aO.index,pointIndex:aU,gridData:null,data:aO.data[aU]}}}break;case L.jqplot.LineRenderer:aJ=al.x;aI=al.y;aP=aO.renderer;if(aO.show){if((aO.fill||(aO.renderer.bands.show&&aO.renderer.bands.fill))&&(!am.plugins.highlighter||!am.plugins.highlighter.show)){var ax=false;if(aJ>aO._boundingBox[0][0]&&aJ<aO._boundingBox[1][0]&&aI>aO._boundingBox[1][1]&&aI<aO._boundingBox[0][1]){var aD=aO._areaPoints.length;var aG;var aU=aD-1;for(var aG=0;aG<aD;aG++){var aC=[aO._areaPoints[aG][0],aO._areaPoints[aG][1]];var aB=[aO._areaPoints[aU][0],aO._areaPoints[aU][1]];if(aC[1]<aI&&aB[1]>=aI||aB[1]<aI&&aC[1]>=aI){if(aC[0]+(aI-aC[1])/(aB[1]-aC[1])*(aB[0]-aC[0])<aJ){ax=!ax}}aU=aG}}if(ax){return{seriesIndex:aW,pointIndex:null,gridData:aO.gridData,data:aO.data,points:aO._areaPoints}}break}else{aN=aO.markerRenderer.size/2+aO.neighborThreshold;an=(aN>0)?aN:0;for(var aU=0;aU<aO.gridData.length;aU++){aQ=aO.gridData[aU];if(aP.constructor==L.jqplot.OHLCRenderer){if(aP.candleStick){var av=aO._yaxis.series_u2p;if(aJ>=aQ[0]-aP._bodyWidth/2&&aJ<=aQ[0]+aP._bodyWidth/2&&aI>=av(aO.data[aU][2])&&aI<=av(aO.data[aU][3])){return{seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}else{if(!aP.hlc){var av=aO._yaxis.series_u2p;if(aJ>=aQ[0]-aP._tickLength&&aJ<=aQ[0]+aP._tickLength&&aI>=av(aO.data[aU][2])&&aI<=av(aO.data[aU][3])){return{seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}else{var av=aO._yaxis.series_u2p;if(aJ>=aQ[0]-aP._tickLength&&aJ<=aQ[0]+aP._tickLength&&aI>=av(aO.data[aU][1])&&aI<=av(aO.data[aU][2])){return{seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}}}else{if(aQ[0]!=null&&aQ[1]!=null){aX=Math.sqrt((aJ-aQ[0])*(aJ-aQ[0])+(aI-aQ[1])*(aI-aQ[1]));if(aX<=an&&(aX<=aS||aS==null)){aS=aX;return{seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}}}}}break;default:aJ=al.x;aI=al.y;aP=aO.renderer;if(aO.show){aN=aO.markerRenderer.size/2+aO.neighborThreshold;an=(aN>0)?aN:0;for(var aU=0;aU<aO.gridData.length;aU++){aQ=aO.gridData[aU];if(aP.constructor==L.jqplot.OHLCRenderer){if(aP.candleStick){var av=aO._yaxis.series_u2p;if(aJ>=aQ[0]-aP._bodyWidth/2&&aJ<=aQ[0]+aP._bodyWidth/2&&aI>=av(aO.data[aU][2])&&aI<=av(aO.data[aU][3])){return{seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}else{if(!aP.hlc){var av=aO._yaxis.series_u2p;if(aJ>=aQ[0]-aP._tickLength&&aJ<=aQ[0]+aP._tickLength&&aI>=av(aO.data[aU][2])&&aI<=av(aO.data[aU][3])){return{seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}else{var av=aO._yaxis.series_u2p;if(aJ>=aQ[0]-aP._tickLength&&aJ<=aQ[0]+aP._tickLength&&aI>=av(aO.data[aU][1])&&aI<=av(aO.data[aU][2])){return{seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}}}else{aX=Math.sqrt((aJ-aQ[0])*(aJ-aQ[0])+(aI-aQ[1])*(aI-aQ[1]));if(aX<=an&&(aX<=aS||aS==null)){aS=aX;return{seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}}}break}}return null}this.onClick=function(an){var am=ai(an);var ap=an.data.plot;var ao=ak(am.gridPos,ap);var al=L.Event("jqplotClick");al.pageX=an.pageX;al.pageY=an.pageY;L(this).trigger(al,[am.gridPos,am.dataPos,ao,ap])};this.onDblClick=function(an){var am=ai(an);var ap=an.data.plot;var ao=ak(am.gridPos,ap);var al=L.Event("jqplotDblClick");al.pageX=an.pageX;al.pageY=an.pageY;L(this).trigger(al,[am.gridPos,am.dataPos,ao,ap])};this.onMouseDown=function(an){var am=ai(an);var ap=an.data.plot;var ao=ak(am.gridPos,ap);var al=L.Event("jqplotMouseDown");al.pageX=an.pageX;al.pageY=an.pageY;L(this).trigger(al,[am.gridPos,am.dataPos,ao,ap])};this.onMouseUp=function(an){var am=ai(an);var al=L.Event("jqplotMouseUp");al.pageX=an.pageX;al.pageY=an.pageY;L(this).trigger(al,[am.gridPos,am.dataPos,null,an.data.plot])};this.onRightClick=function(an){var am=ai(an);var ap=an.data.plot;var ao=ak(am.gridPos,ap);if(ap.captureRightClick){if(an.which==3){var al=L.Event("jqplotRightClick");al.pageX=an.pageX;al.pageY=an.pageY;L(this).trigger(al,[am.gridPos,am.dataPos,ao,ap])}else{var al=L.Event("jqplotMouseUp");al.pageX=an.pageX;al.pageY=an.pageY;L(this).trigger(al,[am.gridPos,am.dataPos,ao,ap])}}};this.onMouseMove=function(an){var am=ai(an);var ap=an.data.plot;var ao=ak(am.gridPos,ap);var al=L.Event("jqplotMouseMove");al.pageX=an.pageX;al.pageY=an.pageY;L(this).trigger(al,[am.gridPos,am.dataPos,ao,ap])};this.onMouseEnter=function(an){var am=ai(an);var ao=an.data.plot;var al=L.Event("jqplotMouseEnter");al.pageX=an.pageX;al.pageY=an.pageY;al.relatedTarget=an.relatedTarget;L(this).trigger(al,[am.gridPos,am.dataPos,null,ao])};this.onMouseLeave=function(an){var am=ai(an);var ao=an.data.plot;var al=L.Event("jqplotMouseLeave");al.pageX=an.pageX;al.pageY=an.pageY;al.relatedTarget=an.relatedTarget;L(this).trigger(al,[am.gridPos,am.dataPos,null,ao])};this.drawSeries=function(an,al){var ap,ao,am;al=(typeof(an)==="number"&&al==null)?an:al;an=(typeof(an)==="object")?an:{};if(al!=u){ao=this.series[al];am=ao.shadowCanvas._ctx;am.clearRect(0,0,am.canvas.width,am.canvas.height);ao.drawShadow(am,an,this);am=ao.canvas._ctx;am.clearRect(0,0,am.canvas.width,am.canvas.height);ao.draw(am,an,this);if(ao.renderer.constructor==L.jqplot.BezierCurveRenderer){if(al<this.series.length-1){this.drawSeries(al+1)}}}else{for(ap=0;ap<this.series.length;ap++){ao=this.series[ap];am=ao.shadowCanvas._ctx;am.clearRect(0,0,am.canvas.width,am.canvas.height);ao.drawShadow(am,an,this);am=ao.canvas._ctx;am.clearRect(0,0,am.canvas.width,am.canvas.height);ao.draw(am,an,this)}}an=al=ap=ao=am=null};this.moveSeriesToFront=function(am){am=parseInt(am,10);var ap=L.inArray(am,this.seriesStack);if(ap==-1){return}if(ap==this.seriesStack.length-1){this.previousSeriesStack=this.seriesStack.slice(0);return}var al=this.seriesStack[this.seriesStack.length-1];var ao=this.series[am].canvas._elem.detach();var an=this.series[am].shadowCanvas._elem.detach();this.series[al].shadowCanvas._elem.after(an);this.series[al].canvas._elem.after(ao);this.previousSeriesStack=this.seriesStack.slice(0);this.seriesStack.splice(ap,1);this.seriesStack.push(am)};this.moveSeriesToBack=function(am){am=parseInt(am,10);var ap=L.inArray(am,this.seriesStack);if(ap==0||ap==-1){return}var al=this.seriesStack[0];var ao=this.series[am].canvas._elem.detach();var an=this.series[am].shadowCanvas._elem.detach();this.series[al].shadowCanvas._elem.before(an);this.series[al].canvas._elem.before(ao);this.previousSeriesStack=this.seriesStack.slice(0);this.seriesStack.splice(ap,1);this.seriesStack.unshift(am)};this.restorePreviousSeriesOrder=function(){var ar,aq,ap,ao,an,al,am;if(this.seriesStack==this.previousSeriesStack){return}for(ar=1;ar<this.previousSeriesStack.length;ar++){al=this.previousSeriesStack[ar];am=this.previousSeriesStack[ar-1];ap=this.series[al].canvas._elem.detach();ao=this.series[al].shadowCanvas._elem.detach();this.series[am].shadowCanvas._elem.after(ao);this.series[am].canvas._elem.after(ap)}an=this.seriesStack.slice(0);this.seriesStack=this.previousSeriesStack.slice(0);this.previousSeriesStack=an};this.restoreOriginalSeriesOrder=function(){var ap,ao,al=[],an,am;for(ap=0;ap<this.series.length;ap++){al.push(ap)}if(this.seriesStack==al){return}this.previousSeriesStack=this.seriesStack.slice(0);this.seriesStack=al;for(ap=1;ap<this.seriesStack.length;ap++){an=this.series[ap].canvas._elem.detach();am=this.series[ap].shadowCanvas._elem.detach();this.series[ap-1].shadowCanvas._elem.after(am);this.series[ap-1].canvas._elem.after(an)}};this.activateTheme=function(al){this.themeEngine.activate(this,al)}}L.jqplot.computeHighlightColors=function(ai){var ak;if(L.isArray(ai)){ak=[];for(var am=0;am<ai.length;am++){var al=L.jqplot.getColorComponents(ai[am]);var ah=[al[0],al[1],al[2]];var an=ah[0]+ah[1]+ah[2];for(var aj=0;aj<3;aj++){ah[aj]=(an>660)?ah[aj]*0.85:0.73*ah[aj]+90;ah[aj]=parseInt(ah[aj],10);(ah[aj]>255)?255:ah[aj]}ah[3]=0.3+0.35*al[3];ak.push("rgba("+ah[0]+","+ah[1]+","+ah[2]+","+ah[3]+")")}}else{var al=L.jqplot.getColorComponents(ai);var ah=[al[0],al[1],al[2]];var an=ah[0]+ah[1]+ah[2];for(var aj=0;aj<3;aj++){ah[aj]=(an>660)?ah[aj]*0.85:0.73*ah[aj]+90;ah[aj]=parseInt(ah[aj],10);(ah[aj]>255)?255:ah[aj]}ah[3]=0.3+0.35*al[3];ak="rgba("+ah[0]+","+ah[1]+","+ah[2]+","+ah[3]+")"}return ak};L.jqplot.ColorGenerator=function(ai){ai=ai||L.jqplot.config.defaultColors;var ah=0;this.next=function(){if(ah<ai.length){return ai[ah++]}else{ah=0;return ai[ah++]}};this.previous=function(){if(ah>0){return ai[ah--]}else{ah=ai.length-1;return ai[ah]}};this.get=function(ak){var aj=ak-ai.length*Math.floor(ak/ai.length);return ai[aj]};this.setColors=function(aj){ai=aj};this.reset=function(){ah=0};this.getIndex=function(){return ah};this.setIndex=function(aj){ah=aj}};L.jqplot.hex2rgb=function(aj,ah){aj=aj.replace("#","");if(aj.length==3){aj=aj.charAt(0)+aj.charAt(0)+aj.charAt(1)+aj.charAt(1)+aj.charAt(2)+aj.charAt(2)}var ai;ai="rgba("+parseInt(aj.slice(0,2),16)+", "+parseInt(aj.slice(2,4),16)+", "+parseInt(aj.slice(4,6),16);if(ah){ai+=", "+ah}ai+=")";return ai};L.jqplot.rgb2hex=function(am){var aj=/rgba?\( *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *(?:, *[0-9.]*)?\)/;var ah=am.match(aj);var al="#";for(var ak=1;ak<4;ak++){var ai;if(ah[ak].search(/%/)!=-1){ai=parseInt(255*ah[ak]/100,10).toString(16);if(ai.length==1){ai="0"+ai}}else{ai=parseInt(ah[ak],10).toString(16);if(ai.length==1){ai="0"+ai}}al+=ai}return al};L.jqplot.normalize2rgb=function(ai,ah){if(ai.search(/^ *rgba?\(/)!=-1){return ai}else{if(ai.search(/^ *#?[0-9a-fA-F]?[0-9a-fA-F]/)!=-1){return L.jqplot.hex2rgb(ai,ah)}else{throw new Error("Invalid color spec")}}};L.jqplot.getColorComponents=function(am){am=L.jqplot.colorKeywordMap[am]||am;var ak=L.jqplot.normalize2rgb(am);var aj=/rgba?\( *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *,? *([0-9.]* *)?\)/;var ah=ak.match(aj);var ai=[];for(var al=1;al<4;al++){if(ah[al].search(/%/)!=-1){ai[al-1]=parseInt(255*ah[al]/100,10)}else{ai[al-1]=parseInt(ah[al],10)}}ai[3]=parseFloat(ah[4])?parseFloat(ah[4]):1;return ai};L.jqplot.colorKeywordMap={aliceblue:"rgb(240, 248, 255)",antiquewhite:"rgb(250, 235, 215)",aqua:"rgb( 0, 255, 255)",aquamarine:"rgb(127, 255, 212)",azure:"rgb(240, 255, 255)",beige:"rgb(245, 245, 220)",bisque:"rgb(255, 228, 196)",black:"rgb( 0, 0, 0)",blanchedalmond:"rgb(255, 235, 205)",blue:"rgb( 0, 0, 255)",blueviolet:"rgb(138, 43, 226)",brown:"rgb(165, 42, 42)",burlywood:"rgb(222, 184, 135)",cadetblue:"rgb( 95, 158, 160)",chartreuse:"rgb(127, 255, 0)",chocolate:"rgb(210, 105, 30)",coral:"rgb(255, 127, 80)",cornflowerblue:"rgb(100, 149, 237)",cornsilk:"rgb(255, 248, 220)",crimson:"rgb(220, 20, 60)",cyan:"rgb( 0, 255, 255)",darkblue:"rgb( 0, 0, 139)",darkcyan:"rgb( 0, 139, 139)",darkgoldenrod:"rgb(184, 134, 11)",darkgray:"rgb(169, 169, 169)",darkgreen:"rgb( 0, 100, 0)",darkgrey:"rgb(169, 169, 169)",darkkhaki:"rgb(189, 183, 107)",darkmagenta:"rgb(139, 0, 139)",darkolivegreen:"rgb( 85, 107, 47)",darkorange:"rgb(255, 140, 0)",darkorchid:"rgb(153, 50, 204)",darkred:"rgb(139, 0, 0)",darksalmon:"rgb(233, 150, 122)",darkseagreen:"rgb(143, 188, 143)",darkslateblue:"rgb( 72, 61, 139)",darkslategray:"rgb( 47, 79, 79)",darkslategrey:"rgb( 47, 79, 79)",darkturquoise:"rgb( 0, 206, 209)",darkviolet:"rgb(148, 0, 211)",deeppink:"rgb(255, 20, 147)",deepskyblue:"rgb( 0, 191, 255)",dimgray:"rgb(105, 105, 105)",dimgrey:"rgb(105, 105, 105)",dodgerblue:"rgb( 30, 144, 255)",firebrick:"rgb(178, 34, 34)",floralwhite:"rgb(255, 250, 240)",forestgreen:"rgb( 34, 139, 34)",fuchsia:"rgb(255, 0, 255)",gainsboro:"rgb(220, 220, 220)",ghostwhite:"rgb(248, 248, 255)",gold:"rgb(255, 215, 0)",goldenrod:"rgb(218, 165, 32)",gray:"rgb(128, 128, 128)",grey:"rgb(128, 128, 128)",green:"rgb( 0, 128, 0)",greenyellow:"rgb(173, 255, 47)",honeydew:"rgb(240, 255, 240)",hotpink:"rgb(255, 105, 180)",indianred:"rgb(205, 92, 92)",indigo:"rgb( 75, 0, 130)",ivory:"rgb(255, 255, 240)",khaki:"rgb(240, 230, 140)",lavender:"rgb(230, 230, 250)",lavenderblush:"rgb(255, 240, 245)",lawngreen:"rgb(124, 252, 0)",lemonchiffon:"rgb(255, 250, 205)",lightblue:"rgb(173, 216, 230)",lightcoral:"rgb(240, 128, 128)",lightcyan:"rgb(224, 255, 255)",lightgoldenrodyellow:"rgb(250, 250, 210)",lightgray:"rgb(211, 211, 211)",lightgreen:"rgb(144, 238, 144)",lightgrey:"rgb(211, 211, 211)",lightpink:"rgb(255, 182, 193)",lightsalmon:"rgb(255, 160, 122)",lightseagreen:"rgb( 32, 178, 170)",lightskyblue:"rgb(135, 206, 250)",lightslategray:"rgb(119, 136, 153)",lightslategrey:"rgb(119, 136, 153)",lightsteelblue:"rgb(176, 196, 222)",lightyellow:"rgb(255, 255, 224)",lime:"rgb( 0, 255, 0)",limegreen:"rgb( 50, 205, 50)",linen:"rgb(250, 240, 230)",magenta:"rgb(255, 0, 255)",maroon:"rgb(128, 0, 0)",mediumaquamarine:"rgb(102, 205, 170)",mediumblue:"rgb( 0, 0, 205)",mediumorchid:"rgb(186, 85, 211)",mediumpurple:"rgb(147, 112, 219)",mediumseagreen:"rgb( 60, 179, 113)",mediumslateblue:"rgb(123, 104, 238)",mediumspringgreen:"rgb( 0, 250, 154)",mediumturquoise:"rgb( 72, 209, 204)",mediumvioletred:"rgb(199, 21, 133)",midnightblue:"rgb( 25, 25, 112)",mintcream:"rgb(245, 255, 250)",mistyrose:"rgb(255, 228, 225)",moccasin:"rgb(255, 228, 181)",navajowhite:"rgb(255, 222, 173)",navy:"rgb( 0, 0, 128)",oldlace:"rgb(253, 245, 230)",olive:"rgb(128, 128, 0)",olivedrab:"rgb(107, 142, 35)",orange:"rgb(255, 165, 0)",orangered:"rgb(255, 69, 0)",orchid:"rgb(218, 112, 214)",palegoldenrod:"rgb(238, 232, 170)",palegreen:"rgb(152, 251, 152)",paleturquoise:"rgb(175, 238, 238)",palevioletred:"rgb(219, 112, 147)",papayawhip:"rgb(255, 239, 213)",peachpuff:"rgb(255, 218, 185)",peru:"rgb(205, 133, 63)",pink:"rgb(255, 192, 203)",plum:"rgb(221, 160, 221)",powderblue:"rgb(176, 224, 230)",purple:"rgb(128, 0, 128)",red:"rgb(255, 0, 0)",rosybrown:"rgb(188, 143, 143)",royalblue:"rgb( 65, 105, 225)",saddlebrown:"rgb(139, 69, 19)",salmon:"rgb(250, 128, 114)",sandybrown:"rgb(244, 164, 96)",seagreen:"rgb( 46, 139, 87)",seashell:"rgb(255, 245, 238)",sienna:"rgb(160, 82, 45)",silver:"rgb(192, 192, 192)",skyblue:"rgb(135, 206, 235)",slateblue:"rgb(106, 90, 205)",slategray:"rgb(112, 128, 144)",slategrey:"rgb(112, 128, 144)",snow:"rgb(255, 250, 250)",springgreen:"rgb( 0, 255, 127)",steelblue:"rgb( 70, 130, 180)",tan:"rgb(210, 180, 140)",teal:"rgb( 0, 128, 128)",thistle:"rgb(216, 191, 216)",tomato:"rgb(255, 99, 71)",turquoise:"rgb( 64, 224, 208)",violet:"rgb(238, 130, 238)",wheat:"rgb(245, 222, 179)",white:"rgb(255, 255, 255)",whitesmoke:"rgb(245, 245, 245)",yellow:"rgb(255, 255, 0)",yellowgreen:"rgb(154, 205, 50)"};L.jqplot.AxisLabelRenderer=function(ah){L.jqplot.ElemContainer.call(this);this.axis;this.show=true;this.label="";this.fontFamily=null;this.fontSize=null;this.textColor=null;this._elem;this.escapeHTML=false;L.extend(true,this,ah)};L.jqplot.AxisLabelRenderer.prototype=new L.jqplot.ElemContainer();L.jqplot.AxisLabelRenderer.prototype.constructor=L.jqplot.AxisLabelRenderer;L.jqplot.AxisLabelRenderer.prototype.init=function(ah){L.extend(true,this,ah)};L.jqplot.AxisLabelRenderer.prototype.draw=function(ah,ai){if(this._elem){this._elem.emptyForce();this._elem=null}this._elem=L('<div style="position:absolute;" class="jqplot-'+this.axis+'-label"></div>');if(Number(this.label)){this._elem.css("white-space","nowrap")}if(!this.escapeHTML){this._elem.html(this.label)}else{this._elem.text(this.label)}if(this.fontFamily){this._elem.css("font-family",this.fontFamily)}if(this.fontSize){this._elem.css("font-size",this.fontSize)}if(this.textColor){this._elem.css("color",this.textColor)}return this._elem};L.jqplot.AxisLabelRenderer.prototype.pack=function(){};L.jqplot.AxisTickRenderer=function(ah){L.jqplot.ElemContainer.call(this);this.mark="outside";this.axis;this.showMark=true;this.showGridline=true;this.isMinorTick=false;this.size=4;this.markSize=6;this.show=true;this.showLabel=true;this.label=null;this.value=null;this._styles={};this.formatter=L.jqplot.DefaultTickFormatter;this.prefix="";this.suffix="";this.formatString="";this.fontFamily;this.fontSize;this.textColor;this.escapeHTML=false;this._elem;this._breakTick=false;L.extend(true,this,ah)};L.jqplot.AxisTickRenderer.prototype.init=function(ah){L.extend(true,this,ah)};L.jqplot.AxisTickRenderer.prototype=new L.jqplot.ElemContainer();L.jqplot.AxisTickRenderer.prototype.constructor=L.jqplot.AxisTickRenderer;L.jqplot.AxisTickRenderer.prototype.setTick=function(ah,aj,ai){this.value=ah;this.axis=aj;if(ai){this.isMinorTick=true}return this};L.jqplot.AxisTickRenderer.prototype.draw=function(){if(this.label===null){this.label=this.prefix+this.formatter(this.formatString,this.value)+this.suffix}var ai={position:"absolute"};if(Number(this.label)){ai.whitSpace="nowrap"}if(this._elem){this._elem.emptyForce();this._elem=null}this._elem=L(document.createElement("div"));this._elem.addClass("jqplot-"+this.axis+"-tick");if(!this.escapeHTML){this._elem.html(this.label)}else{this._elem.text(this.label)}this._elem.css(ai);for(var ah in this._styles){this._elem.css(ah,this._styles[ah])}if(this.fontFamily){this._elem.css("font-family",this.fontFamily)}if(this.fontSize){this._elem.css("font-size",this.fontSize)}if(this.textColor){this._elem.css("color",this.textColor)}if(this._breakTick){this._elem.addClass("jqplot-breakTick")}return this._elem};L.jqplot.DefaultTickFormatter=function(ah,ai){if(typeof ai=="number"){if(!ah){ah=L.jqplot.config.defaultTickFormatString}return L.jqplot.sprintf(ah,ai)}else{return String(ai)}};L.jqplot.PercentTickFormatter=function(ah,ai){if(typeof ai=="number"){ai=100*ai;if(!ah){ah=L.jqplot.config.defaultTickFormatString}return L.jqplot.sprintf(ah,ai)}else{return String(ai)}};L.jqplot.AxisTickRenderer.prototype.pack=function(){};L.jqplot.CanvasGridRenderer=function(){this.shadowRenderer=new L.jqplot.ShadowRenderer()};L.jqplot.CanvasGridRenderer.prototype.init=function(ai){this._ctx;L.extend(true,this,ai);var ah={lineJoin:"miter",lineCap:"round",fill:false,isarc:false,angle:this.shadowAngle,offset:this.shadowOffset,alpha:this.shadowAlpha,depth:this.shadowDepth,lineWidth:this.shadowWidth,closePath:false,strokeStyle:this.shadowColor};this.renderer.shadowRenderer.init(ah)};L.jqplot.CanvasGridRenderer.prototype.createElement=function(ak){var aj;if(this._elem){if(L.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==u){aj=this._elem.get(0);window.G_vmlCanvasManager.uninitElement(aj);aj=null}this._elem.emptyForce();this._elem=null}aj=ak.canvasManager.getCanvas();var ah=this._plotDimensions.width;var ai=this._plotDimensions.height;aj.width=ah;aj.height=ai;this._elem=L(aj);this._elem.addClass("jqplot-grid-canvas");this._elem.css({position:"absolute",left:0,top:0});aj=ak.canvasManager.initCanvas(aj);this._top=this._offsets.top;this._bottom=ai-this._offsets.bottom;this._left=this._offsets.left;this._right=ah-this._offsets.right;this._width=this._right-this._left;this._height=this._bottom-this._top;aj=null;return this._elem};L.jqplot.CanvasGridRenderer.prototype.draw=function(){this._ctx=this._elem.get(0).getContext("2d");var at=this._ctx;var aw=this._axes;at.save();at.clearRect(0,0,this._plotDimensions.width,this._plotDimensions.height);at.fillStyle=this.backgroundColor||this.background;at.fillRect(this._left,this._top,this._width,this._height);at.save();at.lineJoin="miter";at.lineCap="butt";at.lineWidth=this.gridLineWidth;at.strokeStyle=this.gridLineColor;var aA,az,ap,aq;var am=["xaxis","yaxis","x2axis","y2axis"];for(var ay=4;ay>0;ay--){var aD=am[ay-1];var ah=aw[aD];var aB=ah._ticks;var ar=aB.length;if(ah.show){if(ah.drawBaseline){var aC={};if(ah.baselineWidth!==null){aC.lineWidth=ah.baselineWidth}if(ah.baselineColor!==null){aC.strokeStyle=ah.baselineColor}switch(aD){case"xaxis":ao(this._left,this._bottom,this._right,this._bottom,aC);break;case"yaxis":ao(this._left,this._bottom,this._left,this._top,aC);break;case"x2axis":ao(this._left,this._bottom,this._right,this._bottom,aC);break;case"y2axis":ao(this._right,this._bottom,this._right,this._top,aC);break}}for(var au=ar;au>0;au--){var an=aB[au-1];if(an.show){var ak=Math.round(ah.u2p(an.value))+0.5;switch(aD){case"xaxis":if(an.showGridline&&this.drawGridlines&&((!an.isMinorTick&&ah.drawMajorGridlines)||(an.isMinorTick&&ah.drawMinorGridlines))){ao(ak,this._top,ak,this._bottom)}if(an.showMark&&an.mark&&((!an.isMinorTick&&ah.drawMajorTickMarks)||(an.isMinorTick&&ah.drawMinorTickMarks))){ap=an.markSize;aq=an.mark;var ak=Math.round(ah.u2p(an.value))+0.5;switch(aq){case"outside":aA=this._bottom;az=this._bottom+ap;break;case"inside":aA=this._bottom-ap;az=this._bottom;break;case"cross":aA=this._bottom-ap;az=this._bottom+ap;break;default:aA=this._bottom;az=this._bottom+ap;break}if(this.shadow){this.renderer.shadowRenderer.draw(at,[[ak,aA],[ak,az]],{lineCap:"butt",lineWidth:this.gridLineWidth,offset:this.gridLineWidth*0.75,depth:2,fill:false,closePath:false})}ao(ak,aA,ak,az)}break;case"yaxis":if(an.showGridline&&this.drawGridlines&&((!an.isMinorTick&&ah.drawMajorGridlines)||(an.isMinorTick&&ah.drawMinorGridlines))){ao(this._right,ak,this._left,ak)}if(an.showMark&&an.mark&&((!an.isMinorTick&&ah.drawMajorTickMarks)||(an.isMinorTick&&ah.drawMinorTickMarks))){ap=an.markSize;aq=an.mark;var ak=Math.round(ah.u2p(an.value))+0.5;switch(aq){case"outside":aA=this._left-ap;az=this._left;break;case"inside":aA=this._left;az=this._left+ap;break;case"cross":aA=this._left-ap;az=this._left+ap;break;default:aA=this._left-ap;az=this._left;break}if(this.shadow){this.renderer.shadowRenderer.draw(at,[[aA,ak],[az,ak]],{lineCap:"butt",lineWidth:this.gridLineWidth*1.5,offset:this.gridLineWidth*0.75,fill:false,closePath:false})}ao(aA,ak,az,ak,{strokeStyle:ah.borderColor})}break;case"x2axis":if(an.showGridline&&this.drawGridlines&&((!an.isMinorTick&&ah.drawMajorGridlines)||(an.isMinorTick&&ah.drawMinorGridlines))){ao(ak,this._bottom,ak,this._top)}if(an.showMark&&an.mark&&((!an.isMinorTick&&ah.drawMajorTickMarks)||(an.isMinorTick&&ah.drawMinorTickMarks))){ap=an.markSize;aq=an.mark;var ak=Math.round(ah.u2p(an.value))+0.5;switch(aq){case"outside":aA=this._top-ap;az=this._top;break;case"inside":aA=this._top;az=this._top+ap;break;case"cross":aA=this._top-ap;az=this._top+ap;break;default:aA=this._top-ap;az=this._top;break}if(this.shadow){this.renderer.shadowRenderer.draw(at,[[ak,aA],[ak,az]],{lineCap:"butt",lineWidth:this.gridLineWidth,offset:this.gridLineWidth*0.75,depth:2,fill:false,closePath:false})}ao(ak,aA,ak,az)}break;case"y2axis":if(an.showGridline&&this.drawGridlines&&((!an.isMinorTick&&ah.drawMajorGridlines)||(an.isMinorTick&&ah.drawMinorGridlines))){ao(this._left,ak,this._right,ak)}if(an.showMark&&an.mark&&((!an.isMinorTick&&ah.drawMajorTickMarks)||(an.isMinorTick&&ah.drawMinorTickMarks))){ap=an.markSize;aq=an.mark;var ak=Math.round(ah.u2p(an.value))+0.5;switch(aq){case"outside":aA=this._right;az=this._right+ap;break;case"inside":aA=this._right-ap;az=this._right;break;case"cross":aA=this._right-ap;az=this._right+ap;break;default:aA=this._right;az=this._right+ap;break}if(this.shadow){this.renderer.shadowRenderer.draw(at,[[aA,ak],[az,ak]],{lineCap:"butt",lineWidth:this.gridLineWidth*1.5,offset:this.gridLineWidth*0.75,fill:false,closePath:false})}ao(aA,ak,az,ak,{strokeStyle:ah.borderColor})}break;default:break}}}an=null}ah=null;aB=null}am=["y3axis","y4axis","y5axis","y6axis","y7axis","y8axis","y9axis","yMidAxis"];for(var ay=7;ay>0;ay--){var ah=aw[am[ay-1]];var aB=ah._ticks;if(ah.show){var ai=aB[ah.numberTicks-1];var al=aB[0];var aj=ah.getLeft();var av=[[aj,ai.getTop()+ai.getHeight()/2],[aj,al.getTop()+al.getHeight()/2+1]];if(this.shadow){this.renderer.shadowRenderer.draw(at,av,{lineCap:"butt",fill:false,closePath:false})}ao(av[0][0],av[0][1],av[1][0],av[1][1],{lineCap:"butt",strokeStyle:ah.borderColor,lineWidth:ah.borderWidth});for(var au=aB.length;au>0;au--){var an=aB[au-1];ap=an.markSize;aq=an.mark;var ak=Math.round(ah.u2p(an.value))+0.5;if(an.showMark&&an.mark){switch(aq){case"outside":aA=aj;az=aj+ap;break;case"inside":aA=aj-ap;az=aj;break;case"cross":aA=aj-ap;az=aj+ap;break;default:aA=aj;az=aj+ap;break}av=[[aA,ak],[az,ak]];if(this.shadow){this.renderer.shadowRenderer.draw(at,av,{lineCap:"butt",lineWidth:this.gridLineWidth*1.5,offset:this.gridLineWidth*0.75,fill:false,closePath:false})}ao(aA,ak,az,ak,{strokeStyle:ah.borderColor})}an=null}al=null}ah=null;aB=null}at.restore();function ao(aH,aG,aE,ax,aF){at.save();aF=aF||{};if(aF.lineWidth==null||aF.lineWidth!=0){L.extend(true,at,aF);at.beginPath();at.moveTo(aH,aG);at.lineTo(aE,ax);at.stroke();at.restore()}}if(this.shadow){var av=[[this._left,this._bottom],[this._right,this._bottom],[this._right,this._top]];this.renderer.shadowRenderer.draw(at,av)}if(this.borderWidth!=0&&this.drawBorder){ao(this._left,this._top,this._right,this._top,{lineCap:"round",strokeStyle:aw.x2axis.borderColor,lineWidth:aw.x2axis.borderWidth});ao(this._right,this._top,this._right,this._bottom,{lineCap:"round",strokeStyle:aw.y2axis.borderColor,lineWidth:aw.y2axis.borderWidth});ao(this._right,this._bottom,this._left,this._bottom,{lineCap:"round",strokeStyle:aw.xaxis.borderColor,lineWidth:aw.xaxis.borderWidth});ao(this._left,this._bottom,this._left,this._top,{lineCap:"round",strokeStyle:aw.yaxis.borderColor,lineWidth:aw.yaxis.borderWidth})}at.restore();at=null;aw=null};L.jqplot.DivTitleRenderer=function(){};L.jqplot.DivTitleRenderer.prototype.init=function(ah){L.extend(true,this,ah)};L.jqplot.DivTitleRenderer.prototype.draw=function(){if(this._elem){this._elem.emptyForce();this._elem=null}var ak=this.renderer;var aj=document.createElement("div");this._elem=L(aj);this._elem.addClass("jqplot-title");if(!this.text){this.show=false;this._elem.height(0);this._elem.width(0)}else{if(this.text){var ah;if(this.color){ah=this.color}else{if(this.textColor){ah=this.textColor}}var ai={position:"absolute",top:"0px",left:"0px"};if(this._plotWidth){ai.width=this._plotWidth+"px"}if(this.fontSize){ai.fontSize=this.fontSize}if(typeof this.textAlign==="string"){ai.textAlign=this.textAlign}else{ai.textAlign="center"}if(ah){ai.color=ah}if(this.paddingBottom){ai.paddingBottom=this.paddingBottom}if(this.fontFamily){ai.fontFamily=this.fontFamily}this._elem.css(ai);if(this.escapeHtml){this._elem.text(this.text)}else{this._elem.html(this.text)}}}aj=null;return this._elem};L.jqplot.DivTitleRenderer.prototype.pack=function(){};var r=0.1;L.jqplot.LinePattern=function(aw,aq){var ap={dotted:[r,L.jqplot.config.dotGapLength],dashed:[L.jqplot.config.dashLength,L.jqplot.config.gapLength],solid:null};if(typeof aq==="string"){if(aq[0]==="."||aq[0]==="-"){var ax=aq;aq=[];for(var ao=0,al=ax.length;ao<al;ao++){if(ax[ao]==="."){aq.push(r)}else{if(ax[ao]==="-"){aq.push(L.jqplot.config.dashLength)}else{continue}}aq.push(L.jqplot.config.gapLength)}}else{aq=ap[aq]}}if(!(aq&&aq.length)){return aw}var ak=0;var ar=aq[0];var au=0;var at=0;var an=0;var ah=0;var av=function(ay,az){aw.moveTo(ay,az);au=ay;at=az;an=ay;ah=az};var aj=function(ay,aE){var aC=aw.lineWidth;var aA=ay-au;var az=aE-at;var aB=Math.sqrt(aA*aA+az*az);if((aB>0)&&(aC>0)){aA/=aB;az/=aB;while(true){var aD=aC*ar;if(aD<aB){au+=aD*aA;at+=aD*az;if((ak&1)==0){aw.lineTo(au,at)}else{aw.moveTo(au,at)}aB-=aD;ak++;if(ak>=aq.length){ak=0}ar=aq[ak]}else{au=ay;at=aE;if((ak&1)==0){aw.lineTo(au,at)}else{aw.moveTo(au,at)}ar-=aB/aC;break}}}};var ai=function(){aw.beginPath()};var am=function(){aj(an,ah)};return{moveTo:av,lineTo:aj,beginPath:ai,closePath:am}};L.jqplot.LineRenderer=function(){this.shapeRenderer=new L.jqplot.ShapeRenderer();this.shadowRenderer=new L.jqplot.ShadowRenderer()};L.jqplot.LineRenderer.prototype.init=function(ai,an){ai=ai||{};this._type="line";this.renderer.animation={show:false,direction:"left",speed:2500,_supported:true};this.renderer.smooth=false;this.renderer.tension=null;this.renderer.constrainSmoothing=true;this.renderer._smoothedData=[];this.renderer._smoothedPlotData=[];this.renderer._hiBandGridData=[];this.renderer._lowBandGridData=[];this.renderer._hiBandSmoothedData=[];this.renderer._lowBandSmoothedData=[];this.renderer.bandData=[];this.renderer.bands={show:false,hiData:[],lowData:[],color:this.color,showLines:false,fill:true,fillColor:null,_min:null,_max:null,interval:"3%"};var al={highlightMouseOver:ai.highlightMouseOver,highlightMouseDown:ai.highlightMouseDown,highlightColor:ai.highlightColor};delete (ai.highlightMouseOver);delete (ai.highlightMouseDown);delete (ai.highlightColor);L.extend(true,this.renderer,ai);this.renderer.options=ai;if(this.renderer.bandData.length>1&&(!ai.bands||ai.bands.show==null)){this.renderer.bands.show=true}else{if(ai.bands&&ai.bands.show==null&&ai.bands.interval!=null){this.renderer.bands.show=true}}if(this.fill){this.renderer.bands.show=false}if(this.renderer.bands.show){this.renderer.initBands.call(this,this.renderer.options,an)}if(this._stack){this.renderer.smooth=false}var am={lineJoin:this.lineJoin,lineCap:this.lineCap,fill:this.fill,isarc:false,strokeStyle:this.color,fillStyle:this.fillColor,lineWidth:this.lineWidth,linePattern:this.linePattern,closePath:this.fill};this.renderer.shapeRenderer.init(am);var aj=ai.shadowOffset;if(aj==null){if(this.lineWidth>2.5){aj=1.25*(1+(Math.atan((this.lineWidth/2.5))/0.785398163-1)*0.6)}else{aj=1.25*Math.atan((this.lineWidth/2.5))/0.785398163}}var ah={lineJoin:this.lineJoin,lineCap:this.lineCap,fill:this.fill,isarc:false,angle:this.shadowAngle,offset:aj,alpha:this.shadowAlpha,depth:this.shadowDepth,lineWidth:this.lineWidth,linePattern:this.linePattern,closePath:this.fill};this.renderer.shadowRenderer.init(ah);this._areaPoints=[];this._boundingBox=[[],[]];if(!this.isTrendline&&this.fill||this.renderer.bands.show){this.highlightMouseOver=true;this.highlightMouseDown=false;this.highlightColor=null;if(al.highlightMouseDown&&al.highlightMouseOver==null){al.highlightMouseOver=false}L.extend(true,this,{highlightMouseOver:al.highlightMouseOver,highlightMouseDown:al.highlightMouseDown,highlightColor:al.highlightColor});if(!this.highlightColor){var ak=(this.renderer.bands.show)?this.renderer.bands.fillColor:this.fillColor;this.highlightColor=L.jqplot.computeHighlightColors(ak)}if(this.highlighter){this.highlighter.show=false}}if(!this.isTrendline&&an){an.plugins.lineRenderer={};an.postInitHooks.addOnce(z);an.postDrawHooks.addOnce(af);an.eventListenerHooks.addOnce("jqplotMouseMove",h);an.eventListenerHooks.addOnce("jqplotMouseDown",e);an.eventListenerHooks.addOnce("jqplotMouseUp",ad);an.eventListenerHooks.addOnce("jqplotClick",g);an.eventListenerHooks.addOnce("jqplotRightClick",s)}};L.jqplot.LineRenderer.prototype.initBands=function(ak,av){var al=ak.bandData||[];var an=this.renderer.bands;an.hiData=[];an.lowData=[];var aB=this.data;an._max=null;an._min=null;if(al.length==2){if(L.isArray(al[0][0])){var ao;var ah=0,ar=0;for(var aw=0,at=al[0].length;aw<at;aw++){ao=al[0][aw];if((ao[1]!=null&&ao[1]>an._max)||an._max==null){an._max=ao[1]}if((ao[1]!=null&&ao[1]<an._min)||an._min==null){an._min=ao[1]}}for(var aw=0,at=al[1].length;aw<at;aw++){ao=al[1][aw];if((ao[1]!=null&&ao[1]>an._max)||an._max==null){an._max=ao[1];ar=1}if((ao[1]!=null&&ao[1]<an._min)||an._min==null){an._min=ao[1];ah=1}}if(ar===ah){an.show=false}an.hiData=al[ar];an.lowData=al[ah]}else{if(al[0].length===aB.length&&al[1].length===aB.length){var aj=(al[0][0]>al[1][0])?0:1;var aC=(aj)?0:1;for(var aw=0,at=aB.length;aw<at;aw++){an.hiData.push([aB[aw][0],al[aj][aw]]);an.lowData.push([aB[aw][0],al[aC][aw]])}}else{an.show=false}}}else{if(al.length>2&&!L.isArray(al[0][0])){var aj=(al[0][0]>al[0][1])?0:1;var aC=(aj)?0:1;for(var aw=0,at=al.length;aw<at;aw++){an.hiData.push([aB[aw][0],al[aw][aj]]);an.lowData.push([aB[aw][0],al[aw][aC]])}}else{var aq=an.interval;var aA=null;var az=null;var ai=null;var au=null;if(L.isArray(aq)){aA=aq[0];az=aq[1]}else{aA=aq}if(isNaN(aA)){if(aA.charAt(aA.length-1)==="%"){ai="multiply";aA=parseFloat(aA)/100+1}}else{aA=parseFloat(aA);ai="add"}if(az!==null&&isNaN(az)){if(az.charAt(az.length-1)==="%"){au="multiply";az=parseFloat(az)/100+1}}else{if(az!==null){az=parseFloat(az);au="add"}}if(aA!==null){if(az===null){az=-aA;au=ai;if(au==="multiply"){az+=2}}if(aA<az){var ax=aA;aA=az;az=ax;ax=ai;ai=au;au=ax}for(var aw=0,at=aB.length;aw<at;aw++){switch(ai){case"add":an.hiData.push([aB[aw][0],aB[aw][1]+aA]);break;case"multiply":an.hiData.push([aB[aw][0],aB[aw][1]*aA]);break}switch(au){case"add":an.lowData.push([aB[aw][0],aB[aw][1]+az]);break;case"multiply":an.lowData.push([aB[aw][0],aB[aw][1]*az]);break}}}else{an.show=false}}}var am=an.hiData;var ap=an.lowData;for(var aw=0,at=am.length;aw<at;aw++){if((am[aw][1]!=null&&am[aw][1]>an._max)||an._max==null){an._max=am[aw][1]}}for(var aw=0,at=ap.length;aw<at;aw++){if((ap[aw][1]!=null&&ap[aw][1]<an._min)||an._min==null){an._min=ap[aw][1]}}if(an.fillColor===null){var ay=L.jqplot.getColorComponents(an.color);ay[3]=ay[3]*0.5;an.fillColor="rgba("+ay[0]+", "+ay[1]+", "+ay[2]+", "+ay[3]+")"}};function K(ai,ah){return(3.4182054+ah)*Math.pow(ai,-0.3534992)}function n(aj,ai){var ah=Math.sqrt(Math.pow((ai[0]-aj[0]),2)+Math.pow((ai[1]-aj[1]),2));return 5.7648*Math.log(ah)+7.4456}function A(ah){var ai=(Math.exp(2*ah)-1)/(Math.exp(2*ah)+1);return ai}function J(aJ){var at=this.renderer.smooth;var aD=this.canvas.getWidth();var an=this._xaxis.series_p2u;var aG=this._yaxis.series_p2u;var aF=null;var am=null;var az=aJ.length/aD;var aj=[];var ay=[];if(!isNaN(parseFloat(at))){aF=parseFloat(at)}else{aF=K(az,0.5)}var aw=[];var ak=[];for(var aE=0,aA=aJ.length;aE<aA;aE++){aw.push(aJ[aE][1]);ak.push(aJ[aE][0])}function av(aK,aL){if(aK-aL==0){return Math.pow(10,10)}else{return aK-aL}}var ax,ar,aq,ap;var ah=aJ.length-1;for(var al=1,aB=aJ.length;al<aB;al++){var ai=[];var au=[];for(var aC=0;aC<2;aC++){var aE=al-1+aC;if(aE==0||aE==ah){ai[aC]=Math.pow(10,10)}else{if(aw[aE+1]-aw[aE]==0||aw[aE]-aw[aE-1]==0){ai[aC]=0}else{if(((ak[aE+1]-ak[aE])/(aw[aE+1]-aw[aE])+(ak[aE]-ak[aE-1])/(aw[aE]-aw[aE-1]))==0){ai[aC]=0}else{if((aw[aE+1]-aw[aE])*(aw[aE]-aw[aE-1])<0){ai[aC]=0}else{ai[aC]=2/(av(ak[aE+1],ak[aE])/(aw[aE+1]-aw[aE])+av(ak[aE],ak[aE-1])/(aw[aE]-aw[aE-1]))}}}}}if(al==1){ai[0]=3/2*(aw[1]-aw[0])/av(ak[1],ak[0])-ai[1]/2}else{if(al==ah){ai[1]=3/2*(aw[ah]-aw[ah-1])/av(ak[ah],ak[ah-1])-ai[0]/2}}au[0]=-2*(ai[1]+2*ai[0])/av(ak[al],ak[al-1])+6*(aw[al]-aw[al-1])/Math.pow(av(ak[al],ak[al-1]),2);au[1]=2*(2*ai[1]+ai[0])/av(ak[al],ak[al-1])-6*(aw[al]-aw[al-1])/Math.pow(av(ak[al],ak[al-1]),2);ap=1/6*(au[1]-au[0])/av(ak[al],ak[al-1]);aq=1/2*(ak[al]*au[0]-ak[al-1]*au[1])/av(ak[al],ak[al-1]);ar=(aw[al]-aw[al-1]-aq*(Math.pow(ak[al],2)-Math.pow(ak[al-1],2))-ap*(Math.pow(ak[al],3)-Math.pow(ak[al-1],3)))/av(ak[al],ak[al-1]);ax=aw[al-1]-ar*ak[al-1]-aq*Math.pow(ak[al-1],2)-ap*Math.pow(ak[al-1],3);var aI=(ak[al]-ak[al-1])/aF;var aH,ao;for(var aC=0,aA=aF;aC<aA;aC++){aH=[];ao=ak[al-1]+aC*aI;aH.push(ao);aH.push(ax+ar*ao+aq*Math.pow(ao,2)+ap*Math.pow(ao,3));aj.push(aH);ay.push([an(aH[0]),aG(aH[1])])}}aj.push(aJ[aE]);ay.push([an(aJ[aE][0]),aG(aJ[aE][1])]);return[aj,ay]}function F(ap){var ao=this.renderer.smooth;var aU=this.renderer.tension;var ah=this.canvas.getWidth();var aH=this._xaxis.series_p2u;var aq=this._yaxis.series_p2u;var aI=null;var aJ=null;var aT=null;var aO=null;var aM=null;var at=null;var aR=null;var am=null;var aK,aL,aD,aC,aA,ay;var ak,ai,av,au;var aB,az,aN;var aw=[];var aj=[];var al=ap.length/ah;var aS,ax,aF,aG,aE;var ar=[];var an=[];if(!isNaN(parseFloat(ao))){aI=parseFloat(ao)}else{aI=K(al,0.5)}if(!isNaN(parseFloat(aU))){aU=parseFloat(aU)}for(var aQ=0,aP=ap.length-1;aQ<aP;aQ++){if(aU===null){at=Math.abs((ap[aQ+1][1]-ap[aQ][1])/(ap[aQ+1][0]-ap[aQ][0]));aS=0.3;ax=0.6;aF=(ax-aS)/2;aG=2.5;aE=-1.4;am=at/aG+aE;aO=aF*A(am)-aF*A(aE)+aS;if(aQ>0){aR=Math.abs((ap[aQ][1]-ap[aQ-1][1])/(ap[aQ][0]-ap[aQ-1][0]))}am=aR/aG+aE;aM=aF*A(am)-aF*A(aE)+aS;aT=(aO+aM)/2}else{aT=aU}for(aK=0;aK<aI;aK++){aL=aK/aI;aD=(1+2*aL)*Math.pow((1-aL),2);aC=aL*Math.pow((1-aL),2);aA=Math.pow(aL,2)*(3-2*aL);ay=Math.pow(aL,2)*(aL-1);if(ap[aQ-1]){ak=aT*(ap[aQ+1][0]-ap[aQ-1][0]);ai=aT*(ap[aQ+1][1]-ap[aQ-1][1])}else{ak=aT*(ap[aQ+1][0]-ap[aQ][0]);ai=aT*(ap[aQ+1][1]-ap[aQ][1])}if(ap[aQ+2]){av=aT*(ap[aQ+2][0]-ap[aQ][0]);au=aT*(ap[aQ+2][1]-ap[aQ][1])}else{av=aT*(ap[aQ+1][0]-ap[aQ][0]);au=aT*(ap[aQ+1][1]-ap[aQ][1])}aB=aD*ap[aQ][0]+aA*ap[aQ+1][0]+aC*ak+ay*av;az=aD*ap[aQ][1]+aA*ap[aQ+1][1]+aC*ai+ay*au;aN=[aB,az];ar.push(aN);an.push([aH(aB),aq(az)])}}ar.push(ap[aP]);an.push([aH(ap[aP][0]),aq(ap[aP][1])]);return[ar,an]}L.jqplot.LineRenderer.prototype.setGridData=function(ap){var al=this._xaxis.series_u2p;var ah=this._yaxis.series_u2p;var am=this._plotData;var aq=this._prevPlotData;this.gridData=[];this._prevGridData=[];this.renderer._smoothedData=[];this.renderer._smoothedPlotData=[];this.renderer._hiBandGridData=[];this.renderer._lowBandGridData=[];this.renderer._hiBandSmoothedData=[];this.renderer._lowBandSmoothedData=[];var ak=this.renderer.bands;var ai=false;for(var an=0,aj=am.length;an<aj;an++){if(am[an][0]!=null&&am[an][1]!=null){this.gridData.push([al.call(this._xaxis,am[an][0]),ah.call(this._yaxis,am[an][1])])}else{if(am[an][0]==null){ai=true;this.gridData.push([null,ah.call(this._yaxis,am[an][1])])}else{if(am[an][1]==null){ai=true;this.gridData.push([al.call(this._xaxis,am[an][0]),null])}}}if(aq[an]!=null&&aq[an][0]!=null&&aq[an][1]!=null){this._prevGridData.push([al.call(this._xaxis,aq[an][0]),ah.call(this._yaxis,aq[an][1])])}else{if(aq[an]!=null&&aq[an][0]==null){this._prevGridData.push([null,ah.call(this._yaxis,aq[an][1])])}else{if(aq[an]!=null&&aq[an][0]!=null&&aq[an][1]==null){this._prevGridData.push([al.call(this._xaxis,aq[an][0]),null])}}}}if(ai){this.renderer.smooth=false;if(this._type==="line"){ak.show=false}}if(this._type==="line"&&ak.show){for(var an=0,aj=ak.hiData.length;an<aj;an++){this.renderer._hiBandGridData.push([al.call(this._xaxis,ak.hiData[an][0]),ah.call(this._yaxis,ak.hiData[an][1])])}for(var an=0,aj=ak.lowData.length;an<aj;an++){this.renderer._lowBandGridData.push([al.call(this._xaxis,ak.lowData[an][0]),ah.call(this._yaxis,ak.lowData[an][1])])}}if(this._type==="line"&&this.renderer.smooth&&this.gridData.length>2){var ao;if(this.renderer.constrainSmoothing){ao=J.call(this,this.gridData);this.renderer._smoothedData=ao[0];this.renderer._smoothedPlotData=ao[1];if(ak.show){ao=J.call(this,this.renderer._hiBandGridData);this.renderer._hiBandSmoothedData=ao[0];ao=J.call(this,this.renderer._lowBandGridData);this.renderer._lowBandSmoothedData=ao[0]}ao=null}else{ao=F.call(this,this.gridData);this.renderer._smoothedData=ao[0];this.renderer._smoothedPlotData=ao[1];if(ak.show){ao=F.call(this,this.renderer._hiBandGridData);this.renderer._hiBandSmoothedData=ao[0];ao=F.call(this,this.renderer._lowBandGridData);this.renderer._lowBandSmoothedData=ao[0]}ao=null}}};L.jqplot.LineRenderer.prototype.makeGridData=function(ao,aq){var am=this._xaxis.series_u2p;var ah=this._yaxis.series_u2p;var ar=[];var aj=[];this.renderer._smoothedData=[];this.renderer._smoothedPlotData=[];this.renderer._hiBandGridData=[];this.renderer._lowBandGridData=[];this.renderer._hiBandSmoothedData=[];this.renderer._lowBandSmoothedData=[];var al=this.renderer.bands;var ai=false;for(var an=0;an<ao.length;an++){if(ao[an][0]!=null&&ao[an][1]!=null){ar.push([am.call(this._xaxis,ao[an][0]),ah.call(this._yaxis,ao[an][1])])}else{if(ao[an][0]==null){ai=true;ar.push([null,ah.call(this._yaxis,ao[an][1])])}else{if(ao[an][1]==null){ai=true;ar.push([am.call(this._xaxis,ao[an][0]),null])}}}}if(ai){this.renderer.smooth=false;if(this._type==="line"){al.show=false}}if(this._type==="line"&&al.show){for(var an=0,ak=al.hiData.length;an<ak;an++){this.renderer._hiBandGridData.push([am.call(this._xaxis,al.hiData[an][0]),ah.call(this._yaxis,al.hiData[an][1])])}for(var an=0,ak=al.lowData.length;an<ak;an++){this.renderer._lowBandGridData.push([am.call(this._xaxis,al.lowData[an][0]),ah.call(this._yaxis,al.lowData[an][1])])}}if(this._type==="line"&&this.renderer.smooth&&ar.length>2){var ap;if(this.renderer.constrainSmoothing){ap=J.call(this,ar);this.renderer._smoothedData=ap[0];this.renderer._smoothedPlotData=ap[1];if(al.show){ap=J.call(this,this.renderer._hiBandGridData);this.renderer._hiBandSmoothedData=ap[0];ap=J.call(this,this.renderer._lowBandGridData);this.renderer._lowBandSmoothedData=ap[0]}ap=null}else{ap=F.call(this,ar);this.renderer._smoothedData=ap[0];this.renderer._smoothedPlotData=ap[1];if(al.show){ap=F.call(this,this.renderer._hiBandGridData);this.renderer._hiBandSmoothedData=ap[0];ap=F.call(this,this.renderer._lowBandGridData);this.renderer._lowBandSmoothedData=ap[0]}ap=null}}return ar};L.jqplot.LineRenderer.prototype.draw=function(ax,aI,ai,aB){var aC;var aq=L.extend(true,{},ai);var ak=(aq.shadow!=u)?aq.shadow:this.shadow;var aJ=(aq.showLine!=u)?aq.showLine:this.showLine;var aA=(aq.fill!=u)?aq.fill:this.fill;var ah=(aq.fillAndStroke!=u)?aq.fillAndStroke:this.fillAndStroke;var ar,ay,av,aE;ax.save();if(aI.length){if(aJ){if(aA){if(this.fillToZero){var aF=this.negativeColor;if(!this.useNegativeColors){aF=aq.fillStyle}var ao=false;var ap=aq.fillStyle;if(ah){var aH=aI.slice(0)}if(this.index==0||!this._stack){var aw=[];var aL=(this.renderer.smooth)?this.renderer._smoothedPlotData:this._plotData;this._areaPoints=[];var aG=this._yaxis.series_u2p(this.fillToValue);var aj=this._xaxis.series_u2p(this.fillToValue);aq.closePath=true;if(this.fillAxis=="y"){aw.push([aI[0][0],aG]);this._areaPoints.push([aI[0][0],aG]);for(var aC=0;aC<aI.length-1;aC++){aw.push(aI[aC]);this._areaPoints.push(aI[aC]);if(aL[aC][1]*aL[aC+1][1]<=0){if(aL[aC][1]<0){ao=true;aq.fillStyle=aF}else{ao=false;aq.fillStyle=ap}var an=aI[aC][0]+(aI[aC+1][0]-aI[aC][0])*(aG-aI[aC][1])/(aI[aC+1][1]-aI[aC][1]);aw.push([an,aG]);this._areaPoints.push([an,aG]);if(ak){this.renderer.shadowRenderer.draw(ax,aw,aq)}this.renderer.shapeRenderer.draw(ax,aw,aq);aw=[[an,aG]]}}if(aL[aI.length-1][1]<0){ao=true;aq.fillStyle=aF}else{ao=false;aq.fillStyle=ap}aw.push(aI[aI.length-1]);this._areaPoints.push(aI[aI.length-1]);aw.push([aI[aI.length-1][0],aG]);this._areaPoints.push([aI[aI.length-1][0],aG])}if(ak){this.renderer.shadowRenderer.draw(ax,aw,aq)}this.renderer.shapeRenderer.draw(ax,aw,aq)}else{var au=this._prevGridData;for(var aC=au.length;aC>0;aC--){aI.push(au[aC-1])}if(ak){this.renderer.shadowRenderer.draw(ax,aI,aq)}this._areaPoints=aI;this.renderer.shapeRenderer.draw(ax,aI,aq)}}else{if(ah){var aH=aI.slice(0)}if(this.index==0||!this._stack){var al=ax.canvas.height;aI.unshift([aI[0][0],al]);var aD=aI.length;aI.push([aI[aD-1][0],al])}else{var au=this._prevGridData;for(var aC=au.length;aC>0;aC--){aI.push(au[aC-1])}}this._areaPoints=aI;if(ak){this.renderer.shadowRenderer.draw(ax,aI,aq)}this.renderer.shapeRenderer.draw(ax,aI,aq)}if(ah){var az=L.extend(true,{},aq,{fill:false,closePath:false});this.renderer.shapeRenderer.draw(ax,aH,az);if(this.markerRenderer.show){if(this.renderer.smooth){aH=this.gridData}for(aC=0;aC<aH.length;aC++){this.markerRenderer.draw(aH[aC][0],aH[aC][1],ax,aq.markerOptions)}}}}else{if(this.renderer.bands.show){var am;var aK=L.extend(true,{},aq);if(this.renderer.bands.showLines){am=(this.renderer.smooth)?this.renderer._hiBandSmoothedData:this.renderer._hiBandGridData;this.renderer.shapeRenderer.draw(ax,am,aq);am=(this.renderer.smooth)?this.renderer._lowBandSmoothedData:this.renderer._lowBandGridData;this.renderer.shapeRenderer.draw(ax,am,aK)}if(this.renderer.bands.fill){if(this.renderer.smooth){am=this.renderer._hiBandSmoothedData.concat(this.renderer._lowBandSmoothedData.reverse())}else{am=this.renderer._hiBandGridData.concat(this.renderer._lowBandGridData.reverse())}this._areaPoints=am;aK.closePath=true;aK.fill=true;aK.fillStyle=this.renderer.bands.fillColor;this.renderer.shapeRenderer.draw(ax,am,aK)}}if(ak){this.renderer.shadowRenderer.draw(ax,aI,aq)}this.renderer.shapeRenderer.draw(ax,aI,aq)}}var ar=av=ay=aE=null;for(aC=0;aC<this._areaPoints.length;aC++){var at=this._areaPoints[aC];if(ar>at[0]||ar==null){ar=at[0]}if(aE<at[1]||aE==null){aE=at[1]}if(av<at[0]||av==null){av=at[0]}if(ay>at[1]||ay==null){ay=at[1]}}if(this.type==="line"&&this.renderer.bands.show){aE=this._yaxis.series_u2p(this.renderer.bands._min);ay=this._yaxis.series_u2p(this.renderer.bands._max)}this._boundingBox=[[ar,aE],[av,ay]];if(this.markerRenderer.show&&!aA){if(this.renderer.smooth){aI=this.gridData}for(aC=0;aC<aI.length;aC++){if(aI[aC][0]!=null&&aI[aC][1]!=null){this.markerRenderer.draw(aI[aC][0],aI[aC][1],ax,aq.markerOptions)}}}}ax.restore()};L.jqplot.LineRenderer.prototype.drawShadow=function(ah,aj,ai){};function z(ak,aj,ah){for(var ai=0;ai<this.series.length;ai++){if(this.series[ai].renderer.constructor==L.jqplot.LineRenderer){if(this.series[ai].highlightMouseOver){this.series[ai].highlightMouseDown=false}}}}function af(){if(this.plugins.lineRenderer&&this.plugins.lineRenderer.highlightCanvas){this.plugins.lineRenderer.highlightCanvas.resetCanvas();this.plugins.lineRenderer.highlightCanvas=null}this.plugins.lineRenderer.highlightedSeriesIndex=null;this.plugins.lineRenderer.highlightCanvas=new L.jqplot.GenericCanvas();this.eventCanvas._elem.before(this.plugins.lineRenderer.highlightCanvas.createElement(this._gridPadding,"jqplot-lineRenderer-highlight-canvas",this._plotDimensions,this));this.plugins.lineRenderer.highlightCanvas.setContext();this.eventCanvas._elem.bind("mouseleave",{plot:this},function(ah){aa(ah.data.plot)})}function ac(an,am,ak,aj){var ai=an.series[am];var ah=an.plugins.lineRenderer.highlightCanvas;ah._ctx.clearRect(0,0,ah._ctx.canvas.width,ah._ctx.canvas.height);ai._highlightedPoint=ak;an.plugins.lineRenderer.highlightedSeriesIndex=am;var al={fillStyle:ai.highlightColor};if(ai.type==="line"&&ai.renderer.bands.show){al.fill=true;al.closePath=true}ai.renderer.shapeRenderer.draw(ah._ctx,aj,al);ah=null}function aa(aj){var ah=aj.plugins.lineRenderer.highlightCanvas;ah._ctx.clearRect(0,0,ah._ctx.canvas.width,ah._ctx.canvas.height);for(var ai=0;ai<aj.series.length;ai++){aj.series[ai]._highlightedPoint=null}aj.plugins.lineRenderer.highlightedSeriesIndex=null;aj.target.trigger("jqplotDataUnhighlight");ah=null}function h(al,ak,ao,an,am){if(an){var aj=[an.seriesIndex,an.pointIndex,an.data];var ai=jQuery.Event("jqplotDataMouseOver");ai.pageX=al.pageX;ai.pageY=al.pageY;am.target.trigger(ai,aj);if(am.series[aj[0]].highlightMouseOver&&!(aj[0]==am.plugins.lineRenderer.highlightedSeriesIndex)){var ah=jQuery.Event("jqplotDataHighlight");ah.which=al.which;ah.pageX=al.pageX;ah.pageY=al.pageY;am.target.trigger(ah,aj);ac(am,an.seriesIndex,an.pointIndex,an.points)}}else{if(an==null){aa(am)}}}function e(ak,aj,an,am,al){if(am){var ai=[am.seriesIndex,am.pointIndex,am.data];if(al.series[ai[0]].highlightMouseDown&&!(ai[0]==al.plugins.lineRenderer.highlightedSeriesIndex)){var ah=jQuery.Event("jqplotDataHighlight");ah.which=ak.which;ah.pageX=ak.pageX;ah.pageY=ak.pageY;al.target.trigger(ah,ai);ac(al,am.seriesIndex,am.pointIndex,am.points)}}else{if(am==null){aa(al)}}}function ad(aj,ai,am,al,ak){var ah=ak.plugins.lineRenderer.highlightedSeriesIndex;if(ah!=null&&ak.series[ah].highlightMouseDown){aa(ak)}}function g(ak,aj,an,am,al){if(am){var ai=[am.seriesIndex,am.pointIndex,am.data];var ah=jQuery.Event("jqplotDataClick");ah.which=ak.which;ah.pageX=ak.pageX;ah.pageY=ak.pageY;al.target.trigger(ah,ai)}}function s(al,ak,ao,an,am){if(an){var aj=[an.seriesIndex,an.pointIndex,an.data];var ah=am.plugins.lineRenderer.highlightedSeriesIndex;if(ah!=null&&am.series[ah].highlightMouseDown){aa(am)}var ai=jQuery.Event("jqplotDataRightClick");ai.which=al.which;ai.pageX=al.pageX;ai.pageY=al.pageY;am.target.trigger(ai,aj)}}L.jqplot.LinearAxisRenderer=function(){};L.jqplot.LinearAxisRenderer.prototype.init=function(ah){this.breakPoints=null;this.breakTickLabel="&asymp;";this.drawBaseline=true;this.baselineWidth=null;this.baselineColor=null;this.forceTickAt0=false;this.forceTickAt100=false;this.tickInset=0;this.minorTicks=0;this.alignTicks=false;this._autoFormatString="";this._overrideFormatString=false;this._scalefact=1;L.extend(true,this,ah);if(this.breakPoints){if(!L.isArray(this.breakPoints)){this.breakPoints=null}else{if(this.breakPoints.length<2||this.breakPoints[1]<=this.breakPoints[0]){this.breakPoints=null}}}if(this.numberTicks!=null&&this.numberTicks<2){this.numberTicks=2}this.resetDataBounds()};L.jqplot.LinearAxisRenderer.prototype.draw=function(ah,ao){if(this.show){this.renderer.createTicks.call(this,ao);var an=0;var ai;if(this._elem){this._elem.emptyForce();this._elem=null}this._elem=L(document.createElement("div"));this._elem.addClass("jqplot-axis jqplot-"+this.name);this._elem.css("position","absolute");if(this.name=="xaxis"||this.name=="x2axis"){this._elem.width(this._plotDimensions.width)}else{this._elem.height(this._plotDimensions.height)}this.labelOptions.axis=this.name;this._label=new this.labelRenderer(this.labelOptions);if(this._label.show){var am=this._label.draw(ah,ao);am.appendTo(this._elem);am=null}var al=this._ticks;var ak;for(var aj=0;aj<al.length;aj++){ak=al[aj];if(ak.show&&ak.showLabel&&(!ak.isMinorTick||this.showMinorTicks)){this._elem.append(ak.draw(ah,ao))}}ak=null;al=null}return this._elem};L.jqplot.LinearAxisRenderer.prototype.reset=function(){this.min=this._options.min;this.max=this._options.max;this.tickInterval=this._options.tickInterval;this.numberTicks=this._options.numberTicks;this._autoFormatString="";if(this._overrideFormatString&&this.tickOptions&&this.tickOptions.formatString){this.tickOptions.formatString=""}};L.jqplot.LinearAxisRenderer.prototype.set=function(){var ao=0;var aj;var ai=0;var an=0;var ah=(this._label==null)?false:this._label.show;if(this.show){var am=this._ticks;var al;for(var ak=0;ak<am.length;ak++){al=am[ak];if(!al._breakTick&&al.show&&al.showLabel&&(!al.isMinorTick||this.showMinorTicks)){if(this.name=="xaxis"||this.name=="x2axis"){aj=al._elem.outerHeight(true)}else{aj=al._elem.outerWidth(true)}if(aj>ao){ao=aj}}}al=null;am=null;if(ah){ai=this._label._elem.outerWidth(true);an=this._label._elem.outerHeight(true)}if(this.name=="xaxis"){ao=ao+an;this._elem.css({height:ao+"px",left:"0px",bottom:"0px"})}else{if(this.name=="x2axis"){ao=ao+an;this._elem.css({height:ao+"px",left:"0px",top:"0px"})}else{if(this.name=="yaxis"){ao=ao+ai;this._elem.css({width:ao+"px",left:"0px",top:"0px"});if(ah&&this._label.constructor==L.jqplot.AxisLabelRenderer){this._label._elem.css("width",ai+"px")}}else{ao=ao+ai;this._elem.css({width:ao+"px",right:"0px",top:"0px"});if(ah&&this._label.constructor==L.jqplot.AxisLabelRenderer){this._label._elem.css("width",ai+"px")}}}}}};L.jqplot.LinearAxisRenderer.prototype.createTicks=function(aj){var aT=this._ticks;var aK=this.ticks;var az=this.name;var aB=this._dataBounds;var ah=(this.name.charAt(0)==="x")?this._plotDimensions.width:this._plotDimensions.height;var an;var a6,aI;var ap,ao;var a4,a0;var aH=this.min;var a5=this.max;var aW=this.numberTicks;var ba=this.tickInterval;var am=30;this._scalefact=(Math.max(ah,am+1)-am)/300;if(aK.length){for(a0=0;a0<aK.length;a0++){var aO=aK[a0];var aU=new this.tickRenderer(this.tickOptions);if(L.isArray(aO)){aU.value=aO[0];if(this.breakPoints){if(aO[0]==this.breakPoints[0]){aU.label=this.breakTickLabel;aU._breakTick=true;aU.showGridline=false;aU.showMark=false}else{if(aO[0]>this.breakPoints[0]&&aO[0]<=this.breakPoints[1]){aU.show=false;aU.showGridline=false;aU.label=aO[1]}else{aU.label=aO[1]}}}else{aU.label=aO[1]}aU.setTick(aO[0],this.name);this._ticks.push(aU)}else{if(L.isPlainObject(aO)){L.extend(true,aU,aO);aU.axis=this.name;this._ticks.push(aU)}else{aU.value=aO;if(this.breakPoints){if(aO==this.breakPoints[0]){aU.label=this.breakTickLabel;aU._breakTick=true;aU.showGridline=false;aU.showMark=false}else{if(aO>this.breakPoints[0]&&aO<=this.breakPoints[1]){aU.show=false;aU.showGridline=false}}}aU.setTick(aO,this.name);this._ticks.push(aU)}}}this.numberTicks=aK.length;this.min=this._ticks[0].value;this.max=this._ticks[this.numberTicks-1].value;this.tickInterval=(this.max-this.min)/(this.numberTicks-1)}else{if(az=="xaxis"||az=="x2axis"){ah=this._plotDimensions.width}else{ah=this._plotDimensions.height}var ax=this.numberTicks;if(this.alignTicks){if(this.name==="x2axis"&&aj.axes.xaxis.show){ax=aj.axes.xaxis.numberTicks}else{if(this.name.charAt(0)==="y"&&this.name!=="yaxis"&&this.name!=="yMidAxis"&&aj.axes.yaxis.show){ax=aj.axes.yaxis.numberTicks}}}a6=((this.min!=null)?this.min:aB.min);aI=((this.max!=null)?this.max:aB.max);var av=aI-a6;var aS,ay;var at;if(this.tickOptions==null||!this.tickOptions.formatString){this._overrideFormatString=true}if(this.min==null||this.max==null&&this.tickInterval==null&&!this.autoscale){if(this.forceTickAt0){if(a6>0){a6=0}if(aI<0){aI=0}}if(this.forceTickAt100){if(a6>100){a6=100}if(aI<100){aI=100}}var aE=false,a1=false;if(this.min!=null){aE=true}else{if(this.max!=null){a1=true}}var aP=L.jqplot.LinearTickGenerator(a6,aI,this._scalefact,ax,aE,a1);var aw=(this.min!=null)?a6:a6+av*(this.padMin-1);var aQ=(this.max!=null)?aI:aI-av*(this.padMax-1);if(a6<aw||aI>aQ){aw=(this.min!=null)?a6:a6-av*(this.padMin-1);aQ=(this.max!=null)?aI:aI+av*(this.padMax-1);aP=L.jqplot.LinearTickGenerator(aw,aQ,this._scalefact,ax,aE,a1)}this.min=aP[0];this.max=aP[1];this.numberTicks=aP[2];this._autoFormatString=aP[3];this.tickInterval=aP[4]}else{if(a6==aI){var ai=0.05;if(a6>0){ai=Math.max(Math.log(a6)/Math.LN10,0.05)}a6-=ai;aI+=ai}if(this.autoscale&&this.min==null&&this.max==null){var ak,al,ar;var aC=false;var aN=false;var aA={min:null,max:null,average:null,stddev:null};for(var a0=0;a0<this._series.length;a0++){var aV=this._series[a0];var aD=(aV.fillAxis=="x")?aV._xaxis.name:aV._yaxis.name;if(this.name==aD){var aR=aV._plotValues[aV.fillAxis];var aG=aR[0];var a2=aR[0];for(var aZ=1;aZ<aR.length;aZ++){if(aR[aZ]<aG){aG=aR[aZ]}else{if(aR[aZ]>a2){a2=aR[aZ]}}}var au=(a2-aG)/a2;if(aV.renderer.constructor==L.jqplot.BarRenderer){if(aG>=0&&(aV.fillToZero||au>0.1)){aC=true}else{aC=false;if(aV.fill&&aV.fillToZero&&aG<0&&a2>0){aN=true}else{aN=false}}}else{if(aV.fill){if(aG>=0&&(aV.fillToZero||au>0.1)){aC=true}else{if(aG<0&&a2>0&&aV.fillToZero){aC=false;aN=true}else{aC=false;aN=false}}}else{if(aG<0){aC=false}}}}}if(aC){this.numberTicks=2+Math.ceil((ah-(this.tickSpacing-1))/this.tickSpacing);this.min=0;aH=0;al=aI/(this.numberTicks-1);at=Math.pow(10,Math.abs(Math.floor(Math.log(al)/Math.LN10)));if(al/at==parseInt(al/at,10)){al+=at}this.tickInterval=Math.ceil(al/at)*at;this.max=this.tickInterval*(this.numberTicks-1)}else{if(aN){this.numberTicks=2+Math.ceil((ah-(this.tickSpacing-1))/this.tickSpacing);var aJ=Math.ceil(Math.abs(a6)/av*(this.numberTicks-1));var a9=this.numberTicks-1-aJ;al=Math.max(Math.abs(a6/aJ),Math.abs(aI/a9));at=Math.pow(10,Math.abs(Math.floor(Math.log(al)/Math.LN10)));this.tickInterval=Math.ceil(al/at)*at;this.max=this.tickInterval*a9;this.min=-this.tickInterval*aJ}else{if(this.numberTicks==null){if(this.tickInterval){this.numberTicks=3+Math.ceil(av/this.tickInterval)}else{this.numberTicks=2+Math.ceil((ah-(this.tickSpacing-1))/this.tickSpacing)}}if(this.tickInterval==null){al=av/(this.numberTicks-1);if(al<1){at=Math.pow(10,Math.abs(Math.floor(Math.log(al)/Math.LN10)))}else{at=1}this.tickInterval=Math.ceil(al*at*this.pad)/at}else{at=1/this.tickInterval}ak=this.tickInterval*(this.numberTicks-1);ar=(ak-av)/2;if(this.min==null){this.min=Math.floor(at*(a6-ar))/at}if(this.max==null){this.max=this.min+ak}}}var aF=L.jqplot.getSignificantFigures(this.tickInterval);var aM;if(aF.digitsLeft>=aF.significantDigits){aM="%d"}else{var at=Math.max(0,5-aF.digitsLeft);at=Math.min(at,aF.digitsRight);aM="%."+at+"f"}this._autoFormatString=aM}else{aS=(this.min!=null)?this.min:a6-av*(this.padMin-1);ay=(this.max!=null)?this.max:aI+av*(this.padMax-1);av=ay-aS;if(this.numberTicks==null){if(this.tickInterval!=null){this.numberTicks=Math.ceil((ay-aS)/this.tickInterval)+1}else{if(ah>100){this.numberTicks=parseInt(3+(ah-100)/75,10)}else{this.numberTicks=2}}}if(this.tickInterval==null){this.tickInterval=av/(this.numberTicks-1)}if(this.max==null){ay=aS+this.tickInterval*(this.numberTicks-1)}if(this.min==null){aS=ay-this.tickInterval*(this.numberTicks-1)}var aF=L.jqplot.getSignificantFigures(this.tickInterval);var aM;if(aF.digitsLeft>=aF.significantDigits){aM="%d"}else{var at=Math.max(0,5-aF.digitsLeft);at=Math.min(at,aF.digitsRight);aM="%."+at+"f"}this._autoFormatString=aM;this.min=aS;this.max=ay}if(this.renderer.constructor==L.jqplot.LinearAxisRenderer&&this._autoFormatString==""){av=this.max-this.min;var a7=new this.tickRenderer(this.tickOptions);var aL=a7.formatString||L.jqplot.config.defaultTickFormatString;var aL=aL.match(L.jqplot.sprintf.regex)[0];var a3=0;if(aL){if(aL.search(/[fFeEgGpP]/)>-1){var aY=aL.match(/\%\.(\d{0,})?[eEfFgGpP]/);if(aY){a3=parseInt(aY[1],10)}else{a3=6}}else{if(aL.search(/[di]/)>-1){a3=0}}var aq=Math.pow(10,-a3);if(this.tickInterval<aq){if(aW==null&&ba==null){this.tickInterval=aq;if(a5==null&&aH==null){this.min=Math.floor(this._dataBounds.min/aq)*aq;if(this.min==this._dataBounds.min){this.min=this._dataBounds.min-this.tickInterval}this.max=Math.ceil(this._dataBounds.max/aq)*aq;if(this.max==this._dataBounds.max){this.max=this._dataBounds.max+this.tickInterval}var aX=(this.max-this.min)/this.tickInterval;aX=aX.toFixed(11);aX=Math.ceil(aX);this.numberTicks=aX+1}else{if(a5==null){var aX=(this._dataBounds.max-this.min)/this.tickInterval;aX=aX.toFixed(11);this.numberTicks=Math.ceil(aX)+2;this.max=this.min+this.tickInterval*(this.numberTicks-1)}else{if(aH==null){var aX=(this.max-this._dataBounds.min)/this.tickInterval;aX=aX.toFixed(11);this.numberTicks=Math.ceil(aX)+2;this.min=this.max-this.tickInterval*(this.numberTicks-1)}else{this.numberTicks=Math.ceil((a5-aH)/this.tickInterval)+1;this.min=Math.floor(aH*Math.pow(10,a3))/Math.pow(10,a3);this.max=Math.ceil(a5*Math.pow(10,a3))/Math.pow(10,a3);this.numberTicks=Math.ceil((this.max-this.min)/this.tickInterval)+1}}}}}}}}if(this._overrideFormatString&&this._autoFormatString!=""){this.tickOptions=this.tickOptions||{};this.tickOptions.formatString=this._autoFormatString}var aU,a8;for(var a0=0;a0<this.numberTicks;a0++){a4=this.min+a0*this.tickInterval;aU=new this.tickRenderer(this.tickOptions);aU.setTick(a4,this.name);this._ticks.push(aU);if(a0<this.numberTicks-1){for(var aZ=0;aZ<this.minorTicks;aZ++){a4+=this.tickInterval/(this.minorTicks+1);a8=L.extend(true,{},this.tickOptions,{name:this.name,value:a4,label:"",isMinorTick:true});aU=new this.tickRenderer(a8);this._ticks.push(aU)}}aU=null}}if(this.tickInset){this.min=this.min-this.tickInset*this.tickInterval;this.max=this.max+this.tickInset*this.tickInterval}aT=null};L.jqplot.LinearAxisRenderer.prototype.resetTickValues=function(aj){if(L.isArray(aj)&&aj.length==this._ticks.length){var ai;for(var ah=0;ah<aj.length;ah++){ai=this._ticks[ah];ai.value=aj[ah];ai.label=ai.formatter(ai.formatString,aj[ah]);ai.label=ai.prefix+ai.label;ai._elem.html(ai.label)}ai=null;this.min=L.jqplot.arrayMin(aj);this.max=L.jqplot.arrayMax(aj);this.pack()}};L.jqplot.LinearAxisRenderer.prototype.pack=function(aj,ai){aj=aj||{};ai=ai||this._offsets;var ay=this._ticks;var au=this.max;var at=this.min;var ao=ai.max;var am=ai.min;var aq=(this._label==null)?false:this._label.show;for(var ar in aj){this._elem.css(ar,aj[ar])}this._offsets=ai;var ak=ao-am;var al=au-at;if(this.breakPoints){al=al-this.breakPoints[1]+this.breakPoints[0];this.p2u=function(aA){return(aA-am)*al/ak+at};this.u2p=function(aA){if(aA>this.breakPoints[0]&&aA<this.breakPoints[1]){aA=this.breakPoints[0]}if(aA<=this.breakPoints[0]){return(aA-at)*ak/al+am}else{return(aA-this.breakPoints[1]+this.breakPoints[0]-at)*ak/al+am}};if(this.name.charAt(0)=="x"){this.series_u2p=function(aA){if(aA>this.breakPoints[0]&&aA<this.breakPoints[1]){aA=this.breakPoints[0]}if(aA<=this.breakPoints[0]){return(aA-at)*ak/al}else{return(aA-this.breakPoints[1]+this.breakPoints[0]-at)*ak/al}};this.series_p2u=function(aA){return aA*al/ak+at}}else{this.series_u2p=function(aA){if(aA>this.breakPoints[0]&&aA<this.breakPoints[1]){aA=this.breakPoints[0]}if(aA>=this.breakPoints[1]){return(aA-au)*ak/al}else{return(aA+this.breakPoints[1]-this.breakPoints[0]-au)*ak/al}};this.series_p2u=function(aA){return aA*al/ak+au}}}else{this.p2u=function(aA){return(aA-am)*al/ak+at};this.u2p=function(aA){return(aA-at)*ak/al+am};if(this.name=="xaxis"||this.name=="x2axis"){this.series_u2p=function(aA){return(aA-at)*ak/al};this.series_p2u=function(aA){return aA*al/ak+at}}else{this.series_u2p=function(aA){return(aA-au)*ak/al};this.series_p2u=function(aA){return aA*al/ak+au}}}if(this.show){if(this.name=="xaxis"||this.name=="x2axis"){for(var av=0;av<ay.length;av++){var ap=ay[av];if(ap.show&&ap.showLabel){var ah;if(ap.constructor==L.jqplot.CanvasAxisTickRenderer&&ap.angle){var ax=(this.name=="xaxis")?1:-1;switch(ap.labelPosition){case"auto":if(ax*ap.angle<0){ah=-ap.getWidth()+ap._textRenderer.height*Math.sin(-ap._textRenderer.angle)/2}else{ah=-ap._textRenderer.height*Math.sin(ap._textRenderer.angle)/2}break;case"end":ah=-ap.getWidth()+ap._textRenderer.height*Math.sin(-ap._textRenderer.angle)/2;break;case"start":ah=-ap._textRenderer.height*Math.sin(ap._textRenderer.angle)/2;break;case"middle":ah=-ap.getWidth()/2+ap._textRenderer.height*Math.sin(-ap._textRenderer.angle)/2;break;default:ah=-ap.getWidth()/2+ap._textRenderer.height*Math.sin(-ap._textRenderer.angle)/2;break}}else{ah=-ap.getWidth()/2}var az=this.u2p(ap.value)+ah+"px";ap._elem.css("left",az);ap.pack()}}if(aq){var an=this._label._elem.outerWidth(true);this._label._elem.css("left",am+ak/2-an/2+"px");if(this.name=="xaxis"){this._label._elem.css("bottom","0px")}else{this._label._elem.css("top","0px")}this._label.pack()}}else{for(var av=0;av<ay.length;av++){var ap=ay[av];if(ap.show&&ap.showLabel){var ah;if(ap.constructor==L.jqplot.CanvasAxisTickRenderer&&ap.angle){var ax=(this.name=="yaxis")?1:-1;switch(ap.labelPosition){case"auto":case"end":if(ax*ap.angle<0){ah=-ap._textRenderer.height*Math.cos(-ap._textRenderer.angle)/2}else{ah=-ap.getHeight()+ap._textRenderer.height*Math.cos(ap._textRenderer.angle)/2}break;case"start":if(ap.angle>0){ah=-ap._textRenderer.height*Math.cos(-ap._textRenderer.angle)/2}else{ah=-ap.getHeight()+ap._textRenderer.height*Math.cos(ap._textRenderer.angle)/2}break;case"middle":ah=-ap.getHeight()/2;break;default:ah=-ap.getHeight()/2;break}}else{ah=-ap.getHeight()/2}var az=this.u2p(ap.value)+ah+"px";ap._elem.css("top",az);ap.pack()}}if(aq){var aw=this._label._elem.outerHeight(true);this._label._elem.css("top",ao-ak/2-aw/2+"px");if(this.name=="yaxis"){this._label._elem.css("left","0px")}else{this._label._elem.css("right","0px")}this._label.pack()}}}ay=null};function i(ai){var ah;ai=Math.abs(ai);if(ai>=10){ah="%d"}else{if(ai>1){if(ai===parseInt(ai,10)){ah="%d"}else{ah="%.1f"}}else{var aj=-Math.floor(Math.log(ai)/Math.LN10);ah="%."+aj+"f"}}return ah}var b=[0.1,0.2,0.3,0.4,0.5,0.8,1,2,3,4,5];var c=function(ai){var ah=b.indexOf(ai);if(ah>0){return b[ah-1]}else{return b[b.length-1]/100}};var k=function(ai){var ah=b.indexOf(ai);if(ah<b.length-1){return b[ah+1]}else{return b[0]*100}};function d(al,au,at){var aq=Math.floor(at/2);var ai=Math.ceil(at*1.5);var ak=Number.MAX_VALUE;var ah=(au-al);var ax;var ap;var ar;var ay=L.jqplot.getSignificantFigures;var aw;var an;var ao;var av;for(var am=0,aj=ai-aq+1;am<aj;am++){ao=aq+am;ax=ah/(ao-1);ap=ay(ax);ax=Math.abs(at-ao)+ap.digitsRight;if(ax<ak){ak=ax;ar=ao;av=ap.digitsRight}else{if(ax===ak){if(ap.digitsRight<av){ar=ao;av=ap.digitsRight}}}}aw=Math.max(av,Math.max(ay(al).digitsRight,ay(au).digitsRight));if(aw===0){an="%d"}else{an="%."+aw+"f"}ax=ah/(ar-1);return[al,au,ar,an,ax]}function W(ai,al){al=al||7;var ak=ai/(al-1);var aj=Math.pow(10,Math.floor(Math.log(ak)/Math.LN10));var am=ak/aj;var ah;if(aj<1){if(am>5){ah=10*aj}else{if(am>2){ah=5*aj}else{if(am>1){ah=2*aj}else{ah=aj}}}}else{if(am>5){ah=10*aj}else{if(am>4){ah=5*aj}else{if(am>3){ah=4*aj}else{if(am>2){ah=3*aj}else{if(am>1){ah=2*aj}else{ah=aj}}}}}}return ah}function Q(ai,ah){ah=ah||1;var ak=Math.floor(Math.log(ai)/Math.LN10);var am=Math.pow(10,ak);var al=ai/am;var aj;al=al/ah;if(al<=0.38){aj=0.1}else{if(al<=1.6){aj=0.2}else{if(al<=4){aj=0.5}else{if(al<=8){aj=1}else{if(al<=16){aj=2}else{aj=5}}}}}return aj*am}function x(aj,ai){var al=Math.floor(Math.log(aj)/Math.LN10);var an=Math.pow(10,al);var am=aj/an;var ah;var ak;am=am/ai;if(am<=0.38){ak=0.1}else{if(am<=1.6){ak=0.2}else{if(am<=4){ak=0.5}else{if(am<=8){ak=1}else{if(am<=16){ak=2}else{ak=5}}}}}ah=ak*an;return[ah,ak,an]}L.jqplot.LinearTickGenerator=function(an,aq,aj,ak,ao,ar){ao=(ao===null)?false:ao;ar=(ar===null||ao)?false:ar;if(an===aq){aq=(aq)?0:1}aj=aj||1;if(aq<an){var at=aq;aq=an;an=at}var ai=[];var aw=Q(aq-an,aj);var av=L.jqplot.getSignificantFigures;if(ak==null){if(!ao&&!ar){ai[0]=Math.floor(an/aw)*aw;ai[1]=Math.ceil(aq/aw)*aw;ai[2]=Math.round((ai[1]-ai[0])/aw+1);ai[3]=i(aw);ai[4]=aw}else{if(ao){ai[0]=an;ai[2]=Math.ceil((aq-an)/aw+1);ai[1]=an+(ai[2]-1)*aw;var au=av(an).digitsRight;var ap=av(aw).digitsRight;if(au<ap){ai[3]=i(aw)}else{ai[3]="%."+au+"f"}ai[4]=aw}else{if(ar){ai[1]=aq;ai[2]=Math.ceil((aq-an)/aw+1);ai[0]=aq-(ai[2]-1)*aw;var al=av(aq).digitsRight;var ap=av(aw).digitsRight;if(al<ap){ai[3]=i(aw)}else{ai[3]="%."+al+"f"}ai[4]=aw}}}}else{var am=[];am[0]=Math.floor(an/aw)*aw;am[1]=Math.ceil(aq/aw)*aw;am[2]=Math.round((am[1]-am[0])/aw+1);am[3]=i(aw);am[4]=aw;if(am[2]===ak){ai=am}else{var ah=W(am[1]-am[0],ak);ai[0]=am[0];ai[2]=ak;ai[4]=ah;ai[3]=i(ah);ai[1]=ai[0]+(ai[2]-1)*ai[4]}}return ai};L.jqplot.LinearTickGenerator.bestLinearInterval=Q;L.jqplot.LinearTickGenerator.bestInterval=W;L.jqplot.LinearTickGenerator.bestLinearComponents=x;L.jqplot.LinearTickGenerator.bestConstrainedInterval=d;L.jqplot.MarkerRenderer=function(ah){this.show=true;this.style="filledCircle";this.lineWidth=2;this.size=9;this.color="#666666";this.shadow=true;this.shadowAngle=45;this.shadowOffset=1;this.shadowDepth=3;this.shadowAlpha="0.07";this.shadowRenderer=new L.jqplot.ShadowRenderer();this.shapeRenderer=new L.jqplot.ShapeRenderer();L.extend(true,this,ah)};L.jqplot.MarkerRenderer.prototype.init=function(ah){L.extend(true,this,ah);var aj={angle:this.shadowAngle,offset:this.shadowOffset,alpha:this.shadowAlpha,lineWidth:this.lineWidth,depth:this.shadowDepth,closePath:true};if(this.style.indexOf("filled")!=-1){aj.fill=true}if(this.style.indexOf("ircle")!=-1){aj.isarc=true;aj.closePath=false}this.shadowRenderer.init(aj);var ai={fill:false,isarc:false,strokeStyle:this.color,fillStyle:this.color,lineWidth:this.lineWidth,closePath:true};if(this.style.indexOf("filled")!=-1){ai.fill=true}if(this.style.indexOf("ircle")!=-1){ai.isarc=true;ai.closePath=false}this.shapeRenderer.init(ai)};L.jqplot.MarkerRenderer.prototype.drawDiamond=function(aj,ai,am,al,ao){var ah=1.2;var ap=this.size/2/ah;var an=this.size/2*ah;var ak=[[aj-ap,ai],[aj,ai+an],[aj+ap,ai],[aj,ai-an]];if(this.shadow){this.shadowRenderer.draw(am,ak)}this.shapeRenderer.draw(am,ak,ao)};L.jqplot.MarkerRenderer.prototype.drawPlus=function(ak,aj,an,am,aq){var ai=1;var ar=this.size/2*ai;var ao=this.size/2*ai;var ap=[[ak,aj-ao],[ak,aj+ao]];var al=[[ak+ar,aj],[ak-ar,aj]];var ah=L.extend(true,{},this.options,{closePath:false});if(this.shadow){this.shadowRenderer.draw(an,ap,{closePath:false});this.shadowRenderer.draw(an,al,{closePath:false})}this.shapeRenderer.draw(an,ap,ah);this.shapeRenderer.draw(an,al,ah)};L.jqplot.MarkerRenderer.prototype.drawX=function(ak,aj,an,am,aq){var ai=1;var ar=this.size/2*ai;var ao=this.size/2*ai;var ah=L.extend(true,{},this.options,{closePath:false});var ap=[[ak-ar,aj-ao],[ak+ar,aj+ao]];var al=[[ak-ar,aj+ao],[ak+ar,aj-ao]];if(this.shadow){this.shadowRenderer.draw(an,ap,{closePath:false});this.shadowRenderer.draw(an,al,{closePath:false})}this.shapeRenderer.draw(an,ap,ah);this.shapeRenderer.draw(an,al,ah)};L.jqplot.MarkerRenderer.prototype.drawDash=function(aj,ai,am,al,ao){var ah=1;var ap=this.size/2*ah;var an=this.size/2*ah;var ak=[[aj-ap,ai],[aj+ap,ai]];if(this.shadow){this.shadowRenderer.draw(am,ak)}this.shapeRenderer.draw(am,ak,ao)};L.jqplot.MarkerRenderer.prototype.drawLine=function(am,al,ah,ak,ai){var aj=[am,al];if(this.shadow){this.shadowRenderer.draw(ah,aj)}this.shapeRenderer.draw(ah,aj,ai)};L.jqplot.MarkerRenderer.prototype.drawSquare=function(aj,ai,am,al,ao){var ah=1;var ap=this.size/2/ah;var an=this.size/2*ah;var ak=[[aj-ap,ai-an],[aj-ap,ai+an],[aj+ap,ai+an],[aj+ap,ai-an]];if(this.shadow){this.shadowRenderer.draw(am,ak)}this.shapeRenderer.draw(am,ak,ao)};L.jqplot.MarkerRenderer.prototype.drawCircle=function(ai,ao,ak,an,al){var ah=this.size/2;var aj=2*Math.PI;var am=[ai,ao,ah,0,aj,true];if(this.shadow){this.shadowRenderer.draw(ak,am)}this.shapeRenderer.draw(ak,am,al)};L.jqplot.MarkerRenderer.prototype.draw=function(ah,ak,ai,aj){aj=aj||{};if(aj.show==null||aj.show!=false){if(aj.color&&!aj.fillStyle){aj.fillStyle=aj.color}if(aj.color&&!aj.strokeStyle){aj.strokeStyle=aj.color}switch(this.style){case"diamond":this.drawDiamond(ah,ak,ai,false,aj);break;case"filledDiamond":this.drawDiamond(ah,ak,ai,true,aj);break;case"circle":this.drawCircle(ah,ak,ai,false,aj);break;case"filledCircle":this.drawCircle(ah,ak,ai,true,aj);break;case"square":this.drawSquare(ah,ak,ai,false,aj);break;case"filledSquare":this.drawSquare(ah,ak,ai,true,aj);break;case"x":this.drawX(ah,ak,ai,true,aj);break;case"plus":this.drawPlus(ah,ak,ai,true,aj);break;case"dash":this.drawDash(ah,ak,ai,true,aj);break;case"line":this.drawLine(ah,ak,ai,false,aj);break;default:this.drawDiamond(ah,ak,ai,false,aj);break}}};L.jqplot.ShadowRenderer=function(ah){this.angle=45;this.offset=1;this.alpha=0.07;this.lineWidth=1.5;this.lineJoin="miter";this.lineCap="round";this.closePath=false;this.fill=false;this.depth=3;this.strokeStyle="rgba(0,0,0,0.1)";this.isarc=false;L.extend(true,this,ah)};L.jqplot.ShadowRenderer.prototype.init=function(ah){L.extend(true,this,ah)};L.jqplot.ShadowRenderer.prototype.draw=function(av,at,ax){av.save();var ah=(ax!=null)?ax:{};var au=(ah.fill!=null)?ah.fill:this.fill;var ap=(ah.fillRect!=null)?ah.fillRect:this.fillRect;var ao=(ah.closePath!=null)?ah.closePath:this.closePath;var al=(ah.offset!=null)?ah.offset:this.offset;var aj=(ah.alpha!=null)?ah.alpha:this.alpha;var an=(ah.depth!=null)?ah.depth:this.depth;var aw=(ah.isarc!=null)?ah.isarc:this.isarc;var aq=(ah.linePattern!=null)?ah.linePattern:this.linePattern;av.lineWidth=(ah.lineWidth!=null)?ah.lineWidth:this.lineWidth;av.lineJoin=(ah.lineJoin!=null)?ah.lineJoin:this.lineJoin;av.lineCap=(ah.lineCap!=null)?ah.lineCap:this.lineCap;av.strokeStyle=ah.strokeStyle||this.strokeStyle||"rgba(0,0,0,"+aj+")";av.fillStyle=ah.fillStyle||this.fillStyle||"rgba(0,0,0,"+aj+")";for(var ak=0;ak<an;ak++){var ar=L.jqplot.LinePattern(av,aq);av.translate(Math.cos(this.angle*Math.PI/180)*al,Math.sin(this.angle*Math.PI/180)*al);ar.beginPath();if(aw){av.arc(at[0],at[1],at[2],at[3],at[4],true)}else{if(ap){if(ap){av.fillRect(at[0],at[1],at[2],at[3])}}else{if(at&&at.length){var ai=true;for(var am=0;am<at.length;am++){if(at[am][0]!=null&&at[am][1]!=null){if(ai){ar.moveTo(at[am][0],at[am][1]);ai=false}else{ar.lineTo(at[am][0],at[am][1])}}else{ai=true}}}}}if(ao){ar.closePath()}if(au){av.fill()}else{av.stroke()}}av.restore()};L.jqplot.ShapeRenderer=function(ah){this.lineWidth=1.5;this.linePattern="solid";this.lineJoin="miter";this.lineCap="round";this.closePath=false;this.fill=false;this.isarc=false;this.fillRect=false;this.strokeRect=false;this.clearRect=false;this.strokeStyle="#999999";this.fillStyle="#999999";L.extend(true,this,ah)};L.jqplot.ShapeRenderer.prototype.init=function(ah){L.extend(true,this,ah)};L.jqplot.ShapeRenderer.prototype.draw=function(at,aq,av){at.save();var ah=(av!=null)?av:{};var ar=(ah.fill!=null)?ah.fill:this.fill;var am=(ah.closePath!=null)?ah.closePath:this.closePath;var an=(ah.fillRect!=null)?ah.fillRect:this.fillRect;var ak=(ah.strokeRect!=null)?ah.strokeRect:this.strokeRect;var ai=(ah.clearRect!=null)?ah.clearRect:this.clearRect;var au=(ah.isarc!=null)?ah.isarc:this.isarc;var ao=(ah.linePattern!=null)?ah.linePattern:this.linePattern;var ap=L.jqplot.LinePattern(at,ao);at.lineWidth=ah.lineWidth||this.lineWidth;at.lineJoin=ah.lineJoin||this.lineJoin;at.lineCap=ah.lineCap||this.lineCap;at.strokeStyle=(ah.strokeStyle||ah.color)||this.strokeStyle;at.fillStyle=ah.fillStyle||this.fillStyle;at.beginPath();if(au){at.arc(aq[0],aq[1],aq[2],aq[3],aq[4],true);if(am){at.closePath()}if(ar){at.fill()}else{at.stroke()}at.restore();return}else{if(ai){at.clearRect(aq[0],aq[1],aq[2],aq[3]);at.restore();return}else{if(an||ak){if(an){at.fillRect(aq[0],aq[1],aq[2],aq[3])}if(ak){at.strokeRect(aq[0],aq[1],aq[2],aq[3]);at.restore();return}}else{if(aq&&aq.length){var aj=true;for(var al=0;al<aq.length;al++){if(aq[al][0]!=null&&aq[al][1]!=null){if(aj){ap.moveTo(aq[al][0],aq[al][1]);aj=false}else{ap.lineTo(aq[al][0],aq[al][1])}}else{aj=true}}if(am){ap.closePath()}if(ar){at.fill()}else{at.stroke()}}}}}at.restore()};L.jqplot.TableLegendRenderer=function(){};L.jqplot.TableLegendRenderer.prototype.init=function(ah){L.extend(true,this,ah)};L.jqplot.TableLegendRenderer.prototype.addrow=function(aq,ak,ah,ao){var al=(ah)?this.rowSpacing+"px":"0px";var ap;var aj;var ai;var an;var am;ai=document.createElement("tr");ap=L(ai);ap.addClass("jqplot-table-legend");ai=null;if(ao){ap.prependTo(this._elem)}else{ap.appendTo(this._elem)}if(this.showSwatches){aj=L(document.createElement("td"));aj.addClass("jqplot-table-legend jqplot-table-legend-swatch");aj.css({textAlign:"center",paddingTop:al});an=L(document.createElement("div"));an.addClass("jqplot-table-legend-swatch-outline");am=L(document.createElement("div"));am.addClass("jqplot-table-legend-swatch");am.css({backgroundColor:ak,borderColor:ak});ap.append(aj.append(an.append(am)))}if(this.showLabels){aj=L(document.createElement("td"));aj.addClass("jqplot-table-legend jqplot-table-legend-label");aj.css("paddingTop",al);ap.append(aj);if(this.escapeHtml){aj.text(aq)}else{aj.html(aq)}}aj=null;an=null;am=null;ap=null;ai=null};L.jqplot.TableLegendRenderer.prototype.draw=function(){if(this._elem){this._elem.emptyForce();this._elem=null}if(this.show){var am=this._series;var ai=document.createElement("table");this._elem=L(ai);this._elem.addClass("jqplot-table-legend");var ar={position:"absolute"};if(this.background){ar.background=this.background}if(this.border){ar.border=this.border}if(this.fontSize){ar.fontSize=this.fontSize}if(this.fontFamily){ar.fontFamily=this.fontFamily}if(this.textColor){ar.textColor=this.textColor}if(this.marginTop!=null){ar.marginTop=this.marginTop}if(this.marginBottom!=null){ar.marginBottom=this.marginBottom}if(this.marginLeft!=null){ar.marginLeft=this.marginLeft}if(this.marginRight!=null){ar.marginRight=this.marginRight}var ah=false,ao=false,aq;for(var an=0;an<am.length;an++){aq=am[an];if(aq._stack||aq.renderer.constructor==L.jqplot.BezierCurveRenderer){ao=true}if(aq.show&&aq.showLabel){var al=this.labels[an]||aq.label.toString();if(al){var aj=aq.color;if(ao&&an<am.length-1){ah=true}else{if(ao&&an==am.length-1){ah=false}}this.renderer.addrow.call(this,al,aj,ah,ao);ah=true}for(var ak=0;ak<L.jqplot.addLegendRowHooks.length;ak++){var ap=L.jqplot.addLegendRowHooks[ak].call(this,aq);if(ap){this.renderer.addrow.call(this,ap.label,ap.color,ah);ah=true}}al=null}}}return this._elem};L.jqplot.TableLegendRenderer.prototype.pack=function(aj){if(this.show){if(this.placement=="insideGrid"){switch(this.location){case"nw":var ai=aj.left;var ah=aj.top;this._elem.css("left",ai);this._elem.css("top",ah);break;case"n":var ai=(aj.left+(this._plotDimensions.width-aj.right))/2-this.getWidth()/2;var ah=aj.top;this._elem.css("left",ai);this._elem.css("top",ah);break;case"ne":var ai=aj.right;var ah=aj.top;this._elem.css({right:ai,top:ah});break;case"e":var ai=aj.right;var ah=(aj.top+(this._plotDimensions.height-aj.bottom))/2-this.getHeight()/2;this._elem.css({right:ai,top:ah});break;case"se":var ai=aj.right;var ah=aj.bottom;this._elem.css({right:ai,bottom:ah});break;case"s":var ai=(aj.left+(this._plotDimensions.width-aj.right))/2-this.getWidth()/2;var ah=aj.bottom;this._elem.css({left:ai,bottom:ah});break;case"sw":var ai=aj.left;var ah=aj.bottom;this._elem.css({left:ai,bottom:ah});break;case"w":var ai=aj.left;var ah=(aj.top+(this._plotDimensions.height-aj.bottom))/2-this.getHeight()/2;this._elem.css({left:ai,top:ah});break;default:var ai=aj.right;var ah=aj.bottom;this._elem.css({right:ai,bottom:ah});break}}else{if(this.placement=="outside"){switch(this.location){case"nw":var ai=this._plotDimensions.width-aj.left;var ah=aj.top;this._elem.css("right",ai);this._elem.css("top",ah);break;case"n":var ai=(aj.left+(this._plotDimensions.width-aj.right))/2-this.getWidth()/2;var ah=this._plotDimensions.height-aj.top;this._elem.css("left",ai);this._elem.css("bottom",ah);break;case"ne":var ai=this._plotDimensions.width-aj.right;var ah=aj.top;this._elem.css({left:ai,top:ah});break;case"e":var ai=this._plotDimensions.width-aj.right;var ah=(aj.top+(this._plotDimensions.height-aj.bottom))/2-this.getHeight()/2;this._elem.css({left:ai,top:ah});break;case"se":var ai=this._plotDimensions.width-aj.right;var ah=aj.bottom;this._elem.css({left:ai,bottom:ah});break;case"s":var ai=(aj.left+(this._plotDimensions.width-aj.right))/2-this.getWidth()/2;var ah=this._plotDimensions.height-aj.bottom;this._elem.css({left:ai,top:ah});break;case"sw":var ai=this._plotDimensions.width-aj.left;var ah=aj.bottom;this._elem.css({right:ai,bottom:ah});break;case"w":var ai=this._plotDimensions.width-aj.left;var ah=(aj.top+(this._plotDimensions.height-aj.bottom))/2-this.getHeight()/2;this._elem.css({right:ai,top:ah});break;default:var ai=aj.right;var ah=aj.bottom;this._elem.css({right:ai,bottom:ah});break}}else{switch(this.location){case"nw":this._elem.css({left:0,top:aj.top});break;case"n":var ai=(aj.left+(this._plotDimensions.width-aj.right))/2-this.getWidth()/2;this._elem.css({left:ai,top:aj.top});break;case"ne":this._elem.css({right:0,top:aj.top});break;case"e":var ah=(aj.top+(this._plotDimensions.height-aj.bottom))/2-this.getHeight()/2;this._elem.css({right:aj.right,top:ah});break;case"se":this._elem.css({right:aj.right,bottom:aj.bottom});break;case"s":var ai=(aj.left+(this._plotDimensions.width-aj.right))/2-this.getWidth()/2;this._elem.css({left:ai,bottom:aj.bottom});break;case"sw":this._elem.css({left:aj.left,bottom:aj.bottom});break;case"w":var ah=(aj.top+(this._plotDimensions.height-aj.bottom))/2-this.getHeight()/2;this._elem.css({left:aj.left,top:ah});break;default:this._elem.css({right:aj.right,bottom:aj.bottom});break}}}}};L.jqplot.ThemeEngine=function(){this.themes={};this.activeTheme=null};L.jqplot.ThemeEngine.prototype.init=function(){var ak=new L.jqplot.Theme({_name:"Default"});var an,ai,am;for(an in ak.target){if(an=="textColor"){ak.target[an]=this.target.css("color")}else{ak.target[an]=this.target.css(an)}}if(this.title.show&&this.title._elem){for(an in ak.title){if(an=="textColor"){ak.title[an]=this.title._elem.css("color")}else{ak.title[an]=this.title._elem.css(an)}}}for(an in ak.grid){ak.grid[an]=this.grid[an]}if(ak.grid.backgroundColor==null&&this.grid.background!=null){ak.grid.backgroundColor=this.grid.background}if(this.legend.show&&this.legend._elem){for(an in ak.legend){if(an=="textColor"){ak.legend[an]=this.legend._elem.css("color")}else{ak.legend[an]=this.legend._elem.css(an)}}}var aj;for(ai=0;ai<this.series.length;ai++){aj=this.series[ai];if(aj.renderer.constructor==L.jqplot.LineRenderer){ak.series.push(new p())}else{if(aj.renderer.constructor==L.jqplot.BarRenderer){ak.series.push(new T())}else{if(aj.renderer.constructor==L.jqplot.PieRenderer){ak.series.push(new f())}else{if(aj.renderer.constructor==L.jqplot.DonutRenderer){ak.series.push(new G())}else{if(aj.renderer.constructor==L.jqplot.FunnelRenderer){ak.series.push(new Z())}else{if(aj.renderer.constructor==L.jqplot.MeterGaugeRenderer){ak.series.push(new D())}else{ak.series.push({})}}}}}}for(an in ak.series[ai]){ak.series[ai][an]=aj[an]}}var ah,al;for(an in this.axes){al=this.axes[an];ah=ak.axes[an]=new P();ah.borderColor=al.borderColor;ah.borderWidth=al.borderWidth;if(al._ticks&&al._ticks[0]){for(am in ah.ticks){if(al._ticks[0].hasOwnProperty(am)){ah.ticks[am]=al._ticks[0][am]}else{if(al._ticks[0]._elem){ah.ticks[am]=al._ticks[0]._elem.css(am)}}}}if(al._label&&al._label.show){for(am in ah.label){if(al._label[am]){ah.label[am]=al._label[am]}else{if(al._label._elem){if(am=="textColor"){ah.label[am]=al._label._elem.css("color")}else{ah.label[am]=al._label._elem.css(am)}}}}}}this.themeEngine._add(ak);this.themeEngine.activeTheme=this.themeEngine.themes[ak._name]};L.jqplot.ThemeEngine.prototype.get=function(ah){if(!ah){return this.activeTheme}else{return this.themes[ah]}};function O(ai,ah){return ai-ah}L.jqplot.ThemeEngine.prototype.getThemeNames=function(){var ah=[];for(var ai in this.themes){ah.push(ai)}return ah.sort(O)};L.jqplot.ThemeEngine.prototype.getThemes=function(){var ai=[];var ah=[];for(var ak in this.themes){ai.push(ak)}ai.sort(O);for(var aj=0;aj<ai.length;aj++){ah.push(this.themes[ai[aj]])}return ah};L.jqplot.ThemeEngine.prototype.activate=function(av,aB){var ah=false;if(!aB&&this.activeTheme&&this.activeTheme._name){aB=this.activeTheme._name}if(!this.themes.hasOwnProperty(aB)){throw new Error("No theme of that name")}else{var am=this.themes[aB];this.activeTheme=am;var aA,at=false,ar=false;var ai=["xaxis","x2axis","yaxis","y2axis"];for(aw=0;aw<ai.length;aw++){var an=ai[aw];if(am.axesStyles.borderColor!=null){av.axes[an].borderColor=am.axesStyles.borderColor}if(am.axesStyles.borderWidth!=null){av.axes[an].borderWidth=am.axesStyles.borderWidth}}for(var az in av.axes){var ak=av.axes[az];if(ak.show){var aq=am.axes[az]||{};var ao=am.axesStyles;var al=L.jqplot.extend(true,{},aq,ao);aA=(am.axesStyles.borderColor!=null)?am.axesStyles.borderColor:al.borderColor;if(al.borderColor!=null){ak.borderColor=al.borderColor;ah=true}aA=(am.axesStyles.borderWidth!=null)?am.axesStyles.borderWidth:al.borderWidth;if(al.borderWidth!=null){ak.borderWidth=al.borderWidth;ah=true}if(ak._ticks&&ak._ticks[0]){for(var aj in al.ticks){aA=al.ticks[aj];if(aA!=null){ak.tickOptions[aj]=aA;ak._ticks=[];ah=true}}}if(ak._label&&ak._label.show){for(var aj in al.label){aA=al.label[aj];if(aA!=null){ak.labelOptions[aj]=aA;ah=true}}}}}for(var au in am.grid){if(am.grid[au]!=null){av.grid[au]=am.grid[au]}}if(!ah){av.grid.draw()}if(av.legend.show){for(au in am.legend){if(am.legend[au]!=null){av.legend[au]=am.legend[au]}}}if(av.title.show){for(au in am.title){if(am.title[au]!=null){av.title[au]=am.title[au]}}}var aw;for(aw=0;aw<am.series.length;aw++){var ap={};var ay=false;for(au in am.series[aw]){aA=(am.seriesStyles[au]!=null)?am.seriesStyles[au]:am.series[aw][au];if(aA!=null){ap[au]=aA;if(au=="color"){av.series[aw].renderer.shapeRenderer.fillStyle=aA;av.series[aw].renderer.shapeRenderer.strokeStyle=aA;av.series[aw][au]=aA}else{if((au=="lineWidth")||(au=="linePattern")){av.series[aw].renderer.shapeRenderer[au]=aA;av.series[aw][au]=aA}else{if(au=="markerOptions"){V(av.series[aw].markerOptions,aA);V(av.series[aw].markerRenderer,aA)}else{av.series[aw][au]=aA}}}ah=true}}}if(ah){av.target.empty();av.draw()}for(au in am.target){if(am.target[au]!=null){av.target.css(au,am.target[au])}}}};L.jqplot.ThemeEngine.prototype._add=function(ai,ah){if(ah){ai._name=ah}if(!ai._name){ai._name=Date.parse(new Date())}if(!this.themes.hasOwnProperty(ai._name)){this.themes[ai._name]=ai}else{throw new Error("jqplot.ThemeEngine Error: Theme already in use")}};L.jqplot.ThemeEngine.prototype.remove=function(ah){if(ah=="Default"){return false}return delete this.themes[ah]};L.jqplot.ThemeEngine.prototype.newTheme=function(ah,aj){if(typeof(ah)=="object"){aj=aj||ah;ah=null}if(aj&&aj._name){ah=aj._name}else{ah=ah||Date.parse(new Date())}var ai=this.copy(this.themes.Default._name,ah);L.jqplot.extend(ai,aj);return ai};function B(aj){if(aj==null||typeof(aj)!="object"){return aj}var ah=new aj.constructor();for(var ai in aj){ah[ai]=B(aj[ai])}return ah}L.jqplot.clone=B;function V(aj,ai){if(ai==null||typeof(ai)!="object"){return}for(var ah in ai){if(ah=="highlightColors"){aj[ah]=B(ai[ah])}if(ai[ah]!=null&&typeof(ai[ah])=="object"){if(!aj.hasOwnProperty(ah)){aj[ah]={}}V(aj[ah],ai[ah])}else{aj[ah]=ai[ah]}}}L.jqplot.merge=V;L.jqplot.extend=function(){var am=arguments[0]||{},ak=1,al=arguments.length,ah=false,aj;if(typeof am==="boolean"){ah=am;am=arguments[1]||{};ak=2}if(typeof am!=="object"&&!toString.call(am)==="[object Function]"){am={}}for(;ak<al;ak++){if((aj=arguments[ak])!=null){for(var ai in aj){var an=am[ai],ao=aj[ai];if(am===ao){continue}if(ah&&ao&&typeof ao==="object"&&!ao.nodeType){am[ai]=L.jqplot.extend(ah,an||(ao.length!=null?[]:{}),ao)}else{if(ao!==u){am[ai]=ao}}}}}return am};L.jqplot.ThemeEngine.prototype.rename=function(ai,ah){if(ai=="Default"||ah=="Default"){throw new Error("jqplot.ThemeEngine Error: Cannot rename from/to Default")}if(this.themes.hasOwnProperty(ah)){throw new Error("jqplot.ThemeEngine Error: New name already in use.")}else{if(this.themes.hasOwnProperty(ai)){var aj=this.copy(ai,ah);this.remove(ai);return aj}}throw new Error("jqplot.ThemeEngine Error: Old name or new name invalid")};L.jqplot.ThemeEngine.prototype.copy=function(ah,aj,al){if(aj=="Default"){throw new Error("jqplot.ThemeEngine Error: Cannot copy over Default theme")}if(!this.themes.hasOwnProperty(ah)){var ai="jqplot.ThemeEngine Error: Source name invalid";throw new Error(ai)}if(this.themes.hasOwnProperty(aj)){var ai="jqplot.ThemeEngine Error: Target name invalid";throw new Error(ai)}else{var ak=B(this.themes[ah]);ak._name=aj;L.jqplot.extend(true,ak,al);this._add(ak);return ak}};L.jqplot.Theme=function(ah,ai){if(typeof(ah)=="object"){ai=ai||ah;ah=null}ah=ah||Date.parse(new Date());this._name=ah;this.target={backgroundColor:null};this.legend={textColor:null,fontFamily:null,fontSize:null,border:null,background:null};this.title={textColor:null,fontFamily:null,fontSize:null,textAlign:null};this.seriesStyles={};this.series=[];this.grid={drawGridlines:null,gridLineColor:null,gridLineWidth:null,backgroundColor:null,borderColor:null,borderWidth:null,shadow:null};this.axesStyles={label:{},ticks:{}};this.axes={};if(typeof(ai)=="string"){this._name=ai}else{if(typeof(ai)=="object"){L.jqplot.extend(true,this,ai)}}};var P=function(){this.borderColor=null;this.borderWidth=null;this.ticks=new o();this.label=new t()};var o=function(){this.show=null;this.showGridline=null;this.showLabel=null;this.showMark=null;this.size=null;this.textColor=null;this.whiteSpace=null;this.fontSize=null;this.fontFamily=null};var t=function(){this.textColor=null;this.whiteSpace=null;this.fontSize=null;this.fontFamily=null;this.fontWeight=null};var p=function(){this.color=null;this.lineWidth=null;this.linePattern=null;this.shadow=null;this.fillColor=null;this.showMarker=null;this.markerOptions=new I()};var I=function(){this.show=null;this.style=null;this.lineWidth=null;this.size=null;this.color=null;this.shadow=null};var T=function(){this.color=null;this.seriesColors=null;this.lineWidth=null;this.shadow=null;this.barPadding=null;this.barMargin=null;this.barWidth=null;this.highlightColors=null};var f=function(){this.seriesColors=null;this.padding=null;this.sliceMargin=null;this.fill=null;this.shadow=null;this.startAngle=null;this.lineWidth=null;this.highlightColors=null};var G=function(){this.seriesColors=null;this.padding=null;this.sliceMargin=null;this.fill=null;this.shadow=null;this.startAngle=null;this.lineWidth=null;this.innerDiameter=null;this.thickness=null;this.ringMargin=null;this.highlightColors=null};var Z=function(){this.color=null;this.lineWidth=null;this.shadow=null;this.padding=null;this.sectionMargin=null;this.seriesColors=null;this.highlightColors=null};var D=function(){this.padding=null;this.backgroundColor=null;this.ringColor=null;this.tickColor=null;this.ringWidth=null;this.intervalColors=null;this.intervalInnerRadius=null;this.intervalOuterRadius=null;this.hubRadius=null;this.needleThickness=null;this.needlePad=null};L.fn.jqplotChildText=function(){return L(this).contents().filter(function(){return this.nodeType==3}).text()};L.fn.jqplotGetComputedFontStyle=function(){var ak=window.getComputedStyle?window.getComputedStyle(this[0],""):this[0].currentStyle;var ai=ak["font-style"]?["font-style","font-weight","font-size","font-family"]:["fontStyle","fontWeight","fontSize","fontFamily"];var al=[];for(var aj=0;aj<ai.length;++aj){var ah=String(ak[ai[aj]]);if(ah&&ah!="normal"){al.push(ah)}}return al.join(" ")};L.fn.jqplotToImageCanvas=function(aj){aj=aj||{};var av=(aj.x_offset==null)?0:aj.x_offset;var ax=(aj.y_offset==null)?0:aj.y_offset;var al=(aj.backgroundColor==null)?"rgb(255,255,255)":aj.backgroundColor;if(L(this).width()==0||L(this).height()==0){return null}if(L.jqplot.use_excanvas){return null}var an=document.createElement("canvas");var aA=L(this).outerHeight(true);var at=L(this).outerWidth(true);var am=L(this).offset();var ao=am.left;var aq=am.top;var au=0,ar=0;var ay=["jqplot-table-legend","jqplot-xaxis-tick","jqplot-x2axis-tick","jqplot-yaxis-tick","jqplot-y2axis-tick","jqplot-y3axis-tick","jqplot-y4axis-tick","jqplot-y5axis-tick","jqplot-y6axis-tick","jqplot-y7axis-tick","jqplot-y8axis-tick","jqplot-y9axis-tick","jqplot-xaxis-label","jqplot-x2axis-label","jqplot-yaxis-label","jqplot-y2axis-label","jqplot-y3axis-label","jqplot-y4axis-label","jqplot-y5axis-label","jqplot-y6axis-label","jqplot-y7axis-label","jqplot-y8axis-label","jqplot-y9axis-label"];var ap,ah,ai,aB;for(var az=0;az<ay.length;az++){L(this).find("."+ay[az]).each(function(){ap=L(this).offset().top-aq;ah=L(this).offset().left-ao;aB=ah+L(this).outerWidth(true)+au;ai=ap+L(this).outerHeight(true)+ar;if(ah<-au){at=at-au-ah;au=-ah}if(ap<-ar){aA=aA-ar-ap;ar=-ap}if(aB>at){at=aB}if(ai>aA){aA=ai}})}an.width=at+Number(av);an.height=aA+Number(ax);var ak=an.getContext("2d");ak.save();ak.fillStyle=al;ak.fillRect(0,0,an.width,an.height);ak.restore();ak.translate(au,ar);ak.textAlign="left";ak.textBaseline="top";function aC(aE){var aF=parseInt(L(aE).css("line-height"),10);if(isNaN(aF)){aF=parseInt(L(aE).css("font-size"),10)*1.2}return aF}function aD(aF,aE,aS,aG,aO,aH){var aQ=aC(aF);var aK=L(aF).innerWidth();var aL=L(aF).innerHeight();var aN=aS.split(/\s+/);var aR=aN.length;var aP="";var aM=[];var aU=aO;var aT=aG;for(var aJ=0;aJ<aR;aJ++){aP+=aN[aJ];if(aE.measureText(aP).width>aK&&aP.length>aN[aJ].length){aM.push(aJ);aP="";aJ--}}if(aM.length===0){if(L(aF).css("textAlign")==="center"){aT=aG+(aH-aE.measureText(aP).width)/2-au}aE.fillText(aS,aT,aO)}else{aP=aN.slice(0,aM[0]).join(" ");if(L(aF).css("textAlign")==="center"){aT=aG+(aH-aE.measureText(aP).width)/2-au}aE.fillText(aP,aT,aU);aU+=aQ;for(var aJ=1,aI=aM.length;aJ<aI;aJ++){aP=aN.slice(aM[aJ-1],aM[aJ]).join(" ");if(L(aF).css("textAlign")==="center"){aT=aG+(aH-aE.measureText(aP).width)/2-au}aE.fillText(aP,aT,aU);aU+=aQ}aP=aN.slice(aM[aJ-1],aN.length).join(" ");if(L(aF).css("textAlign")==="center"){aT=aG+(aH-aE.measureText(aP).width)/2-au}aE.fillText(aP,aT,aU)}}function aw(aG,aJ,aE){var aN=aG.tagName.toLowerCase();var aF=L(aG).position();var aK=window.getComputedStyle?window.getComputedStyle(aG,""):aG.currentStyle;var aI=aJ+aF.left+parseInt(aK.marginLeft,10)+parseInt(aK.borderLeftWidth,10)+parseInt(aK.paddingLeft,10);var aL=aE+aF.top+parseInt(aK.marginTop,10)+parseInt(aK.borderTopWidth,10)+parseInt(aK.paddingTop,10);var aM=an.width;if((aN=="div"||aN=="span")&&!L(aG).hasClass("jqplot-highlighter-tooltip")){L(aG).children().each(function(){aw(this,aI,aL)});var aO=L(aG).jqplotChildText();if(aO){ak.font=L(aG).jqplotGetComputedFontStyle();ak.fillStyle=L(aG).css("color");aD(aG,ak,aO,aI,aL,aM)}}else{if(aN==="table"&&L(aG).hasClass("jqplot-table-legend")){ak.strokeStyle=L(aG).css("border-top-color");ak.fillStyle=L(aG).css("background-color");ak.fillRect(aI,aL,L(aG).innerWidth(),L(aG).innerHeight());if(parseInt(L(aG).css("border-top-width"),10)>0){ak.strokeRect(aI,aL,L(aG).innerWidth(),L(aG).innerHeight())}L(aG).find("div.jqplot-table-legend-swatch-outline").each(function(){var aU=L(this);ak.strokeStyle=aU.css("border-top-color");var aQ=aI+aU.position().left;var aR=aL+aU.position().top;ak.strokeRect(aQ,aR,aU.innerWidth(),aU.innerHeight());aQ+=parseInt(aU.css("padding-left"),10);aR+=parseInt(aU.css("padding-top"),10);var aT=aU.innerHeight()-2*parseInt(aU.css("padding-top"),10);var aP=aU.innerWidth()-2*parseInt(aU.css("padding-left"),10);var aS=aU.children("div.jqplot-table-legend-swatch");ak.fillStyle=aS.css("background-color");ak.fillRect(aQ,aR,aP,aT)});L(aG).find("td.jqplot-table-legend-label").each(function(){var aR=L(this);var aP=aI+aR.position().left;var aQ=aL+aR.position().top+parseInt(aR.css("padding-top"),10);ak.font=aR.jqplotGetComputedFontStyle();ak.fillStyle=aR.css("color");aD(aR,ak,aR.text(),aP,aQ,aM)});var aH=null}else{if(aN=="canvas"){ak.drawImage(aG,aI,aL)}}}}L(this).children().each(function(){aw(this,av,ax)});return an};L.fn.jqplotToImageStr=function(ai){var ah=L(this).jqplotToImageCanvas(ai);if(ah){return ah.toDataURL("image/png")}else{return null}};L.fn.jqplotToImageElem=function(ah){var ai=document.createElement("img");var aj=L(this).jqplotToImageStr(ah);ai.src=aj;return ai};L.fn.jqplotToImageElemStr=function(ah){var ai="<img src="+L(this).jqplotToImageStr(ah)+" />";return ai};L.fn.jqplotSaveImage=function(){var ah=L(this).jqplotToImageStr({});if(ah){window.location.href=ah.replace("image/png","image/octet-stream")}};L.fn.jqplotViewImage=function(){var ai=L(this).jqplotToImageElemStr({});var aj=L(this).jqplotToImageStr({});if(ai){var ah=window.open("");ah.document.open("image/png");ah.document.write(ai);ah.document.close();ah=null}};var ag=function(){this.syntax=ag.config.syntax;this._type="jsDate";this.proxy=new Date();this.options={};this.locale=ag.regional.getLocale();this.formatString="";this.defaultCentury=ag.config.defaultCentury;switch(arguments.length){case 0:break;case 1:if(l(arguments[0])=="[object Object]"&&arguments[0]._type!="jsDate"){var aj=this.options=arguments[0];this.syntax=aj.syntax||this.syntax;this.defaultCentury=aj.defaultCentury||this.defaultCentury;this.proxy=ag.createDate(aj.date)}else{this.proxy=ag.createDate(arguments[0])}break;default:var ah=[];for(var ai=0;ai<arguments.length;ai++){ah.push(arguments[ai])}this.proxy=new Date();this.proxy.setFullYear.apply(this.proxy,ah.slice(0,3));if(ah.slice(3).length){this.proxy.setHours.apply(this.proxy,ah.slice(3))}break}};ag.config={defaultLocale:"en",syntax:"perl",defaultCentury:1900};ag.prototype.add=function(aj,ai){var ah=E[ai]||E.day;if(typeof ah=="number"){this.proxy.setTime(this.proxy.getTime()+(ah*aj))}else{ah.add(this,aj)}return this};ag.prototype.clone=function(){return new ag(this.proxy.getTime())};ag.prototype.getUtcOffset=function(){return this.proxy.getTimezoneOffset()*60000};ag.prototype.diff=function(ai,al,ah){ai=new ag(ai);if(ai===null){return null}var aj=E[al]||E.day;if(typeof aj=="number"){var ak=(this.proxy.getTime()-ai.proxy.getTime())/aj}else{var ak=aj.diff(this.proxy,ai.proxy)}return(ah?ak:Math[ak>0?"floor":"ceil"](ak))};ag.prototype.getAbbrDayName=function(){return ag.regional[this.locale]["dayNamesShort"][this.proxy.getDay()]};ag.prototype.getAbbrMonthName=function(){return ag.regional[this.locale]["monthNamesShort"][this.proxy.getMonth()]};ag.prototype.getAMPM=function(){return this.proxy.getHours()>=12?"PM":"AM"};ag.prototype.getAmPm=function(){return this.proxy.getHours()>=12?"pm":"am"};ag.prototype.getCentury=function(){return parseInt(this.proxy.getFullYear()/100,10)};ag.prototype.getDate=function(){return this.proxy.getDate()};ag.prototype.getDay=function(){return this.proxy.getDay()};ag.prototype.getDayOfWeek=function(){var ah=this.proxy.getDay();return ah===0?7:ah};ag.prototype.getDayOfYear=function(){var ai=this.proxy;var ah=ai-new Date(""+ai.getFullYear()+"/1/1 GMT");ah+=ai.getTimezoneOffset()*60000;ai=null;return parseInt(ah/60000/60/24,10)+1};ag.prototype.getDayName=function(){return ag.regional[this.locale]["dayNames"][this.proxy.getDay()]};ag.prototype.getFullWeekOfYear=function(){var ak=this.proxy;var ah=this.getDayOfYear();var aj=6-ak.getDay();var ai=parseInt((ah+aj)/7,10);return ai};ag.prototype.getFullYear=function(){return this.proxy.getFullYear()};ag.prototype.getGmtOffset=function(){var ah=this.proxy.getTimezoneOffset()/60;var ai=ah<0?"+":"-";ah=Math.abs(ah);return ai+N(Math.floor(ah),2)+":"+N((ah%1)*60,2)};ag.prototype.getHours=function(){return this.proxy.getHours()};ag.prototype.getHours12=function(){var ah=this.proxy.getHours();return ah>12?ah-12:(ah==0?12:ah)};ag.prototype.getIsoWeek=function(){var ak=this.proxy;var aj=this.getWeekOfYear();var ah=(new Date(""+ak.getFullYear()+"/1/1")).getDay();var ai=aj+(ah>4||ah<=1?0:1);if(ai==53&&(new Date(""+ak.getFullYear()+"/12/31")).getDay()<4){ai=1}else{if(ai===0){ak=new ag(new Date(""+(ak.getFullYear()-1)+"/12/31"));ai=ak.getIsoWeek()}}ak=null;return ai};ag.prototype.getMilliseconds=function(){return this.proxy.getMilliseconds()};ag.prototype.getMinutes=function(){return this.proxy.getMinutes()};ag.prototype.getMonth=function(){return this.proxy.getMonth()};ag.prototype.getMonthName=function(){return ag.regional[this.locale]["monthNames"][this.proxy.getMonth()]};ag.prototype.getMonthNumber=function(){return this.proxy.getMonth()+1};ag.prototype.getSeconds=function(){return this.proxy.getSeconds()};ag.prototype.getShortYear=function(){return this.proxy.getYear()%100};ag.prototype.getTime=function(){return this.proxy.getTime()};ag.prototype.getTimezoneAbbr=function(){return this.proxy.toString().replace(/^.*\(([^)]+)\)$/,"$1")};ag.prototype.getTimezoneName=function(){var ah=/(?:\((.+)\)$| ([A-Z]{3}) )/.exec(this.toString());return ah[1]||ah[2]||"GMT"+this.getGmtOffset()};ag.prototype.getTimezoneOffset=function(){return this.proxy.getTimezoneOffset()};ag.prototype.getWeekOfYear=function(){var ah=this.getDayOfYear();var aj=7-this.getDayOfWeek();var ai=parseInt((ah+aj)/7,10);return ai};ag.prototype.getUnix=function(){return Math.round(this.proxy.getTime()/1000,0)};ag.prototype.getYear=function(){return this.proxy.getYear()};ag.prototype.next=function(ah){ah=ah||"day";return this.clone().add(1,ah)};ag.prototype.set=function(){switch(arguments.length){case 0:this.proxy=new Date();break;case 1:if(l(arguments[0])=="[object Object]"&&arguments[0]._type!="jsDate"){var aj=this.options=arguments[0];this.syntax=aj.syntax||this.syntax;this.defaultCentury=aj.defaultCentury||this.defaultCentury;this.proxy=ag.createDate(aj.date)}else{this.proxy=ag.createDate(arguments[0])}break;default:var ah=[];for(var ai=0;ai<arguments.length;ai++){ah.push(arguments[ai])}this.proxy=new Date();this.proxy.setFullYear.apply(this.proxy,ah.slice(0,3));if(ah.slice(3).length){this.proxy.setHours.apply(this.proxy,ah.slice(3))}break}return this};ag.prototype.setDate=function(ah){this.proxy.setDate(ah);return this};ag.prototype.setFullYear=function(){this.proxy.setFullYear.apply(this.proxy,arguments);return this};ag.prototype.setHours=function(){this.proxy.setHours.apply(this.proxy,arguments);return this};ag.prototype.setMilliseconds=function(ah){this.proxy.setMilliseconds(ah);return this};ag.prototype.setMinutes=function(){this.proxy.setMinutes.apply(this.proxy,arguments);return this};ag.prototype.setMonth=function(){this.proxy.setMonth.apply(this.proxy,arguments);return this};ag.prototype.setSeconds=function(){this.proxy.setSeconds.apply(this.proxy,arguments);return this};ag.prototype.setTime=function(ah){this.proxy.setTime(ah);return this};ag.prototype.setYear=function(){this.proxy.setYear.apply(this.proxy,arguments);return this};ag.prototype.strftime=function(ah){ah=ah||this.formatString||ag.regional[this.locale]["formatString"];return ag.strftime(this,ah,this.syntax)};ag.prototype.toString=function(){return this.proxy.toString()};ag.prototype.toYmdInt=function(){return(this.proxy.getFullYear()*10000)+(this.getMonthNumber()*100)+this.proxy.getDate()};ag.regional={en:{monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],formatString:"%Y-%m-%d %H:%M:%S"},fr:{monthNames:["Janvier","Février","Mars","Avril","Mai","Juin","Juillet","Août","Septembre","Octobre","Novembre","Décembre"],monthNamesShort:["Jan","Fév","Mar","Avr","Mai","Jun","Jul","Aoû","Sep","Oct","Nov","Déc"],dayNames:["Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"],dayNamesShort:["Dim","Lun","Mar","Mer","Jeu","Ven","Sam"],formatString:"%Y-%m-%d %H:%M:%S"},de:{monthNames:["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"],monthNamesShort:["Jan","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],dayNames:["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"],dayNamesShort:["So","Mo","Di","Mi","Do","Fr","Sa"],formatString:"%Y-%m-%d %H:%M:%S"},es:{monthNames:["Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre"],monthNamesShort:["Ene","Feb","Mar","Abr","May","Jun","Jul","Ago","Sep","Oct","Nov","Dic"],dayNames:["Domingo","Lunes","Martes","Mi&eacute;rcoles","Jueves","Viernes","S&aacute;bado"],dayNamesShort:["Dom","Lun","Mar","Mi&eacute;","Juv","Vie","S&aacute;b"],formatString:"%Y-%m-%d %H:%M:%S"},ru:{monthNames:["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],monthNamesShort:["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек"],dayNames:["воскресенье","понедельник","вторник","среда","четверг","пятница","суббота"],dayNamesShort:["вск","пнд","втр","срд","чтв","птн","сбт"],formatString:"%Y-%m-%d %H:%M:%S"},ar:{monthNames:["كانون الثاني","شباط","آذار","نيسان","آذار","حزيران","تموز","آب","أيلول","تشرين الأول","تشرين الثاني","كانون الأول"],monthNamesShort:["1","2","3","4","5","6","7","8","9","10","11","12"],dayNames:["السبت","الأحد","الاثنين","الثلاثاء","الأربعاء","الخميس","الجمعة"],dayNamesShort:["سبت","أحد","اثنين","ثلاثاء","أربعاء","خميس","جمعة"],formatString:"%Y-%m-%d %H:%M:%S"},pt:{monthNames:["Janeiro","Fevereiro","Mar&ccedil;o","Abril","Maio","Junho","Julho","Agosto","Setembro","Outubro","Novembro","Dezembro"],monthNamesShort:["Jan","Fev","Mar","Abr","Mai","Jun","Jul","Ago","Set","Out","Nov","Dez"],dayNames:["Domingo","Segunda-feira","Ter&ccedil;a-feira","Quarta-feira","Quinta-feira","Sexta-feira","S&aacute;bado"],dayNamesShort:["Dom","Seg","Ter","Qua","Qui","Sex","S&aacute;b"],formatString:"%Y-%m-%d %H:%M:%S"},"pt-BR":{monthNames:["Janeiro","Fevereiro","Mar&ccedil;o","Abril","Maio","Junho","Julho","Agosto","Setembro","Outubro","Novembro","Dezembro"],monthNamesShort:["Jan","Fev","Mar","Abr","Mai","Jun","Jul","Ago","Set","Out","Nov","Dez"],dayNames:["Domingo","Segunda-feira","Ter&ccedil;a-feira","Quarta-feira","Quinta-feira","Sexta-feira","S&aacute;bado"],dayNamesShort:["Dom","Seg","Ter","Qua","Qui","Sex","S&aacute;b"],formatString:"%Y-%m-%d %H:%M:%S"},pl:{monthNames:["Styczeń","Luty","Marzec","Kwiecień","Maj","Czerwiec","Lipiec","Sierpień","Wrzesień","Październik","Listopad","Grudzień"],monthNamesShort:["Sty","Lut","Mar","Kwi","Maj","Cze","Lip","Sie","Wrz","Paź","Lis","Gru"],dayNames:["Niedziela","Poniedziałek","Wtorek","Środa","Czwartek","Piątek","Sobota"],dayNamesShort:["Ni","Pn","Wt","Śr","Cz","Pt","Sb"],formatString:"%Y-%m-%d %H:%M:%S"},nl:{monthNames:["Januari","Februari","Maart","April","Mei","Juni","July","Augustus","September","Oktober","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","Mei","Jun","Jul","Aug","Sep","Okt","Nov","Dec"],dayNames:","["Zondag","Maandag","Dinsdag","Woensdag","Donderdag","Vrijdag","Zaterdag"],dayNamesShort:["Zo","Ma","Di","Wo","Do","Vr","Za"],formatString:"%Y-%m-%d %H:%M:%S"},sv:{monthNames:["januari","februari","mars","april","maj","juni","juli","augusti","september","oktober","november","december"],monthNamesShort:["jan","feb","mar","apr","maj","jun","jul","aug","sep","okt","nov","dec"],dayNames:["söndag","måndag","tisdag","onsdag","torsdag","fredag","lördag"],dayNamesShort:["sön","mån","tis","ons","tor","fre","lör"],formatString:"%Y-%m-%d %H:%M:%S"}};ag.regional["en-US"]=ag.regional["en-GB"]=ag.regional.en;ag.regional.getLocale=function(){var ah=ag.config.defaultLocale;if(document&&document.getElementsByTagName("html")&&document.getElementsByTagName("html")[0].lang){ah=document.getElementsByTagName("html")[0].lang;if(!ag.regional.hasOwnProperty(ah)){ah=ag.config.defaultLocale}}return ah};var C=24*60*60*1000;var N=function(ah,ak){ah=String(ah);var ai=ak-ah.length;var aj=String(Math.pow(10,ai)).slice(1);return aj.concat(ah)};var E={millisecond:1,second:1000,minute:60*1000,hour:60*60*1000,day:C,week:7*C,month:{add:function(aj,ah){E.year.add(aj,Math[ah>0?"floor":"ceil"](ah/12));var ai=aj.getMonth()+(ah%12);if(ai==12){ai=0;aj.setYear(aj.getFullYear()+1)}else{if(ai==-1){ai=11;aj.setYear(aj.getFullYear()-1)}}aj.setMonth(ai)},diff:function(al,aj){var ah=al.getFullYear()-aj.getFullYear();var ai=al.getMonth()-aj.getMonth()+(ah*12);var ak=al.getDate()-aj.getDate();return ai+(ak/30)}},year:{add:function(ai,ah){ai.setYear(ai.getFullYear()+Math[ah>0?"floor":"ceil"](ah))},diff:function(ai,ah){return E.month.diff(ai,ah)/12}}};for(var Y in E){if(Y.substring(Y.length-1)!="s"){E[Y+"s"]=E[Y]}}var H=function(al,ak,ai){if(ag.formats[ai]["shortcuts"][ak]){return ag.strftime(al,ag.formats[ai]["shortcuts"][ak],ai)}else{var ah=(ag.formats[ai]["codes"][ak]||"").split(".");var aj=al["get"+ah[0]]?al["get"+ah[0]]():"";if(ah[1]){aj=N(aj,ah[1])}return aj}};ag.strftime=function(an,ak,aj,ao){var ai="perl";var am=ag.regional.getLocale();if(aj&&ag.formats.hasOwnProperty(aj)){ai=aj}else{if(aj&&ag.regional.hasOwnProperty(aj)){am=aj}}if(ao&&ag.formats.hasOwnProperty(ao)){ai=ao}else{if(ao&&ag.regional.hasOwnProperty(ao)){am=ao}}if(l(an)!="[object Object]"||an._type!="jsDate"){an=new ag(an);an.locale=am}if(!ak){ak=an.formatString||ag.regional[am]["formatString"]}var ah=ak||"%Y-%m-%d",ap="",al;while(ah.length>0){if(al=ah.match(ag.formats[ai].codes.matcher)){ap+=ah.slice(0,al.index);ap+=(al[1]||"")+H(an,al[2],ai);ah=ah.slice(al.index+al[0].length)}else{ap+=ah;ah=""}}return ap};ag.formats={ISO:"%Y-%m-%dT%H:%M:%S.%N%G",SQL:"%Y-%m-%d %H:%M:%S"};ag.formats.perl={codes:{matcher:/()%(#?(%|[a-z]))/i,Y:"FullYear",y:"ShortYear.2",m:"MonthNumber.2","#m":"MonthNumber",B:"MonthName",b:"AbbrMonthName",d:"Date.2","#d":"Date",e:"Date",A:"DayName",a:"AbbrDayName",w:"Day",H:"Hours.2","#H":"Hours",I:"Hours12.2","#I":"Hours12",p:"AMPM",M:"Minutes.2","#M":"Minutes",S:"Seconds.2","#S":"Seconds",s:"Unix",N:"Milliseconds.3","#N":"Milliseconds",O:"TimezoneOffset",Z:"TimezoneName",G:"GmtOffset"},shortcuts:{F:"%Y-%m-%d",T:"%H:%M:%S",X:"%H:%M:%S",x:"%m/%d/%y",D:"%m/%d/%y","#c":"%a %b %e %H:%M:%S %Y",v:"%e-%b-%Y",R:"%H:%M",r:"%I:%M:%S %p",t:"\t",n:"\n","%":"%"}};ag.formats.php={codes:{matcher:/()%((%|[a-z]))/i,a:"AbbrDayName",A:"DayName",d:"Date.2",e:"Date",j:"DayOfYear.3",u:"DayOfWeek",w:"Day",U:"FullWeekOfYear.2",V:"IsoWeek.2",W:"WeekOfYear.2",b:"AbbrMonthName",B:"MonthName",m:"MonthNumber.2",h:"AbbrMonthName",C:"Century.2",y:"ShortYear.2",Y:"FullYear",H:"Hours.2",I:"Hours12.2",l:"Hours12",p:"AMPM",P:"AmPm",M:"Minutes.2",S:"Seconds.2",s:"Unix",O:"TimezoneOffset",z:"GmtOffset",Z:"TimezoneAbbr"},shortcuts:{D:"%m/%d/%y",F:"%Y-%m-%d",T:"%H:%M:%S",X:"%H:%M:%S",x:"%m/%d/%y",R:"%H:%M",r:"%I:%M:%S %p",t:"\t",n:"\n","%":"%"}};ag.createDate=function(aj){if(aj==null){return new Date()}if(aj instanceof Date){return aj}if(typeof aj=="number"){return new Date(aj)}var ao=String(aj).replace(/^\s*(.+)\s*$/g,"$1");ao=ao.replace(/^([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,4})/,"$1/$2/$3");ao=ao.replace(/^(3[01]|[0-2]?\d)[-\/]([a-z]{3,})[-\/](\d{4})/i,"$1 $2 $3");var an=ao.match(/^(3[01]|[0-2]?\d)[-\/]([a-z]{3,})[-\/](\d{2})\D*/i);if(an&&an.length>3){var at=parseFloat(an[3]);var am=ag.config.defaultCentury+at;am=String(am);ao=ao.replace(/^(3[01]|[0-2]?\d)[-\/]([a-z]{3,})[-\/](\d{2})\D*/i,an[1]+" "+an[2]+" "+am)}an=ao.match(/^([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{1,2})[^0-9]/);function ar(ax,aw){var aC=parseFloat(aw[1]);var aB=parseFloat(aw[2]);var aA=parseFloat(aw[3]);var az=ag.config.defaultCentury;var av,au,aD,ay;if(aC>31){au=aA;aD=aB;av=az+aC}else{au=aB;aD=aC;av=az+aA}ay=aD+"/"+au+"/"+av;return ax.replace(/^([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{1,2})/,ay)}if(an&&an.length>3){ao=ar(ao,an)}var an=ao.match(/^([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{1,2})$/);if(an&&an.length>3){ao=ar(ao,an)}var al=0;var ai=ag.matchers.length;var aq,ah,ap=ao,ak;while(al<ai){ah=Date.parse(ap);if(!isNaN(ah)){return new Date(ah)}aq=ag.matchers[al];if(typeof aq=="function"){ak=aq.call(ag,ap);if(ak instanceof Date){return ak}}else{ap=ao.replace(aq[0],aq[1])}al++}return NaN};ag.daysInMonth=function(ah,ai){if(ai==2){return new Date(ah,1,29).getDate()==29?29:28}return[u,31,u,31,30,31,30,31,31,30,31,30,31][ai]};ag.matchers=[[/(3[01]|[0-2]\d)\s*\.\s*(1[0-2]|0\d)\s*\.\s*([1-9]\d{3})/,"$2/$1/$3"],[/([1-9]\d{3})\s*-\s*(1[0-2]|0\d)\s*-\s*(3[01]|[0-2]\d)/,"$2/$3/$1"],function(ak){var ai=ak.match(/^(?:(.+)\s+)?([012]?\d)(?:\s*\:\s*(\d\d))?(?:\s*\:\s*(\d\d(\.\d*)?))?\s*(am|pm)?\s*$/i);if(ai){if(ai[1]){var aj=this.createDate(ai[1]);if(isNaN(aj)){return}}else{var aj=new Date();aj.setMilliseconds(0)}var ah=parseFloat(ai[2]);if(ai[6]){ah=ai[6].toLowerCase()=="am"?(ah==12?0:ah):(ah==12?12:ah+12)}aj.setHours(ah,parseInt(ai[3]||0,10),parseInt(ai[4]||0,10),((parseFloat(ai[5]||0))||0)*1000);return aj}else{return ak}},function(ak){var ai=ak.match(/^(?:(.+))[T|\s+]([012]\d)(?:\:(\d\d))(?:\:(\d\d))(?:\.\d+)([\+\-]\d\d\:\d\d)$/i);if(ai){if(ai[1]){var aj=this.createDate(ai[1]);if(isNaN(aj)){return}}else{var aj=new Date();aj.setMilliseconds(0)}var ah=parseFloat(ai[2]);aj.setHours(ah,parseInt(ai[3],10),parseInt(ai[4],10),parseFloat(ai[5])*1000);return aj}else{return ak}},function(al){var aj=al.match(/^([0-3]?\d)\s*[-\/.\s]{1}\s*([a-zA-Z]{3,9})\s*[-\/.\s]{1}\s*([0-3]?\d)$/);if(aj){var ak=new Date();var am=ag.config.defaultCentury;var ao=parseFloat(aj[1]);var an=parseFloat(aj[3]);var ai,ah,ap;if(ao>31){ah=an;ai=am+ao}else{ah=ao;ai=am+an}var ap=ab(aj[2],ag.regional[ag.regional.getLocale()]["monthNamesShort"]);if(ap==-1){ap=ab(aj[2],ag.regional[ag.regional.getLocale()]["monthNames"])}ak.setFullYear(ai,ap,ah);ak.setHours(0,0,0,0);return ak}else{return al}}];function ab(aj,ak){if(ak.indexOf){return ak.indexOf(aj)}for(var ah=0,ai=ak.length;ah<ai;ah++){if(ak[ah]===aj){return ah}}return -1}function l(ah){if(ah===null){return"[object Null]"}return Object.prototype.toString.call(ah)}L.jsDate=ag;L.jqplot.sprintf=function(){function an(au,ap,aq,at){var ar=(au.length>=ap)?"":Array(1+ap-au.length>>>0).join(aq);return at?au+ar:ar+au}function ak(ar){var aq=new String(ar);for(var ap=10;ap>0;ap--){if(aq==(aq=aq.replace(/^(\d+)(\d{3})/,"$1"+L.jqplot.sprintf.thousandsSeparator+"$2"))){break}}return aq}function aj(av,au,ax,ar,at,aq){var aw=ar-av.length;if(aw>0){var ap=" ";if(aq){ap="&nbsp;"}if(ax||!at){av=an(av,ar,ap,ax)}else{av=av.slice(0,au.length)+an("",aw,"0",true)+av.slice(au.length)}}return av}function ao(ay,aq,aw,ar,ap,av,ax,au){var at=ay>>>0;aw=aw&&at&&{"2":"0b","8":"0","16":"0x"}[aq]||"";ay=aw+an(at.toString(aq),av||0,"0",false);return aj(ay,aw,ar,ap,ax,au)}function ah(au,av,ar,ap,at,aq){if(ap!=null){au=au.slice(0,ap)}return aj(au,"",av,ar,at,aq)}var ai=arguments,al=0,am=ai[al++];return am.replace(L.jqplot.sprintf.regex,function(aM,ax,ay,aB,aO,aJ,av){if(aM=="%%"){return"%"}var aD=false,az="",aA=false,aL=false,aw=false,au=false;for(var aI=0;ay&&aI<ay.length;aI++){switch(ay.charAt(aI)){case" ":az=" ";break;case"+":az="+";break;case"-":aD=true;break;case"0":aA=true;break;case"#":aL=true;break;case"&":aw=true;break;case"'":au=true;break}}if(!aB){aB=0}else{if(aB=="*"){aB=+ai[al++]}else{if(aB.charAt(0)=="*"){aB=+ai[aB.slice(1,-1)]}else{aB=+aB}}}if(aB<0){aB=-aB;aD=true}if(!isFinite(aB)){throw new Error("$.jqplot.sprintf: (minimum-)width must be finite")}if(!aJ){aJ="fFeE".indexOf(av)>-1?6:(av=="d")?0:void (0)}else{if(aJ=="*"){aJ=+ai[al++]}else{if(aJ.charAt(0)=="*"){aJ=+ai[aJ.slice(1,-1)]}else{aJ=+aJ}}}var aF=ax?ai[ax.slice(0,-1)]:ai[al++];switch(av){case"s":if(aF==null){return""}return ah(String(aF),aD,aB,aJ,aA,aw);case"c":return ah(String.fromCharCode(+aF),aD,aB,aJ,aA,aw);case"b":return ao(aF,2,aL,aD,aB,aJ,aA,aw);case"o":return ao(aF,8,aL,aD,aB,aJ,aA,aw);case"x":return ao(aF,16,aL,aD,aB,aJ,aA,aw);case"X":return ao(aF,16,aL,aD,aB,aJ,aA,aw).toUpperCase();case"u":return ao(aF,10,aL,aD,aB,aJ,aA,aw);case"i":var ar=parseInt(+aF,10);if(isNaN(ar)){return""}var aH=ar<0?"-":az;var aK=au?ak(String(Math.abs(ar))):String(Math.abs(ar));aF=aH+an(aK,aJ,"0",false);return aj(aF,aH,aD,aB,aA,aw);case"d":var ar=Math.round(+aF);if(isNaN(ar)){return""}var aH=ar<0?"-":az;var aK=au?ak(String(Math.abs(ar))):String(Math.abs(ar));aF=aH+an(aK,aJ,"0",false);return aj(aF,aH,aD,aB,aA,aw);case"e":case"E":case"f":case"F":case"g":case"G":var ar=+aF;if(isNaN(ar)){return""}var aH=ar<0?"-":az;var at=["toExponential","toFixed","toPrecision"]["efg".indexOf(av.toLowerCase())];var aN=["toString","toUpperCase"]["eEfFgG".indexOf(av)%2];var aK=Math.abs(ar)[at](aJ);var aE=aK.toString().split(".");aE[0]=au?ak(aE[0]):aE[0];aK=aE.join(L.jqplot.sprintf.decimalMark);aF=aH+aK;var aC=aj(aF,aH,aD,aB,aA,aw)[aN]();return aC;case"p":case"P":var ar=+aF;if(isNaN(ar)){return""}var aH=ar<0?"-":az;var aE=String(Number(Math.abs(ar)).toExponential()).split(/e|E/);var aq=(aE[0].indexOf(".")!=-1)?aE[0].length-1:String(ar).length;var aG=(aE[1]<0)?-aE[1]-1:0;if(Math.abs(ar)<1){if(aq+aG<=aJ){aF=aH+Math.abs(ar).toPrecision(aq)}else{if(aq<=aJ-1){aF=aH+Math.abs(ar).toExponential(aq-1)}else{aF=aH+Math.abs(ar).toExponential(aJ-1)}}}else{var ap=(aq<=aJ)?aq:aJ;aF=aH+Math.abs(ar).toPrecision(ap)}var aN=["toString","toUpperCase"]["pP".indexOf(av)%2];return aj(aF,aH,aD,aB,aA,aw)[aN]();case"n":return"";default:return aM}})};L.jqplot.sprintf.thousandsSeparator=",";L.jqplot.sprintf.decimalMark=".";L.jqplot.sprintf.regex=/%%|%(\d+\$)?([-+#0&\' ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([nAscboxXuidfegpEGP])/g;L.jqplot.getSignificantFigures=function(al){var an=String(Number(Math.abs(al)).toExponential()).split(/e|E/);var am=(an[0].indexOf(".")!=-1)?an[0].length-1:an[0].length;var ai=(an[1]<0)?-an[1]-1:0;var ah=parseInt(an[1],10);var aj=(ah+1>0)?ah+1:0;var ak=(am<=aj)?0:am-ah-1;return{significantDigits:am,digitsLeft:aj,digitsRight:ak,zeros:ai,exponent:ah}};L.jqplot.getPrecision=function(ah){return L.jqplot.getSignificantFigures(ah).digitsRight};var X=L.uiBackCompat!==false;L.jqplot.effects={effect:{}};var m="jqplot.storage.";L.extend(L.jqplot.effects,{version:"1.9pre",save:function(ai,aj){for(var ah=0;ah<aj.length;ah++){if(aj[ah]!==null){ai.data(m+aj[ah],ai[0].style[aj[ah]])}}},restore:function(ai,aj){for(var ah=0;ah<aj.length;ah++){if(aj[ah]!==null){ai.css(aj[ah],ai.data(m+aj[ah]))}}},setMode:function(ah,ai){if(ai==="toggle"){ai=ah.is(":hidden")?"show":"hide"}return ai},createWrapper:function(ai){if(ai.parent().is(".ui-effects-wrapper")){return ai.parent()}var aj={width:ai.outerWidth(true),height:ai.outerHeight(true),"float":ai.css("float")},al=L("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),ah={width:ai.width(),height:ai.height()},ak=document.activeElement;ai.wrap(al);if(ai[0]===ak||L.contains(ai[0],ak)){L(ak).focus()}al=ai.parent();if(ai.css("position")==="static"){al.css({position:"relative"});ai.css({position:"relative"})}else{L.extend(aj,{position:ai.css("position"),zIndex:ai.css("z-index")});L.each(["top","left","bottom","right"],function(am,an){aj[an]=ai.css(an);if(isNaN(parseInt(aj[an],10))){aj[an]="auto"}});ai.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})}ai.css(ah);return al.css(aj).show()},removeWrapper:function(ah){var ai=document.activeElement;if(ah.parent().is(".ui-effects-wrapper")){ah.parent().replaceWith(ah);if(ah[0]===ai||L.contains(ah[0],ai)){L(ai).focus()}}return ah}});function j(ai,ah,aj,ak){if(L.isPlainObject(ai)){return ai}ai={effect:ai};if(ah===u){ah={}}if(L.isFunction(ah)){ak=ah;aj=null;ah={}}if(L.type(ah)==="number"||L.fx.speeds[ah]){ak=aj;aj=ah;ah={}}if(L.isFunction(aj)){ak=aj;aj=null}if(ah){L.extend(ai,ah)}aj=aj||ah.duration;ai.duration=L.fx.off?0:typeof aj==="number"?aj:aj in L.fx.speeds?L.fx.speeds[aj]:L.fx.speeds._default;ai.complete=ak||ah.complete;return ai}function ae(ah){if(!ah||typeof ah==="number"||L.fx.speeds[ah]){return true}if(typeof ah==="string"&&!L.jqplot.effects.effect[ah]){if(X&&L.jqplot.effects[ah]){return false}return true}return false}L.fn.extend({jqplotEffect:function(ap,aq,ai,ao){var an=j.apply(this,arguments),ak=an.mode,al=an.queue,am=L.jqplot.effects.effect[an.effect],ah=!am&&X&&L.jqplot.effects[an.effect];if(L.fx.off||!(am||ah)){if(ak){return this[ak](an.duration,an.complete)}else{return this.each(function(){if(an.complete){an.complete.call(this)}})}}function aj(au){var av=L(this),at=an.complete,aw=an.mode;function ar(){if(L.isFunction(at)){at.call(av[0])}if(L.isFunction(au)){au()}}if(av.is(":hidden")?aw==="hide":aw==="show"){ar()}else{am.call(av[0],an,ar)}}if(am){return al===false?this.each(aj):this.queue(al||"fx",aj)}else{return ah.call(this,{options:an,duration:an.duration,callback:an.complete,mode:an.mode})}}});var a=/up|down|vertical/,v=/up|left|vertical|horizontal/;L.jqplot.effects.effect.blind=function(aj,ao){var ak=L(this),ar=["position","top","bottom","left","right","height","width"],ap=L.jqplot.effects.setMode(ak,aj.mode||"hide"),au=aj.direction||"up",am=a.test(au),al=am?"height":"width",aq=am?"top":"left",aw=v.test(au),an={},av=ap==="show",ai,ah,at;if(ak.parent().is(".ui-effects-wrapper")){L.jqplot.effects.save(ak.parent(),ar)}else{L.jqplot.effects.save(ak,ar)}ak.show();at=parseInt(ak.css("top"),10);ai=L.jqplot.effects.createWrapper(ak).css({overflow:"hidden"});ah=am?ai[al]()+at:ai[al]();an[al]=av?String(ah):"0";if(!aw){ak.css(am?"bottom":"right",0).css(am?"top":"left","").css({position:"absolute"});an[aq]=av?"0":String(ah)}if(av){ai.css(al,0);if(!aw){ai.css(aq,ah)}}ai.animate(an,{duration:aj.duration,easing:aj.easing,queue:false,complete:function(){if(ap==="hide"){ak.hide()}L.jqplot.effects.restore(ak,ar);L.jqplot.effects.removeWrapper(ak);ao()}})}})(jQuery);
WRFILE: jqplot.pieRenderer.min.js

(function(e){e.jqplot.PieRenderer=function(){e.jqplot.LineRenderer.call(this)};e.jqplot.PieRenderer.prototype=new e.jqplot.LineRenderer();e.jqplot.PieRenderer.prototype.constructor=e.jqplot.PieRenderer;e.jqplot.PieRenderer.prototype.init=function(q,u){this.diameter=null;this.padding=20;this.sliceMargin=0;this.fill=true;this.shadowOffset=2;this.shadowAlpha=0.07;this.shadowDepth=5;this.highlightMouseOver=true;this.highlightMouseDown=false;this.highlightColors=[];this.dataLabels="percent";this.showDataLabels=false;this.dataLabelFormatString=null;this.dataLabelThreshold=3;this.dataLabelPositionFactor=0.52;this.dataLabelNudge=2;this.dataLabelCenterOn=true;this.startAngle=0;this.tickRenderer=e.jqplot.PieTickRenderer;this._drawData=true;this._type="pie";if(q.highlightMouseDown&&q.highlightMouseOver==null){q.highlightMouseOver=false}e.extend(true,this,q);if(this.sliceMargin<0){this.sliceMargin=0}this._diameter=null;this._radius=null;this._sliceAngles=[];this._highlightedPoint=null;if(this.highlightColors.length==0){for(var s=0;s<this.seriesColors.length;s++){var r=e.jqplot.getColorComponents(this.seriesColors[s]);var o=[r[0],r[1],r[2]];var t=o[0]+o[1]+o[2];for(var p=0;p<3;p++){o[p]=(t>570)?o[p]*0.8:o[p]+0.3*(255-o[p]);o[p]=parseInt(o[p],10)}this.highlightColors.push("rgb("+o[0]+","+o[1]+","+o[2]+")")}}this.highlightColorGenerator=new e.jqplot.ColorGenerator(this.highlightColors);u.postParseOptionsHooks.addOnce(m);u.postInitHooks.addOnce(g);u.eventListenerHooks.addOnce("jqplotMouseMove",b);u.eventListenerHooks.addOnce("jqplotMouseDown",a);u.eventListenerHooks.addOnce("jqplotMouseUp",l);u.eventListenerHooks.addOnce("jqplotClick",f);u.eventListenerHooks.addOnce("jqplotRightClick",n);u.postDrawHooks.addOnce(i)};e.jqplot.PieRenderer.prototype.setGridData=function(t){var p=[];var u=[];var o=this.startAngle/180*Math.PI;var s=0;this._drawData=false;for(var r=0;r<this.data.length;r++){if(this.data[r][1]!=0){this._drawData=true}p.push(this.data[r][1]);u.push([this.data[r][0]]);if(r>0){p[r]+=p[r-1]}s+=this.data[r][1]}var q=Math.PI*2/p[p.length-1];for(var r=0;r<p.length;r++){u[r][1]=p[r]*q;u[r][2]=this.data[r][1]/s}this.gridData=u};e.jqplot.PieRenderer.prototype.makeGridData=function(t,u){var p=[];var v=[];var s=0;var o=this.startAngle/180*Math.PI;this._drawData=false;for(var r=0;r<t.length;r++){if(this.data[r][1]!=0){this._drawData=true}p.push(t[r][1]);v.push([t[r][0]]);if(r>0){p[r]+=p[r-1]}s+=t[r][1]}var q=Math.PI*2/p[p.length-1];for(var r=0;r<p.length;r++){v[r][1]=p[r]*q;v[r][2]=t[r][1]/s}return v};function h(o){return Math.sin((o-(o-Math.PI)/8/Math.PI)/2)}function j(u,t,o,v,r){var w=0;var q=t-u;var s=Math.abs(q);var p=o;if(v==false){p+=r}if(p>0&&s>0.01&&s<6.282){w=parseFloat(p)/2/h(q)}return w}e.jqplot.PieRenderer.prototype.drawSlice=function(B,z,y,u,w){if(this._drawData){var p=this._radius;var A=this.fill;var x=this.lineWidth;var s=this.sliceMargin;if(this.fill==false){s+=this.lineWidth}B.save();B.translate(this._center[0],this._center[1]);var D=j(z,y,this.sliceMargin,this.fill,this.lineWidth);var o=D*Math.cos((z+y)/2);var C=D*Math.sin((z+y)/2);if((y-z)<=Math.PI){p-=D}else{p+=D}B.translate(o,C);if(w){for(var v=0,t=this.shadowDepth;v<t;v++){B.save();B.translate(this.shadowOffset*Math.cos(this.shadowAngle/180*Math.PI),this.shadowOffset*Math.sin(this.shadowAngle/180*Math.PI));q(p)}for(var v=0,t=this.shadowDepth;v<t;v++){B.restore()}}else{q(p)}B.restore()}function q(r){if(y>6.282+this.startAngle){y=6.282+this.startAngle;if(z>y){z=6.281+this.startAngle}}if(z>=y){return}B.beginPath();B.fillStyle=u;B.strokeStyle=u;B.lineWidth=x;B.arc(0,0,r,z,y,false);B.lineTo(0,0);B.closePath();if(A){B.fill()}else{B.stroke()}}};e.jqplot.PieRenderer.prototype.draw=function(B,z,E,o){var W;var H=(E!=undefined)?E:{};var t=0;var s=0;var N=1;var L=new e.jqplot.ColorGenerator(this.seriesColors);if(E.legendInfo&&E.legendInfo.placement=="insideGrid"){var J=E.legendInfo;switch(J.location){case"nw":t=J.width+J.xoffset;break;case"w":t=J.width+J.xoffset;break;case"sw":t=J.width+J.xoffset;break;case"ne":t=J.width+J.xoffset;N=-1;break;case"e":t=J.width+J.xoffset;N=-1;break;case"se":t=J.width+J.xoffset;N=-1;break;case"n":s=J.height+J.yoffset;break;case"s":s=J.height+J.yoffset;N=-1;break;default:break}}var K=(H.shadow!=undefined)?H.shadow:this.shadow;var A=(H.fill!=undefined)?H.fill:this.fill;var C=B.canvas.width;var I=B.canvas.height;var Q=C-t-2*this.padding;var X=I-s-2*this.padding;var M=Math.min(Q,X);var Y=M;this._sliceAngles=[];var v=this.sliceMargin;if(this.fill==false){v+=this.lineWidth}var q;var G=0;var R,aa,Z,ab;var D=this.startAngle/180*Math.PI;for(var W=0,V=z.length;W<V;W++){aa=(W==0)?D:z[W-1][1]+D;Z=z[W][1]+D;this._sliceAngles.push([aa,Z]);q=j(aa,Z,this.sliceMargin,this.fill,this.lineWidth);if(Math.abs(Z-aa)>Math.PI){G=Math.max(q,G)}}if(this.diameter!=null&&this.diameter>0){this._diameter=this.diameter-2*G}else{this._diameter=Y-2*G}if(this._diameter<6){e.jqplot.log("Diameter of pie too small, not rendering.");return}var S=this._radius=this._diameter/2;this._center=[(C-N*t)/2+N*t+G*Math.cos(D),(I-N*s)/2+N*s+G*Math.sin(D)];if(this.shadow){for(var W=0,V=z.length;W<V;W++){ab="rgba(0,0,0,"+this.shadowAlpha+")";this.renderer.drawSlice.call(this,B,this._sliceAngles[W][0],this._sliceAngles[W][1],ab,true)}}for(var W=0;W<z.length;W++){this.renderer.drawSlice.call(this,B,this._sliceAngles[W][0],this._sliceAngles[W][1],L.next(),false);if(this.showDataLabels&&z[W][2]*100>=this.dataLabelThreshold){var F,U=(this._sliceAngles[W][0]+this._sliceAngles[W][1])/2,T;if(this.dataLabels=="label"){F=this.dataLabelFormatString||"%s";T=e.jqplot.sprintf(F,z[W][0])}else{if(this.dataLabels=="value"){F=this.dataLabelFormatString||"%d";T=e.jqplot.sprintf(F,this.data[W][1])}else{if(this.dataLabels=="percent"){F=this.dataLabelFormatString||"%d%%";T=e.jqplot.sprintf(F,z[W][2]*100)}else{if(this.dataLabels.constructor==Array){F=this.dataLabelFormatString||"%s";T=e.jqplot.sprintf(F,this.dataLabels[W])}}}}var p=(this._radius)*this.dataLabelPositionFactor+this.sliceMargin+this.dataLabelNudge;var P=this._center[0]+Math.cos(U)*p+this.canvas._offsets.left;var O=this._center[1]+Math.sin(U)*p+this.canvas._offsets.top;var u=e('<div class="jqplot-pie-series jqplot-data-label" style="position:absolute;">'+T+"</div>").insertBefore(o.eventCanvas._elem);if(this.dataLabelCenterOn){P-=u.width()/2;O-=u.height()/2}else{P-=u.width()*Math.sin(U/2);O-=u.height()/2}P=Math.round(P);O=Math.round(O);u.css({left:P,top:O})}}};e.jqplot.PieAxisRenderer=function(){e.jqplot.LinearAxisRenderer.call(this)};e.jqplot.PieAxisRenderer.prototype=new e.jqplot.LinearAxisRenderer();e.jqplot.PieAxisRenderer.prototype.constructor=e.jqplot.PieAxisRenderer;e.jqplot.PieAxisRenderer.prototype.init=function(o){this.tickRenderer=e.jqplot.PieTickRenderer;e.extend(true,this,o);this._dataBounds={min:0,max:100};this.min=0;this.max=100;this.showTicks=false;this.ticks=[];this.showMark=false;this.show=false};e.jqplot.PieLegendRenderer=function(){e.jqplot.TableLegendRenderer.call(this)};e.jqplot.PieLegendRenderer.prototype=new e.jqplot.TableLegendRenderer();e.jqplot.PieLegendRenderer.prototype.constructor=e.jqplot.PieLegendRenderer;e.jqplot.PieLegendRenderer.prototype.init=function(o){this.numberRows=null;this.numberColumns=null;e.extend(true,this,o)};e.jqplot.PieLegendRenderer.prototype.draw=function(){var r=this;if(this.show){var B=this._series;this._elem=e(document.createElement("table"));this._elem.addClass("jqplot-table-legend");var E={position:"absolute"};if(this.background){E.background=this.background}if(this.border){E.border=this.border}if(this.fontSize){E.fontSize=this.fontSize}if(this.fontFamily){E.fontFamily=this.fontFamily}if(this.textColor){E.textColor=this.textColor}if(this.marginTop!=null){E.marginTop=this.marginTop}if(this.marginBottom!=null){E.marginBottom=this.marginBottom}if(this.marginLeft!=null){E.marginLeft=this.marginLeft}if(this.marginRight!=null){E.marginRight=this.marginRight}this._elem.css(E);var I=false,A=false,o,y;var C=B[0];var p=new e.jqplot.ColorGenerator(C.seriesColors);if(C.show){var J=C.data;if(this.numberRows){o=this.numberRows;if(!this.numberColumns){y=Math.ceil(J.length/o)}else{y=this.numberColumns}}else{if(this.numberColumns){y=this.numberColumns;o=Math.ceil(J.length/this.numberColumns)}else{o=J.length;y=1}}var H,G;var q,w,v;var x,z,F;var D=0;var u,t;for(H=0;H<o;H++){q=e(document.createElement("tr"));q.addClass("jqplot-table-legend");if(A){q.prependTo(this._elem)}else{q.appendTo(this._elem)}for(G=0;G<y;G++){if(D<J.length){x=this.labels[D]||J[D][0].toString();F=p.next();if(!A){if(H>0){I=true}else{I=false}}else{if(H==o-1){I=false}else{I=true}}z=(I)?this.rowSpacing:"0";w=e(document.createElement("td"));w.addClass("jqplot-table-legend jqplot-table-legend-swatch");w.css({textAlign:"center",paddingTop:z});u=e(document.createElement("div"));u.addClass("jqplot-table-legend-swatch-outline");t=e(document.createElement("div"));t.addClass("jqplot-table-legend-swatch");t.css({backgroundColor:F,borderColor:F});w.append(u.append(t));v=e(document.createElement("td"));v.addClass("jqplot-table-legend jqplot-table-legend-label");v.css("paddingTop",z);if(this.escapeHtml){v.text(x)}else{v.html(x)}if(A){v.prependTo(q);w.prependTo(q)}else{w.appendTo(q);v.appendTo(q)}I=true}D++}}}}return this._elem};e.jqplot.PieRenderer.prototype.handleMove=function(q,p,t,s,r){if(s){var o=[s.seriesIndex,s.pointIndex,s.data];r.target.trigger("jqplotDataMouseOver",o);if(r.series[o[0]].highlightMouseOver&&!(o[0]==r.plugins.pieRenderer.highlightedSeriesIndex&&o[1]==r.series[o[0]]._highlightedPoint)){r.target.trigger("jqplotDataHighlight",o);d(r,o[0],o[1])}}else{if(s==null){k(r)}}};function c(s,r,p){p=p||{};p.axesDefaults=p.axesDefaults||{};p.legend=p.legend||{};p.seriesDefaults=p.seriesDefaults||{};var o=false;if(p.seriesDefaults.renderer==e.jqplot.PieRenderer){o=true}else{if(p.series){for(var q=0;q<p.series.length;q++){if(p.series[q].renderer==e.jqplot.PieRenderer){o=true}}}}if(o){p.axesDefaults.renderer=e.jqplot.PieAxisRenderer;p.legend.renderer=e.jqplot.PieLegendRenderer;p.legend.preDraw=true;p.seriesDefaults.pointLabels={show:false}}}function g(r,q,o){for(var p=0;p<this.series.length;p++){if(this.series[p].renderer.constructor==e.jqplot.PieRenderer){if(this.series[p].highlightMouseOver){this.series[p].highlightMouseDown=false}}}}function m(o){for(var p=0;p<this.series.length;p++){this.series[p].seriesColors=this.seriesColors;this.series[p].colorGenerator=e.jqplot.colorGenerator}}function d(t,r,q){var p=t.series[r];var o=t.plugins.pieRenderer.highlightCanvas;o._ctx.clearRect(0,0,o._ctx.canvas.width,o._ctx.canvas.height);p._highlightedPoint=q;t.plugins.pieRenderer.highlightedSeriesIndex=r;p.renderer.drawSlice.call(p,o._ctx,p._sliceAngles[q][0],p._sliceAngles[q][1],p.highlightColorGenerator.get(q),false)}function k(q){var o=q.plugins.pieRenderer.highlightCanvas;o._ctx.clearRect(0,0,o._ctx.canvas.width,o._ctx.canvas.height);for(var p=0;p<q.series.length;p++){q.series[p]._highlightedPoint=null}q.plugins.pieRenderer.highlightedSeriesIndex=null;q.target.trigger("jqplotDataUnhighlight")}function b(s,r,v,u,t){if(u){var q=[u.seriesIndex,u.pointIndex,u.data];var p=jQuery.Event("jqplotDataMouseOver");p.pageX=s.pageX;p.pageY=s.pageY;t.target.trigger(p,q);if(t.series[q[0]].highlightMouseOver&&!(q[0]==t.plugins.pieRenderer.highlightedSeriesIndex&&q[1]==t.series[q[0]]._highlightedPoint)){var o=jQuery.Event("jqplotDataHighlight");o.which=s.which;o.pageX=s.pageX;o.pageY=s.pageY;t.target.trigger(o,q);d(t,q[0],q[1])}}else{if(u==null){k(t)}}}function a(r,q,u,t,s){if(t){var p=[t.seriesIndex,t.pointIndex,t.data];if(s.series[p[0]].highlightMouseDown&&!(p[0]==s.plugins.pieRenderer.highlightedSeriesIndex&&p[1]==s.series[p[0]]._highlightedPoint)){var o=jQuery.Event("jqplotDataHighlight");o.which=r.which;o.pageX=r.pageX;o.pageY=r.pageY;s.target.trigger(o,p);d(s,p[0],p[1])}}else{if(t==null){k(s)}}}function l(q,p,t,s,r){var o=r.plugins.pieRenderer.highlightedSeriesIndex;if(o!=null&&r.series[o].highlightMouseDown){k(r)}}function f(r,q,u,t,s){if(t){var p=[t.seriesIndex,t.pointIndex,t.data];var o=jQuery.Event("jqplotDataClick");o.which=r.which;o.pageX=r.pageX;o.pageY=r.pageY;s.target.trigger(o,p)}}function n(s,r,v,u,t){if(u){var q=[u.seriesIndex,u.pointIndex,u.data];var o=t.plugins.pieRenderer.highlightedSeriesIndex;if(o!=null&&t.series[o].highlightMouseDown){k(t)}var p=jQuery.Event("jqplotDataRightClick");p.which=s.which;p.pageX=s.pageX;p.pageY=s.pageY;t.target.trigger(p,q)}}function i(){if(this.plugins.pieRenderer&&this.plugins.pieRenderer.highlightCanvas){this.plugins.pieRenderer.highlightCanvas.resetCanvas();this.plugins.pieRenderer.highlightCanvas=null}this.plugins.pieRenderer={highlightedSeriesIndex:null};this.plugins.pieRenderer.highlightCanvas=new e.jqplot.GenericCanvas();var p=e(this.targetId+" .jqplot-data-label");if(p.length){e(p[0]).before(this.plugins.pieRenderer.highlightCanvas.createElement(this._gridPadding,"jqplot-pieRenderer-highlight-canvas",this._plotDimensions,this))}else{this.eventCanvas._elem.before(this.plugins.pieRenderer.highlightCanvas.createElement(this._gridPadding,"jqplot-pieRenderer-highlight-canvas",this._plotDimensions,this))}var o=this.plugins.pieRenderer.highlightCanvas.setContext();this.eventCanvas._elem.bind("mouseleave",{plot:this},function(q){k(q.data.plot)})}e.jqplot.preInitHooks.push(c);e.jqplot.PieTickRenderer=function(){e.jqplot.AxisTickRenderer.call(this)};e.jqplot.PieTickRenderer.prototype=new e.jqplot.AxisTickRenderer();e.jqplot.PieTickRenderer.prototype.constructor=e.jqplot.PieTickRenderer})(jQuery);
WRFILE: jqplot.barRenderer.min.js

(function(d){d.jqplot.BarRenderer=function(){d.jqplot.LineRenderer.call(this)};d.jqplot.BarRenderer.prototype=new d.jqplot.LineRenderer();d.jqplot.BarRenderer.prototype.constructor=d.jqplot.BarRenderer;d.jqplot.BarRenderer.prototype.init=function(o,q){this.barPadding=8;this.barMargin=10;this.barDirection="vertical";this.barWidth=null;this.shadowOffset=2;this.shadowDepth=5;this.shadowAlpha=0.08;this.waterfall=false;this.groups=1;this.varyBarColor=false;this.highlightMouseOver=true;this.highlightMouseDown=false;this.highlightColors=[];this.transposedData=true;this.renderer.animation={show:false,direction:"down",speed:3000,_supported:true};this._type="bar";if(o.highlightMouseDown&&o.highlightMouseOver==null){o.highlightMouseOver=false}d.extend(true,this,o);d.extend(true,this.renderer,o);this.fill=true;if(this.barDirection==="horizontal"&&this.rendererOptions.animation&&this.rendererOptions.animation.direction==null){this.renderer.animation.direction="left"}if(this.waterfall){this.fillToZero=false;this.disableStack=true}if(this.barDirection=="vertical"){this._primaryAxis="_xaxis";this._stackAxis="y";this.fillAxis="y"}else{this._primaryAxis="_yaxis";this._stackAxis="x";this.fillAxis="x"}this._highlightedPoint=null;this._plotSeriesInfo=null;this._dataColors=[];this._barPoints=[];var p={lineJoin:"miter",lineCap:"round",fill:true,isarc:false,strokeStyle:this.color,fillStyle:this.color,closePath:this.fill};this.renderer.shapeRenderer.init(p);var n={lineJoin:"miter",lineCap:"round",fill:true,isarc:false,angle:this.shadowAngle,offset:this.shadowOffset,alpha:this.shadowAlpha,depth:this.shadowDepth,closePath:this.fill};this.renderer.shadowRenderer.init(n);q.postInitHooks.addOnce(h);q.postDrawHooks.addOnce(j);q.eventListenerHooks.addOnce("jqplotMouseMove",b);q.eventListenerHooks.addOnce("jqplotMouseDown",a);q.eventListenerHooks.addOnce("jqplotMouseUp",l);q.eventListenerHooks.addOnce("jqplotClick",e);q.eventListenerHooks.addOnce("jqplotRightClick",m)};function g(t,p,o,w){if(this.rendererOptions.barDirection=="horizontal"){this._stackAxis="x";this._primaryAxis="_yaxis"}if(this.rendererOptions.waterfall==true){this._data=d.extend(true,[],this.data);var s=0;var u=(!this.rendererOptions.barDirection||this.rendererOptions.barDirection==="vertical"||this.transposedData===false)?1:0;for(var q=0;q<this.data.length;q++){s+=this.data[q][u];if(q>0){this.data[q][u]+=this.data[q-1][u]}}this.data[this.data.length]=(u==1)?[this.data.length+1,s]:[s,this.data.length+1];this._data[this._data.length]=(u==1)?[this._data.length+1,s]:[s,this._data.length+1]}if(this.rendererOptions.groups>1){this.breakOnNull=true;var n=this.data.length;var v=parseInt(n/this.rendererOptions.groups,10);var r=0;for(var q=v;q<n;q+=v){this.data.splice(q+r,0,[null,null]);this._plotData.splice(q+r,0,[null,null]);this._stackData.splice(q+r,0,[null,null]);r++}for(q=0;q<this.data.length;q++){if(this._primaryAxis=="_xaxis"){this.data[q][0]=q+1;this._plotData[q][0]=q+1;this._stackData[q][0]=q+1}else{this.data[q][1]=q+1;this._plotData[q][1]=q+1;this._stackData[q][1]=q+1}}}}d.jqplot.preSeriesInitHooks.push(g);d.jqplot.BarRenderer.prototype.calcSeriesNumbers=function(){var r=0;var t=0;var q=this[this._primaryAxis];var p,o,u;for(var n=0;n<q._series.length;n++){o=q._series[n];if(o===this){u=n}if(o.renderer.constructor==d.jqplot.BarRenderer){r+=o.data.length;t+=1}}return[r,t,u]};d.jqplot.BarRenderer.prototype.setBarWidth=function(){var q;var n=0;var o=0;var t=this[this._primaryAxis];var x,r,v;var w=this._plotSeriesInfo=this.renderer.calcSeriesNumbers.call(this);n=w[0];o=w[1];var u=t.numberTicks;var p=(u-1)/2;if(t.name=="xaxis"||t.name=="x2axis"){if(this._stack){this.barWidth=(t._offsets.max-t._offsets.min)/n*o-this.barMargin}else{this.barWidth=((t._offsets.max-t._offsets.min)/p-this.barPadding*(o-1)-this.barMargin*2)/o}}else{if(this._stack){this.barWidth=(t._offsets.min-t._offsets.max)/n*o-this.barMargin}else{this.barWidth=((t._offsets.min-t._offsets.max)/p-this.barPadding*(o-1)-this.barMargin*2)/o}}return[n,o]};function f(o){var q=[];for(var s=0;s<o.length;s++){var r=d.jqplot.getColorComponents(o[s]);var n=[r[0],r[1],r[2]];var t=n[0]+n[1]+n[2];for(var p=0;p<3;p++){n[p]=(t>570)?n[p]*0.8:n[p]+0.3*(255-n[p]);n[p]=parseInt(n[p],10)}q.push("rgb("+n[0]+","+n[1]+","+n[2]+")")}return q}function i(v,u,s,t,o){var q=v,w=v-1,n,p,r=(o==="x")?0:1;if(q>0){p=t.series[w]._plotData[u][r];if((s*p)<0){n=i(w,u,s,t,o)}else{n=t.series[w].gridData[u][r]}}else{n=(r===0)?t.series[q]._xaxis.series_u2p(0):t.series[q]._yaxis.series_u2p(0)}return n}d.jqplot.BarRenderer.prototype.draw=function(E,L,q,G){var I;var A=d.extend({},q);var w=(A.shadow!=undefined)?A.shadow:this.shadow;var O=(A.showLine!=undefined)?A.showLine:this.showLine;var F=(A.fill!=undefined)?A.fill:this.fill;var p=this.xaxis;var J=this.yaxis;var y=this._xaxis.series_u2p;var K=this._yaxis.series_u2p;var D,C;this._dataColors=[];this._barPoints=[];if(this.barWidth==null){this.renderer.setBarWidth.call(this)}var N=this._plotSeriesInfo=this.renderer.calcSeriesNumbers.call(this);var x=N[0];var v=N[1];var s=N[2];var H=[];if(this._stack){this._barNudge=0}else{this._barNudge=(-Math.abs(v/2-0.5)+s)*(this.barWidth+this.barPadding)}if(O){var u=new d.jqplot.ColorGenerator(this.negativeSeriesColors);var B=new d.jqplot.ColorGenerator(this.seriesColors);var M=u.get(this.index);if(!this.useNegativeColors){M=A.fillStyle}var t=A.fillStyle;var r;var P;var o;if(this.barDirection=="vertical"){for(var I=0;I<L.length;I++){if(!this._stack&&this.data[I][1]==null){continue}H=[];r=L[I][0]+this._barNudge;if(this._stack&&this._prevGridData.length){o=i(this.index,I,this._plotData[I][1],G,"y")}else{if(this.fillToZero){o=this._yaxis.series_u2p(0)}else{if(this.waterfall&&I>0&&I<this.gridData.length-1){o=this.gridData[I-1][1]}else{if(this.waterfall&&I==0&&I<this.gridData.length-1){if(this._yaxis.min<=0&&this._yaxis.max>=0){o=this._yaxis.series_u2p(0)}else{if(this._yaxis.min>0){o=E.canvas.height}else{o=0}}}else{if(this.waterfall&&I==this.gridData.length-1){if(this._yaxis.min<=0&&this._yaxis.max>=0){o=this._yaxis.series_u2p(0)}else{if(this._yaxis.min>0){o=E.canvas.height}else{o=0}}}else{o=E.canvas.height}}}}}if((this.fillToZero&&this._plotData[I][1]<0)||(this.waterfall&&this._data[I][1]<0)){if(this.varyBarColor&&!this._stack){if(this.useNegativeColors){A.fillStyle=u.next()}else{A.fillStyle=B.next()}}else{A.fillStyle=M}}else{if(this.varyBarColor&&!this._stack){A.fillStyle=B.next()}else{A.fillStyle=t}}if(!this.fillToZero||this._plotData[I][1]>=0){H.push([r-this.barWidth/2,o]);H.push([r-this.barWidth/2,L[I][1]]);H.push([r+this.barWidth/2,L[I][1]]);H.push([r+this.barWidth/2,o])}else{H.push([r-this.barWidth/2,L[I][1]]);H.push([r-this.barWidth/2,o]);H.push([r+this.barWidth/2,o]);H.push([r+this.barWidth/2,L[I][1]])}this._barPoints.push(H);if(w&&!this._stack){var z=d.extend(true,{},A);delete z.fillStyle;this.renderer.shadowRenderer.draw(E,H,z)}var n=A.fillStyle||this.color;this._dataColors.push(n);this.renderer.shapeRenderer.draw(E,H,A)}}else{if(this.barDirection=="horizontal"){for(var I=0;I<L.length;I++){if(!this._stack&&this.data[I][0]==null){continue}H=[];r=L[I][1]-this._barNudge;P;if(this._stack&&this._prevGridData.length){P=i(this.index,I,this._plotData[I][0],G,"x")}else{if(this.fillToZero){P=this._xaxis.series_u2p(0)}else{if(this.waterfall&&I>0&&I<this.gridData.length-1){P=this.gridData[I-1][0]}else{if(this.waterfall&&I==0&&I<this.gridData.length-1){if(this._xaxis.min<=0&&this._xaxis.max>=0){P=this._xaxis.series_u2p(0)}else{if(this._xaxis.min>0){P=0}else{P=0}}}else{if(this.waterfall&&I==this.gridData.length-1){if(this._xaxis.min<=0&&this._xaxis.max>=0){P=this._xaxis.series_u2p(0)}else{if(this._xaxis.min>0){P=0}else{P=E.canvas.width}}}else{P=0}}}}}if((this.fillToZero&&this._plotData[I][0]<0)||(this.waterfall&&this._data[I][0]<0)){if(this.varyBarColor&&!this._stack){if(this.useNegativeColors){A.fillStyle=u.next()}else{A.fillStyle=B.next()}}else{A.fillStyle=M}}else{if(this.varyBarColor&&!this._stack){A.fillStyle=B.next()}else{A.fillStyle=t}}if(!this.fillToZero||this._plotData[I][0]>=0){H.push([P,r+this.barWidth/2]);H.push([P,r-this.barWidth/2]);H.push([L[I][0],r-this.barWidth/2]);H.push([L[I][0],r+this.barWidth/2])}else{H.push([L[I][0],r+this.barWidth/2]);H.push([L[I][0],r-this.barWidth/2]);H.push([P,r-this.barWidth/2]);H.push([P,r+this.barWidth/2])}this._barPoints.push(H);if(w&&!this._stack){var z=d.extend(true,{},A);delete z.fillStyle;this.renderer.shadowRenderer.draw(E,H,z)}var n=A.fillStyle||this.color;this._dataColors.push(n);this.renderer.shapeRenderer.draw(E,H,A)}}}}if(this.highlightColors.length==0){this.highlightColors=d.jqplot.computeHighlightColors(this._dataColors)}else{if(typeof(this.highlightColors)=="string"){var N=this.highlightColors;this.highlightColors=[];for(var I=0;I<this._dataColors.length;I++){this.highlightColors.push(N)}}}};d.jqplot.BarRenderer.prototype.drawShadow=function(z,G,p,B){var D;var w=(p!=undefined)?p:{};var t=(w.shadow!=undefined)?w.shadow:this.shadow;var I=(w.showLine!=undefined)?w.showLine:this.showLine;var A=(w.fill!=undefined)?w.fill:this.fill;var o=this.xaxis;var E=this.yaxis;var v=this._xaxis.series_u2p;var F=this._yaxis.series_u2p;var y,C,x,u,s,r;if(this._stack&&this.shadow){if(this.barWidth==null){this.renderer.setBarWidth.call(this)}var H=this._plotSeriesInfo=this.renderer.calcSeriesNumbers.call(this);u=H[0];s=H[1];r=H[2];if(this._stack){this._barNudge=0}else{this._barNudge=(-Math.abs(s/2-0.5)+r)*(this.barWidth+this.barPadding)}if(I){if(this.barDirection=="vertical"){for(var D=0;D<G.length;D++){if(this.data[D][1]==null){continue}C=[];var q=G[D][0]+this._barNudge;var n;if(this._stack&&this._prevGridData.length){n=i(this.index,D,this._plotData[D][1],B,"y")}else{if(this.fillToZero){n=this._yaxis.series_u2p(0)}else{n=z.canvas.height}}C.push([q-this.barWidth/2,n]);C.push([q-this.barWidth/2,G[D][1]]);C.push([q+this.barWidth/2,G[D][1]]);C.push([q+this.barWidth/2,n]);this.renderer.shadowRenderer.draw(z,C,w)}}else{if(this.barDirection=="horizontal"){for(var D=0;D<G.length;D++){if(this.data[D][0]==null){continue}C=[];var q=G[D][1]-this._barNudge;var J;if(this._stack&&this._prevGridData.length){J=i(this.index,D,this._plotData[D][0],B,"x")}else{if(this.fillToZero){J=this._xaxis.series_u2p(0)}else{J=0}}C.push([J,q+this.barWidth/2]);C.push([G[D][0],q+this.barWidth/2]);C.push([G[D][0],q-this.barWidth/2]);C.push([J,q-this.barWidth/2]);this.renderer.shadowRenderer.draw(z,C,w)}}}}}};function h(q,p,n){for(var o=0;o<this.series.length;o++){if(this.series[o].renderer.constructor==d.jqplot.BarRenderer){if(this.series[o].highlightMouseOver){this.series[o].highlightMouseDown=false}}}}function j(){if(this.plugins.barRenderer&&this.plugins.barRenderer.highlightCanvas){this.plugins.barRenderer.highlightCanvas.resetCanvas();this.plugins.barRenderer.highlightCanvas=null}this.plugins.barRenderer={highlightedSeriesIndex:null};this.plugins.barRenderer.highlightCanvas=new d.jqplot.GenericCanvas();this.eventCanvas._elem.before(this.plugins.barRenderer.highlightCanvas.createElement(this._gridPadding,"jqplot-barRenderer-highlight-canvas",this._plotDimensions,this));this.plugins.barRenderer.highlightCanvas.setContext();this.eventCanvas._elem.bind("mouseleave",{plot:this},function(n){k(n.data.plot)})}function c(u,t,q,p){var o=u.series[t];var n=u.plugins.barRenderer.highlightCanvas;n._ctx.clearRect(0,0,n._ctx.canvas.width,n._ctx.canvas.height);o._highlightedPoint=q;u.plugins.barRenderer.highlightedSeriesIndex=t;var r={fillStyle:o.highlightColors[q]};o.renderer.shapeRenderer.draw(n._ctx,p,r);n=null}function k(p){var n=p.plugins.barRenderer.highlightCanvas;n._ctx.clearRect(0,0,n._ctx.canvas.width,n._ctx.canvas.height);for(var o=0;o<p.series.length;o++){p.series[o]._highlightedPoint=null}p.plugins.barRenderer.highlightedSeriesIndex=null;p.target.trigger("jqplotDataUnhighlight");n=null}function b(r,q,u,t,s){if(t){var p=[t.seriesIndex,t.pointIndex,t.data];var o=jQuery.Event("jqplotDataMouseOver");o.pageX=r.pageX;o.pageY=r.pageY;s.target.trigger(o,p);if(s.series[p[0]].show&&s.series[p[0]].highlightMouseOver&&!(p[0]==s.plugins.barRenderer.highlightedSeriesIndex&&p[1]==s.series[p[0]]._highlightedPoint)){var n=jQuery.Event("jqplotDataHighlight");n.which=r.which;n.pageX=r.pageX;n.pageY=r.pageY;s.target.trigger(n,p);c(s,t.seriesIndex,t.pointIndex,t.points)}}else{if(t==null){k(s)}}}function a(q,p,t,s,r){if(s){var o=[s.seriesIndex,s.pointIndex,s.data];if(r.series[o[0]].highlightMouseDown&&!(o[0]==r.plugins.barRenderer.highlightedSeriesIndex&&o[1]==r.series[o[0]]._highlightedPoint)){var n=jQuery.Event("jqplotDataHighlight");n.which=q.which;n.pageX=q.pageX;n.pageY=q.pageY;r.target.trigger(n,o);c(r,s.seriesIndex,s.pointIndex,s.points)}}else{if(s==null){k(r)}}}function l(p,o,s,r,q){var n=q.plugins.barRenderer.highlightedSeriesIndex;if(n!=null&&q.series[n].highlightMouseDown){k(q)}}function e(q,p,t,s,r){if(s){var o=[s.seriesIndex,s.pointIndex,s.data];var n=jQuery.Event("jqplotDataClick");n.which=q.which;n.pageX=q.pageX;n.pageY=q.pageY;r.target.trigger(n,o)}}function m(r,q,u,t,s){if(t){var p=[t.seriesIndex,t.pointIndex,t.data];var n=s.plugins.barRenderer.highlightedSeriesIndex;if(n!=null&&s.series[n].highlightMouseDown){k(s)}var o=jQuery.Event("jqplotDataRightClick");o.which=r.which;o.pageX=r.pageX;o.pageY=r.pageY;s.target.trigger(o,p)}}})(jQuery);
WRFILE: jqplot.dateAxisRenderer.min.js

(function(h){h.jqplot.DateAxisRenderer=function(){h.jqplot.LinearAxisRenderer.call(this);this.date=new h.jsDate()};var c=1000;var e=60*c;var f=60*e;var l=24*f;var b=7*l;var j=30.4368499*l;var k=365.242199*l;var g=[31,28,31,30,31,30,31,30,31,30,31,30];var i=["%M:%S.%#N","%M:%S.%#N","%M:%S.%#N","%M:%S","%M:%S","%M:%S","%M:%S","%H:%M:%S","%H:%M:%S","%H:%M","%H:%M","%H:%M","%H:%M","%H:%M","%H:%M","%a %H:%M","%a %H:%M","%b %e %H:%M","%b %e %H:%M","%b %e %H:%M","%b %e %H:%M","%v","%v","%v","%v","%v","%v","%v"];var m=[0.1*c,0.2*c,0.5*c,c,2*c,5*c,10*c,15*c,30*c,e,2*e,5*e,10*e,15*e,30*e,f,2*f,4*f,6*f,8*f,12*f,l,2*l,3*l,4*l,5*l,b,2*b];var d=[];function a(p,s,t){var o=Number.MAX_VALUE;var u,r,v;for(var q=0,n=m.length;q<n;q++){u=Math.abs(t-m[q]);if(u<o){o=u;r=m[q];v=i[q]}}return[r,v]}h.jqplot.DateAxisRenderer.prototype=new h.jqplot.LinearAxisRenderer();h.jqplot.DateAxisRenderer.prototype.constructor=h.jqplot.DateAxisRenderer;h.jqplot.DateTickFormatter=function(n,o){if(!n){n="%Y/%m/%d"}return h.jsDate.strftime(o,n)};h.jqplot.DateAxisRenderer.prototype.init=function(E){this.tickOptions.formatter=h.jqplot.DateTickFormatter;this.tickInset=0;this.drawBaseline=true;this.baselineWidth=null;this.baselineColor=null;this.daTickInterval=null;this._daTickInterval=null;h.extend(true,this,E);var C=this._dataBounds,u,x,D,y,A,z,o;for(var t=0;t<this._series.length;t++){u={intervals:[],frequencies:{},sortedIntervals:[],min:null,max:null,mean:null};x=0;D=this._series[t];y=D.data;A=D._plotData;z=D._stackData;o=0;for(var r=0;r<y.length;r++){if(this.name=="xaxis"||this.name=="x2axis"){y[r][0]=new h.jsDate(y[r][0]).getTime();A[r][0]=new h.jsDate(y[r][0]).getTime();z[r][0]=new h.jsDate(y[r][0]).getTime();if((y[r][0]!=null&&y[r][0]<C.min)||C.min==null){C.min=y[r][0]}if((y[r][0]!=null&&y[r][0]>C.max)||C.max==null){C.max=y[r][0]}if(r>0){o=Math.abs(y[r][0]-y[r-1][0]);u.intervals.push(o);if(u.frequencies.hasOwnProperty(o)){u.frequencies[o]+=1}else{u.frequencies[o]=1}}x+=o}else{y[r][1]=new h.jsDate(y[r][1]).getTime();A[r][1]=new h.jsDate(y[r][1]).getTime();z[r][1]=new h.jsDate(y[r][1]).getTime();if((y[r][1]!=null&&y[r][1]<C.min)||C.min==null){C.min=y[r][1]}if((y[r][1]!=null&&y[r][1]>C.max)||C.max==null){C.max=y[r][1]}if(r>0){o=Math.abs(y[r][1]-y[r-1][1]);u.intervals.push(o);if(u.frequencies.hasOwnProperty(o)){u.frequencies[o]+=1}else{u.frequencies[o]=1}}}x+=o}if(D.renderer.bands){if(D.renderer.bands.hiData.length){var w=D.renderer.bands.hiData;for(var r=0,q=w.length;r<q;r++){if(this.name==="xaxis"||this.name==="x2axis"){w[r][0]=new h.jsDate(w[r][0]).getTime();if((w[r][0]!=null&&w[r][0]>C.max)||C.max==null){C.max=w[r][0]}}else{w[r][1]=new h.jsDate(w[r][1]).getTime();if((w[r][1]!=null&&w[r][1]>C.max)||C.max==null){C.max=w[r][1]}}}}if(D.renderer.bands.lowData.length){var w=D.renderer.bands.lowData;for(var r=0,q=w.length;r<q;r++){if(this.name==="xaxis"||this.name==="x2axis"){w[r][0]=new h.jsDate(w[r][0]).getTime();if((w[r][0]!=null&&w[r][0]<C.min)||C.min==null){C.min=w[r][0]}}else{w[r][1]=new h.jsDate(w[r][1]).getTime();if((w[r][1]!=null&&w[r][1]<C.min)||C.min==null){C.min=w[r][1]}}}}}var B=0,v=0;for(var p in u.frequencies){u.sortedIntervals.push({interval:p,frequency:u.frequencies[p]})}u.sortedIntervals.sort(function(s,n){return n.frequency-s.frequency});u.min=h.jqplot.arrayMin(u.intervals);u.max=h.jqplot.arrayMax(u.intervals);u.mean=x/y.length;this._intervalStats.push(u);u=x=D=y=A=z=null}C=null};h.jqplot.DateAxisRenderer.prototype.reset=function(){this.min=this._options.min;this.max=this._options.max;this.tickInterval=this._options.tickInterval;this.numberTicks=this._options.numberTicks;this._autoFormatString="";if(this._overrideFormatString&&this.tickOptions&&this.tickOptions.formatString){this.tickOptions.formatString=""}this.daTickInterval=this._daTickInterval};h.jqplot.DateAxisRenderer.prototype.createTicks=function(p){var X=this._ticks;var L=this.ticks;var F=this.name;var H=this._dataBounds;var M=this._intervalStats;var n=(this.name.charAt(0)==="x")?this._plotDimensions.width:this._plotDimensions.height;var w;var ae,J;var y,x;var ad,aa;var s=30;var O=1;var U=null;if(this.tickInterval!=null){if(Number(this.tickInterval)){U=[Number(this.tickInterval),"seconds"]}else{if(typeof this.tickInterval=="string"){var ac=this.tickInterval.split(" ");if(ac.length==1){U=[1,ac[0]]}else{if(ac.length==2){U=[ac[0],ac[1]]}}}}}var v=this.tickInterval;ae=new h.jsDate((this.min!=null)?this.min:H.min).getTime();J=new h.jsDate((this.max!=null)?this.max:H.max).getTime();var A=p.plugins.cursor;if(A&&A._zoom&&A._zoom.zooming){this.min=null;this.max=null}var B=J-ae;if(this.tickOptions==null||!this.tickOptions.formatString){this._overrideFormatString=true}if(L.length){for(aa=0;aa<L.length;aa++){var P=L[aa];var Y=new this.tickRenderer(this.tickOptions);if(P.constructor==Array){Y.value=new h.jsDate(P[0]).getTime();Y.label=P[1];if(!this.showTicks){Y.showLabel=false;Y.showMark=false}else{if(!this.showTickMarks){Y.showMark=false}}Y.setTick(Y.value,this.name);this._ticks.push(Y)}else{Y.value=new h.jsDate(P).getTime();if(!this.showTicks){Y.showLabel=false;Y.showMark=false}else{if(!this.showTickMarks){Y.showMark=false}}Y.setTick(Y.value,this.name);this._ticks.push(Y)}}this.numberTicks=L.length;this.min=this._ticks[0].value;this.max=this._ticks[this.numberTicks-1].value;this.daTickInterval=[(this.max-this.min)/(this.numberTicks-1)/1000,"seconds"]}else{if(this.min==null&&this.max==null&&H.min==H.max){var E=h.extend(true,{},this.tickOptions,{name:this.name,value:null});var T=300000;this.min=H.min-T;this.max=H.max+T;this.numberTicks=3;for(var aa=this.min;aa<=this.max;aa+=T){E.value=aa;var Y=new this.tickRenderer(E);if(this._overrideFormatString&&this._autoFormatString!=""){Y.formatString=this._autoFormatString}Y.showLabel=false;Y.showMark=false;this._ticks.push(Y)}if(this.showTicks){this._ticks[1].showLabel=true}if(this.showTickMarks){this._ticks[1].showTickMarks=true}}else{if(this.min==null&&this.max==null){var N=h.extend(true,{},this.tickOptions,{name:this.name,value:null});var ab,I;if(!this.tickInterval&&!this.numberTicks){var R=Math.max(n,s+1);var Z=115;if(this.tickRenderer===h.jqplot.CanvasAxisTickRenderer&&this.tickOptions.angle){Z=115-40*Math.abs(Math.sin(this.tickOptions.angle/180*Math.PI))}ab=Math.ceil((R-s)/Z+1);I=(J-ae)/(ab-1)}else{if(this.tickInterval){I=new h.jsDate(0).add(U[0],U[1]).getTime()}else{if(this.numberTicks){ab=this.numberTicks;I=(J-ae)/(ab-1)}}}if(I<=19*l){var Q=a(ae,J,I);var r=Q[0];this._autoFormatString=Q[1];ae=new h.jsDate(ae);ae=Math.floor((ae.getTime()-ae.getUtcOffset())/r)*r+ae.getUtcOffset();ab=Math.ceil((J-ae)/r)+1;this.min=ae;this.max=ae+(ab-1)*r;if(this.max<J){this.max+=r;ab+=1}this.tickInterval=r;this.numberTicks=ab;for(var aa=0;aa<ab;aa++){N.value=this.min+aa*r;Y=new this.tickRenderer(N);if(this._overrideFormatString&&this._autoFormatString!=""){Y.formatString=this._autoFormatString}if(!this.showTicks){Y.showLabel=false;Y.showMark=false}else{if(!this.showTickMarks){Y.showMark=false}}this._ticks.push(Y)}O=this.tickInterval}else{if(I<=9*j){this._autoFormatString="%v";var D=Math.round(I/j);if(D<1){D=1}else{if(D>6){D=6}}var V=new h.jsDate(ae).setDate(1).setHours(0,0,0,0);var q=new h.jsDate(J);var z=new h.jsDate(J).setDate(1).setHours(0,0,0,0);if(q.getTime()!==z.getTime()){z=z.add(1,"month")}var S=z.diff(V,"month");ab=Math.ceil(S/D)+1;this.min=V.getTime();this.max=V.clone().add((ab-1)*D,"month").getTime();this.numberTicks=ab;for(var aa=0;aa<ab;aa++){if(aa===0){N.value=V.getTime()}else{N.value=V.add(D,"month").getTime()}Y=new this.tickRenderer(N);if(this._overrideFormatString&&this._autoFormatString!=""){Y.formatString=this._autoFormatString}if(!this.showTicks){Y.showLabel=false;Y.showMark=false}else{if(!this.showTickMarks){Y.showMark=false}}this._ticks.push(Y)}O=D*j}else{this._autoFormatString="%v";var D=Math.round(I/k);if(D<1){D=1}var V=new h.jsDate(ae).setMonth(0,1).setHours(0,0,0,0);var z=new h.jsDate(J).add(1,"year").setMonth(0,1).setHours(0,0,0,0);var K=z.diff(V,"year");ab=Math.ceil(K/D)+1;this.min=V.getTime();this.max=V.clone().add((ab-1)*D,"year").getTime();this.numberTicks=ab;for(var aa=0;aa<ab;aa++){if(aa===0){N.value=V.getTime()}else{N.value=V.add(D,"year").getTime()}Y=new this.tickRenderer(N);if(this._overrideFormatString&&this._autoFormatString!=""){Y.formatString=this._autoFormatString}if(!this.showTicks){Y.showLabel=false;Y.showMark=false}else{if(!this.showTickMarks){Y.showMark=false}}this._ticks.push(Y)}O=D*k}}}else{if(F=="xaxis"||F=="x2axis"){n=this._plotDimensions.width}else{n=this._plotDimensions.height}if(this.min!=null&&this.max!=null&&this.numberTicks!=null){this.tickInterval=null}if(this.tickInterval!=null&&U!=null){this.daTickInterval=U}if(ae==J){var o=24*60*60*500;ae-=o;J+=o}B=J-ae;var G=2+parseInt(Math.max(0,n-100)/100,10);var W,C;W=(this.min!=null)?new h.jsDate(this.min).getTime():ae-B/2*(this.padMin-1);C=(this.max!=null)?new h.jsDate(this.max).getTime():J+B/2*(this.padMax-1);this.min=W;this.max=C;B=this.max-this.min;if(this.numberTicks==null){if(this.daTickInterval!=null){var u=new h.jsDate(this.max).diff(this.min,this.daTickInterval[1],true);this.numberTicks=Math.ceil(u/this.daTickInterval[0])+1;this.max=new h.jsDate(this.min).add((this.numberTicks-1)*this.daTickInterval[0],this.daTickInterval[1]).getTime()}else{if(n>200){this.numberTicks=parseInt(3+(n-200)/100,10)}else{this.numberTicks=2}}}O=B/(this.numberTicks-1)/1000;if(this.daTickInterval==null){this.daTickInterval=[O,"seconds"]}for(var aa=0;aa<this.numberTicks;aa++){var ae=new h.jsDate(this.min);ad=ae.add(aa*this.daTickInterval[0],this.daTickInterval[1]).getTime();var Y=new this.tickRenderer(this.tickOptions);if(!this.showTicks){Y.showLabel=false;Y.showMark=false}else{if(!this.showTickMarks){Y.showMark=false}}Y.setTick(ad,this.name);this._ticks.push(Y)}}}}if(this.tickInset){this.min=this.min-this.tickInset*O;this.max=this.max+this.tickInset*O}if(this._daTickInterval==null){this._daTickInterval=this.daTickInterval}X=null}})(jQuery);
WRFILE: jqplot.canvasTextRenderer.min.js

(function(a){a.jqplot.CanvasTextRenderer=function(b){this.fontStyle="normal";this.fontVariant="normal";this.fontWeight="normal";this.fontSize="10px";this.fontFamily="sans-serif";this.fontStretch=1;this.fillStyle="#666666";this.angle=0;this.textAlign="start";this.textBaseline="alphabetic";this.text;this.width;this.height;this.pt2px=1.28;a.extend(true,this,b);this.normalizedFontSize=this.normalizeFontSize(this.fontSize);this.setHeight()};a.jqplot.CanvasTextRenderer.prototype.init=function(b){a.extend(true,this,b);this.normalizedFontSize=this.normalizeFontSize(this.fontSize);this.setHeight()};a.jqplot.CanvasTextRenderer.prototype.normalizeFontSize=function(b){b=String(b);var c=parseFloat(b);if(b.indexOf("px")>-1){return c/this.pt2px}else{if(b.indexOf("pt")>-1){return c}else{if(b.indexOf("em")>-1){return c*12}else{if(b.indexOf("%")>-1){return c*12/100}else{return c/this.pt2px}}}}};a.jqplot.CanvasTextRenderer.prototype.fontWeight2Float=function(b){if(Number(b)){return b/400}else{switch(b){case"normal":return 1;break;case"bold":return 1.75;break;case"bolder":return 2.25;break;case"lighter":return 0.75;break;default:return 1;break}}};a.jqplot.CanvasTextRenderer.prototype.getText=function(){return this.text};a.jqplot.CanvasTextRenderer.prototype.setText=function(c,b){this.text=c;this.setWidth(b);return this};a.jqplot.CanvasTextRenderer.prototype.getWidth=function(b){return this.width};a.jqplot.CanvasTextRenderer.prototype.setWidth=function(c,b){if(!b){this.width=this.measure(c,this.text)}else{this.width=b}return this};a.jqplot.CanvasTextRenderer.prototype.getHeight=function(b){return this.height};a.jqplot.CanvasTextRenderer.prototype.setHeight=function(b){if(!b){this.height=this.normalizedFontSize*this.pt2px}else{this.height=b}return this};a.jqplot.CanvasTextRenderer.prototype.letter=function(b){return this.letters[b]};a.jqplot.CanvasTextRenderer.prototype.ascent=function(){return this.normalizedFontSize};a.jqplot.CanvasTextRenderer.prototype.descent=function(){return 7*this.normalizedFontSize/25};a.jqplot.CanvasTextRenderer.prototype.measure=function(d,g){var f=0;var b=g.length;for(var e=0;e<b;e++){var h=this.letter(g.charAt(e));if(h){f+=h.width*this.normalizedFontSize/25*this.fontStretch}}return f};a.jqplot.CanvasTextRenderer.prototype.draw=function(s,n){var r=0;var o=this.height*0.72;var p=0;var l=n.length;var k=this.normalizedFontSize/25;s.save();var h,f;if((-Math.PI/2<=this.angle&&this.angle<=0)||(Math.PI*3/2<=this.angle&&this.angle<=Math.PI*2)){h=0;f=-Math.sin(this.angle)*this.width}else{if((0<this.angle&&this.angle<=Math.PI/2)||(-Math.PI*2<=this.angle&&this.angle<=-Math.PI*3/2)){h=Math.sin(this.angle)*this.height;f=0}else{if((-Math.PI<this.angle&&this.angle<-Math.PI/2)||(Math.PI<=this.angle&&this.angle<=Math.PI*3/2)){h=-Math.cos(this.angle)*this.width;f=-Math.sin(this.angle)*this.width-Math.cos(this.angle)*this.height}else{if((-Math.PI*3/2<this.angle&&this.angle<Math.PI)||(Math.PI/2<this.angle&&this.angle<Math.PI)){h=Math.sin(this.angle)*this.height-Math.cos(this.angle)*this.width;f=-Math.cos(this.angle)*this.height}}}}s.strokeStyle=this.fillStyle;s.fillStyle=this.fillStyle;s.translate(h,f);s.rotate(this.angle);s.lineCap="round";var t=(this.normalizedFontSize>30)?2:2+(30-this.normalizedFontSize)/20;s.lineWidth=t*k*this.fontWeight2Float(this.fontWeight);for(var g=0;g<l;g++){var m=this.letter(n.charAt(g));if(!m){continue}s.beginPath();var e=1;var b=0;for(var d=0;d<m.points.length;d++){var q=m.points[d];if(q[0]==-1&&q[1]==-1){e=1;continue}if(e){s.moveTo(r+q[0]*k*this.fontStretch,o-q[1]*k);e=false}else{s.lineTo(r+q[0]*k*this.fontStretch,o-q[1]*k)}}s.stroke();r+=m.width*k*this.fontStretch}s.restore();return p};a.jqplot.CanvasTextRenderer.prototype.letters={" ":{width:16,points:[]},"!":{width:10,points:[[5,21],[5,7],[-1,-1],[5,2],[4,1],[5,0],[6,1],[5,2]]},'"':{width:16,points:[[4,21],[4,14],[-1,-1],[12,21],[12,14]]},"#":{width:21,points:[[11,25],[4,-7],[-1,-1],[17,25],[10,-7],[-1,-1],[4,12],[18,12],[-1,-1],[3,6],[17,6]]},"$":{width:20,points:[[8,25],[8,-4],[-1,-1],[12,25],[12,-4],[-1,-1],[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]]},"%":{width:24,points:[[21,21],[3,0],[-1,-1],[8,21],[10,19],[10,17],[9,15],[7,14],[5,14],[3,16],[3,18],[4,20],[6,21],[8,21],[10,20],[13,19],[16,19],[19,20],[21,21],[-1,-1],[17,7],[15,6],[14,4],[14,2],[16,0],[18,0],[20,1],[21,3],[21,5],[19,7],[17,7]]},"&":{width:26,points:[[23,12],[23,13],[22,14],[21,14],[20,13],[19,11],[17,6],[15,3],[13,1],[11,0],[7,0],[5,1],[4,2],[3,4],[3,6],[4,8],[5,9],[12,13],[13,14],[14,16],[14,18],[13,20],[11,21],[9,20],[8,18],[8,16],[9,13],[11,10],[16,3],[18,1],[20,0],[22,0],[23,1],[23,2]]},"'":{width:10,points:[[5,19],[4,20],[5,21],[6,20],[6,18],[5,16],[4,15]]},"(":{width:14,points:[[11,25],[9,23],[7,20],[5,16],[4,11],[4,7],[5,2],[7,-2],[9,-5],[11,-7]]},")":{width:14,points:[[3,25],[5,23],[7,20],[9,16],[10,11],[10,7],[9,2],[7,-2],[5,-5],[3,-7]]},"*":{width:16,points:[[8,21],[8,9],[-1,-1],[3,18],[13,12],[-1,-1],[13,18],[3,12]]},"+":{width:26,points:[[13,18],[13,0],[-1,-1],[4,9],[22,9]]},",":{width:10,points:[[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]]},"-":{width:18,points:[[6,9],[12,9]]},".":{width:10,points:[[5,2],[4,1],[5,0],[6,1],[5,2]]},"/":{width:22,points:[[20,25],[2,-7]]},"0":{width:20,points:[[9,21],[6,20],[4,17],[3,12],[3,9],[4,4],[6,1],[9,0],[11,0],[14,1],[16,4],[17,9],[17,12],[16,17],[14,20],[11,21],[9,21]]},"1":{width:20,points:[[6,17],[8,18],[11,21],[11,0]]},"2":{width:20,points:[[4,16],[4,17],[5,19],[6,20],[8,21],[12,21],[14,20],[15,19],[16,17],[16,15],[15,13],[13,10],[3,0],[17,0]]},"3":{width:20,points:[[5,21],[16,21],[10,13],[13,13],[15,12],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]]},"4":{width:20,points:[[13,21],[3,7],[18,7],[-1,-1],[13,21],[13,0]]},"5":{width:20,points:[[15,21],[5,21],[4,12],[5,13],[8,14],[11,14],[14,13],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]]},"6":{width:20,points:[[16,18],[15,20],[12,21],[10,21],[7,20],[5,17],[4,12],[4,7],[5,3],[7,1],[10,0],[11,0],[14,1],[16,3],[17,6],[17,7],[16,10],[14,12],[11,13],[10,13],[7,12],[5,10],[4,7]]},"7":{width:20,points:[[17,21],[7,0],[-1,-1],[3,21],[17,21]]},"8":{width:20,points:[[8,21],[5,20],[4,18],[4,16],[5,14],[7,13],[11,12],[14,11],[16,9],[17,7],[17,4],[16,2],[15,1],[12,0],[8,0],[5,1],[4,2],[3,4],[3,7],[4,9],[6,11],[9,12],[13,13],[15,14],[16,16],[16,18],[15,20],[12,21],[8,21]]},"9":{width:20,points:[[16,14],[15,11],[13,9],[10,8],[9,8],[6,9],[4,11],[3,14],[3,15],[4,18],[6,20],[9,21],[10,21],[13,20],[15,18],[16,14],[16,9],[15,4],[13,1],[10,0],[8,0],[5,1],[4,3]]},":":{width:10,points:[[5,14],[4,13],[5,12],[6,13],[5,14],[-1,-1],[5,2],[4,1],[5,0],[6,1],[5,2]]},";":{width:10,points:[[5,14],[4,13],[5,12],[6,13],[5,14],[-1,-1],[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]]},"<":{width:24,points:[[20,18],[4,9],[20,0]]},"=":{width:26,points:[[4,12],[22,12],[-1,-1],[4,6],[22,6]]},">":{width:24,points:[[4,18],[20,9],[4,0]]},"?":{width:18,points:[[3,16],[3,17],[4,19],[5,20],[7,21],[11,21],[13,20],[14,19],[15,17],[15,15],[14,13],[13,12],[9,10],[9,7],[-1,-1],[9,2],[8,1],[9,0],[10,1],[9,2]]},"@":{width:27,points:[[18,13],[17,15],[15,16],[12,16],[10,15],[9,14],[8,11],[8,8],[9,6],[11,5],[14,5],[16,6],[17,8],[-1,-1],[12,16],[10,14],[9,11],[9,8],[10,6],[11,5],[-1,-1],[18,16],[17,8],[17,6],[19,5],[21,5],[23,7],[24,10],[24,12],[23,15],[22,17],[20,19],[18,20],[15,21],[12,21],[9,20],[7,19],[5,17],[4,15],[3,12],[3,9],[4,6],[5,4],[7,2],[9,1],[12,0],[15,0],[18,1],[20,2],[21,3],[-1,-1],[19,16],[18,8],[18,6],[19,5]]},A:{width:18,points:[[9,21],[1,0],[-1,-1],[9,21],[17,0],[-1,-1],[4,7],[14,7]]},B:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[-1,-1],[4,11],[13,11],[16,10],[17,9],[18,7],[18,4],[17,2],[16,1],[13,0],[4,0]]},C:{width:21,points:[[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5]]},D:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[11,21],[14,20],[16,18],[17,16],[18,13],[18,8],[17,5],[16,3],[14,1],[11,0],[4,0]]},E:{width:19,points:[[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11],[-1,-1],[4,0],[17,0]]},F:{width:18,points:[[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11]]},G:{width:21,points:[[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[18,8],[-1,-1],[13,8],[18,8]]},H:{width:22,points:[[4,21],[4,0],[-1,-1],[18,21],[18,0],[-1,-1],[4,11],[18,11]]},I:{width:8,points:[[4,21],[4,0]]},J:{width:16,points:[[12,21],[12,5],[11,2],[10,1],[8,0],[6,0],[4,1],[3,2],[2,5],[2,7]]},K:{width:21,points:[[4,21],[4,0],[-1,-1],[18,21],[4,7],[-1,-1],[9,12],[18,0]]},L:{width:17,points:[[4,21],[4,0],[-1,-1],[4,0],[16,0]]},M:{width:24,points:[[4,21],[4,0],[-1,-1],[4,21],[12,0],[-1,-1],[20,21],[12,0],[-1,-1],[20,21],[20,0]]},N:{width:22,points:[[4,21],[4,0],[-1,-1],[4,21],[18,0],[-1,-1],[18,21],[18,0]]},O:{width:22,points:[[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21]]},P:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,14],[17,12],[16,11],[13,10],[4,10]]},Q:{width:22,points:[[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21],[-1,-1],[12,4],[18,-2]]},R:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[4,11],[-1,-1],[11,11],[18,0]]},S:{width:20,points:[[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]]},T:{width:16,points:[[8,21],[8,0],[-1,-1],[1,21],[15,21]]},U:{width:22,points:[[4,21],[4,6],[5,3],[7,1],[10,0],[12,0],[15,1],[17,3],[18,6],[18,21]]},V:{width:18,points:[[1,21],[9,0],[-1,-1],[17,21],[9,0]]},W:{width:24,points:[[2,21],[7,0],[-1,-1],[12,21],[7,0],[-1,-1],[12,21],[17,0],[-1,-1],[22,21],[17,0]]},X:{width:20,points:[[3,21],[17,0],[-1,-1],[17,21],[3,0]]},Y:{width:18,points:[[1,21],[9,11],[9,0],[-1,-1],[17,21],[9,11]]},Z:{width:20,points:[[17,21],[3,0],[-1,-1],[3,21],[17,21],[-1,-1],[3,0],[17,0]]},"[":{width:14,points:[[4,25],[4,-7],[-1,-1],[5,25],[5,-7],[-1,-1],[4,25],[11,25],[-1,-1],[4,-7],[11,-7]]},"\\":{width:14,points:[[0,21],[14,-3]]},"]":{width:14,points:[[9,25],[9,-7],[-1,-1],[10,25],[10,-7],[-1,-1],[3,25],[10,25],[-1,-1],[3,-7],[10,-7]]},"^":{width:16,points:[[6,15],[8,18],[10,15],[-1,-1],[3,12],[8,17],[13,12],[-1,-1],[8,17],[8,0]]},_:{width:16,points:[[0,-2],[16,-2]]},"`":{width:10,points:[[6,21],[5,20],[4,18],[4,16],[5,15],[6,16],[5,17]]},a:{width:19,points:[[15,14],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},b:{width:19,points:[[4,21],[4,0],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]]},c:{width:18,points:[[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},d:{width:19,points:[[15,21],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},e:{width:18,points:[[3,8],[15,8],[15,10],[14,12],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},f:{width:12,points:[[10,21],[8,21],[6,20],[5,17],[5,0],[-1,-1],[2,14],[9,14]]},g:{width:19,points:[[15,14],[15,-2],[14,-5],[13,-6],[11,-7],[8,-7],[6,-6],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},h:{width:19,points:[[4,21],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]]},i:{width:8,points:[[3,21],[4,20],[5,21],[4,22],[3,21],[-1,-1],[4,14],[4,0]]},j:{width:10,points:[[5,21],[6,20],[7,21],[6,22],[5,21],[-1,-1],[6,14],[6,-3],[5,-6],[3,-7],[1,-7]]},k:{width:17,points:[[4,21],[4,0],[-1,-1],[14,14],[4,4],[-1,-1],[8,8],[15,0]]},l:{width:8,points:[[4,21],[4,0]]},m:{width:30,points:[[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0],[-1,-1],[15,10],[18,13],[20,14],[23,14],[25,13],[26,10],[26,0]]},n:{width:19,points:[[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]]},o:{width:19,points:[[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3],[16,6],[16,8],[15,11],[13,13],[11,14],[8,14]]},p:{width:19,points:[[4,14],[4,-7],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]]},q:{width:19,points:[[15,14],[15,-7],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},r:{width:13,points:[[4,14],[4,0],[-1,-1],[4,8],[5,11],[7,13],[9,14],[12,14]]},s:{width:17,points:[[14,11],[13,13],[10,14],[7,14],[4,13],[3,11],[4,9],[6,8],[11,7],[13,6],[14,4],[14,3],[13,1],[10,0],[7,0],[4,1],[3,3]]},t:{width:12,points:[[5,21],[5,4],[6,1],[8,0],[10,0],[-1,-1],[2,14],[9,14]]},u:{width:19,points:[[4,14],[4,4],[5,1],[7,0],[10,0],[12,1],[15,4],[-1,-1],[15,14],[15,0]]},v:{width:16,points:[[2,14],[8,0],[-1,-1],[14,14],[8,0]]},w:{width:22,points:[[3,14],[7,0],[-1,-1],[11,14],[7,0],[-1,-1],[11,14],[15,0],[-1,-1],[19,14],[15,0]]},x:{width:17,points:[[3,14],[14,0],[-1,-1],[14,14],[3,0]]},y:{width:16,points:[[2,14],[8,0],[-1,-1],[14,14],[8,0],[6,-4],[4,-6],[2,-7],[1,-7]]},z:{width:17,points:[[14,14],[3,0],[-1,-1],[3,14],[14,14],[-1,-1],[3,0],[14,0]]},"{":{width:14,points:[[9,25],[7,24],[6,23],[5,21],[5,19],[6,17],[7,16],[8,14],[8,12],[6,10],[-1,-1],[7,24],[6,22],[6,20],[7,18],[8,17],[9,15],[9,13],[8,11],[4,9],[8,7],[9,5],[9,3],[8,1],[7,0],[6,-2],[6,-4],[7,-6],[-1,-1],[6,8],[8,6],[8,4],[7,2],[6,1],[5,-1],[5,-3],[6,-5],[7,-6],[9,-7]]},"|":{width:8,points:[[4,25],[4,-7]]},"}":{width:14,points:[[5,25],[7,24],[8,23],[9,21],[9,19],[8,17],[7,16],[6,14],[6,12],[8,10],[-1,-1],[7,24],[8,22],[8,20],[7,18],[6,17],[5,15],[5,13],[6,11],[10,9],[6,7],[5,5],[5,3],[6,1],[7,0],[8,-2],[8,-4],[7,-6],[-1,-1],[8,8],[6,6],[6,4],[7,2],[8,1],[9,-1],[9,-3],[8,-5],[7,-6],[5,-7]]},"~":{width:24,points:[[3,6],[3,8],[4,11],[6,12],[8,12],[10,11],[14,8],[16,7],[18,7],[20,8],[21,10],[-1,-1],[3,8],[4,10],[6,11],[8,11],[10,10],[14,7],[16,6],[18,6],[20,7],[21,10],[21,12]]}};a.jqplot.CanvasFontRenderer=function(b){b=b||{};if(!b.pt2px){b.pt2px=1.5}a.jqplot.CanvasTextRenderer.call(this,b)};a.jqplot.CanvasFontRenderer.prototype=new a.jqplot.CanvasTextRenderer({});a.jqplot.CanvasFontRenderer.prototype.constructor=a.jqplot.CanvasFontRenderer;a.jqplot.CanvasFontRenderer.prototype.measure=function(c,e){var d=this.fontSize+" "+this.fontFamily;c.save();c.font=d;var b=c.measureText(e).width;c.restore();return b};a.jqplot.CanvasFontRenderer.prototype.draw=function(e,g){var c=0;var h=this.height*0.72;e.save();var d,b;if((-Math.PI/2<=this.angle&&this.angle<=0)||(Math.PI*3/2<=this.angle&&this.angle<=Math.PI*2)){d=0;b=-Math.sin(this.angle)*this.width}else{if((0<this.angle&&this.angle<=Math.PI/2)||(-Math.PI*2<=this.angle&&this.angle<=-Math.PI*3/2)){d=Math.sin(this.angle)*this.height;b=0}else{if((-Math.PI<this.angle&&this.angle<-Math.PI/2)||(Math.PI<=this.angle&&this.angle<=Math.PI*3/2)){d=-Math.cos(this.angle)*this.width;b=-Math.sin(this.angle)*this.width-Math.cos(this.angle)*this.height}else{if((-Math.PI*3/2<this.angle&&this.angle<Math.PI)||(Math.PI/2<this.angle&&this.angle<Math.PI)){d=Math.sin(this.angle)*this.height-Math.cos(this.angle)*this.width;b=-Math.cos(this.angle)*this.height}}}}e.strokeStyle=this.fillStyle;e.fillStyle=this.fillStyle;var f=this.fontSize+" "+this.fontFamily;e.font=f;e.translate(d,b);e.rotate(this.angle);e.fillText(g,c,h);e.restore()}})(jQuery);
WRFILE: jqplot.categoryAxisRenderer.min.js

(function(a){a.jqplot.CategoryAxisRenderer=function(b){a.jqplot.LinearAxisRenderer.call(this);this.sortMergedLabels=false};a.jqplot.CategoryAxisRenderer.prototype=new a.jqplot.LinearAxisRenderer();a.jqplot.CategoryAxisRenderer.prototype.constructor=a.jqplot.CategoryAxisRenderer;a.jqplot.CategoryAxisRenderer.prototype.init=function(e){this.groups=1;this.groupLabels=[];this._groupLabels=[];this._grouped=false;this._barsPerGroup=null;this.reverse=false;a.extend(true,this,{tickOptions:{formatString:"%d"}},e);var b=this._dataBounds;for(var f=0;f<this._series.length;f++){var g=this._series[f];if(g.groups){this.groups=g.groups}var h=g.data;for(var c=0;c<h.length;c++){if(this.name=="xaxis"||this.name=="x2axis"){if(h[c][0]<b.min||b.min==null){b.min=h[c][0]}if(h[c][0]>b.max||b.max==null){b.max=h[c][0]}}else{if(h[c][1]<b.min||b.min==null){b.min=h[c][1]}if(h[c][1]>b.max||b.max==null){b.max=h[c][1]}}}}if(this.groupLabels.length){this.groups=this.groupLabels.length}};a.jqplot.CategoryAxisRenderer.prototype.createTicks=function(){var D=this._ticks;var z=this.ticks;var F=this.name;var C=this._dataBounds;var v,A;var q,w;var d,c;var b,x;if(z.length){if(this.groups>1&&!this._grouped){var r=z.length;var p=parseInt(r/this.groups,10);var e=0;for(var x=p;x<r;x+=p){z.splice(x+e,0," ");e++}this._grouped=true}this.min=0.5;this.max=z.length+0.5;var m=this.max-this.min;this.numberTicks=2*z.length+1;for(x=0;x<z.length;x++){b=this.min+2*x*m/(this.numberTicks-1);var h=new this.tickRenderer(this.tickOptions);h.showLabel=false;h.setTick(b,this.name);this._ticks.push(h);var h=new this.tickRenderer(this.tickOptions);h.label=z[x];h.showMark=false;h.showGridline=false;h.setTick(b+0.5,this.name);this._ticks.push(h)}var h=new this.tickRenderer(this.tickOptions);h.showLabel=false;h.setTick(b+1,this.name);this._ticks.push(h)}else{if(F=="xaxis"||F=="x2axis"){v=this._plotDimensions.width}else{v=this._plotDimensions.height}if(this.min!=null&&this.max!=null&&this.numberTicks!=null){this.tickInterval=null}if(this.min!=null&&this.max!=null&&this.tickInterval!=null){if(parseInt((this.max-this.min)/this.tickInterval,10)!=(this.max-this.min)/this.tickInterval){this.tickInterval=null}}var y=[];var B=0;var q=0.5;var w,E;var f=false;for(var x=0;x<this._series.length;x++){var k=this._series[x];for(var u=0;u<k.data.length;u++){if(this.name=="xaxis"||this.name=="x2axis"){E=k.data[u][0]}else{E=k.data[u][1]}if(a.inArray(E,y)==-1){f=true;B+=1;y.push(E)}}}if(f&&this.sortMergedLabels){if(typeof y[0]=="string"){y.sort()}else{y.sort(function(j,i){return j-i})}}this.ticks=y;for(var x=0;x<this._series.length;x++){var k=this._series[x];for(var u=0;u<k.data.length;u++){if(this.name=="xaxis"||this.name=="x2axis"){E=k.data[u][0]}else{E=k.data[u][1]}var n=a.inArray(E,y)+1;if(this.name=="xaxis"||this.name=="x2axis"){k.data[u][0]=n}else{k.data[u][1]=n}}}if(this.groups>1&&!this._grouped){var r=y.length;var p=parseInt(r/this.groups,10);var e=0;for(var x=p;x<r;x+=p+1){y[x]=" "}this._grouped=true}w=B+0.5;if(this.numberTicks==null){this.numberTicks=2*B+1}var m=w-q;this.min=q;this.max=w;var o=0;var g=parseInt(3+v/10,10);var p=parseInt(B/g,10);if(this.tickInterval==null){this.tickInterval=m/(this.numberTicks-1)}for(var x=0;x<this.numberTicks;x++){b=this.min+x*this.tickInterval;var h=new this.tickRenderer(this.tickOptions);if(x/2==parseInt(x/2,10)){h.showLabel=false;h.showMark=true}else{if(p>0&&o<p){h.showLabel=false;o+=1}else{h.showLabel=true;o=0}h.label=h.formatter(h.formatString,y[(x-1)/2]);h.showMark=false;h.showGridline=false}h.setTick(b,this.name);this._ticks.push(h)}}};a.jqplot.CategoryAxisRenderer.prototype.draw=function(b,j){if(this.show){this.renderer.createTicks.call(this);var h=0;var c;if(this._elem){this._elem.emptyForce()}this._elem=this._elem||a('<div class="jqplot-axis jqplot-'+this.name+'" style="position:absolute;"></div>');if(this.name=="xaxis"||this.name=="x2axis"){this._elem.width(this._plotDimensions.width)}else{this._elem.height(this._plotDimensions.height)}this.labelOptions.axis=this.name;this._label=new this.labelRenderer(this.labelOptions);if(this._label.show){var g=this._label.draw(b,j);g.appendTo(this._elem)}var f=this._ticks;for(var e=0;e<f.length;e++){var d=f[e];if(d.showLabel&&(!d.isMinorTick||this.showMinorTicks)){var g=d.draw(b,j);g.appendTo(this._elem)}}this._groupLabels=[];for(var e=0;e<this.groupLabels.length;e++){var g=a('<div style="position:absolute;" class="jqplot-'+this.name+'-groupLabel"></div>');g.html(this.groupLabels[e]);this._groupLabels.push(g);g.appendTo(this._elem)}}return this._elem};a.jqplot.CategoryAxisRenderer.prototype.set=function(){var e=0;var m;var k=0;var f=0;var d=(this._label==null)?false:this._label.show;if(this.show){var n=this._ticks;for(var c=0;c<n.length;c++){var g=n[c];if(g.showLabel&&(!g.isMinorTick||this.showMinorTicks)){if(this.name=="xaxis"||this.name=="x2axis"){m=g._elem.outerHeight(true)}else{m=g._elem.outerWidth(true)}if(m>e){e=m}}}var j=0;for(var c=0;c<this._groupLabels.length;c++){var b=this._groupLabels[c];if(this.name=="xaxis"||this.name=="x2axis"){m=b.outerHeight(true)}else{m=b.outerWidth(true)}if(m>j){j=m}}if(d){k=this._label._elem.outerWidth(true);f=this._label._elem.outerHeight(true)}if(this.name=="xaxis"){e+=j+f;this._elem.css({height:e+"px",left:"0px",bottom:"0px"})}else{if(this.name=="x2axis"){e+=j+f;this._elem.css({height:e+"px",left:"0px",top:"0px"})}else{if(this.name=="yaxis"){e+=j+k;this._elem.css({width:e+"px",left:"0px",top:"0px"});if(d&&this._label.constructor==a.jqplot.AxisLabelRenderer){this._label._elem.css("width",k+"px")}}else{e+=j+k;this._elem.css({width:e+"px",right:"0px",top:"0px"});if(d&&this._label.constructor==a.jqplot.AxisLabelRenderer){this._label._elem.css("width",k+"px")}}}}}};a.jqplot.CategoryAxisRenderer.prototype.pack=function(e,c){var C=this._ticks;var v=this.max;var s=this.min;var n=c.max;var l=c.min;var q=(this._label==null)?false:this._label.show;var x;for(var r in e){this._elem.css(r,e[r])}this._offsets=c;var g=n-l;var k=v-s;if(!this.reverse){this.u2p=function(h){return(h-s)*g/k+l};this.p2u=function(h){return(h-l)*k/g+s};if(this.name=="xaxis"||this.name=="x2axis"){this.series_u2p=function(h){return(h-s)*g/k};this.series_p2u=function(h){return h*k/g+s}}else{this.series_u2p=function(h){return(h-v)*g/k};this.series_p2u=function(h){return h*k/g+v}}}else{this.u2p=function(h){return l+(v-h)*g/k};this.p2u=function(h){return s+(h-l)*k/g};if(this.name=="xaxis"||this.name=="x2axis"){this.series_u2p=function(h){return(v-h)*g/k};this.series_p2u=function(h){return h*k/g+v}}else{this.series_u2p=function(h){return(s-h)*g/k};this.series_p2u=function(h){return h*k/g+s}}}if(this.show){if(this.name=="xaxis"||this.name=="x2axis"){for(x=0;x<C.length;x++){var o=C[x];if(o.show&&o.showLabel){var b;if(o.constructor==a.jqplot.CanvasAxisTickRenderer&&o.angle){var A=(this.name=="xaxis")?1:-1;switch(o.labelPosition){case"auto":if(A*o.angle<0){b=-o.getWidth()+o._textRenderer.height*Math.sin(-o._textRenderer.angle)/2}else{b=-o._textRenderer.height*Math.sin(o._textRenderer.angle)/2}break;case"end":b=-o.getWidth()+o._textRenderer.height*Math.sin(-o._textRenderer.angle)/2;break;case"start":b=-o._textRenderer.height*Math.sin(o._textRenderer.angle)/2;break;case"middle":b=-o.getWidth()/2+o._textRenderer.height*Math.sin(-o._textRenderer.angle)/2;break;default:b=-o.getWidth()/2+o._textRenderer.height*Math.sin(-o._textRenderer.angle)/2;break}}else{b=-o.getWidth()/2}var D=this.u2p(o.value)+b+"px";o._elem.css("left",D);o.pack()}}var z=["bottom",0];if(q){var m=this._label._elem.outerWidth(true);this._label._elem.css("left",l+g/2-m/2+"px");if(this.name=="xaxis"){this._label._elem.css("bottom","0px");z=["bottom",this._label._elem.outerHeight(true)]}else{this._label._elem.css("top","0px");z=["top",this._label._elem.outerHeight(true)]}this._label.pack()}var d=parseInt(this._ticks.length/this.groups,10)+1;for(x=0;x<this._groupLabels.length;x++){var B=0;var f=0;for(var u=x*d;u<(x+1)*d;u++){if(u>=this._ticks.length-1){continue}if(this._ticks[u]._elem&&this._ticks[u].label!=" "){var o=this._ticks[u]._elem;var r=o.position();B+=r.left+o.outerWidth(true)/2;f++}}B=B/f;this._groupLabels[x].css({left:(B-this._groupLabels[x].outerWidth(true)/2)});this._groupLabels[x].css(z[0],z[1])}}else{for(x=0;x<C.length;x++){var o=C[x];if(o.show&&o.showLabel){var b;if(o.constructor==a.jqplot.CanvasAxisTickRenderer&&o.angle){var A=(this.name=="yaxis")?1:-1;switch(o.labelPosition){case"auto":case"end":if(A*o.angle<0){b=-o._textRenderer.height*Math.cos(-o._textRenderer.angle)/2}else{b=-o.getHeight()+o._textRenderer.height*Math.cos(o._textRenderer.angle)/2}break;case"start":if(o.angle>0){b=-o._textRenderer.height*Math.cos(-o._textRenderer.angle)/2}else{b=-o.getHeight()+o._textRenderer.height*Math.cos(o._textRenderer.angle)/2}break;case"middle":b=-o.getHeight()/2;break;default:b=-o.getHeight()/2;break}}else{b=-o.getHeight()/2}var D=this.u2p(o.value)+b+"px";o._elem.css("top",D);o.pack()}}var z=["left",0];if(q){var y=this._label._elem.outerHeight(true);this._label._elem.css("top",n-g/2-y/2+"px");if(this.name=="yaxis"){this._label._elem.css("left","0px");z=["left",this._label._elem.outerWidth(true)]}else{this._label._elem.css("right","0px");z=["right",this._label._elem.outerWidth(true)]}this._label.pack()}var d=parseInt(this._ticks.length/this.groups,10)+1;for(x=0;x<this._groupLabels.length;x++){var B=0;var f=0;for(var u=x*d;u<(x+1)*d;u++){if(u>=this._ticks.length-1){continue}if(this._ticks[u]._elem&&this._ticks[u].label!=" "){var o=this._ticks[u]._elem;var r=o.position();B+=r.top+o.outerHeight()/2;f++}}B=B/f;this._groupLabels[x].css({top:B-this._groupLabels[x].outerHeight()/2});this._groupLabels[x].css(z[0],z[1])}}}}})(jQuery);
WRFILE: jqplot.canvasAxisTickRenderer.min.js

(function(a){a.jqplot.CanvasAxisTickRenderer=function(b){this.mark="outside";this.showMark=true;this.showGridline=true;this.isMinorTick=false;this.angle=0;this.markSize=4;this.show=true;this.showLabel=true;this.labelPosition="auto";this.label="";this.value=null;this._styles={};this.formatter=a.jqplot.DefaultTickFormatter;this.formatString="";this.prefix="";this.fontFamily='"Trebuchet MS", Arial, Helvetica, sans-serif';this.fontSize="10pt";this.fontWeight="normal";this.fontStretch=1;this.textColor="#666666";this.enableFontSupport=true;this.pt2px=null;this._elem;this._ctx;this._plotWidth;this._plotHeight;this._plotDimensions={height:null,width:null};a.extend(true,this,b);var c={fontSize:this.fontSize,fontWeight:this.fontWeight,fontStretch:this.fontStretch,fillStyle:this.textColor,angle:this.getAngleRad(),fontFamily:this.fontFamily};if(this.pt2px){c.pt2px=this.pt2px}if(this.enableFontSupport){if(a.jqplot.support_canvas_text()){this._textRenderer=new a.jqplot.CanvasFontRenderer(c)}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(c)}}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(c)}};a.jqplot.CanvasAxisTickRenderer.prototype.init=function(b){a.extend(true,this,b);this._textRenderer.init({fontSize:this.fontSize,fontWeight:this.fontWeight,fontStretch:this.fontStretch,fillStyle:this.textColor,angle:this.getAngleRad(),fontFamily:this.fontFamily})};a.jqplot.CanvasAxisTickRenderer.prototype.getWidth=function(d){if(this._elem){return this._elem.outerWidth(true)}else{var f=this._textRenderer;var c=f.getWidth(d);var e=f.getHeight(d);var b=Math.abs(Math.sin(f.angle)*e)+Math.abs(Math.cos(f.angle)*c);return b}};a.jqplot.CanvasAxisTickRenderer.prototype.getHeight=function(d){if(this._elem){return this._elem.outerHeight(true)}else{var f=this._textRenderer;var c=f.getWidth(d);var e=f.getHeight(d);var b=Math.abs(Math.cos(f.angle)*e)+Math.abs(Math.sin(f.angle)*c);return b}};a.jqplot.CanvasAxisTickRenderer.prototype.getTop=function(b){if(this._elem){return this._elem.position().top}else{return null}};a.jqplot.CanvasAxisTickRenderer.prototype.getAngleRad=function(){var b=this.angle*Math.PI/180;return b};a.jqplot.CanvasAxisTickRenderer.prototype.setTick=function(b,d,c){this.value=b;if(c){this.isMinorTick=true}return this};a.jqplot.CanvasAxisTickRenderer.prototype.draw=function(c,f){if(!this.label){this.label=this.prefix+this.formatter(this.formatString,this.value)}if(this._elem){if(a.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==undefined){window.G_vmlCanvasManager.uninitElement(this._elem.get(0))}this._elem.emptyForce();this._elem=null}var e=f.canvasManager.getCanvas();this._textRenderer.setText(this.label,c);var b=this.getWidth(c);var d=this.getHeight(c);e.width=b;e.height=d;e.style.width=b;e.style.height=d;e.style.textAlign="left";e.style.position="absolute";e=f.canvasManager.initCanvas(e);this._elem=a(e);this._elem.css(this._styles);this._elem.addClass("jqplot-"+this.axis+"-tick");e=null;return this._elem};a.jqplot.CanvasAxisTickRenderer.prototype.pack=function(){this._textRenderer.draw(this._elem.get(0).getContext("2d"),this.label)}})(jQuery);
WRFILE: jqplot.canvasAxisLabelRenderer.min.js

(function(a){a.jqplot.CanvasAxisLabelRenderer=function(b){this.angle=0;this.axis;this.show=true;this.showLabel=true;this.label="";this.fontFamily='"Trebuchet MS", Arial, Helvetica, sans-serif';this.fontSize="11pt";this.fontWeight="normal";this.fontStretch=1;this.textColor="#666666";this.enableFontSupport=true;this.pt2px=null;this._elem;this._ctx;this._plotWidth;this._plotHeight;this._plotDimensions={height:null,width:null};a.extend(true,this,b);if(b.angle==null&&this.axis!="xaxis"&&this.axis!="x2axis"){this.angle=-90}var c={fontSize:this.fontSize,fontWeight:this.fontWeight,fontStretch:this.fontStretch,fillStyle:this.textColor,angle:this.getAngleRad(),fontFamily:this.fontFamily};if(this.pt2px){c.pt2px=this.pt2px}if(this.enableFontSupport){if(a.jqplot.support_canvas_text()){this._textRenderer=new a.jqplot.CanvasFontRenderer(c)}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(c)}}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(c)}};a.jqplot.CanvasAxisLabelRenderer.prototype.init=function(b){a.extend(true,this,b);this._textRenderer.init({fontSize:this.fontSize,fontWeight:this.fontWeight,fontStretch:this.fontStretch,fillStyle:this.textColor,angle:this.getAngleRad(),fontFamily:this.fontFamily})};a.jqplot.CanvasAxisLabelRenderer.prototype.getWidth=function(d){if(this._elem){return this._elem.outerWidth(true)}else{var f=this._textRenderer;var c=f.getWidth(d);var e=f.getHeight(d);var b=Math.abs(Math.sin(f.angle)*e)+Math.abs(Math.cos(f.angle)*c);return b}};a.jqplot.CanvasAxisLabelRenderer.prototype.getHeight=function(d){if(this._elem){return this._elem.outerHeight(true)}else{var f=this._textRenderer;var c=f.getWidth(d);var e=f.getHeight(d);var b=Math.abs(Math.cos(f.angle)*e)+Math.abs(Math.sin(f.angle)*c);return b}};a.jqplot.CanvasAxisLabelRenderer.prototype.getAngleRad=function(){var b=this.angle*Math.PI/180;return b};a.jqplot.CanvasAxisLabelRenderer.prototype.draw=function(c,f){if(this._elem){if(a.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==undefined){window.G_vmlCanvasManager.uninitElement(this._elem.get(0))}this._elem.emptyForce();this._elem=null}var e=f.canvasManager.getCanvas();this._textRenderer.setText(this.label,c);var b=this.getWidth(c);var d=this.getHeight(c);e.width=b;e.height=d;e.style.width=b;e.style.height=d;e=f.canvasManager.initCanvas(e);this._elem=a(e);this._elem.css({position:"absolute"});this._elem.addClass("jqplot-"+this.axis+"-label");e=null;return this._elem};a.jqplot.CanvasAxisLabelRenderer.prototype.pack=function(){this._textRenderer.draw(this._elem.get(0).getContext("2d"),this.label)}})(jQuery);
WRFILE: jqplot.highlighter.min.js

(function(d){d.jqplot.eventListenerHooks.push(["jqplotMouseMove",f]);d.jqplot.Highlighter=function(h){this.show=d.jqplot.config.enablePlugins;this.markerRenderer=new d.jqplot.MarkerRenderer({shadow:false});this.showMarker=true;this.lineWidthAdjust=2.5;this.sizeAdjust=5;this.showTooltip=true;this.tooltipLocation="nw";this.fadeTooltip=true;this.tooltipFadeSpeed="fast";this.tooltipOffset=2;this.tooltipAxes="both";this.tooltipSeparator=", ";this.tooltipContentEditor=null;this.useAxesFormatters=true;this.tooltipFormatString="%.5P";this.formatString=null;this.yvalues=1;this.bringSeriesToFront=false;this._tooltipElem;this.isHighlighting=false;this.currentNeighbor=null;d.extend(true,this,h)};var b=["nw","n","ne","e","se","s","sw","w"];var e={nw:0,n:1,ne:2,e:3,se:4,s:5,sw:6,w:7};var c=["se","s","sw","w","nw","n","ne","e"];d.jqplot.Highlighter.init=function(k,j,i){var h=i||{};this.plugins.highlighter=new d.jqplot.Highlighter(h.highlighter)};d.jqplot.Highlighter.parseOptions=function(i,h){this.showHighlight=true};d.jqplot.Highlighter.postPlotDraw=function(){if(this.plugins.highlighter&&this.plugins.highlighter.highlightCanvas){this.plugins.highlighter.highlightCanvas.resetCanvas();this.plugins.highlighter.highlightCanvas=null}if(this.plugins.highlighter&&this.plugins.highlighter._tooltipElem){this.plugins.highlighter._tooltipElem.emptyForce();this.plugins.highlighter._tooltipElem=null}this.plugins.highlighter.highlightCanvas=new d.jqplot.GenericCanvas();this.eventCanvas._elem.before(this.plugins.highlighter.highlightCanvas.createElement(this._gridPadding,"jqplot-highlight-canvas",this._plotDimensions,this));this.plugins.highlighter.highlightCanvas.setContext();var h=document.createElement("div");this.plugins.highlighter._tooltipElem=d(h);h=null;this.plugins.highlighter._tooltipElem.addClass("jqplot-highlighter-tooltip");this.plugins.highlighter._tooltipElem.css({position:"absolute",display:"none"});this.eventCanvas._elem.before(this.plugins.highlighter._tooltipElem)};d.jqplot.preInitHooks.push(d.jqplot.Highlighter.init);d.jqplot.preParseSeriesOptionsHooks.push(d.jqplot.Highlighter.parseOptions);d.jqplot.postDrawHooks.push(d.jqplot.Highlighter.postPlotDraw);function a(m,o){var j=m.plugins.highlighter;var p=m.series[o.seriesIndex];var h=p.markerRenderer;var i=j.markerRenderer;i.style=h.style;i.lineWidth=h.lineWidth+j.lineWidthAdjust;i.size=h.size+j.sizeAdjust;var l=d.jqplot.getColorComponents(h.color);var n=[l[0],l[1],l[2]];var k=(l[3]>=0.6)?l[3]*0.6:l[3]*(2-l[3]);i.color="rgba("+n[0]+","+n[1]+","+n[2]+","+k+")";i.init();i.draw(p.gridData[o.pointIndex][0],p.gridData[o.pointIndex][1],j.highlightCanvas._ctx)}function g(A,q,m){var k=A.plugins.highlighter;var D=k._tooltipElem;var r=q.highlighter||{};var t=d.extend(true,{},k,r);if(t.useAxesFormatters){var w=q._xaxis._ticks[0].formatter;var h=q._yaxis._ticks[0].formatter;var E=q._xaxis._ticks[0].formatString;var s=q._yaxis._ticks[0].formatString;var z;var u=w(E,m.data[0]);var l=[];for(var B=1;B<t.yvalues+1;B++){l.push(h(s,m.data[B]))}if(typeof t.formatString==="string"){switch(t.tooltipAxes){case"both":case"xy":l.unshift(u);l.unshift(t.formatString);z=d.jqplot.sprintf.apply(d.jqplot.sprintf,l);break;case"yx":l.push(u);l.unshift(t.formatString);z=d.jqplot.sprintf.apply(d.jqplot.sprintf,l);break;case"x":z=d.jqplot.sprintf.apply(d.jqplot.sprintf,[t.formatString,u]);break;case"y":l.unshift(t.formatString);z=d.jqplot.sprintf.apply(d.jqplot.sprintf,l);break;default:l.unshift(u);l.unshift(t.formatString);z=d.jqplot.sprintf.apply(d.jqplot.sprintf,l);break}}else{switch(t.tooltipAxes){case"both":case"xy":z=u;for(var B=0;B<l.length;B++){z+=t.tooltipSeparator+l[B]}break;case"yx":z="";for(var B=0;B<l.length;B++){z+=l[B]+t.tooltipSeparator}z+=u;break;case"x":z=u;break;case"y":z=l.join(t.tooltipSeparator);break;default:z=u;for(var B=0;B<l.length;B++){z+=t.tooltipSeparator+l[B]}break}}}else{var z;if(typeof t.formatString==="string"){z=d.jqplot.sprintf.apply(d.jqplot.sprintf,[t.formatString].concat(m.data))}else{if(t.tooltipAxes=="both"||t.tooltipAxes=="xy"){z=d.jqplot.sprintf(t.tooltipFormatString,m.data[0])+t.tooltipSeparator+d.jqplot.sprintf(t.tooltipFormatString,m.data[1])}else{if(t.tooltipAxes=="yx"){z=d.jqplot.sprintf(t.tooltipFormatString,m.data[1])+t.tooltipSeparator+d.jqplot.sprintf(t.tooltipFormatString,m.data[0])}else{if(t.tooltipAxes=="x"){z=d.jqplot.sprintf(t.tooltipFormatString,m.data[0])}else{if(t.tooltipAxes=="y"){z=d.jqplot.sprintf(t.tooltipFormatString,m.data[1])}}}}}}if(d.isFunction(t.tooltipContentEditor)){z=t.tooltipContentEditor(z,m.seriesIndex,m.pointIndex,A)}D.html(z);var C={x:m.gridData[0],y:m.gridData[1]};var v=0;var j=0.707;if(q.markerRenderer.show==true){v=(q.markerRenderer.size+t.sizeAdjust)/2}var o=b;if(q.fillToZero&&q.fill&&m.data[1]<0){o=c}switch(o[e[t.tooltipLocation]]){case"nw":var p=C.x+A._gridPadding.left-D.outerWidth(true)-t.tooltipOffset-j*v;var n=C.y+A._gridPadding.top-t.tooltipOffset-D.outerHeight(true)-j*v;break;case"n":var p=C.x+A._gridPadding.left-D.outerWidth(true)/2;var n=C.y+A._gridPadding.top-t.tooltipOffset-D.outerHeight(true)-v;break;case"ne":var p=C.x+A._gridPadding.left+t.tooltipOffset+j*v;var n=C.y+A._gridPadding.top-t.tooltipOffset-D.outerHeight(true)-j*v;break;case"e":var p=C.x+A._gridPadding.left+t.tooltipOffset+v;var n=C.y+A._gridPadding.top-D.outerHeight(true)/2;break;case"se":var p=C.x+A._gridPadding.left+t.tooltipOffset+j*v;var n=C.y+A._gridPadding.top+t.tooltipOffset+j*v;break;case"s":var p=C.x+A._gridPadding.left-D.outerWidth(true)/2;var n=C.y+A._gridPadding.top+t.tooltipOffset+v;break;case"sw":var p=C.x+A._gridPadding.left-D.outerWidth(true)-t.tooltipOffset-j*v;var n=C.y+A._gridPadding.top+t.tooltipOffset+j*v;break;case"w":var p=C.x+A._gridPadding.left-D.outerWidth(true)-t.tooltipOffset-v;var n=C.y+A._gridPadding.top-D.outerHeight(true)/2;break;default:var p=C.x+A._gridPadding.left-D.outerWidth(true)-t.tooltipOffset-j*v;var n=C.y+A._gridPadding.top-t.tooltipOffset-D.outerHeight(true)-j*v;break}D.css("left",p);D.css("top",n);if(t.fadeTooltip){D.stop(true,true).fadeIn(t.tooltipFadeSpeed)}else{D.show()}D=null}function f(n,j,i,p,l){var h=l.plugins.highlighter;var m=l.plugins.cursor;if(h.show){if(p==null&&h.isHighlighting){var o=jQuery.Event("jqplotHighlighterUnhighlight");l.target.trigger(o);var q=h.highlightCanvas._ctx;q.clearRect(0,0,q.canvas.width,q.canvas.height);if(h.fadeTooltip){h._tooltipElem.fadeOut(h.tooltipFadeSpeed)}else{h._tooltipElem.hide()}if(h.bringSeriesToFront){l.restorePreviousSeriesOrder()}h.isHighlighting=false;h.currentNeighbor=null;q=null}else{if(p!=null&&l.series[p.seriesIndex].showHighlight&&!h.isHighlighting){var o=jQuery.Event("jqplotHighlighterHighlight");o.which=n.which;o.pageX=n.pageX;o.pageY=n.pageY;var k=[p.seriesIndex,p.pointIndex,p.data,l];l.target.trigger(o,k);h.isHighlighting=true;h.currentNeighbor=p;if(h.showMarker){a(l,p)}if(l.series[p.seriesIndex].show&&h.showTooltip&&(!m||!m._zoom.started)){g(l,l.series[p.seriesIndex],p)}if(h.bringSeriesToFront){l.moveSeriesToFront(p.seriesIndex)}}else{if(p!=null&&h.isHighlighting&&h.currentNeighbor!=p){if(l.series[p.seriesIndex].showHighlight){var q=h.highlightCanvas._ctx;q.clearRect(0,0,q.canvas.width,q.canvas.height);h.isHighlighting=true;h.currentNeighbor=p;if(h.showMarker){a(l,p)}if(l.series[p.seriesIndex].show&&h.showTooltip&&(!m||!m._zoom.started)){g(l,l.series[p.seriesIndex],p)}if(h.bringSeriesToFront){l.moveSeriesToFront(p.seriesIndex)}}}}}}}})(jQuery);
WRFILE: jqplot.highlighter.min.js

(function(d){d.jqplot.eventListenerHooks.push(["jqplotMouseMove",f]);d.jqplot.Highlighter=function(h){this.show=d.jqplot.config.enablePlugins;this.markerRenderer=new d.jqplot.MarkerRenderer({shadow:false});this.showMarker=true;this.lineWidthAdjust=2.5;this.sizeAdjust=5;this.showTooltip=true;this.tooltipLocation="nw";this.fadeTooltip=true;this.tooltipFadeSpeed="fast";this.tooltipOffset=2;this.tooltipAxes="both";this.tooltipSeparator=", ";this.tooltipContentEditor=null;this.useAxesFormatters=true;this.tooltipFormatString="%.5P";this.formatString=null;this.yvalues=1;this.bringSeriesToFront=false;this._tooltipElem;this.isHighlighting=false;this.currentNeighbor=null;d.extend(true,this,h)};var b=["nw","n","ne","e","se","s","sw","w"];var e={nw:0,n:1,ne:2,e:3,se:4,s:5,sw:6,w:7};var c=["se","s","sw","w","nw","n","ne","e"];d.jqplot.Highlighter.init=function(k,j,i){var h=i||{};this.plugins.highlighter=new d.jqplot.Highlighter(h.highlighter)};d.jqplot.Highlighter.parseOptions=function(i,h){this.showHighlight=true};d.jqplot.Highlighter.postPlotDraw=function(){if(this.plugins.highlighter&&this.plugins.highlighter.highlightCanvas){this.plugins.highlighter.highlightCanvas.resetCanvas();this.plugins.highlighter.highlightCanvas=null}if(this.plugins.highlighter&&this.plugins.highlighter._tooltipElem){this.plugins.highlighter._tooltipElem.emptyForce();this.plugins.highlighter._tooltipElem=null}this.plugins.highlighter.highlightCanvas=new d.jqplot.GenericCanvas();this.eventCanvas._elem.before(this.plugins.highlighter.highlightCanvas.createElement(this._gridPadding,"jqplot-highlight-canvas",this._plotDimensions,this));this.plugins.highlighter.highlightCanvas.setContext();var h=document.createElement("div");this.plugins.highlighter._tooltipElem=d(h);h=null;this.plugins.highlighter._tooltipElem.addClass("jqplot-highlighter-tooltip");this.plugins.highlighter._tooltipElem.css({position:"absolute",display:"none"});this.eventCanvas._elem.before(this.plugins.highlighter._tooltipElem)};d.jqplot.preInitHooks.push(d.jqplot.Highlighter.init);d.jqplot.preParseSeriesOptionsHooks.push(d.jqplot.Highlighter.parseOptions);d.jqplot.postDrawHooks.push(d.jqplot.Highlighter.postPlotDraw);function a(m,o){var j=m.plugins.highlighter;var p=m.series[o.seriesIndex];var h=p.markerRenderer;var i=j.markerRenderer;i.style=h.style;i.lineWidth=h.lineWidth+j.lineWidthAdjust;i.size=h.size+j.sizeAdjust;var l=d.jqplot.getColorComponents(h.color);var n=[l[0],l[1],l[2]];var k=(l[3]>=0.6)?l[3]*0.6:l[3]*(2-l[3]);i.color="rgba("+n[0]+","+n[1]+","+n[2]+","+k+")";i.init();i.draw(p.gridData[o.pointIndex][0],p.gridData[o.pointIndex][1],j.highlightCanvas._ctx)}function g(A,q,m){var k=A.plugins.highlighter;var D=k._tooltipElem;var r=q.highlighter||{};var t=d.extend(true,{},k,r);if(t.useAxesFormatters){var w=q._xaxis._ticks[0].formatter;var h=q._yaxis._ticks[0].formatter;var E=q._xaxis._ticks[0].formatString;var s=q._yaxis._ticks[0].formatString;var z;var u=w(E,m.data[0]);var l=[];for(var B=1;B<t.yvalues+1;B++){l.push(h(s,m.data[B]))}if(typeof t.formatString==="string"){switch(t.tooltipAxes){case"both":case"xy":l.unshift(u);l.unshift(t.formatString);z=d.jqplot.sprintf.apply(d.jqplot.sprintf,l);break;case"yx":l.push(u);l.unshift(t.formatString);z=d.jqplot.sprintf.apply(d.jqplot.sprintf,l);break;case"x":z=d.jqplot.sprintf.apply(d.jqplot.sprintf,[t.formatString,u]);break;case"y":l.unshift(t.formatString);z=d.jqplot.sprintf.apply(d.jqplot.sprintf,l);break;default:l.unshift(u);l.unshift(t.formatString);z=d.jqplot.sprintf.apply(d.jqplot.sprintf,l);break}}else{switch(t.tooltipAxes){case"both":case"xy":z=u;for(var B=0;B<l.length;B++){z+=t.tooltipSeparator+l[B]}break;case"yx":z="";for(var B=0;B<l.length;B++){z+=l[B]+t.tooltipSeparator}z+=u;break;case"x":z=u;break;case"y":z=l.join(t.tooltipSeparator);break;default:z=u;for(var B=0;B<l.length;B++){z+=t.tooltipSeparator+l[B]}break}}}else{var z;if(typeof t.formatString==="string"){z=d.jqplot.sprintf.apply(d.jqplot.sprintf,[t.formatString].concat(m.data))}else{if(t.tooltipAxes=="both"||t.tooltipAxes=="xy"){z=d.jqplot.sprintf(t.tooltipFormatString,m.data[0])+t.tooltipSeparator+d.jqplot.sprintf(t.tooltipFormatString,m.data[1])}else{if(t.tooltipAxes=="yx"){z=d.jqplot.sprintf(t.tooltipFormatString,m.data[1])+t.tooltipSeparator+d.jqplot.sprintf(t.tooltipFormatString,m.data[0])}else{if(t.tooltipAxes=="x"){z=d.jqplot.sprintf(t.tooltipFormatString,m.data[0])}else{if(t.tooltipAxes=="y"){z=d.jqplot.sprintf(t.tooltipFormatString,m.data[1])}}}}}}if(d.isFunction(t.tooltipContentEditor)){z=t.tooltipContentEditor(z,m.seriesIndex,m.pointIndex,A)}D.html(z);var C={x:m.gridData[0],y:m.gridData[1]};var v=0;var j=0.707;if(q.markerRenderer.show==true){v=(q.markerRenderer.size+t.sizeAdjust)/2}var o=b;if(q.fillToZero&&q.fill&&m.data[1]<0){o=c}switch(o[e[t.tooltipLocation]]){case"nw":var p=C.x+A._gridPadding.left-D.outerWidth(true)-t.tooltipOffset-j*v;var n=C.y+A._gridPadding.top-t.tooltipOffset-D.outerHeight(true)-j*v;break;case"n":var p=C.x+A._gridPadding.left-D.outerWidth(true)/2;var n=C.y+A._gridPadding.top-t.tooltipOffset-D.outerHeight(true)-v;break;case"ne":var p=C.x+A._gridPadding.left+t.tooltipOffset+j*v;var n=C.y+A._gridPadding.top-t.tooltipOffset-D.outerHeight(true)-j*v;break;case"e":var p=C.x+A._gridPadding.left+t.tooltipOffset+v;var n=C.y+A._gridPadding.top-D.outerHeight(true)/2;break;case"se":var p=C.x+A._gridPadding.left+t.tooltipOffset+j*v;var n=C.y+A._gridPadding.top+t.tooltipOffset+j*v;break;case"s":var p=C.x+A._gridPadding.left-D.outerWidth(true)/2;var n=C.y+A._gridPadding.top+t.tooltipOffset+v;break;case"sw":var p=C.x+A._gridPadding.left-D.outerWidth(true)-t.tooltipOffset-j*v;var n=C.y+A._gridPadding.top+t.tooltipOffset+j*v;break;case"w":var p=C.x+A._gridPadding.left-D.outerWidth(true)-t.tooltipOffset-v;var n=C.y+A._gridPadding.top-D.outerHeight(true)/2;break;default:var p=C.x+A._gridPadding.left-D.outerWidth(true)-t.tooltipOffset-j*v;var n=C.y+A._gridPadding.top-t.tooltipOffset-D.outerHeight(true)-j*v;break}D.css("left",p);D.css("top",n);if(t.fadeTooltip){D.stop(true,true).fadeIn(t.tooltipFadeSpeed)}else{D.show()}D=null}function f(n,j,i,p,l){var h=l.plugins.highlighter;var m=l.plugins.cursor;if(h.show){if(p==null&&h.isHighlighting){var o=jQuery.Event("jqplotHighlighterUnhighlight");l.target.trigger(o);var q=h.highlightCanvas._ctx;q.clearRect(0,0,q.canvas.width,q.canvas.height);if(h.fadeTooltip){h._tooltipElem.fadeOut(h.tooltipFadeSpeed)}else{h._tooltipElem.hide()}if(h.bringSeriesToFront){l.restorePreviousSeriesOrder()}h.isHighlighting=false;h.currentNeighbor=null;q=null}else{if(p!=null&&l.series[p.seriesIndex].showHighlight&&!h.isHighlighting){var o=jQuery.Event("jqplotHighlighterHighlight");o.which=n.which;o.pageX=n.pageX;o.pageY=n.pageY;var k=[p.seriesIndex,p.pointIndex,p.data,l];l.target.trigger(o,k);h.isHighlighting=true;h.currentNeighbor=p;if(h.showMarker){a(l,p)}if(l.series[p.seriesIndex].show&&h.showTooltip&&(!m||!m._zoom.started)){g(l,l.series[p.seriesIndex],p)}if(h.bringSeriesToFront){l.moveSeriesToFront(p.seriesIndex)}}else{if(p!=null&&h.isHighlighting&&h.currentNeighbor!=p){if(l.series[p.seriesIndex].showHighlight){var q=h.highlightCanvas._ctx;q.clearRect(0,0,q.canvas.width,q.canvas.height);h.isHighlighting=true;h.currentNeighbor=p;if(h.showMarker){a(l,p)}if(l.series[p.seriesIndex].show&&h.showTooltip&&(!m||!m._zoom.started)){g(l,l.series[p.seriesIndex],p)}if(h.bringSeriesToFront){l.moveSeriesToFront(p.seriesIndex)}}}}}}}})(jQuery);
WRFILE: jqplot.cursor.min.js

(function(j){j.jqplot.Cursor=function(q){this.style="crosshair";this.previousCursor="auto";this.show=j.jqplot.config.enablePlugins;this.showTooltip=true;this.followMouse=false;this.tooltipLocation="se";this.tooltipOffset=6;this.showTooltipGridPosition=false;this.showTooltipUnitPosition=true;this.showTooltipDataPosition=false;this.tooltipFormatString="%.4P, %.4P";this.useAxesFormatters=true;this.tooltipAxisGroups=[];this.zoom=false;this.zoomProxy=false;this.zoomTarget=false;this.looseZoom=true;this.clickReset=false;this.dblClickReset=true;this.showVerticalLine=false;this.showHorizontalLine=false;this.constrainZoomTo="none";this.shapeRenderer=new j.jqplot.ShapeRenderer();this._zoom={start:[],end:[],started:false,zooming:false,isZoomed:false,axes:{start:{},end:{}},gridpos:{},datapos:{}};this._tooltipElem;this.zoomCanvas;this.cursorCanvas;this.intersectionThreshold=2;this.showCursorLegend=false;this.cursorLegendFormatString=j.jqplot.Cursor.cursorLegendFormatString;this._oldHandlers={onselectstart:null,ondrag:null,onmousedown:null};this.constrainOutsideZoom=true;this.showTooltipOutsideZoom=false;this.onGrid=false;j.extend(true,this,q)};j.jqplot.Cursor.cursorLegendFormatString="%s x:%s, y:%s";j.jqplot.Cursor.init=function(t,s,r){var q=r||{};this.plugins.cursor=new j.jqplot.Cursor(q.cursor);var u=this.plugins.cursor;if(u.show){j.jqplot.eventListenerHooks.push(["jqplotMouseEnter",b]);j.jqplot.eventListenerHooks.push(["jqplotMouseLeave",f]);j.jqplot.eventListenerHooks.push(["jqplotMouseMove",i]);if(u.showCursorLegend){r.legend=r.legend||{};r.legend.renderer=j.jqplot.CursorLegendRenderer;r.legend.formatString=this.plugins.cursor.cursorLegendFormatString;r.legend.show=true}if(u.zoom){j.jqplot.eventListenerHooks.push(["jqplotMouseDown",a]);if(u.clickReset){j.jqplot.eventListenerHooks.push(["jqplotClick",k])}if(u.dblClickReset){j.jqplot.eventListenerHooks.push(["jqplotDblClick",c])}}this.resetZoom=function(){var x=this.axes;if(!u.zoomProxy){for(var w in x){x[w].reset();x[w]._ticks=[];if(u._zoom.axes[w]!==undefined){x[w]._autoFormatString=u._zoom.axes[w].tickFormatString}}this.redraw()}else{var v=this.plugins.cursor.zoomCanvas._ctx;v.clearRect(0,0,v.canvas.width,v.canvas.height);v=null}this.plugins.cursor._zoom.isZoomed=false;this.target.trigger("jqplotResetZoom",[this,this.plugins.cursor])};if(u.showTooltipDataPosition){u.showTooltipUnitPosition=false;u.showTooltipGridPosition=false;if(q.cursor.tooltipFormatString==undefined){u.tooltipFormatString=j.jqplot.Cursor.cursorLegendFormatString}}}};j.jqplot.Cursor.postDraw=function(){var x=this.plugins.cursor;if(x.zoomCanvas){x.zoomCanvas.resetCanvas();x.zoomCanvas=null}if(x.cursorCanvas){x.cursorCanvas.resetCanvas();x.cursorCanvas=null}if(x._tooltipElem){x._tooltipElem.emptyForce();x._tooltipElem=null}if(x.zoom){x.zoomCanvas=new j.jqplot.GenericCanvas();this.eventCanvas._elem.before(x.zoomCanvas.createElement(this._gridPadding,"jqplot-zoom-canvas",this._plotDimensions,this));x.zoomCanvas.setContext()}var v=document.createElement("div");x._tooltipElem=j(v);v=null;x._tooltipElem.addClass("jqplot-cursor-tooltip");x._tooltipElem.css({position:"absolute",display:"none"});if(x.zoomCanvas){x.zoomCanvas._elem.before(x._tooltipElem)}else{this.eventCanvas._elem.before(x._tooltipElem)}if(x.showVerticalLine||x.showHorizontalLine){x.cursorCanvas=new j.jqplot.GenericCanvas();this.eventCanvas._elem.before(x.cursorCanvas.createElement(this._gridPadding,"jqplot-cursor-canvas",this._plotDimensions,this));x.cursorCanvas.setContext()}if(x.showTooltipUnitPosition){if(x.tooltipAxisGroups.length===0){var t=this.series;var u;var q=[];for(var r=0;r<t.length;r++){u=t[r];var w=u.xaxis+","+u.yaxis;if(j.inArray(w,q)==-1){q.push(w)}}for(var r=0;r<q.length;r++){x.tooltipAxisGroups.push(q[r].split(","))}}}};j.jqplot.Cursor.zoomProxy=function(v,r){var q=v.plugins.cursor;var u=r.plugins.cursor;q.zoomTarget=true;q.zoom=true;q.style="auto";q.dblClickReset=false;u.zoom=true;u.zoomProxy=true;r.target.bind("jqplotZoom",t);r.target.bind("jqplotResetZoom",s);function t(x,w,z,y,A){q.doZoom(w,z,v,A)}function s(w,x,y){v.resetZoom()}};j.jqplot.Cursor.prototype.resetZoom=function(u,v){var t=u.axes;var s=v._zoom.axes;if(!u.plugins.cursor.zoomProxy&&v._zoom.isZoomed){for(var r in t){t[r].reset();t[r]._ticks=[];t[r]._autoFormatString=s[r].tickFormatString}u.redraw();v._zoom.isZoomed=false}else{var q=v.zoomCanvas._ctx;q.clearRect(0,0,q.canvas.width,q.canvas.height);q=null}u.target.trigger("jqplotResetZoom",[u,v])};j.jqplot.Cursor.resetZoom=function(q){q.resetZoom()};j.jqplot.Cursor.prototype.doZoom=function(G,t,C,u){var I=u;var F=C.axes;var r=I._zoom.axes;var w=r.start;var s=r.end;var B,E,z,D,v,x,q,H,J;var A=C.plugins.cursor.zoomCanvas._ctx;if((I.constrainZoomTo=="none"&&Math.abs(G.x-I._zoom.start[0])>6&&Math.abs(G.y-I._zoom.start[1])>6)||(I.constrainZoomTo=="x"&&Math.abs(G.x-I._zoom.start[0])>6)||(I.constrainZoomTo=="y"&&Math.abs(G.y-I._zoom.start[1])>6)){if(!C.plugins.cursor.zoomProxy){for(var y in t){if(I._zoom.axes[y]==undefined){I._zoom.axes[y]={};I._zoom.axes[y].numberTicks=F[y].numberTicks;I._zoom.axes[y].tickInterval=F[y].tickInterval;I._zoom.axes[y].daTickInterval=F[y].daTickInterval;I._zoom.axes[y].min=F[y].min;I._zoom.axes[y].max=F[y].max;I._zoom.axes[y].tickFormatString=(F[y].tickOptions!=null)?F[y].tickOptions.formatString:""}if((I.constrainZoomTo=="none")||(I.constrainZoomTo=="x"&&y.charAt(0)=="x")||(I.constrainZoomTo=="y"&&y.charAt(0)=="y")){z=t[y];if(z!=null){if(z>w[y]){v=w[y];x=z}else{D=w[y]-z;v=z;x=w[y]}q=F[y];H=null;if(q.alignTicks){if(q.name==="x2axis"&&C.axes.xaxis.show){H=C.axes.xaxis.numberTicks}else{if(q.name.charAt(0)==="y"&&q.name!=="yaxis"&&q.name!=="yMidAxis"&&C.axes.yaxis.show){H=C.axes.yaxis.numberTicks}}}if(this.looseZoom&&(F[y].renderer.constructor===j.jqplot.LinearAxisRenderer||F[y].renderer.constructor===j.jqplot.LogAxisRenderer)){J=j.jqplot.LinearTickGenerator(v,x,q._scalefact,H);if(F[y].tickInset&&J[0]<F[y].min+F[y].tickInset*F[y].tickInterval){J[0]+=J[4];J[2]-=1}if(F[y].tickInset&&J[1]>F[y].max-F[y].tickInset*F[y].tickInterval){J[1]-=J[4];J[2]-=1}if(F[y].renderer.constructor===j.jqplot.LogAxisRenderer&&J[0]<F[y].min){J[0]+=J[4];J[2]-=1}F[y].min=J[0];F[y].max=J[1];F[y]._autoFormatString=J[3];F[y].numberTicks=J[2];F[y].tickInterval=J[4];F[y].daTickInterval=[J[4]/1000,"seconds"]}else{F[y].min=v;F[y].max=x;F[y].tickInterval=null;F[y].numberTicks=null;F[y].daTickInterval=null}F[y]._ticks=[]}}}A.clearRect(0,0,A.canvas.width,A.canvas.height);C.redraw();I._zoom.isZoomed=true;A=null}C.target.trigger("jqplotZoom",[G,t,C,u])}};j.jqplot.preInitHooks.push(j.jqplot.Cursor.init);j.jqplot.postDrawHooks.push(j.jqplot.Cursor.postDraw);function e(G,r,C){var J=C.plugins.cursor;var w="";var N=false;if(J.showTooltipGridPosition){w=G.x+", "+G.y;N=true}if(J.showTooltipUnitPosition){var F;for(var E=0;E<J.tooltipAxisGroups.length;E++){F=J.tooltipAxisGroups[E];if(N){w+="<br />"}if(J.useAxesFormatters){for(var D=0;D<F.length;D++){if(D){w+=", "}var H=C.axes[F[D]]._ticks[0].formatter;var B=C.axes[F[D]]._ticks[0].formatString;w+=H(B,r[F[D]])}}else{w+=j.jqplot.sprintf(J.tooltipFormatString,r[F[0]],r[F[1]])}N=true}}if(J.showTooltipDataPosition){var u=C.series;var M=d(C,G.x,G.y);var N=false;for(var E=0;E<u.length;E++){if(u[E].show){var y=u[E].index;var t=u[E].label.toString();var I=j.inArray(y,M.indices);var z=undefined;var x=undefined;if(I!=-1){var L=M.data[I].data;if(J.useAxesFormatters){var A=u[E]._xaxis._ticks[0].formatter;var q=u[E]._yaxis._ticks[0].formatter;var K=u[E]._xaxis._ticks[0].formatString;var v=u[E]._yaxis._ticks[0].formatString;z=A(K,L[0]);x=q(v,L[1])}else{z=L[0];x=L[1]}if(N){w+="<br />"}w+=j.jqplot.sprintf(J.tooltipFormatString,t,z,x);N=true}}}}J._tooltipElem.html(w)}function g(C,A){var E=A.plugins.cursor;var z=E.cursorCanvas._ctx;z.clearRect(0,0,z.canvas.width,z.canvas.height);if(E.showVerticalLine){E.shapeRenderer.draw(z,[[C.x,0],[C.x,z.canvas.height]])}if(E.showHorizontalLine){E.shapeRenderer.draw(z,[[0,C.y],[z.canvas.width,C.y]])}var G=d(A,C.x,C.y);if(E.showCursorLegend){var r=j(A.targetId+" td.jqplot-cursor-legend-label");for(var B=0;B<r.length;B++){var v=j(r[B]).data("seriesIndex");var t=A.series[v];var s=t.label.toString();var D=j.inArray(v,G.indices);var x=undefined;var w=undefined;if(D!=-1){var H=G.data[D].data;if(E.useAxesFormatters){var y=t._xaxis._ticks[0].formatter;var q=t._yaxis._ticks[0].formatter;var F=t._xaxis._ticks[0].formatString;var u=t._yaxis._ticks[0].formatString;x=y(F,H[0]);w=q(u,H[1])}else{x=H[0];w=H[1]}}if(A.legend.escapeHtml){j(r[B]).text(j.jqplot.sprintf(E.cursorLegendFormatString,s,x,w))}else{j(r[B]).html(j.jqplot.sprintf(E.cursorLegendFormatString,s,x,w))}}}z=null}function d(A,F,E){var B={indices:[],data:[]};var G,w,u,C,v,q,t;var z;var D=A.plugins.cursor;for(var w=0;w<A.series.length;w++){G=A.series[w];q=G.renderer;if(G.show){z=D.intersectionThreshold;if(G.showMarker){z+=G.markerRenderer.size/2}for(var v=0;v<G.gridData.length;v++){t=G.gridData[v];if(D.showVerticalLine){if(Math.abs(F-t[0])<=z){B.indices.push(w);B.data.push({seriesIndex:w,pointIndex:v,gridData:t,data:G.data[v]})}}}}}return B}function n(r,t){var v=t.plugins.cursor;var s=v._tooltipElem;switch(v.tooltipLocation){case"nw":var q=r.x+t._gridPadding.left-s.outerWidth(true)-v.tooltipOffset;var u=r.y+t._gridPadding.top-v.tooltipOffset-s.outerHeight(true);break;case"n":var q=r.x+t._gridPadding.left-s.outerWidth(true)/2;var u=r.y+t._gridPadding.top-v.tooltipOffset-s.outerHeight(true);break;case"ne":var q=r.x+t._gridPadding.left+v.tooltipOffset;var u=r.y+t._gridPadding.top-v.tooltipOffset-s.outerHeight(true);break;case"e":var q=r.x+t._gridPadding.left+v.tooltipOffset;var u=r.y+t._gridPadding.top-s.outerHeight(true)/2;break;case"se":var q=r.x+t._gridPadding.left+v.tooltipOffset;var u=r.y+t._gridPadding.top+v.tooltipOffset;break;case"s":var q=r.x+t._gridPadding.left-s.outerWidth(true)/2;var u=r.y+t._gridPadding.top+v.tooltipOffset;break;case"sw":var q=r.x+t._gridPadding.left-s.outerWidth(true)-v.tooltipOffset;var u=r.y+t._gridPadding.top+v.tooltipOffset;break;case"w":var q=r.x+t._gridPadding.left-s.outerWidth(true)-v.tooltipOffset;var u=r.y+t._gridPadding.top-s.outerHeight(true)/2;break;default:var q=r.x+t._gridPadding.left+v.tooltipOffset;var u=r.y+t._gridPadding.top+v.tooltipOffset;break}s.css("left",q);s.css("top",u);s=null}function m(u){var s=u._gridPadding;var v=u.plugins.cursor;var t=v._tooltipElem;switch(v.tooltipLocation){case"nw":var r=s.left+v.tooltipOffset;var q=s.top+v.tooltipOffset;t.css("left",r);t.css("top",q);break;case"n":var r=(s.left+(u._plotDimensions.width-s.right))/2-t.outerWidth(true)/2;var q=s.top+v.tooltipOffset;t.css("left",r);t.css("top",q);break;case"ne":var r=s.right+v.tooltipOffset;var q=s.top+v.tooltipOffset;t.css({right:r,top:q});break;case"e":var r=s.right+v.tooltipOffset;var q=(s.top+(u._plotDimensions.height-s.bottom))/2-t.outerHeight(true)/2;t.css({right:r,top:q});break;case"se":var r=s.right+v.tooltipOffset;var q=s.bottom+v.tooltipOffset;t.css({right:r,bottom:q});break;case"s":var r=(s.left+(u._plotDimensions.width-s.right))/2-t.outerWidth(true)/2;var q=s.bottom+v.tooltipOffset;t.css({left:r,bottom:q});break;case"sw":var r=s.left+v.tooltipOffset;var q=s.bottom+v.tooltipOffset;t.css({left:r,bottom:q});break;case"w":var r=s.left+v.tooltipOffset;var q=(s.top+(u._plotDimensions.height-s.bottom))/2-t.outerHeight(true)/2;t.css({left:r,top:q});break;default:var r=s.right-v.tooltipOffset;var q=s.bottom+v.tooltipOffset;t.css({right:r,bottom:q});break}t=null}function k(r,q,v,u,t){r.preventDefault();r.stopImmediatePropagation();var w=t.plugins.cursor;if(w.clickReset){w.resetZoom(t,w)}var s=window.getSelection;if(document.selection&&document.selection.empty){document.selection.empty()}else{if(s&&!s().isCollapsed){s().collapse()}}return false}function c(r,q,v,u,t){r.preventDefault();r.stopImmediatePropagation();var w=t.plugins.cursor;if(w.dblClickReset){w.resetZoom(t,w)}var s=window.getSelection;if(document.selection&&document.selection.empty){document.selection.empty()}else{if(s&&!s().isCollapsed){s().collapse()}}return false}function f(w,t,q,z,u){var v=u.plugins.cursor;v.onGrid=false;if(v.show){j(w.target).css("cursor",v.previousCursor);if(v.showTooltip&&!(v._zoom.zooming&&v.showTooltipOutsideZoom&&!v.constrainOutsideZoom)){v._tooltipElem.empty();v._tooltipElem.hide()}if(v.zoom){v._zoom.gridpos=t;v._zoom.datapos=q}if(v.showVerticalLine||v.showHorizontalLine){var B=v.cursorCanvas._ctx;B.clearRect(0,0,B.canvas.width,B.canvas.height);B=null}if(v.showCursorLegend){var A=j(u.targetId+" td.jqplot-cursor-legend-label");for(var s=0;s<A.length;s++){var y=j(A[s]).data("seriesIndex");var r=u.series[y];var x=r.label.toString();if(u.legend.escapeHtml){j(A[s]).text(j.jqplot.sprintf(v.cursorLegendFormatString,x,undefined,undefined))}else{j(A[s]).html(j.jqplot.sprintf(v.cursorLegendFormatString,x,undefined,undefined))}}}}}function b(r,q,u,t,s){var v=s.plugins.cursor;v.onGrid=true;if(v.show){v.previousCursor=r.target.style.cursor;r.target.style.cursor=v.style;if(v.showTooltip){e(q,u,s);if(v.followMouse){n(q,s)}else{m(s)}v._tooltipElem.show()}if(v.showVerticalLine||v.showHorizontalLine){g(q,s)}}}function i(r,q,u,t,s){var v=s.plugins.cursor;if(v.show){if(v.showTooltip){e(q,u,s);if(v.followMouse){n(q,s)}}if(v.showVerticalLine||v.showHorizontalLine){g(q,s)}}}function o(y){var x=y.data.plot;var t=x.eventCanvas._elem.offset();var w={x:y.pageX-t.left,y:y.pageY-t.top};var u={xaxis:null,yaxis:null,x2axis:null,y2axis:null,y3axis:null,y4axis:null,y5axis:null,y6axis:null,y7axis:null,y8axis:null,y9axis:null,yMidAxis:null};var v=["xaxis","yaxis","x2axis","y2axis","y3axis","y4axis","y5axis","y6axis","y7axis","y8axis","y9axis","yMidAxis"];var q=x.axes;var r,s;for(r=11;r>0;r--){s=v[r-1];if(q[s].show){u[s]=q[s].series_p2u(w[s.charAt(0)])}}return{offsets:t,gridPos:w,dataPos:u}}function h(z){var x=z.data.plot;var y=x.plugins.cursor;if(y.show&&y.zoom&&y._zoom.started&&!y.zoomTarget){z.preventDefault();var B=y.zoomCanvas._ctx;var v=o(z);var w=v.gridPos;var t=v.dataPos;y._zoom.gridpos=w;y._zoom.datapos=t;y._zoom.zooming=true;var u=w.x;var s=w.y;var A=B.canvas.height;var q=B.canvas.width;if(y.showTooltip&&!y.onGrid&&y.showTooltipOutsideZoom){e(w,t,x);if(y.followMouse){n(w,x)}}if(y.constrainZoomTo=="x"){y._zoom.end=[u,A]}else{if(y.constrainZoomTo=="y"){y._zoom.end=[q,s]}else{y._zoom.end=[u,s]}}var r=window.getSelection;if(document.selection&&document.selection.empty){document.selection.empty()}else{if(r&&!r().isCollapsed){r().collapse()}}l.call(y);B=null}}function a(w,s,r,x,t){var v=t.plugins.cursor;if(t.plugins.mobile){j(document).one("vmouseup.jqplot_cursor",{plot:t},p)}else{j(document).one("mouseup.jqplot_cursor",{plot:t},p)}var u=t.axes;if(document.onselectstart!=undefined){v._oldHandlers.onselectstart=document.onselectstart;document.onselectstart=function(){return false}}if(document.ondrag!=undefined){v._oldHandlers.ondrag=document.ondrag;document.ondrag=function(){return false}}if(document.onmousedown!=undefined){v._oldHandlers.onmousedown=document.onmousedown;document.onmousedown=function(){return false}}if(v.zoom){if(!v.zoomProxy){var y=v.zoomCanvas._ctx;y.clearRect(0,0,y.canvas.width,y.canvas.height);y=null}if(v.constrainZoomTo=="x"){v._zoom.start=[s.x,0]}else{if(v.constrainZoomTo=="y"){v._zoom.start=[0,s.y]}else{v._zoom.start=[s.x,s.y]}}v._zoom.started=true;for(var q in r){v._zoom.axes.start[q]=r[q]}if(t.plugins.mobile){j(document).bind("vmousemove.jqplotCursor",{plot:t},h)}else{j(document).bind("mousemove.jqplotCursor",{plot:t},h)}}}function p(y){var v=y.data.plot;var x=v.plugins.cursor;if(x.zoom&&x._zoom.zooming&&!x.zoomTarget){var u=x._zoom.gridpos.x;var r=x._zoom.gridpos.y;var t=x._zoom.datapos;var z=x.zoomCanvas._ctx.canvas.height;var q=x.zoomCanvas._ctx.canvas.width;var w=v.axes;if(x.constrainOutsideZoom&&!x.onGrid){if(u<0){u=0}else{if(u>q){u=q}}if(r<0){r=0}else{if(r>z){r=z}}for(var s in t){if(t[s]){if(s.charAt(0)=="x"){t[s]=w[s].series_p2u(u)}else{t[s]=w[s].series_p2u(r)}}}}if(x.constrainZoomTo=="x"){r=z}else{if(x.constrainZoomTo=="y"){u=q}}x._zoom.end=[u,r];x._zoom.gridpos={x:u,y:r};x.doZoom(x._zoom.gridpos,t,v,x)}x._zoom.started=false;x._zoom.zooming=false;j(document).unbind("mousemove.jqplotCursor",h);if(document.onselectstart!=undefined&&x._oldHandlers.onselectstart!=null){document.onselectstart=x._oldHandlers.onselectstart;x._oldHandlers.onselectstart=null}if(document.ondrag!=undefined&&x._oldHandlers.ondrag!=null){document.ondrag=x._oldHandlers.ondrag;x._oldHandlers.ondrag=null}if(document.onmousedown!=undefined&&x._oldHandlers.onmousedown!=null){document.onmousedown=x._oldHandlers.onmousedown;x._oldHandlers.onmousedown=null}}function l(){var y=this._zoom.start;var u=this._zoom.end;var s=this.zoomCanvas._ctx;var r,v,x,q;if(u[0]>y[0]){r=y[0];q=u[0]-y[0]}else{r=u[0];q=y[0]-u[0]}if(u[1]>y[1]){v=y[1];x=u[1]-y[1]}else{v=u[1];x=y[1]-u[1]}s.fillStyle="rgba(0,0,0,0.2)";s.strokeStyle="#999999";s.lineWidth=1;s.clearRect(0,0,s.canvas.width,s.canvas.height);s.fillRect(0,0,s.canvas.width,s.canvas.height);s.clearRect(r,v,q,x);s.strokeRect(r,v,q,x);s=null}j.jqplot.CursorLegendRenderer=function(q){j.jqplot.TableLegendRenderer.call(this,q);this.formatString="%s"};j.jqplot.CursorLegendRenderer.prototype=new j.jqplot.TableLegendRenderer();j.jqplot.CursorLegendRenderer.prototype.constructor=j.jqplot.CursorLegendRenderer;j.jqplot.CursorLegendRenderer.prototype.draw=function(){if(this._elem){this._elem.emptyForce();this._elem=null}if(this.show){var w=this._series,A;var r=document.createElement("table");this._elem=j(r);r=null;this._elem.addClass("jqplot-legend jqplot-cursor-legend");this._elem.css("position","absolute");var q=false;for(var x=0;x<w.length;x++){A=w[x];if(A.show&&A.showLabel){var v=j.jqplot.sprintf(this.formatString,A.label.toString());if(v){var t=A.color;if(A._stack&&!A.fill){t=""}z.call(this,v,t,q,x);q=true}for(var u=0;u<j.jqplot.addLegendRowHooks.length;u++){var y=j.jqplot.addLegendRowHooks[u].call(this,A);if(y){z.call(this,y.label,y.color,q);q=true}}}}w=A=null;delete w;delete A}function z(D,C,F,s){var B=(F)?this.rowSpacing:"0";var E=j('<tr class="jqplot-legend jqplot-cursor-legend"></tr>').appendTo(this._elem);E.data("seriesIndex",s);j('<td class="jqplot-legend jqplot-cursor-legend-swatch" style="padding-top:'+B+';"><div style="border:1px solid #cccccc;padding:0.2em;"><div class="jqplot-cursor-legend-swatch" style="background-color:'+C+';"></div></div></td>').appendTo(E);var G=j('<td class="jqplot-legend jqplot-cursor-legend-label" style="vertical-align:middle;padding-top:'+B+';"></td>');G.appendTo(E);G.data("seriesIndex",s);if(this.escapeHtml){G.text(D)}else{G.html(D)}E=null;G=null}return this._elem}})(jQuery);
WRFILE: jqplot.pointLabels.min.js

(function(c){c.jqplot.PointLabels=function(e){this.show=c.jqplot.config.enablePlugins;this.location="n";this.labelsFromSeries=false;this.seriesLabelIndex=null;this.labels=[];this._labels=[];this.stackedValue=false;this.ypadding=6;this.xpadding=6;this.escapeHTML=true;this.edgeTolerance=-5;this.formatter=c.jqplot.DefaultTickFormatter;this.formatString="";this.hideZeros=false;this._elems=[];c.extend(true,this,e)};var a=["nw","n","ne","e","se","s","sw","w"];var d={nw:0,n:1,ne:2,e:3,se:4,s:5,sw:6,w:7};var b=["se","s","sw","w","nw","n","ne","e"];c.jqplot.PointLabels.init=function(j,h,f,g,i){var e=c.extend(true,{},f,g);e.pointLabels=e.pointLabels||{};if(this.renderer.constructor===c.jqplot.BarRenderer&&this.barDirection==="horizontal"&&!e.pointLabels.location){e.pointLabels.location="e"}this.plugins.pointLabels=new c.jqplot.PointLabels(e.pointLabels);this.plugins.pointLabels.setLabels.call(this)};c.jqplot.PointLabels.prototype.setLabels=function(){var f=this.plugins.pointLabels;var h;if(f.seriesLabelIndex!=null){h=f.seriesLabelIndex}else{if(this.renderer.constructor===c.jqplot.BarRenderer&&this.barDirection==="horizontal"){h=(this._plotData[0].length<3)?0:this._plotData[0].length-1}else{h=(this._plotData.length===0)?0:this._plotData[0].length-1}}f._labels=[];if(f.labels.length===0||f.labelsFromSeries){if(f.stackedValue){if(this._plotData.length&&this._plotData[0].length){for(var e=0;e<this._plotData.length;e++){f._labels.push(this._plotData[e][h])}}}else{var g=this.data;if(this.renderer.constructor===c.jqplot.BarRenderer&&this.waterfall){g=this._data}if(g.length&&g[0].length){for(var e=0;e<g.length;e++){f._labels.push(g[e][h])}}g=null}}else{if(f.labels.length){f._labels=f.labels}}};c.jqplot.PointLabels.prototype.xOffset=function(f,e,g){e=e||this.location;g=g||this.xpadding;var h;switch(e){case"nw":h=-f.outerWidth(true)-this.xpadding;break;case"n":h=-f.outerWidth(true)/2;break;case"ne":h=this.xpadding;break;case"e":h=this.xpadding;break;case"se":h=this.xpadding;break;case"s":h=-f.outerWidth(true)/2;break;case"sw":h=-f.outerWidth(true)-this.xpadding;break;case"w":h=-f.outerWidth(true)-this.xpadding;break;default:h=-f.outerWidth(true)-this.xpadding;break}return h};c.jqplot.PointLabels.prototype.yOffset=function(f,e,g){e=e||this.location;g=g||this.xpadding;var h;switch(e){case"nw":h=-f.outerHeight(true)-this.ypadding;break;case"n":h=-f.outerHeight(true)-this.ypadding;break;case"ne":h=-f.outerHeight(true)-this.ypadding;break;case"e":h=-f.outerHeight(true)/2;break;case"se":h=this.ypadding;break;case"s":h=this.ypadding;break;case"sw":h=this.ypadding;break;case"w":h=-f.outerHeight(true)/2;break;default:h=-f.outerHeight(true)-this.ypadding;break}return h};c.jqplot.PointLabels.draw=function(x,j,v){var t=this.plugins.pointLabels;t.setLabels.call(this);for(var w=0;w<t._elems.length;w++){t._elems[w].emptyForce()}t._elems.splice(0,t._elems.length);if(t.show){var r="_"+this._stackAxis+"axis";if(!t.formatString){t.formatString=this[r]._ticks[0].formatString;t.formatter=this[r]._ticks[0].formatter}var E=this._plotData;var D=this._prevPlotData;var A=this._xaxis;var q=this._yaxis;var z,f;for(var w=0,u=t._labels.length;w<u;w++){var o=t._labels[w];if(o==null||(t.hideZeros&&parseInt(o,10)==0)){continue}o=t.formatter(t.formatString,o);f=document.createElement("div");t._elems[w]=c(f);z=t._elems[w];z.addClass("jqplot-point-label jqplot-series-"+this.index+" jqplot-point-"+w);z.css("position","absolute");z.insertAfter(x.canvas);if(t.escapeHTML){z.text(o)}else{z.html(o)}var g=t.location;if((this.fillToZero&&E[w][1]<0)||(this.fillToZero&&this._type==="bar"&&this.barDirection==="horizontal"&&E[w][0]<0)||(this.waterfall&&parseInt(o,10))<0){g=b[d[g]]}var n=A.u2p(E[w][0])+t.xOffset(z,g);var h=q.u2p(E[w][1])+t.yOffset(z,g);if(this._stack&&!t.stackedValue){if(this.barDirection==="vertical"){h=(this._barPoints[w][0][1]+this._barPoints[w][1][1])/2+v._gridPadding.top-0.5*z.outerHeight(true)}else{n=(this._barPoints[w][2][0]+this._barPoints[w][0][0])/2+v._gridPadding.left-0.5*z.outerWidth(true)}}if(this.renderer.constructor==c.jqplot.BarRenderer){if(this.barDirection=="vertical"){n+=this._barNudge}else{h-=this._barNudge}}z.css("left",n);z.css("top",h);var k=n+z.width();var s=h+z.height();var C=t.edgeTolerance;var e=c(x.canvas).position().left;var y=c(x.canvas).position().top;var B=x.canvas.width+e;var m=x.canvas.height+y;if(n-C<e||h-C<y||k+C>B||s+C>m){z.remove()}z=null;f=null}}};c.jqplot.postSeriesInitHooks.push(c.jqplot.PointLabels.init);c.jqplot.postDrawSeriesHooks.push(c.jqplot.PointLabels.draw)})(jQuery);
WRFILE: bean.min.js

/*!
  * Bean - copyright (c) Jacob Thornton 2011-2012
  * https://github.com/fat/bean
  * MIT license
  */
(function(a,c,b){if(typeof module!="undefined"&&module.exports){module.exports=b()}else{if(typeof define=="function"&&define.amd){define(b)}else{c[a]=b()}}})("bean",this,function(l,O){l=l||"bean";O=O||this;var G=window,H=O[l],t=/[^\.]*(?=\..*)\.|.*/,C=/\..*/,j="addEventListener",a="removeEventListener",g=document||{},u=g.documentElement||{},q=u[j],v=q?j:"attachEvent",A={},n=Array.prototype.slice,I=function(P,Q){return P.split(Q||" ")},k=function(P){return typeof P=="string"},o=function(P){return typeof P=="function"},z="click dblclick mouseup mousedown contextmenu mousewheel mousemultiwheel DOMMouseScroll mouseover mouseout mousemove selectstart selectend keydown keypress keyup orientationchange focus blur change reset select submit load unload beforeunload resize move DOMContentLoaded readystatechange message error abort scroll ",c="show input invalid touchstart touchmove touchend touchcancel gesturestart gesturechange gestureend textinput readystatechange pageshow pagehide popstate hashchange offline online afterprint beforeprint dragstart dragenter dragover dragleave drag drop dragend loadstart progress suspend emptied stalled loadmetadata loadeddata canplay canplaythrough playing waiting seeking seeked ended durationchange timeupdate play pause ratechange volumechange cuechange checking noupdate downloading cached updateready obsolete ",M=(function(R,Q,P){for(P=0;P<Q.length;P++){Q[P]&&(R[Q[P]]=1)}return R}({},I(z+(q?c:"")))),y=(function(){var Q="compareDocumentPosition" in u?function(S,R){return R.compareDocumentPosition&&(R.compareDocumentPosition(S)&16)===16}:"contains" in u?function(S,R){R=R.nodeType===9||R===window?u:R;return R!==S&&R.contains(S)}:function(S,R){while(S=S.parentNode){if(S===R){return 1}}return 0},P=function(R){var S=R.relatedTarget;return !S?S==null:(S!==this&&S.prefix!=="xul"&&!/document/.test(this.toString())&&!Q(S,this))};return{mouseenter:{base:"mouseover",condition:P},mouseleave:{base:"mouseout",condition:P},mousewheel:{base:/Firefox/.test(navigator.userAgent)?"DOMMouseScroll":"mousewheel"}}}()),E=(function(){var Y=I("altKey attrChange attrName bubbles cancelable ctrlKey currentTarget detail eventPhase getModifierState isTrusted metaKey relatedNode relatedTarget shiftKey srcElement target timeStamp type view which propertyName"),W=Y.concat(I("button buttons clientX clientY dataTransfer fromElement offsetX offsetY pageX pageY screenX screenY toElement")),Q=W.concat(I("wheelDelta wheelDeltaX wheelDeltaY wheelDeltaZ axis")),S=Y.concat(I("char charCode key keyCode keyIdentifier keyLocation location")),R=Y.concat(I("data")),X=Y.concat(I("touches targetTouches changedTouches scale rotation")),aa=Y.concat(I("data origin source")),T=Y.concat(I("state")),U=/over|out/,P=[{reg:/key/i,fix:function(ab,ac){ac.keyCode=ab.keyCode||ab.which;return S}},{reg:/click|mouse(?!(.*wheel|scroll))|menu|drag|drop/i,fix:function(ac,ad,ab){ad.rightClick=ac.which===3||ac.button===2;ad.pos={x:0,y:0};if(ac.pageX||ac.pageY){ad.clientX=ac.pageX;ad.clientY=ac.pageY}else{if(ac.clientX||ac.clientY){ad.clientX=ac.clientX+g.body.scrollLeft+u.scrollLeft;ad.clientY=ac.clientY+g.body.scrollTop+u.scrollTop}}if(U.test(ab)){ad.relatedTarget=ac.relatedTarget||ac[(ab=="mouseover"?"from":"to")+"Element"]}return W}},{reg:/mouse.*(wheel|scroll)/i,fix:function(){return Q}},{reg:/^text/i,fix:function(){return R}},{reg:/^touch|^gesture/i,fix:function(){return X}},{reg:/^message$/i,fix:function(){return aa}},{reg:/^popstate$/i,fix:function(){return T}},{reg:/.*/,fix:function(){return Y}}],V={},Z=function(ac,af,ab){if(!arguments.length){return}ac=ac||((af.ownerDocument||af.document||af).parentWindow||G).event;this.originalEvent=ac;this.isNative=ab;this.isBean=true;if(!ac){return}var aj=ac.type,ah=ac.target||ac.srcElement,ag,ae,ad,ai,ak;this.target=ah&&ah.nodeType===3?ah.parentNode:ah;if(ab){ak=V[aj];if(!ak){for(ag=0,ae=P.length;ag<ae;ag++){if(P[ag].reg.test(aj)){V[aj]=ak=P[ag].fix;break}}}ai=ak(ac,this,aj);for(ag=ai.length;ag--;){if(!((ad=ai[ag]) in this)&&ad in ac){this[ad]=ac[ad]}}}};Z.prototype.preventDefault=function(){if(this.originalEvent.preventDefault){this.originalEvent.preventDefault()}else{this.originalEvent.returnValue=false}};Z.prototype.stopPropagation=function(){if(this.originalEvent.stopPropagation){this.originalEvent.stopPropagation()}else{this.originalEvent.cancelBubble=true}};Z.prototype.stop=function(){this.preventDefault();this.stopPropagation();this.stopped=true};Z.prototype.stopImmediatePropagation=function(){if(this.originalEvent.stopImmediatePropagation){this.originalEvent.stopImmediatePropagation()}this.isImmediatePropagationStopped=function(){return true}};Z.prototype.isImmediatePropagationStopped=function(){return this.originalEvent.isImmediatePropagationStopped&&this.originalEvent.isImmediatePropagationStopped()};Z.prototype.clone=function(ac){var ab=new Z(this,this.element,this.isNative);ab.currentTarget=ac;return ab};return Z}()),d=function(Q,P){return !q&&!P&&(Q===g||Q===G)?u:Q},i=(function(){var Q=function(S,V,X,R){var U=function(Z,Y){return V.apply(S,R?n.call(Y,Z?0:1).concat(R):Y)},W=function(Z,Y){return V.__beanDel?V.__beanDel.ft(Z.target,S):Y},T=X?function(Y){var Z=W(Y,this);if(X.apply(Z,arguments)){if(Y){Y.currentTarget=Z}return U(Y,arguments)}}:function(Y){if(V.__beanDel){Y=Y.clone(W(Y))}return U(Y,arguments)};T.__beanDel=V.__beanDel;return T},P=function(V,X,Z,T,S,W,Y){var U=y[X],R;if(X=="unload"){Z=s(b,V,X,Z,T)}if(U){if(U.condition){Z=Q(V,Z,U.condition,W)}X=U.base||X}this.isNative=R=M[X]&&!!V[v];this.customType=!q&&!R&&X;this.element=V;this.type=X;this.original=T;this.namespaces=S;this.eventType=q||R?X:"propertychange";this.target=d(V,R);this[v]=!!this.target[v];this.root=Y;this.handler=Q(V,Z,null,W)};P.prototype.inNamespaces=function(T){var S,R,U=0;if(!T){return true}if(!this.namespaces){return false}for(S=T.length;S--;){for(R=this.namespaces.length;R--;){if(T[S]==this.namespaces[R]){U++}}}return T.length===U};P.prototype.matches=function(S,R,T){return this.element===S&&(!R||this.original===R)&&(!T||this.handler===T)};return P}()),K=(function(){var U={},T=function(Z,ac,W,ag,ae,ad){var ab=ae?"r":"$";if(!ac||ac=="*"){for(var ah in U){if(ah.charAt(0)==ab){T(Z,ah.substr(1),W,ag,ae,ad)}}}else{var Y=0,X,aa=U[ab+ac],af=Z=="*";if(!aa){return}for(X=aa.length;Y<X;Y++){if((af||aa[Y].matches(Z,W,ag))&&!ad(aa[Y],aa,Y,ac)){return}}}},S=function(Z,aa,Y,W){var X,ab=U[(W?"r":"$")+aa];if(ab){for(X=ab.length;X--;){if(!ab[X].root&&ab[X].matches(Z,Y,null)){return true}}}return false},R=function(Z,aa,Y,X){var W=[];T(Z,aa,Y,null,X,function(ab){return W.push(ab)});return W},V=function(Y){var W=!Y.root&&!this.has(Y.element,Y.type,null,false),X=(Y.root?"r":"$")+Y.type;(U[X]||(U[X]=[])).push(Y);return W},Q=function(W){T(W.element,W.type,null,W.handler,W.root,function(Y,Z,X){Z.splice(X,1);Y.removed=true;if(Z.length===0){delete U[(Y.root?"r":"$")+Y.type]}return false})},P=function(){var X,W=[];for(X in U){if(X.charAt(0)=="$"){W=W.concat(U[X])}}return W};return{has:S,get:R,put:V,del:Q,entries:P}}()),w,N=function(P){if(!arguments.length){w=g.querySelectorAll?function(Q,R){return R.querySelectorAll(Q)}:function(){throw new Error("Bean: No selector engine installed")}}else{w=P}},D=function(T,S){if(!q&&S&&T&&T.propertyName!="_on"+S){return}var R=K.get(this,S||T.type,null,false),P=R.length,Q=0;T=new E(T,this,true);if(S){T.type=S}for(;Q<P&&!T.isImmediatePropagationStopped();Q++){if(!R[Q].removed){R[Q].handler.call(this,T)}}},J=q?function(P,Q,R){P[R?j:a](Q,D,false)}:function(P,Q,T,S){var R;if(T){K.put(R=new i(P,S||Q,function(U){D.call(P,U,S)},D,null,null,true));if(S&&P["_on"+S]==null){P["_on"+S]=0}R.target.attachEvent("on"+R.eventType,R.handler)}else{R=K.get(P,S||Q,D,true)[0];if(R){R.target.detachEvent("on"+R.eventType,R.handler);K.del(R)}}},s=function(T,P,R,Q,S){return function(){Q.apply(this,arguments);T(P,R,S)}},b=function(T,S,X,P){var W=S&&S.replace(C,""),Q=K.get(T,W,null,false),V={},U,R;for(U=0,R=Q.length;U<R;U++){if((!X||Q[U].original===X)&&Q[U].inNamespaces(P)){K.del(Q[U]);if(!V[Q[U].eventType]&&Q[U][v]){V[Q[U].eventType]={t:Q[U].eventType,c:Q[U].type}}}}for(U in V){if(!K.has(T,V[U].t,null,false)){J(T,V[U].t,false,V[U].c)}}},m=function(P,R){var S=function(V,T){var U,W=k(P)?w(P,T):P;for(;V&&V!==T;V=V.parentNode){for(U=W.length;U--;){if(W[U]===V){return V}}}},Q=function(U){var T=S(U.target,this);if(T){R.apply(T,arguments)}};Q.__beanDel={ft:S,selector:P};return Q},L=q?function(Q,S,R){var P=g.createEvent(Q?"HTMLEvents":"UIEvents");P[Q?"initEvent":"initUIEvent"](S,true,true,G,1);R.dispatchEvent(P)}:function(P,R,Q){Q=d(Q,P);P?Q.fireEvent("on"+R,g.createEventObject()):Q["_on"+R]++},F=function(T,P,V){var S=k(P),Q,U,W,R;if(S&&P.indexOf(" ")>0){P=I(P);for(R=P.length;R--;){F(T,P[R],V)}return T}U=S&&P.replace(C,"");if(U&&y[U]){U=y[U].base}if(!P||S){if(W=S&&P.replace(t,"")){W=I(W,".")}b(T,U,V,W)}else{if(o(P)){b(T,null,P)}else{for(Q in P){if(P.hasOwnProperty(Q)){F(T,Q,P[Q])}}}}return T},x=function(Q,Z,P,X){var W,V,T,R,U,Y,S;if(P===undefined&&typeof Z=="object"){for(V in Z){if(Z.hasOwnProperty(V)){x.call(this,Q,V,Z[V])}}return}if(!o(P)){W=X;U=n.call(arguments,4);X=m(P,W,w)}else{U=n.call(arguments,3);X=W=P}T=I(Z);if(this===A){X=s(F,Q,Z,X,W)}for(R=T.length;R--;){S=K.put(Y=new i(Q,T[R].replace(C,""),X,W,I(T[R].replace(t,""),"."),U,false));if(Y[v]&&S){J(Q,Y.eventType,true,Y.customType)}}return Q},f=function(R,Q,S,P){return x.apply(null,!k(S)?n.call(arguments):[R,S,Q,P].concat(arguments.length>3?n.call(arguments,5):[]))},h=function(){return x.apply(A,arguments)},r=function(S,X,V){var U=I(X),T,R,Q,W,P;for(T=U.length;T--;){X=U[T].replace(C,"");if(W=U[T].replace(t,"")){W=I(W,".")}if(!W&&!V&&S[v]){L(M[X],X,S)}else{P=K.get(S,X,null,false);V=[false].concat(V);for(R=0,Q=P.length;R<Q;R++){if(P[R].inNamespaces(W)){P[R].handler.apply(S,V)}}}}return S},p=function(T,W,U){var Q=K.get(W,U,null,false),P=Q.length,S=0,R,V;for(;S<P;S++){if(Q[S].original){R=[T,Q[S].type];if(V=Q[S].handler.__beanDel){R.push(V.selector)}R.push(Q[S].original);x.apply(null,R)}}return T},B={on:x,add:f,one:h,off:F,remove:F,clone:p,fire:r,Event:E,setSelectorEngine:N,noConflict:function(){O[l]=H;return this}};if(G.attachEvent){var e=function(){var Q,P=K.entries();for(Q in P){if(P[Q].type&&P[Q].type!=="unload"){F(P[Q].element,P[Q].type)}}G.detachEvent("onunload",e);G.CollectGarbage&&G.CollectGarbage()};G.attachEvent("onunload",e)}N();return B});
WRFILE: underscore.min.js

(function(){var v=this;var k=v._;var I=Array.prototype,g=Object.prototype,n=Function.prototype;var L=I.push,l=I.slice,c=g.toString,j=g.hasOwnProperty;var s=Array.isArray,e=Object.keys,J=n.bind,B=Object.create;var E=function(){};var P=function(Q){if(Q instanceof P){return Q}if(!(this instanceof P)){return new P(Q)}this._wrapped=Q};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports){exports=module.exports=P}exports._=P}else{v._=P}P.VERSION="1.8.3";var b=function(R,Q,S){if(Q===void 0){return R}switch(S==null?3:S){case 1:return function(T){return R.call(Q,T)};case 2:return function(U,T){return R.call(Q,U,T)};case 3:return function(U,T,V){return R.call(Q,U,T,V)};case 4:return function(T,V,U,W){return R.call(Q,T,V,U,W)}}return function(){return R.apply(Q,arguments)}};var F=function(R,Q,S){if(R==null){return P.identity}if(P.isFunction(R)){return b(R,Q,S)}if(P.isObject(R)){return P.matcher(R)}return P.property(R)};P.iteratee=function(R,Q){return F(R,Q,Infinity)};var p=function(R,Q){return function(Z){var X=arguments.length;if(X<2||Z==null){return Z}for(var T=1;T<X;T++){var Y=arguments[T],W=R(Y),S=W.length;for(var V=0;V<S;V++){var U=W[V];if(!Q||Z[U]===void 0){Z[U]=Y[U]}}}return Z}};var C=function(R){if(!P.isObject(R)){return{}}if(B){return B(R)}E.prototype=R;var Q=new E;E.prototype=null;return Q};var M=function(Q){return function(R){return R==null?void 0:R[Q]}};var K=Math.pow(2,53)-1;var O=M("length");var D=function(R){var Q=O(R);return typeof Q=="number"&&Q>=0&&Q<=K};P.each=P.forEach=function(U,V,R){V=b(V,R);var Q,T;if(D(U)){for(Q=0,T=U.length;Q<T;Q++){V(U[Q],Q,U)}}else{var S=P.keys(U);for(Q=0,T=S.length;Q<T;Q++){V(U[S[Q]],S[Q],U)}}return U};P.map=P.collect=function(V,X,S){X=F(X,S);var U=!D(V)&&P.keys(V),T=(U||V).length,R=Array(T);for(var Q=0;Q<T;Q++){var W=U?U[Q]:Q;R[Q]=X(V[W],W,V)}return R};function z(Q){function R(W,Y,S,V,T,U){for(;T>=0&&T<U;T+=Q){var X=V?V[T]:T;S=Y(S,W[X],X,W)}return S}return function(X,Y,S,U){Y=b(Y,U,4);var W=!D(X)&&P.keys(X),V=(W||X).length,T=Q>0?0:V-1;if(arguments.length<3){S=X[W?W[T]:T];T+=Q}return R(X,Y,S,W,T,V)}}P.reduce=P.foldl=P.inject=z(1);P.reduceRight=P.foldr=z(-1);P.find=P.detect=function(T,Q,S){var R;if(D(T)){R=P.findIndex(T,Q,S)}else{R=P.findKey(T,Q,S)}if(R!==void 0&&R!==-1){return T[R]}};P.filter=P.select=function(T,Q,S){var R=[];Q=F(Q,S);P.each(T,function(W,U,V){if(Q(W,U,V)){R.push(W)}});return R};P.reject=function(S,Q,R){return P.filter(S,P.negate(F(Q)),R)};P.every=P.all=function(V,Q,S){Q=F(Q,S);var U=!D(V)&&P.keys(V),T=(U||V).length;for(var R=0;R<T;R++){var W=U?U[R]:R;if(!Q(V[W],W,V)){return false}}return true};P.some=P.any=function(V,Q,S){Q=F(Q,S);var U=!D(V)&&P.keys(V),T=(U||V).length;for(var R=0;R<T;R++){var W=U?U[R]:R;if(Q(V[W],W,V)){return true}}return false};P.contains=P.includes=P.include=function(T,S,Q,R){if(!D(T)){T=P.values(T)}if(typeof Q!="number"||R){Q=0}return P.indexOf(T,S,Q)>=0};P.invoke=function(S,T){var Q=l.call(arguments,2);var R=P.isFunction(T);return P.map(S,function(V){var U=R?T:V[T];return U==null?U:U.apply(V,Q)})};P.pluck=function(R,Q){return P.map(R,P.property(Q))};P.where=function(R,Q){return P.filter(R,P.matcher(Q))};P.findWhere=function(R,Q){return P.find(R,P.matcher(Q))};P.max=function(T,V,Q){var Y=-Infinity,W=-Infinity,X,S;if(V==null&&T!=null){T=D(T)?T:P.values(T);for(var U=0,R=T.length;U<R;U++){X=T[U];if(X>Y){Y=X}}}else{V=F(V,Q);P.each(T,function(ab,Z,aa){S=V(ab,Z,aa);if(S>W||S===-Infinity&&Y===-Infinity){Y=ab;W=S}})}return Y};P.min=function(T,V,Q){var Y=Infinity,W=Infinity,X,S;if(V==null&&T!=null){T=D(T)?T:P.values(T);for(var U=0,R=T.length;U<R;U++){X=T[U];if(X<Y){Y=X}}}else{V=F(V,Q);P.each(T,function(ab,Z,aa){S=V(ab,Z,aa);if(S<W||S===Infinity&&Y===Infinity){Y=ab;W=S}})}return Y};P.shuffle=function(U){var V=D(U)?U:P.values(U);var T=V.length;var Q=Array(T);for(var R=0,S;R<T;R++){S=P.random(0,R);if(S!==R){Q[R]=Q[S]}Q[S]=V[R]}return Q};P.sample=function(R,S,Q){if(S==null||Q){if(!D(R)){R=P.values(R)}return R[P.random(R.length-1)]}return P.shuffle(R).slice(0,Math.max(0,S))};P.sortBy=function(R,S,Q){S=F(S,Q);return P.pluck(P.map(R,function(V,T,U){return{value:V,index:T,criteria:S(V,T,U)}}).sort(function(W,V){var U=W.criteria;var T=V.criteria;if(U!==T){if(U>T||U===void 0){return 1}if(U<T||T===void 0){return -1}}return W.index-V.index}),"value")};var q=function(Q){return function(T,U,S){var R={};U=F(U,S);P.each(T,function(X,V){var W=U(X,V,T);Q(R,X,W)});return R}};P.groupBy=q(function(Q,S,R){if(P.has(Q,R)){Q[R].push(S)}else{Q[R]=[S]}});P.indexBy=q(function(Q,S,R){Q[R]=S});P.countBy=q(function(Q,S,R){if(P.has(Q,R)){Q[R]++}else{Q[R]=1}});P.toArray=function(Q){if(!Q){return[]}if(P.isArray(Q)){return l.call(Q)}if(D(Q)){return P.map(Q,P.identity)}return P.values(Q)};P.size=function(Q){if(Q==null){return 0}return D(Q)?Q.length:P.keys(Q).length};P.partition=function(U,Q,S){Q=F(Q,S);var T=[],R=[];P.each(U,function(W,V,X){(Q(W,V,X)?T:R).push(W)});return[T,R]};P.first=P.head=P.take=function(S,R,Q){if(S==null){return void 0}if(R==null||Q){return S[0]}return P.initial(S,S.length-R)};P.initial=function(S,R,Q){return l.call(S,0,Math.max(0,S.length-(R==null||Q?1:R)))};P.last=function(S,R,Q){if(S==null){return void 0}if(R==null||Q){return S[S.length-1]}return P.rest(S,Math.max(0,S.length-R))};P.rest=P.tail=P.drop=function(S,R,Q){return l.call(S,R==null||Q?1:R)};P.compact=function(Q){return P.filter(Q,P.identity)};var x=function(W,S,X,aa){var R=[],Z=0;for(var U=aa||0,Q=O(W);U<Q;U++){var Y=W[U];if(D(Y)&&(P.isArray(Y)||P.isArguments(Y))){if(!S){Y=x(Y,S,X)}var T=0,V=Y.length;R.length+=V;while(T<V){R[Z++]=Y[T++]}}else{if(!X){R[Z++]=Y}}}return R};P.flatten=function(R,Q){return x(R,Q,false)};P.without=function(Q){return P.difference(Q,l.call(arguments,1))};P.uniq=P.unique=function(X,T,W,R){if(!P.isBoolean(T)){R=W;W=T;T=false}if(W!=null){W=F(W,R)}var Z=[];var Q=[];for(var V=0,S=O(X);V<S;V++){var Y=X[V],U=W?W(Y,V,X):Y;if(T){if(!V||Q!==U){Z.push(Y)}Q=U}else{if(W){if(!P.contains(Q,U)){Q.push(U);Z.push(Y)}}else{if(!P.contains(Z,Y)){Z.push(Y)}}}}return Z};P.union=function(){return P.uniq(x(arguments,true,true))};P.intersection=function(W){var Q=[];var V=arguments.length;for(var S=0,U=O(W);S<U;S++){var T=W[S];if(P.contains(Q,T)){continue}for(var R=1;R<V;R++){if(!P.contains(arguments[R],T)){break}}if(R===V){Q.push(T)}}return Q};P.difference=function(R){var Q=x(arguments,true,true,1);return P.filter(R,function(S){return !P.contains(Q,S)})};P.zip=function(){return P.unzip(arguments)};P.unzip=function(T){var S=T&&P.max(T,O).length||0;var Q=Array(S);for(var R=0;R<S;R++){Q[R]=P.pluck(T,R)}return Q};P.object=function(U,R){var Q={};for(var S=0,T=O(U);S<T;S++){if(R){Q[U[S]]=R[S]}else{Q[U[S][0]]=U[S][1]}}return Q};function u(Q){return function(V,R,T){R=F(R,T);var U=O(V);var S=Q>0?0:U-1;for(;S>=0&&S<U;S+=Q){if(R(V[S],S,V)){return S}}return -1}}P.findIndex=u(1);P.findLastIndex=u(-1);P.sortedIndex=function(X,V,W,S){W=F(W,S,1);var U=W(V);var Q=0,T=O(X);while(Q<T){var R=Math.floor((Q+T)/2);if(W(X[R])<U){Q=R+1}else{T=R}}return Q};function f(Q,R,S){return function(X,W,T){var U=0,V=O(X);if(typeof T=="number"){if(Q>0){U=T>=0?T:Math.max(T+V,U)}else{V=T>=0?Math.min(T+1,V):T+V+1}}else{if(S&&T&&V){T=S(X,W);return X[T]===W?T:-1}}if(W!==W){T=R(l.call(X,U,V),P.isNaN);return T>=0?T+U:-1}for(T=Q>0?U:V-1;T>=0&&T<V;T+=Q){if(X[T]===W){return T}}return -1}}P.indexOf=f(1,P.findIndex,P.sortedIndex);P.lastIndexOf=f(-1,P.findLastIndex);P.range=function(V,S,U){if(S==null){S=V||0;V=0}U=U||1;var T=Math.max(Math.ceil((S-V)/U),0);var R=Array(T);for(var Q=0;Q<T;Q++,V+=U){R[Q]=V}return R};var y=function(V,S,U,W,T){if(!(W instanceof S)){return V.apply(U,T)}var R=C(V.prototype);var Q=V.apply(R,T);if(P.isObject(Q)){return Q}return R};P.bind=function(T,R){if(J&&T.bind===J){return J.apply(T,l.call(arguments,1))}if(!P.isFunction(T)){throw new TypeError("Bind must be called on a function")}var Q=l.call(arguments,2);var S=function(){return y(T,S,R,this,Q.concat(l.call(arguments)))};return S};P.partial=function(R){var S=l.call(arguments,1);var Q=function(){var T=0,W=S.length;var U=Array(W);for(var V=0;V<W;V++){U[V]=S[V]===P?arguments[T++]:S[V]}while(T<arguments.length){U.push(arguments[T++])}return y(R,Q,this,this,U)};return Q};P.bindAll=function(T){var R,S=arguments.length,Q;if(S<=1){throw new Error("bindAll must be passed function names")}for(R=1;R<S;R++){Q=arguments[R];T[Q]=P.bind(T[Q],T)}return T};P.memoize=function(R,Q){var S=function(V){var U=S.cache;var T=""+(Q?Q.apply(this,arguments):V);if(!P.has(U,T)){U[T]=R.apply(this,arguments)}return U[T]};S.cache={};return S};P.delay=function(R,S){var Q=l.call(arguments,2);return setTimeout(function(){return R.apply(null,Q)},S)};P.defer=P.partial(P.delay,P,1);P.throttle=function(R,T,X){var Q,V,Y;var W=null;var U=0;if(!X){X={}}var S=function(){U=X.leading===false?0:P.now();W=null;Y=R.apply(Q,V);if(!W){Q=V=null}};return function(){var Z=P.now();if(!U&&X.leading===false){U=Z}var aa=T-(Z-U);Q=this;V=arguments;if(aa<=0||aa>T){if(W){clearTimeout(W);W=null}U=Z;Y=R.apply(Q,V);if(!W){Q=V=null}}else{if(!W&&X.trailing!==false){W=setTimeout(S,aa)}}return Y}};P.debounce=function(S,U,R){var X,W,Q,V,Y;var T=function(){var Z=P.now()-V;if(Z<U&&Z>=0){X=setTimeout(T,U-Z)}else{X=null;if(!R){Y=S.apply(Q,W);if(!X){Q=W=null}}}};return function(){Q=this;W=arguments;V=P.now();var Z=R&&!X;if(!X){X=setTimeout(T,U)}if(Z){Y=S.apply(Q,W);Q=W=null}return Y}};P.wrap=function(Q,R){return P.partial(R,Q)};P.negate=function(Q){return function(){return !Q.apply(this,arguments)}};P.compose=function(){var Q=arguments;var R=Q.length-1;return function(){var T=R;var S=Q[R].apply(this,arguments);while(T--){S=Q[T].call(this,S)}return S}};P.after=function(R,Q){return function(){if(--R<1){return Q.apply(this,arguments)}}};P.before=function(S,R){var Q;return function(){if(--S>0){Q=R.apply(this,arguments)}if(S<=1){R=null}return Q}};P.once=P.partial(P.before,2);var G=!{toString:null}.propertyIsEnumerable("toString");var a=["valueOf","isPrototypeOf","toString","propertyIsEnumerable","hasOwnProperty","toLocaleString"];function d(U,T){var Q=a.length;var R=U.constructor;var S=(P.isFunction(R)&&R.prototype)||g;var V="constructor";if(P.has(U,V)&&!P.contains(T,V)){T.push(V)}while(Q--){V=a[Q];if(V in U&&U[V]!==S[V]&&!P.contains(T,V)){T.push(V)}}}P.keys=function(S){if(!P.isObject(S)){return[]}if(e){return e(S)}var R=[];for(var Q in S){if(P.has(S,Q)){R.push(Q)}}if(G){d(S,R)}return R};P.allKeys=function(S){if(!P.isObject(S)){return[]}var R=[];for(var Q in S){R.push(Q)}if(G){d(S,R)}return R};P.values=function(U){var T=P.keys(U);var S=T.length;var Q=Array(S);for(var R=0;R<S;R++){Q[R]=U[T[R]]}return Q};P.mapObject=function(V,X,S){X=F(X,S);var U=P.keys(V),T=U.length,R={},W;for(var Q=0;Q<T;Q++){W=U[Q];R[W]=X(V[W],W,V)}return R};P.pairs=function(U){var S=P.keys(U);var R=S.length;var T=Array(R);for(var Q=0;Q<R;Q++){T[Q]=[S[Q],U[S[Q]]]}return T};P.invert=function(U){var Q={};var T=P.keys(U);for(var R=0,S=T.length;R<S;R++){Q[U[T[R]]]=T[R]}return Q};P.functions=P.methods=function(S){var R=[];for(var Q in S){if(P.isFunction(S[Q])){R.push(Q)}}return R.sort()};P.extend=p(P.allKeys);P.extendOwn=P.assign=p(P.keys);P.findKey=function(W,Q,T){Q=F(Q,T);var V=P.keys(W),S;for(var R=0,U=V.length;R<U;R++){S=V[R];if(Q(W[S],S,W)){return S}}};P.pick=function(S,W,Q){var aa={},T=S,V,Z;if(T==null){return aa}if(P.isFunction(W)){Z=P.allKeys(T);V=b(W,Q)}else{Z=x(arguments,false,false,1);V=function(ac,ab,ad){return ab in ad};T=Object(T)}for(var U=0,R=Z.length;U<R;U++){var Y=Z[U];var X=T[Y];if(V(X,Y,T)){aa[Y]=X}}return aa};P.omit=function(S,T,Q){if(P.isFunction(T)){T=P.negate(T)}else{var R=P.map(x(arguments,false,false,1),String);T=function(V,U){return !P.contains(R,U)}}return P.pick(S,T,Q)};P.defaults=p(P.allKeys,true);P.create=function(R,S){var Q=C(R);if(S){P.extendOwn(Q,S)}return Q};P.clone=function(Q){if(!P.isObject(Q)){return Q}return P.isArray(Q)?Q.slice():P.extend({},Q)};P.tap=function(R,Q){Q(R);return R};P.isMatch=function(R,Q){var V=P.keys(Q),U=V.length;if(R==null){return !U}var W=Object(R);for(var T=0;T<U;T++){var S=V[T];if(Q[S]!==W[S]||!(S in W)){return false}}return true};var N=function(Y,X,R,T){if(Y===X){return Y!==0||1/Y===1/X}if(Y==null||X==null){return Y===X}if(Y instanceof P){Y=Y._wrapped}if(X instanceof P){X=X._wrapped}var V=c.call(Y);if(V!==c.call(X)){return false}switch(V){case"[object RegExp]":case"[object String]":return""+Y===""+X;case"[object Number]":if(+Y!==+Y){return +X!==+X}return +Y===0?1/+Y===1/X:+Y===+X;case"[object Date]":case"[object Boolean]":return +Y===+X}var S=V==="[object Array]";if(!S){if(typeof Y!="object"||typeof X!="object"){return false}var W=Y.constructor,U=X.constructor;if(W!==U&&!(P.isFunction(W)&&W instanceof W&&P.isFunction(U)&&U instanceof U)&&("constructor" in Y&&"constructor" in X)){return false}}R=R||[];T=T||[];var Q=R.length;while(Q--){if(R[Q]===Y){return T[Q]===X}}R.push(Y);T.push(X);if(S){Q=Y.length;if(Q!==X.length){return false}while(Q--){if(!N(Y[Q],X[Q],R,T)){return false}}}else{var aa=P.keys(Y),Z;Q=aa.length;if(P.keys(X).length!==Q){return false}while(Q--){Z=aa[Q];if(!(P.has(X,Z)&&N(Y[Z],X[Z],R,T))){return false}}}R.pop();T.pop();return true};P.isEqual=function(R,Q){return N(R,Q)};P.isEmpty=function(Q){if(Q==null){return true}if(D(Q)&&(P.isArray(Q)||P.isString(Q)||P.isArguments(Q))){return Q.length===0}return P.keys(Q).length===0};P.isElement=function(Q){return !!(Q&&Q.nodeType===1)};P.isArray=s||function(Q){return c.call(Q)==="[object Array]"};P.isObject=function(R){var Q=typeof R;return Q==="function"||Q==="object"&&!!R};P.each(["Arguments","Function","String","Number","Date","RegExp","Error"],function(Q){P["is"+Q]=function(R){return c.call(R)==="[object "+Q+"]"}});if(!P.isArguments(arguments)){P.isArguments=function(Q){return P.has(Q,"callee")}}if(typeof/./!="function"&&typeof Int8Array!="object"){P.isFunction=function(Q){return typeof Q=="function"||false}}P.isFinite=function(Q){return isFinite(Q)&&!isNaN(parseFloat(Q))};P.isNaN=function(Q){return P.isNumber(Q)&&Q!==+Q};P.isBoolean=function(Q){return Q===true||Q===false||c.call(Q)==="[object Boolean]"};P.isNull=function(Q){return Q===null};P.isUndefined=function(Q){return Q===void 0};P.has=function(R,Q){return R!=null&&j.call(R,Q)};P.noConflict=function(){v._=k;return this};P.identity=function(Q){return Q};P.constant=function(Q){return function(){return Q}};P.noop=function(){};P.property=M;P.propertyOf=function(Q){return Q==null?function(){}:function(R){return Q[R]}};P.matcher=P.matches=function(Q){Q=P.extendOwn({},Q);return function(R){return P.isMatch(R,Q)}};P.times=function(U,T,S){var Q=Array(Math.max(0,U));T=b(T,S,1);for(var R=0;R<U;R++){Q[R]=T(R)}return Q};P.random=function(R,Q){if(Q==null){Q=R;R=0}return R+Math.floor(Math.random()*(Q-R+1))};P.now=Date.now||function(){return new Date().getTime()};var r={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","`":"&#x60;"};var m=P.invert(r);var w=function(U){var R=function(V){return U[V]};var T="(?:"+P.keys(U).join("|")+")";var S=RegExp(T);var Q=RegExp(T,"g");return function(V){V=V==null?"":""+V;return S.test(V)?V.replace(Q,R):V}};P.escape=w(r);P.unescape=w(m);P.result=function(Q,S,T){var R=Q==null?void 0:Q[S];if(R===void 0){R=T}return P.isFunction(R)?R.call(Q):R};var A=0;P.uniqueId=function(Q){var R=++A+"";return Q?Q+R:R};P.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var t=/(.)^/;var h={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"};var i=/\\|'|\r|\n|\u2028|\u2029/g;var H=function(Q){return"\\"+h[Q]};P.template=function(Z,T,W){if(!T&&W){T=W}T=P.defaults({},T,P.templateSettings);var U=RegExp([(T.escape||t).source,(T.interpolate||t).source,(T.evaluate||t).source].join("|")+"|$","g");var V=0;var Q="__p+='";Z.replace(U,function(ab,ac,aa,ae,ad){Q+=Z.slice(V,ad).replace(i,H);V=ad+ab.length;if(ac){Q+="'+\n((__t=("+ac+"))==null?'':_.escape(__t))+\n'"}else{if(aa){Q+="'+\n((__t=("+aa+"))==null?'':__t)+\n'"}else{if(ae){Q+="';\n"+ae+"\n__p+='"}}}return ab});Q+="';\n";if(!T.variable){Q="with(obj||{}){\n"+Q+"}\n"}Q="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+Q+"return __p;\n";try{var S=new Function(T.variable||"obj","_",Q)}catch(X){X.source=Q;throw X}var Y=function(aa){return S.call(this,aa,P)};var R=T.variable||"obj";Y.source="function("+R+"){\n"+Q+"}";return Y};P.chain=function(R){var Q=P(R);Q._chain=true;return Q};var o=function(Q,R){return Q._chain?P(R).chain():R};P.mixin=function(Q){P.each(P.functions(Q),function(R){var S=P[R]=Q[R];P.prototype[R]=function(){var T=[this._wrapped];L.apply(T,arguments);return o(this,S.apply(P,T))}})};P.mixin(P);P.each(["pop","push","reverse","shift","sort","splice","unshift"],function(Q){var R=I[Q];P.prototype[Q]=function(){var S=this._wrapped;R.apply(S,arguments);if((Q==="shift"||Q==="splice")&&S.length===0){delete S[0]}return o(this,S)}});P.each(["concat","join","slice"],function(Q){var R=I[Q];P.prototype[Q]=function(){return o(this,R.apply(this._wrapped,arguments))}});P.prototype.value=function(){return this._wrapped};P.prototype.valueOf=P.prototype.toJSON=P.prototype.value;P.prototype.toString=function(){return""+this._wrapped};if(typeof define==="function"&&define.amd){define("underscore",[],function(){return P})}}.call(this));
WRFILE: bootstrap.min.css

/*!
 * Bootstrap v3.3.7 (http://getbootstrap.com)
 * Copyright 2011-2016 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,*:before,*:after{color:#000 !important;text-shadow:none !important;background:transparent !important;-webkit-box-shadow:none !important;box-shadow:none !important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000 !important}.label{border:1px solid #000}.table{border-collapse:collapse !important}.table td,.table th{background-color:#fff !important}.table-bordered th,.table-bordered td{border:1px solid #ddd !important}}@font-face{font-family:'Glyphicons Halflings';src:url('../fonts/glyphicons-halflings-regular.eot');src:url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'),url('../fonts/glyphicons-halflings-regular.woff') format('woff'),url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'),url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-euro:before,.glyphicon-eur:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:hover,a:focus{color:#23527c;text-decoration:underline}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive,.thumbnail>img,.thumbnail a>img,.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role="button"]{cursor:pointer}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:normal;line-height:1;color:#777}h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10px;margin-bottom:10px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media(min-width:768px){.lead{font-size:21px}}small,.small{font-size:85%}mark,.mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:hover,a.text-primary:focus{color:#286090}.text-success{color:#3c763d}a.text-success:hover,a.text-success:focus{color:#2b542c}.text-info{color:#31708f}a.text-info:hover,a.text-info:focus{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover,a.text-warning:focus{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover,a.text-danger:focus{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:hover,a.bg-primary:focus{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:hover,a.bg-success:focus{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover,a.bg-info:focus{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover,a.bg-warning:focus{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover,a.bg-danger:focus{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.42857143}dt{font-weight:bold}dd{margin-left:0}@media(min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:bold;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media(min-width:768px){.container{width:750px}}@media(min-width:992px){.container{width:970px}}@media(min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media(min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media(min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media(min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*="col-"]{position:static;display:table-column;float:none}table td[class*="col-"],table th[class*="col-"]{position:static;display:table-cell;float:none}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:bold}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type="file"]{display:block}input[type="range"]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{background-color:transparent;border:0}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type="search"]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type="date"].form-control,input[type="time"].form-control,input[type="datetime-local"].form-control,input[type="month"].form-control{line-height:34px}input[type="date"].input-sm,input[type="time"].input-sm,input[type="datetime-local"].input-sm,input[type="month"].input-sm,.input-group-sm input[type="date"],.input-group-sm input[type="time"],.input-group-sm input[type="datetime-local"],.input-group-sm input[type="month"]{line-height:30px}input[type="date"].input-lg,input[type="time"].input-lg,input[type="datetime-local"].input-lg,input[type="month"].input-lg,.input-group-lg input[type="date"],.input-group-lg input[type="time"],.input-group-lg input[type="datetime-local"],.input-group-lg input[type="month"]{line-height:46px}}.form-group{margin-bottom:15px}.radio,.checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.radio label,.checkbox label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:normal;cursor:pointer}.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{position:absolute;margin-top:4px \9;margin-left:-20px}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:normal;vertical-align:middle;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"].disabled,input[type="checkbox"].disabled,fieldset[disabled] input[type="radio"],fieldset[disabled] input[type="checkbox"]{cursor:not-allowed}.radio-inline.disabled,.checkbox-inline.disabled,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.radio.disabled label,.checkbox.disabled label,fieldset[disabled] .radio label,fieldset[disabled] .checkbox label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}textarea.input-sm,select[multiple].input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm textarea.form-control,.form-group-sm select[multiple].form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}textarea.input-lg,select[multiple].input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg textarea.form-control,.form-group-lg select[multiple].form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback,.input-group-lg+.form-control-feedback,.form-group-lg .form-control+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback,.input-group-sm+.form-control-feedback,.form-group-sm .form-control+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline,.has-success.radio label,.has-success.checkbox label,.has-success.radio-inline label,.has-success.checkbox-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline,.has-warning.radio label,.has-warning.checkbox label,.has-warning.radio-inline label,.has-warning.checkbox-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline,.has-error.radio label,.has-error.checkbox label,.has-error.radio-inline label,.has-error.checkbox-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label ~ .form-control-feedback{top:25px}.has-feedback label.sr-only ~ .form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media(min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn,.form-inline .input-group .form-control{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .radio label,.form-inline .checkbox label{padding-left:0}.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media(min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media(min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media(min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:normal;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn:focus,.btn:active:focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn.active.focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus,.btn.focus{color:#333;text-decoration:none}.btn:active,.btn.active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:focus,.btn-default.focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default:active:hover,.btn-default.active:hover,.open>.dropdown-toggle.btn-default:hover,.btn-default:active:focus,.btn-default.active:focus,.open>.dropdown-toggle.btn-default:focus,.btn-default:active.focus,.btn-default.active.focus,.open>.dropdown-toggle.btn-default.focus{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled.focus,.btn-default[disabled].focus,fieldset[disabled] .btn-default.focus{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary:focus,.btn-primary.focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary:active:hover,.btn-primary.active:hover,.open>.dropdown-toggle.btn-primary:hover,.btn-primary:active:focus,.btn-primary.active:focus,.open>.dropdown-toggle.btn-primary:focus,.btn-primary:active.focus,.btn-primary.active.focus,.open>.dropdown-toggle.btn-primary.focus{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled.focus,.btn-primary[disabled].focus,fieldset[disabled] .btn-primary.focus{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:focus,.btn-success.focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success:active:hover,.btn-success.active:hover,.open>.dropdown-toggle.btn-success:hover,.btn-success:active:focus,.btn-success.active:focus,.open>.dropdown-toggle.btn-success:focus,.btn-success:active.focus,.btn-success.active.focus,.open>.dropdown-toggle.btn-success.focus{color:#fff;background-color:#398439;border-color:#255625}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled.focus,.btn-success[disabled].focus,fieldset[disabled] .btn-success.focus{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:focus,.btn-info.focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info:active:hover,.btn-info.active:hover,.open>.dropdown-toggle.btn-info:hover,.btn-info:active:focus,.btn-info.active:focus,.open>.dropdown-toggle.btn-info:focus,.btn-info:active.focus,.btn-info.active.focus,.open>.dropdown-toggle.btn-info.focus{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled.focus,.btn-info[disabled].focus,fieldset[disabled] .btn-info.focus{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:focus,.btn-warning.focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning:active:hover,.btn-warning.active:hover,.open>.dropdown-toggle.btn-warning:hover,.btn-warning:active:focus,.btn-warning.active:focus,.open>.dropdown-toggle.btn-warning:focus,.btn-warning:active.focus,.btn-warning.active.focus,.open>.dropdown-toggle.btn-warning.focus{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled.focus,.btn-warning[disabled].focus,fieldset[disabled] .btn-warning.focus{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:focus,.btn-danger.focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger:active:hover,.btn-danger.active:hover,.open>.dropdown-toggle.btn-danger:hover,.btn-danger:active:focus,.btn-danger.active:focus,.open>.dropdown-toggle.btn-danger:focus,.btn-danger:active.focus,.btn-danger.active.focus,.open>.dropdown-toggle.btn-danger.focus{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled.focus,.btn-danger[disabled].focus,fieldset[disabled] .btn-danger.focus{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:normal;color:#337ab7;border-radius:0}.btn-link,.btn-link:active,.btn-link.active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#777;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-sm,.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs,.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid \9;border-right:4px solid transparent;border-left:4px solid transparent}.dropup,.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#777}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid \9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media(min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle="buttons"]>.btn input[type="radio"],[data-toggle="buttons"]>.btn-group>.btn input[type="radio"],[data-toggle="buttons"]>.btn input[type="checkbox"],[data-toggle="buttons"]>.btn-group>.btn input[type="checkbox"]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*="col-"]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:normal;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type="radio"],.input-group-addon input[type="checkbox"]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media(min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #ddd}@media(min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media(min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #ddd}@media(min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media(min-width:768px){.navbar{border-radius:4px}}@media(min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media(min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block !important;height:auto !important;padding-bottom:0;overflow:visible !important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:340px}@media(max-device-width:480px) and (orientation:landscape){.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:200px}}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media(min-width:768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media(min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}@media(min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}.navbar-brand>img{display:block}@media(min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media(min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media(max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media(min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media(min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn,.navbar-form .input-group .form-control{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .radio label,.navbar-form .checkbox label{padding-left:0}.navbar-form .radio input[type="radio"],.navbar-form .checkbox input[type="checkbox"]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media(max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media(min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media(min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media(min-width:768px){.navbar-left{float:left !important}.navbar-right{float:right !important;margin-right:-15px}.navbar-right ~ .navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{color:#555;background-color:#e7e7e7}@media(max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:hover,.navbar-default .btn-link:focus{color:#333}.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:hover,.navbar-default .btn-link[disabled]:focus,fieldset[disabled] .navbar-default .btn-link:focus{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{color:#fff;background-color:#080808}@media(max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:hover,.navbar-inverse .btn-link:focus{color:#fff}.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:hover,.navbar-inverse .btn-link[disabled]:focus,fieldset[disabled] .navbar-inverse .btn-link:focus{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:3;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:bold;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:hover,a.label:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:hover,.label-default[href]:focus{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:bold;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge,.btn-group-xs>.btn .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron h1,.jumbotron .h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{padding-right:15px;padding-left:15px;border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron h1,.jumbotron .h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail>img,.thumbnail a>img{margin-right:auto;margin-left:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:bold}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-striped .progress-bar,.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress.active .progress-bar,.progress-bar.active{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-left,.media-right,.media-body{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,button.list-group-item:hover,a.list-group-item:focus,button.list-group-item:focus{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:hover,.list-group-item.disabled:focus{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>.small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:hover .list-group-item-text,.list-group-item.active:focus .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:hover,button.list-group-item-success:hover,a.list-group-item-success:focus,button.list-group-item-success:focus{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,button.list-group-item-success.active,a.list-group-item-success.active:hover,button.list-group-item-success.active:hover,a.list-group-item-success.active:focus,button.list-group-item-success.active:focus{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:hover,button.list-group-item-info:hover,a.list-group-item-info:focus,button.list-group-item-info:focus{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,button.list-group-item-info.active,a.list-group-item-info.active:hover,button.list-group-item-info.active:hover,a.list-group-item-info.active:focus,button.list-group-item-info.active:focus{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:hover,button.list-group-item-warning:hover,a.list-group-item-warning:focus,button.list-group-item-warning:focus{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,button.list-group-item-warning.active,a.list-group-item-warning.active:hover,button.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus,button.list-group-item-warning.active:focus{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:hover,button.list-group-item-danger:hover,a.list-group-item-danger:focus,button.list-group-item-danger:focus{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,button.list-group-item-danger.active,a.list-group-item-danger.active:hover,button.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus,button.list-group-item-danger.active:focus{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>a,.panel-title>small,.panel-title>.small,.panel-title>small>a,.panel-title>.small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.table,.panel>.table-responsive>.table,.panel>.panel-collapse>.table{margin-bottom:0}.panel>.table caption,.panel>.table-responsive>.table caption,.panel>.panel-collapse>.table caption{padding-right:15px;padding-left:15px}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.panel-body,.panel-group .panel-heading+.panel-collapse>.list-group{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive iframe,.embed-responsive embed,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:bold;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:transparent;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media(min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media(min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-style:normal;font-weight:normal;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:normal;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.next,.carousel-inner>.item.active.right{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.prev,.carousel-inner>.item.active.left{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right,.carousel-inner>.item.active{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);background-color:rgba(0,0,0,0);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000',endColorstr='#00000000',GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000',endColorstr='#80000000',GradientType=1);background-repeat:repeat-x}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%;margin-left:-10px}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%;margin-right:-10px}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after,.dl-horizontal dd:before,.dl-horizontal dd:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.panel-body:before,.panel-body:after,.modal-header:before,.modal-header:after,.modal-footer:before,.modal-footer:after{display:table;content:" "}.clearfix:after,.dl-horizontal dd:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.panel-body:after,.modal-header:after,.modal-footer:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right !important}.pull-left{float:left !important}.hide{display:none !important}.show{display:block !important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none !important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none !important}.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block{display:none !important}@media(max-width:767px){.visible-xs{display:block !important}table.visible-xs{display:table !important}tr.visible-xs{display:table-row !important}th.visible-xs,td.visible-xs{display:table-cell !important}}@media(max-width:767px){.visible-xs-block{display:block !important}}@media(max-width:767px){.visible-xs-inline{display:inline !important}}@media(max-width:767px){.visible-xs-inline-block{display:inline-block !important}}@media(min-width:768px) and (max-width:991px){.visible-sm{display:block !important}table.visible-sm{display:table !important}tr.visible-sm{display:table-row !important}th.visible-sm,td.visible-sm{display:table-cell !important}}@media(min-width:768px) and (max-width:991px){.visible-sm-block{display:block !important}}@media(min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline !important}}@media(min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block !important}}@media(min-width:992px) and (max-width:1199px){.visible-md{display:block !important}table.visible-md{display:table !important}tr.visible-md{display:table-row !important}th.visible-md,td.visible-md{display:table-cell !important}}@media(min-width:992px) and (max-width:1199px){.visible-md-block{display:block !important}}@media(min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline !important}}@media(min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block !important}}@media(min-width:1200px){.visible-lg{display:block !important}table.visible-lg{display:table !important}tr.visible-lg{display:table-row !important}th.visible-lg,td.visible-lg{display:table-cell !important}}@media(min-width:1200px){.visible-lg-block{display:block !important}}@media(min-width:1200px){.visible-lg-inline{display:inline !important}}@media(min-width:1200px){.visible-lg-inline-block{display:inline-block !important}}@media(max-width:767px){.hidden-xs{display:none !important}}@media(min-width:768px) and (max-width:991px){.hidden-sm{display:none !important}}@media(min-width:992px) and (max-width:1199px){.hidden-md{display:none !important}}@media(min-width:1200px){.hidden-lg{display:none !important}}.visible-print{display:none !important}@media print{.visible-print{display:block !important}table.visible-print{display:table !important}tr.visible-print{display:table-row !important}th.visible-print,td.visible-print{display:table-cell !important}}.visible-print-block{display:none !important}@media print{.visible-print-block{display:block !important}}.visible-print-inline{display:none !important}@media print{.visible-print-inline{display:inline !important}}.visible-print-inline-block{display:none !important}@media print{.visible-print-inline-block{display:inline-block !important}}@media print{.hidden-print{display:none !important}}
WRFILE: bootstrap-datetimepicker.min.css

/*!
 * Datetimepicker for Bootstrap
 *
 * Copyright 2012 Stefan Petre
 * Improvements by Andrew Rowls
 * Licensed under the Apache License v2.0
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 */.datetimepicker{padding:4px;margin-top:1px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;direction:ltr}.datetimepicker-inline{width:220px}.datetimepicker.datetimepicker-rtl{direction:rtl}.datetimepicker.datetimepicker-rtl table tr td span{float:right}.datetimepicker-dropdown,.datetimepicker-dropdown-left{top:0;left:0}[class*=" datetimepicker-dropdown"]:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:rgba(0,0,0,0.2);position:absolute}[class*=" datetimepicker-dropdown"]:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #fff;position:absolute}[class*=" datetimepicker-dropdown-top"]:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-top:7px solid #ccc;border-top-color:rgba(0,0,0,0.2);border-bottom:0}[class*=" datetimepicker-dropdown-top"]:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid #fff;border-bottom:0}.datetimepicker-dropdown-bottom-left:before{top:-7px;right:6px}.datetimepicker-dropdown-bottom-left:after{top:-6px;right:7px}.datetimepicker-dropdown-bottom-right:before{top:-7px;left:6px}.datetimepicker-dropdown-bottom-right:after{top:-6px;left:7px}.datetimepicker-dropdown-top-left:before{bottom:-7px;right:6px}.datetimepicker-dropdown-top-left:after{bottom:-6px;right:7px}.datetimepicker-dropdown-top-right:before{bottom:-7px;left:6px}.datetimepicker-dropdown-top-right:after{bottom:-6px;left:7px}.datetimepicker>div{display:none}.datetimepicker.minutes div.datetimepicker-minutes{display:block}.datetimepicker.hours div.datetimepicker-hours{display:block}.datetimepicker.days div.datetimepicker-days{display:block}.datetimepicker.months div.datetimepicker-months{display:block}.datetimepicker.years div.datetimepicker-years{display:block}.datetimepicker table{margin:0}.datetimepicker td,.datetimepicker th{text-align:center;width:20px;height:20px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;border:0}.table-striped .datetimepicker table tr td,.table-striped .datetimepicker table tr th{background-color:transparent}.datetimepicker table tr td.minute:hover{background:#eee;cursor:pointer}.datetimepicker table tr td.hour:hover{background:#eee;cursor:pointer}.datetimepicker table tr td.day:hover{background:#eee;cursor:pointer}.datetimepicker table tr td.old,.datetimepicker table tr td.new{color:#999}.datetimepicker table tr td.disabled,.datetimepicker table tr td.disabled:hover{background:0;color:#999;cursor:default}.datetimepicker table tr td.today,.datetimepicker table tr td.today:hover,.datetimepicker table tr td.today.disabled,.datetimepicker table tr td.today.disabled:hover{background-color:#fde19a;background-image:-moz-linear-gradient(top,#fdd49a,#fdf59a);background-image:-ms-linear-gradient(top,#fdd49a,#fdf59a);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fdd49a),to(#fdf59a));background-image:-webkit-linear-gradient(top,#fdd49a,#fdf59a);background-image:-o-linear-gradient(top,#fdd49a,#fdf59a);background-image:linear-gradient(to bottom,#fdd49a,#fdf59a);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fdd49a',endColorstr='#fdf59a',GradientType=0);border-color:#fdf59a #fdf59a #fbed50;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.datetimepicker table tr td.today:hover,.datetimepicker table tr td.today:hover:hover,.datetimepicker table tr td.today.disabled:hover,.datetimepicker table tr td.today.disabled:hover:hover,.datetimepicker table tr td.today:active,.datetimepicker table tr td.today:hover:active,.datetimepicker table tr td.today.disabled:active,.datetimepicker table tr td.today.disabled:hover:active,.datetimepicker table tr td.today.active,.datetimepicker table tr td.today:hover.active,.datetimepicker table tr td.today.disabled.active,.datetimepicker table tr td.today.disabled:hover.active,.datetimepicker table tr td.today.disabled,.datetimepicker table tr td.today:hover.disabled,.datetimepicker table tr td.today.disabled.disabled,.datetimepicker table tr td.today.disabled:hover.disabled,.datetimepicker table tr td.today[disabled],.datetimepicker table tr td.today:hover[disabled],.datetimepicker table tr td.today.disabled[disabled],.datetimepicker table tr td.today.disabled:hover[disabled]{background-color:#fdf59a}.datetimepicker table tr td.today:active,.datetimepicker table tr td.today:hover:active,.datetimepicker table tr td.today.disabled:active,.datetimepicker table tr td.today.disabled:hover:active,.datetimepicker table tr td.today.active,.datetimepicker table tr td.today:hover.active,.datetimepicker table tr td.today.disabled.active,.datetimepicker table tr td.today.disabled:hover.active{background-color:#fbf069}.datetimepicker table tr td.active,.datetimepicker table tr td.active:hover,.datetimepicker table tr td.active.disabled,.datetimepicker table tr td.active.disabled:hover{background-color:#006dcc;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-ms-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc',endColorstr='#0044cc',GradientType=0);border-color:#04c #04c #002a80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.datetimepicker table tr td.active:hover,.datetimepicker table tr td.active:hover:hover,.datetimepicker table tr td.active.disabled:hover,.datetimepicker table tr td.active.disabled:hover:hover,.datetimepicker table tr td.active:active,.datetimepicker table tr td.active:hover:active,.datetimepicker table tr td.active.disabled:active,.datetimepicker table tr td.active.disabled:hover:active,.datetimepicker table tr td.active.active,.datetimepicker table tr td.active:hover.active,.datetimepicker table tr td.active.disabled.active,.datetimepicker table tr td.active.disabled:hover.active,.datetimepicker table tr td.active.disabled,.datetimepicker table tr td.active:hover.disabled,.datetimepicker table tr td.active.disabled.disabled,.datetimepicker table tr td.active.disabled:hover.disabled,.datetimepicker table tr td.active[disabled],.datetimepicker table tr td.active:hover[disabled],.datetimepicker table tr td.active.disabled[disabled],.datetimepicker table tr td.active.disabled:hover[disabled]{background-color:#04c}.datetimepicker table tr td.active:active,.datetimepicker table tr td.active:hover:active,.datetimepicker table tr td.active.disabled:active,.datetimepicker table tr td.active.disabled:hover:active,.datetimepicker table tr td.active.active,.datetimepicker table tr td.active:hover.active,.datetimepicker table tr td.active.disabled.active,.datetimepicker table tr td.active.disabled:hover.active{background-color:#039}.datetimepicker table tr td span{display:block;width:23%;height:54px;line-height:54px;float:left;margin:1%;cursor:pointer;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.datetimepicker .datetimepicker-hours span{height:26px;line-height:26px}.datetimepicker .datetimepicker-hours table tr td span.hour_am,.datetimepicker .datetimepicker-hours table tr td span.hour_pm{width:14.6%}.datetimepicker .datetimepicker-hours fieldset legend,.datetimepicker .datetimepicker-minutes fieldset legend{margin-bottom:inherit;line-height:30px}.datetimepicker .datetimepicker-minutes span{height:26px;line-height:26px}.datetimepicker table tr td span:hover{background:#eee}.datetimepicker table tr td span.disabled,.datetimepicker table tr td span.disabled:hover{background:0;color:#999;cursor:default}.datetimepicker table tr td span.active,.datetimepicker table tr td span.active:hover,.datetimepicker table tr td span.active.disabled,.datetimepicker table tr td span.active.disabled:hover{background-color:#006dcc;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-ms-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc',endColorstr='#0044cc',GradientType=0);border-color:#04c #04c #002a80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.datetimepicker table tr td span.active:hover,.datetimepicker table tr td span.active:hover:hover,.datetimepicker table tr td span.active.disabled:hover,.datetimepicker table tr td span.active.disabled:hover:hover,.datetimepicker table tr td span.active:active,.datetimepicker table tr td span.active:hover:active,.datetimepicker table tr td span.active.disabled:active,.datetimepicker table tr td span.active.disabled:hover:active,.datetimepicker table tr td span.active.active,.datetimepicker table tr td span.active:hover.active,.datetimepicker table tr td span.active.disabled.active,.datetimepicker table tr td span.active.disabled:hover.active,.datetimepicker table tr td span.active.disabled,.datetimepicker table tr td span.active:hover.disabled,.datetimepicker table tr td span.active.disabled.disabled,.datetimepicker table tr td span.active.disabled:hover.disabled,.datetimepicker table tr td span.active[disabled],.datetimepicker table tr td span.active:hover[disabled],.datetimepicker table tr td span.active.disabled[disabled],.datetimepicker table tr td span.active.disabled:hover[disabled]{background-color:#04c}.datetimepicker table tr td span.active:active,.datetimepicker table tr td span.active:hover:active,.datetimepicker table tr td span.active.disabled:active,.datetimepicker table tr td span.active.disabled:hover:active,.datetimepicker table tr td span.active.active,.datetimepicker table tr td span.active:hover.active,.datetimepicker table tr td span.active.disabled.active,.datetimepicker table tr td span.active.disabled:hover.active{background-color:#039}.datetimepicker table tr td span.old{color:#999}.datetimepicker th.switch{width:145px}.datetimepicker th span.glyphicon{pointer-events:none}.datetimepicker thead tr:first-child th,.datetimepicker tfoot th{cursor:pointer}.datetimepicker thead tr:first-child th:hover,.datetimepicker tfoot th:hover{background:#eee}.input-append.date .add-on i,.input-prepend.date .add-on i,.input-group.date .input-group-addon span{cursor:pointer;width:14px;height:14px}
WRFILE: fontawesome.min.css

/*!
 *  Font Awesome 3.2.1
 *  the iconic font designed for Bootstrap
 *  ------------------------------------------------------------------------------
 *  The full suite of pictographic icons, examples, and documentation can be
 *  found at http://fontawesome.io.  Stay up to date on Twitter at
 *  http://twitter.com/fontawesome.
 *
 *  License
 *  ------------------------------------------------------------------------------
 *  - The Font Awesome font is licensed under SIL OFL 1.1 -
 *    http://scripts.sil.org/OFL
 *  - Font Awesome CSS, LESS, and SASS files are licensed under MIT License -
 *    http://opensource.org/licenses/mit-license.html
 *  - Font Awesome documentation licensed under CC BY 3.0 -
 *    http://creativecommons.org/licenses/by/3.0/
 *  - Attribution is no longer required in Font Awesome 3.0, but much appreciated:
 *    "Font Awesome by Dave Gandy - http://fontawesome.io"
 *
 *  Author - Dave Gandy
 *  ------------------------------------------------------------------------------
 *  Email: dave@fontawesome.io
 *  Twitter: http://twitter.com/davegandy
 *  Work: Lead Product Designer @ Kyruus - http://kyruus.com
 */@font-face{font-family:'FontAwesome';src: url('data:font/opentype;charset=utf-8;base64,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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAsAAwAKAAIDgABwAcAAAAaAAHYFgAAABAAAXwcAAAAHAAAABwAAAAcAAAAHAAAABYAAAAcAAAAHAABdBgAAAAaAAAAHAAAABwAAAAaAAAAGgAAABYAAAAeAAAAGgAAABwAAAAcAAAAHAAB5BYAAbgaAAAAGgAAABgAAAAcAAAAGAAAABYAAAAaAABoFAAAABgAAAAeAADIGgAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABwAAAASAAAAHAABABoAAAAMAAAAEgAAABoAAAAWAAAAHAAAABgAAAAeAAAAGgP//BQAAAAaAAAAHgAAABoAAAAWAAAAEAAAABwAAAAYAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAeAAAAGAAAABAAAAAYAAAAEAAAABwAAAAaAAAAGgAAABwAAAAQAAAAHAAAABoAAegWAAAAGAAAABgAAAAaAAAAHAAAABAAAAAYC//8EgAA1BIAAdQYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAABABgAAAAaAADUGgAA1BwAAAAYAAAAGAAANBgAAAAYAAAAHAAAABYAAAAcAAAAHAAAABwAAAAWAAAAGgAAABwAAAAcAAAAGAAAABoAANQaAADUHgAAABoAAAAaAAAAHgAAAAwAAQAcAAAAHgAAABgAAAAYAAAAHAAAABwAAAAeAAAAHAAAABgAAAAYAAAADgAAABwAAAAaAAAAGAAAABIAAAAcAAAAGAAAABoAAAAYAAAAGgAAABgAAAAWAAAAFgAAABQAAAAYAAAAGgAAsAwAAAAYAAAAGgAAAB4AAAAWAAAAGAAAABwAAAAaAAAAGAP//BwAAAAcAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABoAAFQcAAAAFgAAABwAAAAYAAAAHAAAABwAAAAcAAAAHgAAABoAAEAeAAAAGgABmBwAAAAcAAAAFgAAEBgAAAAYAAAAGAAAABwAAAAcAAA8HAAAABgAAAAaAAAAGgAAbBwAAQAYAAAAGAAAABgAAAAaAAAAHgAAABAAAAAQAAAACgABAAoAAAAaAAAAEAAAABAAAAAQAAAAHAAAABgAAAAYAAAAHAAAoBwAAAAcAAAAHAAAAA4AAAAcAAAAGgAAABwAAAAQAAAAHAAAAB4AAAAeAAAAFgAAABYAAAAcAAAAGgAAAB4AAAAWAAAAFAAAABYAAAAWAAAAHgABABwAAAAeAAAAGgABABgAAAAYAAAAEAAAtBAAADQSAAE0EgABNAoAALQKAAA0EgABNBIAATQeAAAAHgAAABIAAAAMAAAAGAAAABoAAAAaAAAAGIAAABgAAAAcAAAAGgAAABoAAAAeAAAAEgAAABIAAAAYAAAAGAAAABgAAAAeAAAAHgAAABwAAQAcAAEAGgAANB4AALQcAAAAGgAAABYAAAAaAAAAEAAAABoAAAAKAAAACgABiBgAABQYAAAUHgAAABoAAAASAAAAFgAANBQAAAAaAAAAFgAAABoAAIAcAAAAGAAAABgAAAAYAAAAGAAAABYAAAAcAAAwHAAAABIAAAAYAAAAFgAAAAYAAAAYAAAAGAAAABwAANQYAAAAFgAAABAAAAAQAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAQAAAAEAAAABAAALQOCAAAEAwAABoAAHAcAAAAFAAA4BQAAAAUAAAAGgAAfBoAAHwcAAB8HAAAfBgAAHwYAAB8GgAAABoAAAAYAAAAGAAAbBYAAAAYAAAAHAAAABwAAQAWAAAAGAAAABgAAAAYAAAAFgAAABgAAAAQAAE4GAAAAAwAAAAMAAAAHAABABwAAAAWAAAAGgAAABYAAAAYAAAYGAAAABgAAAAaA//8GAAAABQAAAAQAAAAGAAAABwAAKgYAAAAHAABABoAAIAeA//8HAAAAB4AAAAcAAAAAAAAAAAMAAAAAAAD/egBaAAAAAAAAAAAAAAAAAAAAAAAAAAABAAQCAAEBAQxGb250QXdlc29tZQABAQFE+BAA+YUB+YYC+YYD+BkE+0cMA+UMBIr7lRwHgRwGAQUeoABVgDb/i4seoABVgDb/i4sMBxwghQ8cIKcRrh0AANUuEgFsAgABAAYACwARABkAHgAiACwAMAA0ADwAPgBFAEcATQBUAFwAXwBlAGgAbQBxAHkAfQCBAI0AlQCbAKAAqwCxALgAwADEAMgA0gDcAOcA8AD2AP0BAAEEAQgBEAEVARsBHwEjASkBNAE+AUgBVAFfAWwBcAF7AYcBlQGcAaIBrAGyAbYBugG/AcQByAHVAeIB6gHuAfMB9wH+AgoCFgIbAicCNAI9AkcCUgJZAmYCbwJ5AoYCjwKZAqMCrgK2AsACyQLUAuAC8AL0AvgC/AMEAw0DGQMeAyYDLAMzAzkDQwNPA1YDYwNvA3oDiQOaA6MDrwO8A8gDywPPA9cD5APzA/wEBwQOBBsEIgQvBDUEOwRGBFAEVQRaBGUEcwR9BIQEjASSBJgEowSmBKkEsQS1BMAEygTTBNoE4wT0BQYFFQUmBSsFMQU2BTwFRQVPBVcFXwVoBW0FcQV2BXwFfwWDBY0FkQWbBaIFpAWmBbMFvAXBBcYFywXUBeIF8gX9BgIGDAYUBh4GKQYwBjQGPQZEBlAGWAZcBmEGagZ1BoEGhQaMBpQGmQajBqsGuQbFBswG1wbfBucG7QbxBv4HBgcOBxcHHQcoBywHMgc2B0cHWQdoB3kHgweOB5YHoAenB60Hswe/B8sH1QfgB+cH7QfyB/wIDAgbCCUIMQg2CDsIPghFCE0IVQhjCGsIbwh4CIcIlQiZCKIIqAisCLcIwgjLCM8I2wjlCPMI+QkHCRgJHgkkCTUJRwlWCWcJbAlwCXYJgAmICZsJrAmwCbkJvwnNCdgJ4AnqCfQJ/QoBCgsKEgoaCiYKKgotCjAKMwo2CjkKPAo/CkIKRgpPCl8KYwp1CosKmAqpCq0KsQq9CsQKyArRCt0K5ArxCvoLAAsDCwcLFQsbCyYLNQtCC1ELYQtmC20LdAt5C4ALhQuPC5ULmwufC6ULqAusC7MLtgu4C70LwwvHC8sLzwvoC/NnbGFzc211c2ljc2VhcmNoZW52ZWxvcGVoZWFydHN0YXJzdGFyX2VtcHR5dXNlcmZpbG10aF9sYXJnZXRodGhfbGlzdG9rcmVtb3Zlem9vbV9pbnpvb21fb3V0b2Zmc2lnbmFsY29ndHJhc2hob21lZmlsZV9hbHR0aW1lcm9hZGRvd25sb2FkX2FsdGRvd25sb2FkdXBsb2FkaW5ib3hwbGF5X2NpcmNsZXJlcGVhdHJlZnJlc2hsaXN0X2FsdGxvY2tmbGFnaGVhZHBob25lc3ZvbHVtZV9vZmZ2b2x1bWVfZG93bnZvbHVtZV91cHFyY29kZWJhcmNvZGV0YWd0YWdzYm9va2Jvb2ttYXJrcHJpbnRjYW1lcmFmb250Ym9sZGl0YWxpY3RleHRfaGVpZ2h0dGV4dF93aWR0aGFsaWduX2xlZnRhbGlnbl9jZW50ZXJhbGlnbl9yaWdodGFsaWduX2p1c3RpZnlsaXN0aW5kZW50X2xlZnRpbmRlbnRfcmlnaHRmYWNldGltZV92aWRlb3BpY3R1cmVwZW5jaWxtYXBfbWFya2VyYWRqdXN0dGludGVkaXRzaGFyZWNoZWNrbW92ZXN0ZXBfYmFja3dhcmRmYXN0X2JhY2t3YXJkYmFja3dhcmRwbGF5cGF1c2VzdG9wZm9yd2FyZGZhc3RfZm9yd2FyZHN0ZXBfZm9yd2FyZGVqZWN0Y2hldnJvbl9sZWZ0Y2hldnJvbl9yaWdodHBsdXNfc2lnbm1pbnVzX3NpZ25yZW1vdmVfc2lnbm9rX3NpZ25xdWVzdGlvbl9zaWduaW5mb19zaWduc2NyZWVuc2hvdHJlbW92ZV9jaXJjbGVva19jaXJjbGViYW5fY2lyY2xlYXJyb3dfbGVmdGFycm93X3JpZ2h0YXJyb3dfdXBhcnJvd19kb3duc2hhcmVfYWx0cmVzaXplX2Z1bGxyZXNpemVfc21hbGxleGNsYW1hdGlvbl9zaWduZ2lmdGxlYWZmaXJlZXllX29wZW5leWVfY2xvc2V3YXJuaW5nX3NpZ25wbGFuZWNhbGVuZGFycmFuZG9tY29tbWVudG1hZ25ldGNoZXZyb25fdXBjaGV2cm9uX2Rvd25yZXR3ZWV0c2hvcHBpbmdfY2FydGZvbGRlcl9jbG9zZWZvbGRlcl9vcGVucmVzaXplX3ZlcnRpY2FscmVzaXplX2hvcml6b250YWxiYXJfY2hhcnR0d2l0dGVyX3NpZ25mYWNlYm9va19zaWduY2FtZXJhX3JldHJva2V5Y29nc2NvbW1lbnRzdGh1bWJzX3VwX2FsdHRodW1ic19kb3duX2FsdHN0YXJfaGFsZmhlYXJ0X2VtcHR5c2lnbm91dGxpbmtlZGluX3NpZ25wdXNocGluZXh0ZXJuYWxfbGlua3NpZ25pbnRyb3BoeWdpdGh1Yl9zaWdudXBsb2FkX2FsdGxlbW9ucGhvbmVjaGVja19lbXB0eWJvb2ttYXJrX2VtcHR5cGhvbmVfc2lnbnR3aXR0ZXJmYWNlYm9va2dpdGh1YnVubG9ja2NyZWRpdF9jYXJkcnNzaGRkYnVsbGhvcm5iZWxsY2VydGlmaWNhdGVoYW5kX3JpZ2h0aGFuZF9sZWZ0aGFuZF91cGhhbmRfZG93bmNpcmNsZV9hcnJvd19sZWZ0Y2lyY2xlX2Fycm93X3JpZ2h0Y2lyY2xlX2Fycm93X3VwY2lyY2xlX2Fycm93X2Rvd25nbG9iZXdyZW5jaHRhc2tzZmlsdGVyYnJpZWZjYXNlZnVsbHNjcmVlbm5vdGVxdWFsaW5maW5pdHlsZXNzZXF1YWxncm91cGxpbmtjbG91ZGJlYWtlcmN1dGNvcHlwYXBlcl9jbGlwc2F2ZXNpZ25fYmxhbmtyZW9yZGVydWxvbHN0cmlrZXRocm91Z2h1bmRlcmxpbmV0YWJsZW1hZ2ljdHJ1Y2twaW50ZXJlc3RwaW50ZXJlc3Rfc2lnbmdvb2dsZV9wbHVzX3NpZ25nb29nbGVfcGx1c21vbmV5Y2FyZXRfZG93bmNhcmV0X3VwY2FyZXRfbGVmdGNhcmV0X3JpZ2h0Y29sdW1uc3NvcnRzb3J0X2Rvd25zb3J0X3VwZW52ZWxvcGVfYWx0bGlua2VkaW51bmRvbGVnYWxkYXNoYm9hcmRjb21tZW50X2FsdGNvbW1lbnRzX2FsdGJvbHRzaXRlbWFwdW1icmVsbGFwYXN0ZWxpZ2h0X2J1bGJleGNoYW5nZWNsb3VkX2Rvd25sb2FkY2xvdWRfdXBsb2FkdXNlcl9tZHN0ZXRob3Njb3Blc3VpdGNhc2ViZWxsX2FsdGNvZmZlZWZvb2RmaWxlX3RleHRfYWx0YnVpbGRpbmdob3NwaXRhbGFtYnVsYW5jZW1lZGtpdGZpZ2h0ZXJfamV0YmVlcmhfc2lnbmYwZmVkb3VibGVfYW5nbGVfbGVmdGRvdWJsZV9hbmdsZV9yaWdodGRvdWJsZV9hbmdsZV91cGRvdWJsZV9hbmdsZV9kb3duYW5nbGVfbGVmdGFuZ2xlX3JpZ2h0YW5nbGVfdXBhbmdsZV9kb3duZGVza3RvcGxhcHRvcHRhYmxldG1vYmlsZV9waG9uZWNpcmNsZV9ibGFua3F1b3RlX2xlZnRxdW90ZV9yaWdodHNwaW5uZXJjaXJjbGVyZXBseWdpdGh1Yl9hbHRmb2xkZXJfY2xvc2VfYWx0Zm9sZGVyX29wZW5fYWx0ZXhwYW5kX2FsdGNvbGxhcHNlX2FsdHNtaWxlZnJvd25tZWhnYW1lcGFka2V5Ym9hcmRmbGFnX2FsdGZsYWdfY2hlY2tlcmVkdGVybWluYWxjb2RlcmVwbHlfYWxsc3Rhcl9oYWxmX2VtcHR5bG9jYXRpb25fYXJyb3djcm9wY29kZV9mb3JrdW5saW5rXzI3OWV4Y2xhbWF0aW9uc3VwZXJzY3JpcHRzdWJzY3JpcHRfMjgzcHV6emxlX3BpZWNlbWljcm9waG9uZW1pY3JvcGhvbmVfb2Zmc2hpZWxkY2FsZW5kYXJfZW1wdHlmaXJlX2V4dGluZ3Vpc2hlcnJvY2tldG1heGNkbmNoZXZyb25fc2lnbl9sZWZ0Y2hldnJvbl9zaWduX3JpZ2h0Y2hldnJvbl9zaWduX3VwY2hldnJvbl9zaWduX2Rvd25odG1sNWNzczNhbmNob3J1bmxvY2tfYWx0YnVsbHNleWVlbGxpcHNpc19ob3Jpem9udGFsZWxsaXBzaXNfdmVydGljYWxfMzAzcGxheV9zaWdudGlja2V0bWludXNfc2lnbl9hbHRjaGVja19taW51c2xldmVsX3VwbGV2ZWxfZG93bmNoZWNrX3NpZ25lZGl0X3NpZ25fMzEyc2hhcmVfc2lnbmNvbXBhc3Njb2xsYXBzZWNvbGxhcHNlX3RvcF8zMTdldXJnYnB1c2RpbnJqcHljbnlrcndidGNmaWxlZmlsZV90ZXh0c29ydF9ieV9hbHBoYWJldF8zMjlzb3J0X2J5X2F0dHJpYnV0ZXNzb3J0X2J5X2F0dHJpYnV0ZXNfYWx0c29ydF9ieV9vcmRlcnNvcnRfYnlfb3JkZXJfYWx0XzMzNF8zMzV5b3V0dWJlX3NpZ255b3V0dWJleGluZ3hpbmdfc2lnbnlvdXR1YmVfcGxheWRyb3Bib3hzdGFja2V4Y2hhbmdlaW5zdGFncmFtZmxpY2tyYWRuZjE3MWJpdGJ1Y2tldF9zaWdudHVtYmxydHVtYmxyX3NpZ25sb25nX2Fycm93X2Rvd25sb25nX2Fycm93X3VwbG9uZ19hcnJvd19sZWZ0bG9uZ19hcnJvd19yaWdodGFwcGxld2luZG93c2FuZHJvaWRsaW51eGRyaWJibGVza3lwZWZvdXJzcXVhcmV0cmVsbG9mZW1hbGVtYWxlZ2l0dGlwc3VuXzM2NmFyY2hpdmVidWd2a3dlaWJvcmVucmVuXzM3Ml8zNzNf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') format('truetype');font-weight:normal;font-style:normal}[class^="icon-"],[class*=" icon-"]{font-family:FontAwesome;font-weight:normal;font-style:normal;text-decoration:inherit;-webkit-font-smoothing:antialiased;*margin-right:.3em}[class^="icon-"]:before,[class*=" icon-"]:before{text-decoration:inherit;display:inline-block;speak:none}.icon-large:before{vertical-align:-10%;font-size:1.3333333333333333em}a [class^="icon-"],a [class*=" icon-"]{display:inline}[class^="icon-"].icon-fixed-width,[class*=" icon-"].icon-fixed-width{display:inline-block;width:1.1428571428571428em;text-align:right;padding-right:.2857142857142857em}[class^="icon-"].icon-fixed-width.icon-large,[class*=" icon-"].icon-fixed-width.icon-large{width:1.4285714285714286em}.icons-ul{margin-left:2.142857142857143em;list-style-type:none}.icons-ul>li{position:relative}.icons-ul .icon-li{position:absolute;left:-2.142857142857143em;width:2.142857142857143em;text-align:center;line-height:inherit}[class^="icon-"].hide,[class*=" icon-"].hide{display:none}.icon-muted{color:#eee}.icon-light{color:#fff}.icon-dark{color:#333}.icon-border{border:solid 1px #eee;padding:.2em .25em .15em;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.icon-2x{font-size:2em}.icon-2x.icon-border{border-width:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.icon-3x{font-size:3em}.icon-3x.icon-border{border-width:3px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.icon-4x{font-size:4em}.icon-4x.icon-border{border-width:4px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.icon-5x{font-size:5em}.icon-5x.icon-border{border-width:5px;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px}.pull-right{float:right}.pull-left{float:left}[class^="icon-"].pull-left,[class*=" icon-"].pull-left{margin-right:.3em}[class^="icon-"].pull-right,[class*=" icon-"].pull-right{margin-left:.3em}[class^="icon-"],[class*=" icon-"]{display:inline;width:auto;height:auto;line-height:normal;vertical-align:baseline;background-image:none;background-position:0 0;background-repeat:repeat;margin-top:0}.icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"]{background-image:none}.btn [class^="icon-"].icon-large,.nav [class^="icon-"].icon-large,.btn [class*=" icon-"].icon-large,.nav [class*=" icon-"].icon-large{line-height:.9em}.btn [class^="icon-"].icon-spin,.nav [class^="icon-"].icon-spin,.btn [class*=" icon-"].icon-spin,.nav [class*=" icon-"].icon-spin{display:inline-block}.nav-tabs [class^="icon-"],.nav-pills [class^="icon-"],.nav-tabs [class*=" icon-"],.nav-pills [class*=" icon-"],.nav-tabs [class^="icon-"].icon-large,.nav-pills [class^="icon-"].icon-large,.nav-tabs [class*=" icon-"].icon-large,.nav-pills [class*=" icon-"].icon-large{line-height:.9em}.btn [class^="icon-"].pull-left.icon-2x,.btn [class*=" icon-"].pull-left.icon-2x,.btn [class^="icon-"].pull-right.icon-2x,.btn [class*=" icon-"].pull-right.icon-2x{margin-top:.18em}.btn [class^="icon-"].icon-spin.icon-large,.btn [class*=" icon-"].icon-spin.icon-large{line-height:.8em}.btn.btn-small [class^="icon-"].pull-left.icon-2x,.btn.btn-small [class*=" icon-"].pull-left.icon-2x,.btn.btn-small [class^="icon-"].pull-right.icon-2x,.btn.btn-small [class*=" icon-"].pull-right.icon-2x{margin-top:.25em}.btn.btn-large [class^="icon-"],.btn.btn-large [class*=" icon-"]{margin-top:0}.btn.btn-large [class^="icon-"].pull-left.icon-2x,.btn.btn-large [class*=" icon-"].pull-left.icon-2x,.btn.btn-large [class^="icon-"].pull-right.icon-2x,.btn.btn-large [class*=" icon-"].pull-right.icon-2x{margin-top:.05em}.btn.btn-large [class^="icon-"].pull-left.icon-2x,.btn.btn-large [class*=" icon-"].pull-left.icon-2x{margin-right:.2em}.btn.btn-large [class^="icon-"].pull-right.icon-2x,.btn.btn-large [class*=" icon-"].pull-right.icon-2x{margin-left:.2em}.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{line-height:inherit}.icon-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:-35%}.icon-stack [class^="icon-"],.icon-stack [class*=" icon-"]{display:block;text-align:center;position:absolute;width:100%;height:100%;font-size:1em;line-height:inherit;*line-height:2em}.icon-stack .icon-stack-base{font-size:2em;*line-height:1em}.icon-spin{display:inline-block;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear}a .icon-stack,a .icon-spin{display:inline-block;text-decoration:none}@-moz-keyframes spin{0{-moz-transform:rotate(0)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0{-webkit-transform:rotate(0)}100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0{-o-transform:rotate(0)}100%{-o-transform:rotate(359deg)}}@-ms-keyframes spin{0{-ms-transform:rotate(0)}100%{-ms-transform:rotate(359deg)}}@keyframes spin{0{transform:rotate(0)}100%{transform:rotate(359deg)}}.icon-rotate-90:before{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1)}.icon-rotate-180:before{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2)}.icon-rotate-270:before{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3)}.icon-flip-horizontal:before{-webkit-transform:scale(-1,1);-moz-transform:scale(-1,1);-ms-transform:scale(-1,1);-o-transform:scale(-1,1);transform:scale(-1,1)}.icon-flip-vertical:before{-webkit-transform:scale(1,-1);-moz-transform:scale(1,-1);-ms-transform:scale(1,-1);-o-transform:scale(1,-1);transform:scale(1,-1)}a .icon-rotate-90:before,a .icon-rotate-180:before,a .icon-rotate-270:before,a .icon-flip-horizontal:before,a .icon-flip-vertical:before{display:inline-block}.icon-glass:before{content:"\f000"}.icon-music:before{content:"\f001"}.icon-search:before{content:"\f002"}.icon-envelope-alt:before{content:"\f003"}.icon-heart:before{content:"\f004"}.icon-star:before{content:"\f005"}.icon-star-empty:before{content:"\f006"}.icon-user:before{content:"\f007"}.icon-film:before{content:"\f008"}.icon-th-large:before{content:"\f009"}.icon-th:before{content:"\f00a"}.icon-th-list:before{content:"\f00b"}.icon-ok:before{content:"\f00c"}.icon-remove:before{content:"\f00d"}.icon-zoom-in:before{content:"\f00e"}.icon-zoom-out:before{content:"\f010"}.icon-power-off:before,.icon-off:before{content:"\f011"}.icon-signal:before{content:"\f012"}.icon-gear:before,.icon-cog:before{content:"\f013"}.icon-trash:before{content:"\f014"}.icon-home:before{content:"\f015"}.icon-file-alt:before{content:"\f016"}.icon-time:before{content:"\f017"}.icon-road:before{content:"\f018"}.icon-download-alt:before{content:"\f019"}.icon-download:before{content:"\f01a"}.icon-upload:before{content:"\f01b"}.icon-inbox:before{content:"\f01c"}.icon-play-circle:before{content:"\f01d"}.icon-rotate-right:before,.icon-repeat:before{content:"\f01e"}.icon-refresh:before{content:"\f021"}.icon-list-alt:before{content:"\f022"}.icon-lock:before{content:"\f023"}.icon-flag:before{content:"\f024"}.icon-headphones:before{content:"\f025"}.icon-volume-off:before{content:"\f026"}.icon-volume-down:before{content:"\f027"}.icon-volume-up:before{content:"\f028"}.icon-qrcode:before{content:"\f029"}.icon-barcode:before{content:"\f02a"}.icon-tag:before{content:"\f02b"}.icon-tags:before{content:"\f02c"}.icon-book:before{content:"\f02d"}.icon-bookmark:before{content:"\f02e"}.icon-print:before{content:"\f02f"}.icon-camera:before{content:"\f030"}.icon-font:before{content:"\f031"}.icon-bold:before{content:"\f032"}.icon-italic:before{content:"\f033"}.icon-text-height:before{content:"\f034"}.icon-text-width:before{content:"\f035"}.icon-align-left:before{content:"\f036"}.icon-align-center:before{content:"\f037"}.icon-align-right:before{content:"\f038"}.icon-align-justify:before{content:"\f039"}.icon-list:before{content:"\f03a"}.icon-indent-left:before{content:"\f03b"}.icon-indent-right:before{content:"\f03c"}.icon-facetime-video:before{content:"\f03d"}.icon-picture:before{content:"\f03e"}.icon-pencil:before{content:"\f040"}.icon-map-marker:before{content:"\f041"}.icon-adjust:before{content:"\f042"}.icon-tint:before{content:"\f043"}.icon-edit:before{content:"\f044"}.icon-share:before{content:"\f045"}.icon-check:before{content:"\f046"}.icon-move:before{content:"\f047"}.icon-step-backward:before{content:"\f048"}.icon-fast-backward:before{content:"\f049"}.icon-backward:before{content:"\f04a"}.icon-play:before{content:"\f04b"}.icon-pause:before{content:"\f04c"}.icon-stop:before{content:"\f04d"}.icon-forward:before{content:"\f04e"}.icon-fast-forward:before{content:"\f050"}.icon-step-forward:before{content:"\f051"}.icon-eject:before{content:"\f052"}.icon-chevron-left:before{content:"\f053"}.icon-chevron-right:before{content:"\f054"}.icon-plus-sign:before{content:"\f055"}.icon-minus-sign:before{content:"\f056"}.icon-remove-sign:before{content:"\f057"}.icon-ok-sign:before{content:"\f058"}.icon-question-sign:before{content:"\f059"}.icon-info-sign:before{content:"\f05a"}.icon-screenshot:before{content:"\f05b"}.icon-remove-circle:before{content:"\f05c"}.icon-ok-circle:before{content:"\f05d"}.icon-ban-circle:before{content:"\f05e"}.icon-arrow-left:before{content:"\f060"}.icon-arrow-right:before{content:"\f061"}.icon-arrow-up:before{content:"\f062"}.icon-arrow-down:before{content:"\f063"}.icon-mail-forward:before,.icon-share-alt:before{content:"\f064"}.icon-resize-full:before{content:"\f065"}.icon-resize-small:before{content:"\f066"}.icon-plus:before{content:"\f067"}.icon-minus:before{content:"\f068"}.icon-asterisk:before{content:"\f069"}.icon-exclamation-sign:before{content:"\f06a"}.icon-gift:before{content:"\f06b"}.icon-leaf:before{content:"\f06c"}.icon-fire:before{content:"\f06d"}.icon-eye-open:before{content:"\f06e"}.icon-eye-close:before{content:"\f070"}.icon-warning-sign:before{content:"\f071"}.icon-plane:before{content:"\f072"}.icon-calendar:before{content:"\f073"}.icon-random:before{content:"\f074"}.icon-comment:before{content:"\f075"}.icon-magnet:before{content:"\f076"}.icon-chevron-up:before{content:"\f077"}.icon-chevron-down:before{content:"\f078"}.icon-retweet:before{content:"\f079"}.icon-shopping-cart:before{content:"\f07a"}.icon-folder-close:before{content:"\f07b"}.icon-folder-open:before{content:"\f07c"}.icon-resize-vertical:before{content:"\f07d"}.icon-resize-horizontal:before{content:"\f07e"}.icon-bar-chart:before{content:"\f080"}.icon-twitter-sign:before{content:"\f081"}.icon-facebook-sign:before{content:"\f082"}.icon-camera-retro:before{content:"\f083"}.icon-key:before{content:"\f084"}.icon-gears:before,.icon-cogs:before{content:"\f085"}.icon-comments:before{content:"\f086"}.icon-thumbs-up-alt:before{content:"\f087"}.icon-thumbs-down-alt:before{content:"\f088"}.icon-star-half:before{content:"\f089"}.icon-heart-empty:before{content:"\f08a"}.icon-signout:before{content:"\f08b"}.icon-linkedin-sign:before{content:"\f08c"}.icon-pushpin:before{content:"\f08d"}.icon-external-link:before{content:"\f08e"}.icon-signin:before{content:"\f090"}.icon-trophy:before{content:"\f091"}.icon-github-sign:before{content:"\f092"}.icon-upload-alt:before{content:"\f093"}.icon-lemon:before{content:"\f094"}.icon-phone:before{content:"\f095"}.icon-unchecked:before,.icon-check-empty:before{content:"\f096"}.icon-bookmark-empty:before{content:"\f097"}.icon-phone-sign:before{content:"\f098"}.icon-twitter:before{content:"\f099"}.icon-facebook:before{content:"\f09a"}.icon-github:before{content:"\f09b"}.icon-unlock:before{content:"\f09c"}.icon-credit-card:before{content:"\f09d"}.icon-rss:before{content:"\f09e"}.icon-hdd:before{content:"\f0a0"}.icon-bullhorn:before{content:"\f0a1"}.icon-bell:before{content:"\f0a2"}.icon-certificate:before{content:"\f0a3"}.icon-hand-right:before{content:"\f0a4"}.icon-hand-left:before{content:"\f0a5"}.icon-hand-up:before{content:"\f0a6"}.icon-hand-down:before{content:"\f0a7"}.icon-circle-arrow-left:before{content:"\f0a8"}.icon-circle-arrow-right:before{content:"\f0a9"}.icon-circle-arrow-up:before{content:"\f0aa"}.icon-circle-arrow-down:before{content:"\f0ab"}.icon-globe:before{content:"\f0ac"}.icon-wrench:before{content:"\f0ad"}.icon-tasks:before{content:"\f0ae"}.icon-filter:before{content:"\f0b0"}.icon-briefcase:before{content:"\f0b1"}.icon-fullscreen:before{content:"\f0b2"}.icon-group:before{content:"\f0c0"}.icon-link:before{content:"\f0c1"}.icon-cloud:before{content:"\f0c2"}.icon-beaker:before{content:"\f0c3"}.icon-cut:before{content:"\f0c4"}.icon-copy:before{content:"\f0c5"}.icon-paperclip:before,.icon-paper-clip:before{content:"\f0c6"}.icon-save:before{content:"\f0c7"}.icon-sign-blank:before{content:"\f0c8"}.icon-reorder:before{content:"\f0c9"}.icon-list-ul:before{content:"\f0ca"}.icon-list-ol:before{content:"\f0cb"}.icon-strikethrough:before{content:"\f0cc"}.icon-underline:before{content:"\f0cd"}.icon-table:before{content:"\f0ce"}.icon-magic:before{content:"\f0d0"}.icon-truck:before{content:"\f0d1"}.icon-pinterest:before{content:"\f0d2"}.icon-pinterest-sign:before{content:"\f0d3"}.icon-google-plus-sign:before{content:"\f0d4"}.icon-google-plus:before{content:"\f0d5"}.icon-money:before{content:"\f0d6"}.icon-caret-down:before{content:"\f0d7"}.icon-caret-up:before{content:"\f0d8"}.icon-caret-left:before{content:"\f0d9"}.icon-caret-right:before{content:"\f0da"}.icon-columns:before{content:"\f0db"}.icon-sort:before{content:"\f0dc"}.icon-sort-down:before{content:"\f0dd"}.icon-sort-up:before{content:"\f0de"}.icon-envelope:before{content:"\f0e0"}.icon-linkedin:before{content:"\f0e1"}.icon-rotate-left:before,.icon-undo:before{content:"\f0e2"}.icon-legal:before{content:"\f0e3"}.icon-dashboard:before{content:"\f0e4"}.icon-comment-alt:before{content:"\f0e5"}.icon-comments-alt:before{content:"\f0e6"}.icon-bolt:before{content:"\f0e7"}.icon-sitemap:before{content:"\f0e8"}.icon-umbrella:before{content:"\f0e9"}.icon-paste:before{content:"\f0ea"}.icon-lightbulb:before{content:"\f0eb"}.icon-exchange:before{content:"\f0ec"}.icon-cloud-download:before{content:"\f0ed"}.icon-cloud-upload:before{content:"\f0ee"}.icon-user-md:before{content:"\f0f0"}.icon-stethoscope:before{content:"\f0f1"}.icon-suitcase:before{content:"\f0f2"}.icon-bell-alt:before{content:"\f0f3"}.icon-coffee:before{content:"\f0f4"}.icon-food:before{content:"\f0f5"}.icon-file-text-alt:before{content:"\f0f6"}.icon-building:before{content:"\f0f7"}.icon-hospital:before{content:"\f0f8"}.icon-ambulance:before{content:"\f0f9"}.icon-medkit:before{content:"\f0fa"}.icon-fighter-jet:before{content:"\f0fb"}.icon-beer:before{content:"\f0fc"}.icon-h-sign:before{content:"\f0fd"}.icon-plus-sign-alt:before{content:"\f0fe"}.icon-double-angle-left:before{content:"\f100"}.icon-double-angle-right:before{content:"\f101"}.icon-double-angle-up:before{content:"\f102"}.icon-double-angle-down:before{content:"\f103"}.icon-angle-left:before{content:"\f104"}.icon-angle-right:before{content:"\f105"}.icon-angle-up:before{content:"\f106"}.icon-angle-down:before{content:"\f107"}.icon-desktop:before{content:"\f108"}.icon-laptop:before{content:"\f109"}.icon-tablet:before{content:"\f10a"}.icon-mobile-phone:before{content:"\f10b"}.icon-circle-blank:before{content:"\f10c"}.icon-quote-left:before{content:"\f10d"}.icon-quote-right:before{content:"\f10e"}.icon-spinner:before{content:"\f110"}.icon-circle:before{content:"\f111"}.icon-mail-reply:before,.icon-reply:before{content:"\f112"}.icon-github-alt:before{content:"\f113"}.icon-folder-close-alt:before{content:"\f114"}.icon-folder-open-alt:before{content:"\f115"}.icon-expand-alt:before{content:"\f116"}.icon-collapse-alt:before{content:"\f117"}.icon-smile:before{content:"\f118"}.icon-frown:before{content:"\f119"}.icon-meh:before{content:"\f11a"}.icon-gamepad:before{content:"\f11b"}.icon-keyboard:before{content:"\f11c"}.icon-flag-alt:before{content:"\f11d"}.icon-flag-checkered:before{content:"\f11e"}.icon-terminal:before{content:"\f120"}.icon-code:before{content:"\f121"}.icon-reply-all:before{content:"\f122"}.icon-mail-reply-all:before{content:"\f122"}.icon-star-half-full:before,.icon-star-half-empty:before{content:"\f123"}.icon-location-arrow:before{content:"\f124"}.icon-crop:before{content:"\f125"}.icon-code-fork:before{content:"\f126"}.icon-unlink:before{content:"\f127"}.icon-question:before{content:"\f128"}.icon-info:before{content:"\f129"}.icon-exclamation:before{content:"\f12a"}.icon-superscript:before{content:"\f12b"}.icon-subscript:before{content:"\f12c"}.icon-eraser:before{content:"\f12d"}.icon-puzzle-piece:before{content:"\f12e"}.icon-microphone:before{content:"\f130"}.icon-microphone-off:before{content:"\f131"}.icon-shield:before{content:"\f132"}.icon-calendar-empty:before{content:"\f133"}.icon-fire-extinguisher:before{content:"\f134"}.icon-rocket:before{content:"\f135"}.icon-maxcdn:before{content:"\f136"}.icon-chevron-sign-left:before{content:"\f137"}.icon-chevron-sign-right:before{content:"\f138"}.icon-chevron-sign-up:before{content:"\f139"}.icon-chevron-sign-down:before{content:"\f13a"}.icon-html5:before{content:"\f13b"}.icon-css3:before{content:"\f13c"}.icon-anchor:before{content:"\f13d"}.icon-unlock-alt:before{content:"\f13e"}.icon-bullseye:before{content:"\f140"}.icon-ellipsis-horizontal:before{content:"\f141"}.icon-ellipsis-vertical:before{content:"\f142"}.icon-rss-sign:before{content:"\f143"}.icon-play-sign:before{content:"\f144"}.icon-ticket:before{content:"\f145"}.icon-minus-sign-alt:before{content:"\f146"}.icon-check-minus:before{content:"\f147"}.icon-level-up:before{content:"\f148"}.icon-level-down:before{content:"\f149"}.icon-check-sign:before{content:"\f14a"}.icon-edit-sign:before{content:"\f14b"}.icon-external-link-sign:before{content:"\f14c"}.icon-share-sign:before{content:"\f14d"}.icon-compass:before{content:"\f14e"}.icon-collapse:before{content:"\f150"}.icon-collapse-top:before{content:"\f151"}.icon-expand:before{content:"\f152"}.icon-euro:before,.icon-eur:before{content:"\f153"}.icon-gbp:before{content:"\f154"}.icon-dollar:before,.icon-usd:before{content:"\f155"}.icon-rupee:before,.icon-inr:before{content:"\f156"}.icon-yen:before,.icon-jpy:before{content:"\f157"}.icon-renminbi:before,.icon-cny:before{content:"\f158"}.icon-won:before,.icon-krw:before{content:"\f159"}.icon-bitcoin:before,.icon-btc:before{content:"\f15a"}.icon-file:before{content:"\f15b"}.icon-file-text:before{content:"\f15c"}.icon-sort-by-alphabet:before{content:"\f15d"}.icon-sort-by-alphabet-alt:before{content:"\f15e"}.icon-sort-by-attributes:before{content:"\f160"}.icon-sort-by-attributes-alt:before{content:"\f161"}.icon-sort-by-order:before{content:"\f162"}.icon-sort-by-order-alt:before{content:"\f163"}.icon-thumbs-up:before{content:"\f164"}.icon-thumbs-down:before{content:"\f165"}.icon-youtube-sign:before{content:"\f166"}.icon-youtube:before{content:"\f167"}.icon-xing:before{content:"\f168"}.icon-xing-sign:before{content:"\f169"}.icon-youtube-play:before{content:"\f16a"}.icon-dropbox:before{content:"\f16b"}.icon-stackexchange:before{content:"\f16c"}.icon-instagram:before{content:"\f16d"}.icon-flickr:before{content:"\f16e"}.icon-adn:before{content:"\f170"}.icon-bitbucket:before{content:"\f171"}.icon-bitbucket-sign:before{content:"\f172"}.icon-tumblr:before{content:"\f173"}.icon-tumblr-sign:before{content:"\f174"}.icon-long-arrow-down:before{content:"\f175"}.icon-long-arrow-up:before{content:"\f176"}.icon-long-arrow-left:before{content:"\f177"}.icon-long-arrow-right:before{content:"\f178"}.icon-apple:before{content:"\f179"}.icon-windows:before{content:"\f17a"}.icon-android:before{content:"\f17b"}.icon-linux:before{content:"\f17c"}.icon-dribbble:before{content:"\f17d"}.icon-skype:before{content:"\f17e"}.icon-foursquare:before{content:"\f180"}.icon-trello:before{content:"\f181"}.icon-female:before{content:"\f182"}.icon-male:before{content:"\f183"}.icon-gittip:before{content:"\f184"}.icon-sun:before{content:"\f185"}.icon-moon:before{content:"\f186"}.icon-archive:before{content:"\f187"}.icon-bug:before{content:"\f188"}.icon-vk:before{content:"\f189"}.icon-weibo:before{content:"\f18a"}.icon-renren:before{content:"\f18b"}
WRFILE: bootstrap.min.js

/*!
 * Bootstrap v3.3.7 (http://getbootstrap.com)
 * Copyright 2011-2016 Twitter, Inc.
 * Licensed under the MIT license
 */
if(typeof jQuery==="undefined"){throw new Error("Bootstrap's JavaScript requires jQuery")}+function(b){var a=b.fn.jquery.split(" ")[0].split(".");if((a[0]<2&&a[1]<9)||(a[0]==1&&a[1]==9&&a[2]<1)||(a[0]>3)){throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4")}}(jQuery);+function(b){function a(){var e=document.createElement("bootstrap");var d={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in d){if(e.style[c]!==undefined){return{end:d[c]}}}return false}b.fn.emulateTransitionEnd=function(e){var d=false;var c=this;b(this).one("bsTransitionEnd",function(){d=true});var f=function(){if(!d){b(c).trigger(b.support.transition.end)}};setTimeout(f,e);return this};b(function(){b.support.transition=a();if(!b.support.transition){return}b.event.special.bsTransitionEnd={bindType:b.support.transition.end,delegateType:b.support.transition.end,handle:function(c){if(b(c.target).is(this)){return c.handleObj.handler.apply(this,arguments)}}}})}(jQuery);+function(e){var d='[data-dismiss="alert"]';var b=function(f){e(f).on("click",d,this.close)};b.VERSION="3.3.7";b.TRANSITION_DURATION=150;b.prototype.close=function(j){var i=e(this);var g=i.attr("data-target");if(!g){g=i.attr("href");g=g&&g.replace(/.*(?=#[^\s]*$)/,"")}var h=e(g==="#"?[]:g);if(j){j.preventDefault()}if(!h.length){h=i.closest(".alert")}h.trigger(j=e.Event("close.bs.alert"));if(j.isDefaultPrevented()){return}h.removeClass("in");function f(){h.detach().trigger("closed.bs.alert").remove()}e.support.transition&&h.hasClass("fade")?h.one("bsTransitionEnd",f).emulateTransitionEnd(b.TRANSITION_DURATION):f()};function c(f){return this.each(function(){var h=e(this);var g=h.data("bs.alert");if(!g){h.data("bs.alert",(g=new b(this)))}if(typeof f=="string"){g[f].call(h)}})}var a=e.fn.alert;e.fn.alert=c;e.fn.alert.Constructor=b;e.fn.alert.noConflict=function(){e.fn.alert=a;return this};e(document).on("click.bs.alert.data-api",d,b.prototype.close)}(jQuery);+function(d){var b=function(f,e){this.$element=d(f);this.options=d.extend({},b.DEFAULTS,e);this.isLoading=false};b.VERSION="3.3.7";b.DEFAULTS={loadingText:"loading..."};b.prototype.setState=function(g){var i="disabled";var e=this.$element;var h=e.is("input")?"val":"html";var f=e.data();g+="Text";if(f.resetText==null){e.data("resetText",e[h]())}setTimeout(d.proxy(function(){e[h](f[g]==null?this.options[g]:f[g]);if(g=="loadingText"){this.isLoading=true;e.addClass(i).attr(i,i).prop(i,true)}else{if(this.isLoading){this.isLoading=false;e.removeClass(i).removeAttr(i).prop(i,false)}}},this),0)};b.prototype.toggle=function(){var f=true;var e=this.$element.closest('[data-toggle="buttons"]');if(e.length){var g=this.$element.find("input");if(g.prop("type")=="radio"){if(g.prop("checked")){f=false}e.find(".active").removeClass("active");this.$element.addClass("active")}else{if(g.prop("type")=="checkbox"){if((g.prop("checked"))!==this.$element.hasClass("active")){f=false}this.$element.toggleClass("active")}}g.prop("checked",this.$element.hasClass("active"));if(f){g.trigger("change")}}else{this.$element.attr("aria-pressed",!this.$element.hasClass("active"));this.$element.toggleClass("active")}};function c(e){return this.each(function(){var h=d(this);var g=h.data("bs.button");var f=typeof e=="object"&&e;if(!g){h.data("bs.button",(g=new b(this,f)))}if(e=="toggle"){g.toggle()}else{if(e){g.setState(e)}}})}var a=d.fn.button;d.fn.button=c;d.fn.button.Constructor=b;d.fn.button.noConflict=function(){d.fn.button=a;return this};d(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(g){var f=d(g.target).closest(".btn");c.call(f,"toggle");if(!(d(g.target).is('input[type="radio"], input[type="checkbox"]'))){g.preventDefault();if(f.is("input,button")){f.trigger("focus")}else{f.find("input:visible,button:visible").first().trigger("focus")}}}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(f){d(f.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(f.type))})}(jQuery);+function(c){var d=function(g,f){this.$element=c(g);this.$indicators=this.$element.find(".carousel-indicators");this.options=f;this.paused=null;this.sliding=null;this.interval=null;this.$active=null;this.$items=null;this.options.keyboard&&this.$element.on("keydown.bs.carousel",c.proxy(this.keydown,this));this.options.pause=="hover"&&!("ontouchstart" in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",c.proxy(this.pause,this)).on("mouseleave.bs.carousel",c.proxy(this.cycle,this))};d.VERSION="3.3.7";d.TRANSITION_DURATION=600;d.DEFAULTS={interval:5000,pause:"hover",wrap:true,keyboard:true};d.prototype.keydown=function(f){if(/input|textarea/i.test(f.target.tagName)){return}switch(f.which){case 37:this.prev();break;case 39:this.next();break;default:return}f.preventDefault()};d.prototype.cycle=function(f){f||(this.paused=false);this.interval&&clearInterval(this.interval);this.options.interval&&!this.paused&&(this.interval=setInterval(c.proxy(this.next,this),this.options.interval));return this};d.prototype.getItemIndex=function(f){this.$items=f.parent().children(".item");return this.$items.index(f||this.$active)};d.prototype.getItemForDirection=function(j,i){var f=this.getItemIndex(i);var g=(j=="prev"&&f===0)||(j=="next"&&f==(this.$items.length-1));if(g&&!this.options.wrap){return i}var k=j=="prev"?-1:1;var h=(f+k)%this.$items.length;return this.$items.eq(h)};d.prototype.to=function(h){var g=this;var f=this.getItemIndex(this.$active=this.$element.find(".item.active"));if(h>(this.$items.length-1)||h<0){return}if(this.sliding){return this.$element.one("slid.bs.carousel",function(){g.to(h)})}if(f==h){return this.pause().cycle()}return this.slide(h>f?"next":"prev",this.$items.eq(h))};d.prototype.pause=function(f){f||(this.paused=true);if(this.$element.find(".next, .prev").length&&c.support.transition){this.$element.trigger(c.support.transition.end);this.cycle(true)}this.interval=clearInterval(this.interval);return this};d.prototype.next=function(){if(this.sliding){return}return this.slide("next")};d.prototype.prev=function(){if(this.sliding){return}return this.slide("prev")};d.prototype.slide=function(m,i){var p=this.$element.find(".item.active");var g=i||this.getItemForDirection(m,p);var k=this.interval;var n=m=="next"?"left":"right";var j=this;if(g.hasClass("active")){return(this.sliding=false)}var l=g[0];var f=c.Event("slide.bs.carousel",{relatedTarget:l,direction:n});this.$element.trigger(f);if(f.isDefaultPrevented()){return}this.sliding=true;k&&this.pause();if(this.$indicators.length){this.$indicators.find(".active").removeClass("active");var h=c(this.$indicators.children()[this.getItemIndex(g)]);h&&h.addClass("active")}var o=c.Event("slid.bs.carousel",{relatedTarget:l,direction:n});if(c.support.transition&&this.$element.hasClass("slide")){g.addClass(m);g[0].offsetWidth;p.addClass(n);g.addClass(n);p.one("bsTransitionEnd",function(){g.removeClass([m,n].join(" ")).addClass("active");p.removeClass(["active",n].join(" "));j.sliding=false;setTimeout(function(){j.$element.trigger(o)},0)}).emulateTransitionEnd(d.TRANSITION_DURATION)}else{p.removeClass("active");g.addClass("active");this.sliding=false;this.$element.trigger(o)}k&&this.cycle();return this};function b(f){return this.each(function(){var j=c(this);var i=j.data("bs.carousel");var g=c.extend({},d.DEFAULTS,j.data(),typeof f=="object"&&f);var h=typeof f=="string"?f:g.slide;if(!i){j.data("bs.carousel",(i=new d(this,g)))}if(typeof f=="number"){i.to(f)}else{if(h){i[h]()}else{if(g.interval){i.pause().cycle()}}}})}var a=c.fn.carousel;c.fn.carousel=b;c.fn.carousel.Constructor=d;c.fn.carousel.noConflict=function(){c.fn.carousel=a;return this};var e=function(k){var g;var j=c(this);var f=c(j.attr("data-target")||(g=j.attr("href"))&&g.replace(/.*(?=#[^\s]+$)/,""));if(!f.hasClass("carousel")){return}var h=c.extend({},f.data(),j.data());var i=j.attr("data-slide-to");if(i){h.interval=false}b.call(f,h);if(i){f.data("bs.carousel").to(i)}k.preventDefault()};c(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e);c(window).on("load",function(){c('[data-ride="carousel"]').each(function(){var f=c(this);b.call(f,f.data())})})}(jQuery);+function(d){var e=function(g,f){this.$element=d(g);this.options=d.extend({},e.DEFAULTS,f);this.$trigger=d('[data-toggle="collapse"][href="#'+g.id+'"],[data-toggle="collapse"][data-target="#'+g.id+'"]');this.transitioning=null;if(this.options.parent){this.$parent=this.getParent()}else{this.addAriaAndCollapsedClass(this.$element,this.$trigger)}if(this.options.toggle){this.toggle()}};e.VERSION="3.3.7";e.TRANSITION_DURATION=350;e.DEFAULTS={toggle:true};e.prototype.dimension=function(){var f=this.$element.hasClass("width");return f?"width":"height"};e.prototype.show=function(){if(this.transitioning||this.$element.hasClass("in")){return}var h;var j=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(j&&j.length){h=j.data("bs.collapse");if(h&&h.transitioning){return}}var g=d.Event("show.bs.collapse");this.$element.trigger(g);if(g.isDefaultPrevented()){return}if(j&&j.length){b.call(j,"hide");h||j.data("bs.collapse",null)}var k=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[k](0).attr("aria-expanded",true);this.$trigger.removeClass("collapsed").attr("aria-expanded",true);this.transitioning=1;var f=function(){this.$element.removeClass("collapsing").addClass("collapse in")[k]("");this.transitioning=0;this.$element.trigger("shown.bs.collapse")};if(!d.support.transition){return f.call(this)}var i=d.camelCase(["scroll",k].join("-"));this.$element.one("bsTransitionEnd",d.proxy(f,this)).emulateTransitionEnd(e.TRANSITION_DURATION)[k](this.$element[0][i])};e.prototype.hide=function(){if(this.transitioning||!this.$element.hasClass("in")){return}var g=d.Event("hide.bs.collapse");this.$element.trigger(g);if(g.isDefaultPrevented()){return}var h=this.dimension();this.$element[h](this.$element[h]())[0].offsetHeight;this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",false);this.$trigger.addClass("collapsed").attr("aria-expanded",false);this.transitioning=1;var f=function(){this.transitioning=0;this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};if(!d.support.transition){return f.call(this)}this.$element[h](0).one("bsTransitionEnd",d.proxy(f,this)).emulateTransitionEnd(e.TRANSITION_DURATION)};e.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()};e.prototype.getParent=function(){return d(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(d.proxy(function(h,g){var f=d(g);this.addAriaAndCollapsedClass(c(f),f)},this)).end()};e.prototype.addAriaAndCollapsedClass=function(g,f){var h=g.hasClass("in");g.attr("aria-expanded",h);f.toggleClass("collapsed",!h).attr("aria-expanded",h)};function c(f){var g;var h=f.attr("data-target")||(g=f.attr("href"))&&g.replace(/.*(?=#[^\s]+$)/,"");return d(h)}function b(f){return this.each(function(){var i=d(this);var h=i.data("bs.collapse");var g=d.extend({},e.DEFAULTS,i.data(),typeof f=="object"&&f);if(!h&&g.toggle&&/show|hide/.test(f)){g.toggle=false}if(!h){i.data("bs.collapse",(h=new e(this,g)))}if(typeof f=="string"){h[f]()}})}var a=d.fn.collapse;d.fn.collapse=b;d.fn.collapse.Constructor=e;d.fn.collapse.noConflict=function(){d.fn.collapse=a;return this};d(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(j){var i=d(this);if(!i.attr("data-target")){j.preventDefault()}var f=c(i);var h=f.data("bs.collapse");var g=h?"toggle":i.data();b.call(f,g)})}(jQuery);+function(h){var e=".dropdown-backdrop";var b='[data-toggle="dropdown"]';var a=function(i){h(i).on("click.bs.dropdown",this.toggle)};a.VERSION="3.3.7";function f(k){var i=k.attr("data-target");if(!i){i=k.attr("href");i=i&&/#[A-Za-z]/.test(i)&&i.replace(/.*(?=#[^\s]*$)/,"")}var j=i&&h(i);return j&&j.length?j:k.parent()}function d(i){if(i&&i.which===3){return}h(e).remove();h(b).each(function(){var l=h(this);var k=f(l);var j={relatedTarget:this};if(!k.hasClass("open")){return}if(i&&i.type=="click"&&/input|textarea/i.test(i.target.tagName)&&h.contains(k[0],i.target)){return}k.trigger(i=h.Event("hide.bs.dropdown",j));if(i.isDefaultPrevented()){return}l.attr("aria-expanded","false");k.removeClass("open").trigger(h.Event("hidden.bs.dropdown",j))})}a.prototype.toggle=function(m){var l=h(this);if(l.is(".disabled, :disabled")){return}var k=f(l);var j=k.hasClass("open");d();if(!j){if("ontouchstart" in document.documentElement&&!k.closest(".navbar-nav").length){h(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(h(this)).on("click",d)}var i={relatedTarget:this};k.trigger(m=h.Event("show.bs.dropdown",i));if(m.isDefaultPrevented()){return}l.trigger("focus").attr("aria-expanded","true");k.toggleClass("open").trigger(h.Event("shown.bs.dropdown",i))}return false};a.prototype.keydown=function(m){if(!/(38|40|27|32)/.test(m.which)||/input|textarea/i.test(m.target.tagName)){return}var l=h(this);m.preventDefault();m.stopPropagation();if(l.is(".disabled, :disabled")){return}var k=f(l);var j=k.hasClass("open");if(!j&&m.which!=27||j&&m.which==27){if(m.which==27){k.find(b).trigger("focus")}return l.trigger("click")}var n=" li:not(.disabled):visible a";var o=k.find(".dropdown-menu"+n);if(!o.length){return}var i=o.index(m.target);if(m.which==38&&i>0){i--}if(m.which==40&&i<o.length-1){i++}if(!~i){i=0}o.eq(i).trigger("focus")};function g(i){return this.each(function(){var k=h(this);var j=k.data("bs.dropdown");if(!j){k.data("bs.dropdown",(j=new a(this)))}if(typeof i=="string"){j[i].call(k)}})}var c=h.fn.dropdown;h.fn.dropdown=g;h.fn.dropdown.Constructor=a;h.fn.dropdown.noConflict=function(){h.fn.dropdown=c;return this};h(document).on("click.bs.dropdown.data-api",d).on("click.bs.dropdown.data-api",".dropdown form",function(i){i.stopPropagation()}).on("click.bs.dropdown.data-api",b,a.prototype.toggle).on("keydown.bs.dropdown.data-api",b,a.prototype.keydown).on("keydown.bs.dropdown.data-api",".dropdown-menu",a.prototype.keydown)}(jQuery);+function(d){var b=function(f,e){this.options=e;this.$body=d(document.body);this.$element=d(f);this.$dialog=this.$element.find(".modal-dialog");this.$backdrop=null;this.isShown=null;this.originalBodyPad=null;this.scrollbarWidth=0;this.ignoreBackdropClick=false;if(this.options.remote){this.$element.find(".modal-content").load(this.options.remote,d.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))}};b.VERSION="3.3.7";b.TRANSITION_DURATION=300;b.BACKDROP_TRANSITION_DURATION=150;b.DEFAULTS={backdrop:true,keyboard:true,show:true};b.prototype.toggle=function(e){return this.isShown?this.hide():this.show(e)};b.prototype.show=function(h){var f=this;var g=d.Event("show.bs.modal",{relatedTarget:h});this.$element.trigger(g);if(this.isShown||g.isDefaultPrevented()){return}this.isShown=true;this.checkScrollbar();this.setScrollbar();this.$body.addClass("modal-open");this.escape();this.resize();this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',d.proxy(this.hide,this));this.$dialog.on("mousedown.dismiss.bs.modal",function(){f.$element.one("mouseup.dismiss.bs.modal",function(i){if(d(i.target).is(f.$element)){f.ignoreBackdropClick=true}})});this.backdrop(function(){var j=d.support.transition&&f.$element.hasClass("fade");if(!f.$element.parent().length){f.$element.appendTo(f.$body)}f.$element.show().scrollTop(0);f.adjustDialog();if(j){f.$element[0].offsetWidth}f.$element.addClass("in");f.enforceFocus();var i=d.Event("shown.bs.modal",{relatedTarget:h});j?f.$dialog.one("bsTransitionEnd",function(){f.$element.trigger("focus").trigger(i)}).emulateTransitionEnd(b.TRANSITION_DURATION):f.$element.trigger("focus").trigger(i)})};b.prototype.hide=function(f){if(f){f.preventDefault()}f=d.Event("hide.bs.modal");this.$element.trigger(f);if(!this.isShown||f.isDefaultPrevented()){return}this.isShown=false;this.escape();this.resize();d(document).off("focusin.bs.modal");this.$element.removeClass("in").off("click.dismiss.bs.modal").off("mouseup.dismiss.bs.modal");this.$dialog.off("mousedown.dismiss.bs.modal");d.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",d.proxy(this.hideModal,this)).emulateTransitionEnd(b.TRANSITION_DURATION):this.hideModal()};b.prototype.enforceFocus=function(){d(document).off("focusin.bs.modal").on("focusin.bs.modal",d.proxy(function(f){if(document!==f.target&&this.$element[0]!==f.target&&!this.$element.has(f.target).length){this.$element.trigger("focus")}},this))};b.prototype.escape=function(){if(this.isShown&&this.options.keyboard){this.$element.on("keydown.dismiss.bs.modal",d.proxy(function(f){f.which==27&&this.hide()},this))}else{if(!this.isShown){this.$element.off("keydown.dismiss.bs.modal")}}};b.prototype.resize=function(){if(this.isShown){d(window).on("resize.bs.modal",d.proxy(this.handleUpdate,this))}else{d(window).off("resize.bs.modal")}};b.prototype.hideModal=function(){var e=this;this.$element.hide();this.backdrop(function(){e.$body.removeClass("modal-open");e.resetAdjustments();e.resetScrollbar();e.$element.trigger("hidden.bs.modal")})};b.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove();this.$backdrop=null};b.prototype.backdrop=function(i){var h=this;var f=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var e=d.support.transition&&f;this.$backdrop=d(document.createElement("div")).addClass("modal-backdrop "+f).appendTo(this.$body);this.$element.on("click.dismiss.bs.modal",d.proxy(function(j){if(this.ignoreBackdropClick){this.ignoreBackdropClick=false;return}if(j.target!==j.currentTarget){return}this.options.backdrop=="static"?this.$element[0].focus():this.hide()},this));if(e){this.$backdrop[0].offsetWidth}this.$backdrop.addClass("in");if(!i){return}e?this.$backdrop.one("bsTransitionEnd",i).emulateTransitionEnd(b.BACKDROP_TRANSITION_DURATION):i()}else{if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var g=function(){h.removeBackdrop();i&&i()};d.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",g).emulateTransitionEnd(b.BACKDROP_TRANSITION_DURATION):g()}else{if(i){i()}}}};b.prototype.handleUpdate=function(){this.adjustDialog()};b.prototype.adjustDialog=function(){var e=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&e?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!e?this.scrollbarWidth:""})};b.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})};b.prototype.checkScrollbar=function(){var f=window.innerWidth;if(!f){var e=document.documentElement.getBoundingClientRect();f=e.right-Math.abs(e.left)}this.bodyIsOverflowing=document.body.clientWidth<f;this.scrollbarWidth=this.measureScrollbar()};b.prototype.setScrollbar=function(){var e=parseInt((this.$body.css("padding-right")||0),10);this.originalBodyPad=document.body.style.paddingRight||"";if(this.bodyIsOverflowing){this.$body.css("padding-right",e+this.scrollbarWidth)}};b.prototype.resetScrollbar=function(){this.$body.css("padding-right",this.originalBodyPad)};b.prototype.measureScrollbar=function(){var f=document.createElement("div");f.className="modal-scrollbar-measure";this.$body.append(f);var e=f.offsetWidth-f.clientWidth;this.$body[0].removeChild(f);return e};function c(e,f){return this.each(function(){var i=d(this);var h=i.data("bs.modal");var g=d.extend({},b.DEFAULTS,i.data(),typeof e=="object"&&e);if(!h){i.data("bs.modal",(h=new b(this,g)))}if(typeof e=="string"){h[e](f)}else{if(g.show){h.show(f)}}})}var a=d.fn.modal;d.fn.modal=c;d.fn.modal.Constructor=b;d.fn.modal.noConflict=function(){d.fn.modal=a;return this};d(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(j){var i=d(this);var g=i.attr("href");var f=d(i.attr("data-target")||(g&&g.replace(/.*(?=#[^\s]+$)/,"")));var h=f.data("bs.modal")?"toggle":d.extend({remote:!/#/.test(g)&&g},f.data(),i.data());if(i.is("a")){j.preventDefault()}f.one("show.bs.modal",function(e){if(e.isDefaultPrevented()){return}f.one("hidden.bs.modal",function(){i.is(":visible")&&i.trigger("focus")})});c.call(f,h,this)})}(jQuery);+function(d){var c=function(f,e){this.type=null;this.options=null;this.enabled=null;this.timeout=null;this.hoverState=null;this.$element=null;this.inState=null;this.init("tooltip",f,e)};c.VERSION="3.3.7";c.TRANSITION_DURATION=150;c.DEFAULTS={animation:true,placement:"top",selector:false,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:false,container:false,viewport:{selector:"body",padding:0}};c.prototype.init=function(l,j,g){this.enabled=true;this.type=l;this.$element=d(j);this.options=this.getOptions(g);this.$viewport=this.options.viewport&&d(d.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):(this.options.viewport.selector||this.options.viewport));this.inState={click:false,hover:false,focus:false};if(this.$element[0] instanceof document.constructor&&!this.options.selector){throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!")}var k=this.options.trigger.split(" ");for(var h=k.length;h--;){var f=k[h];if(f=="click"){this.$element.on("click."+this.type,this.options.selector,d.proxy(this.toggle,this))}else{if(f!="manual"){var m=f=="hover"?"mouseenter":"focusin";var e=f=="hover"?"mouseleave":"focusout";this.$element.on(m+"."+this.type,this.options.selector,d.proxy(this.enter,this));this.$element.on(e+"."+this.type,this.options.selector,d.proxy(this.leave,this))}}}this.options.selector?(this._options=d.extend({},this.options,{trigger:"manual",selector:""})):this.fixTitle()};c.prototype.getDefaults=function(){return c.DEFAULTS};c.prototype.getOptions=function(e){e=d.extend({},this.getDefaults(),this.$element.data(),e);if(e.delay&&typeof e.delay=="number"){e.delay={show:e.delay,hide:e.delay}}return e};c.prototype.getDelegateOptions=function(){var e={};var f=this.getDefaults();this._options&&d.each(this._options,function(g,h){if(f[g]!=h){e[g]=h}});return e};c.prototype.enter=function(f){var e=f instanceof this.constructor?f:d(f.currentTarget).data("bs."+this.type);if(!e){e=new this.constructor(f.currentTarget,this.getDelegateOptions());d(f.currentTarget).data("bs."+this.type,e)}if(f instanceof d.Event){e.inState[f.type=="focusin"?"focus":"hover"]=true}if(e.tip().hasClass("in")||e.hoverState=="in"){e.hoverState="in";return}clearTimeout(e.timeout);e.hoverState="in";if(!e.options.delay||!e.options.delay.show){return e.show()}e.timeout=setTimeout(function(){if(e.hoverState=="in"){e.show()}},e.options.delay.show)};c.prototype.isInStateTrue=function(){for(var e in this.inState){if(this.inState[e]){return true}}return false};c.prototype.leave=function(f){var e=f instanceof this.constructor?f:d(f.currentTarget).data("bs."+this.type);if(!e){e=new this.constructor(f.currentTarget,this.getDelegateOptions());d(f.currentTarget).data("bs."+this.type,e)}if(f instanceof d.Event){e.inState[f.type=="focusout"?"focus":"hover"]=false}if(e.isInStateTrue()){return}clearTimeout(e.timeout);e.hoverState="out";if(!e.options.delay||!e.options.delay.hide){return e.hide()}e.timeout=setTimeout(function(){if(e.hoverState=="out"){e.hide()}},e.options.delay.hide)};c.prototype.show=function(){var o=d.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(o);var p=d.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(o.isDefaultPrevented()||!p){return}var n=this;var l=this.tip();var h=this.getUID(this.type);this.setContent();l.attr("id",h);this.$element.attr("aria-describedby",h);if(this.options.animation){l.addClass("fade")}var k=typeof this.options.placement=="function"?this.options.placement.call(this,l[0],this.$element[0]):this.options.placement;var s=/\s?auto?\s?/i;var t=s.test(k);if(t){k=k.replace(s,"")||"top"}l.detach().css({top:0,left:0,display:"block"}).addClass(k).data("bs."+this.type,this);this.options.container?l.appendTo(this.options.container):l.insertAfter(this.$element);this.$element.trigger("inserted.bs."+this.type);var q=this.getPosition();var f=l[0].offsetWidth;var m=l[0].offsetHeight;if(t){var j=k;var r=this.getPosition(this.$viewport);k=k=="bottom"&&q.bottom+m>r.bottom?"top":k=="top"&&q.top-m<r.top?"bottom":k=="right"&&q.right+f>r.width?"left":k=="left"&&q.left-f<r.left?"right":k;l.removeClass(j).addClass(k)}var i=this.getCalculatedOffset(k,q,f,m);this.applyPlacement(i,k);var g=function(){var e=n.hoverState;n.$element.trigger("shown.bs."+n.type);n.hoverState=null;if(e=="out"){n.leave(n)}};d.support.transition&&this.$tip.hasClass("fade")?l.one("bsTransitionEnd",g).emulateTransitionEnd(c.TRANSITION_DURATION):g()}};c.prototype.applyPlacement=function(j,k){var l=this.tip();var g=l[0].offsetWidth;var q=l[0].offsetHeight;var f=parseInt(l.css("margin-top"),10);var i=parseInt(l.css("margin-left"),10);if(isNaN(f)){f=0}if(isNaN(i)){i=0}j.top+=f;j.left+=i;d.offset.setOffset(l[0],d.extend({using:function(r){l.css({top:Math.round(r.top),left:Math.round(r.left)})}},j),0);l.addClass("in");var e=l[0].offsetWidth;var m=l[0].offsetHeight;if(k=="top"&&m!=q){j.top=j.top+q-m}var p=this.getViewportAdjustedDelta(k,j,e,m);if(p.left){j.left+=p.left}else{j.top+=p.top}var n=/top|bottom/.test(k);var h=n?p.left*2-g+e:p.top*2-q+m;var o=n?"offsetWidth":"offsetHeight";l.offset(j);this.replaceArrow(h,l[0][o],n)};c.prototype.replaceArrow=function(g,e,f){this.arrow().css(f?"left":"top",50*(1-g/e)+"%").css(f?"top":"left","")};c.prototype.setContent=function(){var f=this.tip();var e=this.getTitle();f.find(".tooltip-inner")[this.options.html?"html":"text"](e);f.removeClass("fade in top bottom left right")};c.prototype.hide=function(j){var g=this;var i=d(this.$tip);var h=d.Event("hide.bs."+this.type);function f(){if(g.hoverState!="in"){i.detach()}if(g.$element){g.$element.removeAttr("aria-describedby").trigger("hidden.bs."+g.type)}j&&j()}this.$element.trigger(h);if(h.isDefaultPrevented()){return}i.removeClass("in");d.support.transition&&i.hasClass("fade")?i.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f();this.hoverState=null;return this};c.prototype.fixTitle=function(){var e=this.$element;if(e.attr("title")||typeof e.attr("data-original-title")!="string"){e.attr("data-original-title",e.attr("title")||"").attr("title","")}};c.prototype.hasContent=function(){return this.getTitle()};c.prototype.getPosition=function(g){g=g||this.$element;var i=g[0];var f=i.tagName=="BODY";var h=i.getBoundingClientRect();if(h.width==null){h=d.extend({},h,{width:h.right-h.left,height:h.bottom-h.top})}var k=window.SVGElement&&i instanceof window.SVGElement;var l=f?{top:0,left:0}:(k?null:g.offset());var e={scroll:f?document.documentElement.scrollTop||document.body.scrollTop:g.scrollTop()};var j=f?{width:d(window).width(),height:d(window).height()}:null;return d.extend({},h,e,j,l)};c.prototype.getCalculatedOffset=function(e,h,f,g){return e=="bottom"?{top:h.top+h.height,left:h.left+h.width/2-f/2}:e=="top"?{top:h.top-g,left:h.left+h.width/2-f/2}:e=="left"?{top:h.top+h.height/2-g/2,left:h.left-f}:{top:h.top+h.height/2-g/2,left:h.left+h.width}};c.prototype.getViewportAdjustedDelta=function(h,k,e,j){var m={top:0,left:0};if(!this.$viewport){return m}var g=this.options.viewport&&this.options.viewport.padding||0;var l=this.getPosition(this.$viewport);if(/right|left/.test(h)){var n=k.top-g-l.scroll;var i=k.top+g-l.scroll+j;if(n<l.top){m.top=l.top-n}else{if(i>l.top+l.height){m.top=l.top+l.height-i}}}else{var o=k.left-g;var f=k.left+g+e;if(o<l.left){m.left=l.left-o}else{if(f>l.right){m.left=l.left+l.width-f}}}return m};c.prototype.getTitle=function(){var g;var e=this.$element;var f=this.options;g=e.attr("data-original-title")||(typeof f.title=="function"?f.title.call(e[0]):f.title);return g};c.prototype.getUID=function(e){do{e+=~~(Math.random()*1000000)}while(document.getElementById(e));return e};c.prototype.tip=function(){if(!this.$tip){this.$tip=d(this.options.template);if(this.$tip.length!=1){throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!")}}return this.$tip};c.prototype.arrow=function(){return(this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow"))};c.prototype.enable=function(){this.enabled=true};c.prototype.disable=function(){this.enabled=false};c.prototype.toggleEnabled=function(){this.enabled=!this.enabled};c.prototype.toggle=function(g){var f=this;if(g){f=d(g.currentTarget).data("bs."+this.type);if(!f){f=new this.constructor(g.currentTarget,this.getDelegateOptions());d(g.currentTarget).data("bs."+this.type,f)}}if(g){f.inState.click=!f.inState.click;if(f.isInStateTrue()){f.enter(f)}else{f.leave(f)}}else{f.tip().hasClass("in")?f.leave(f):f.enter(f)}};c.prototype.destroy=function(){var e=this;clearTimeout(this.timeout);this.hide(function(){e.$element.off("."+e.type).removeData("bs."+e.type);if(e.$tip){e.$tip.detach()}e.$tip=null;e.$arrow=null;e.$viewport=null;e.$element=null})};function b(e){return this.each(function(){var h=d(this);var g=h.data("bs.tooltip");var f=typeof e=="object"&&e;if(!g&&/destroy|hide/.test(e)){return}if(!g){h.data("bs.tooltip",(g=new c(this,f)))}if(typeof e=="string"){g[e]()}})}var a=d.fn.tooltip;d.fn.tooltip=b;d.fn.tooltip.Constructor=c;d.fn.tooltip.noConflict=function(){d.fn.tooltip=a;return this}}(jQuery);+function(d){var c=function(f,e){this.init("popover",f,e)};if(!d.fn.tooltip){throw new Error("Popover requires tooltip.js")}c.VERSION="3.3.7";c.DEFAULTS=d.extend({},d.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'});c.prototype=d.extend({},d.fn.tooltip.Constructor.prototype);c.prototype.constructor=c;c.prototype.getDefaults=function(){return c.DEFAULTS};c.prototype.setContent=function(){var g=this.tip();var f=this.getTitle();var e=this.getContent();g.find(".popover-title")[this.options.html?"html":"text"](f);g.find(".popover-content").children().detach().end()[this.options.html?(typeof e=="string"?"html":"append"):"text"](e);g.removeClass("fade top bottom left right in");if(!g.find(".popover-title").html()){g.find(".popover-title").hide()}};c.prototype.hasContent=function(){return this.getTitle()||this.getContent()};c.prototype.getContent=function(){var e=this.$element;var f=this.options;return e.attr("data-content")||(typeof f.content=="function"?f.content.call(e[0]):f.content)};c.prototype.arrow=function(){return(this.$arrow=this.$arrow||this.tip().find(".arrow"))};function b(e){return this.each(function(){var h=d(this);var g=h.data("bs.popover");var f=typeof e=="object"&&e;if(!g&&/destroy|hide/.test(e)){return}if(!g){h.data("bs.popover",(g=new c(this,f)))}if(typeof e=="string"){g[e]()}})}var a=d.fn.popover;d.fn.popover=b;d.fn.popover.Constructor=c;d.fn.popover.noConflict=function(){d.fn.popover=a;return this}}(jQuery);+function(d){function c(f,e){this.$body=d(document.body);this.$scrollElement=d(f).is(document.body)?d(window):d(f);this.options=d.extend({},c.DEFAULTS,e);this.selector=(this.options.target||"")+" .nav li > a";this.offsets=[];this.targets=[];this.activeTarget=null;this.scrollHeight=0;this.$scrollElement.on("scroll.bs.scrollspy",d.proxy(this.process,this));this.refresh();this.process()}c.VERSION="3.3.7";c.DEFAULTS={offset:10};c.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)};c.prototype.refresh=function(){var g=this;var e="offset";var f=0;this.offsets=[];this.targets=[];this.scrollHeight=this.getScrollHeight();if(!d.isWindow(this.$scrollElement[0])){e="position";f=this.$scrollElement.scrollTop()}this.$body.find(this.selector).map(function(){var i=d(this);var h=i.data("target")||i.attr("href");var j=/^#./.test(h)&&d(h);return(j&&j.length&&j.is(":visible")&&[[j[e]().top+f,h]])||null}).sort(function(i,h){return i[0]-h[0]}).each(function(){g.offsets.push(this[0]);g.targets.push(this[1])})};c.prototype.process=function(){var k=this.$scrollElement.scrollTop()+this.options.offset;var g=this.getScrollHeight();var j=this.options.offset+g-this.$scrollElement.height();var h=this.offsets;var e=this.targets;var l=this.activeTarget;var f;if(this.scrollHeight!=g){this.refresh()}if(k>=j){return l!=(f=e[e.length-1])&&this.activate(f)}if(l&&k<h[0]){this.activeTarget=null;return this.clear()}for(f=h.length;f--;){l!=e[f]&&k>=h[f]&&(h[f+1]===undefined||k<h[f+1])&&this.activate(e[f])}};c.prototype.activate=function(g){this.activeTarget=g;this.clear();var e=this.selector+'[data-target="'+g+'"],'+this.selector+'[href="'+g+'"]';var f=d(e).parents("li").addClass("active");if(f.parent(".dropdown-menu").length){f=f.closest("li.dropdown").addClass("active")}f.trigger("activate.bs.scrollspy")};c.prototype.clear=function(){d(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};function b(e){return this.each(function(){var h=d(this);var g=h.data("bs.scrollspy");var f=typeof e=="object"&&e;if(!g){h.data("bs.scrollspy",(g=new c(this,f)))}if(typeof e=="string"){g[e]()}})}var a=d.fn.scrollspy;d.fn.scrollspy=b;d.fn.scrollspy.Constructor=c;d.fn.scrollspy.noConflict=function(){d.fn.scrollspy=a;return this};d(window).on("load.bs.scrollspy.data-api",function(){d('[data-spy="scroll"]').each(function(){var e=d(this);b.call(e,e.data())})})}(jQuery);+function(d){var b=function(f){this.element=d(f)};b.VERSION="3.3.7";b.TRANSITION_DURATION=150;b.prototype.show=function(){var l=this.element;var h=l.closest("ul:not(.dropdown-menu)");var g=l.data("target");if(!g){g=l.attr("href");g=g&&g.replace(/.*(?=#[^\s]*$)/,"")}if(l.parent("li").hasClass("active")){return}var j=h.find(".active:last a");var k=d.Event("hide.bs.tab",{relatedTarget:l[0]});var i=d.Event("show.bs.tab",{relatedTarget:j[0]});j.trigger(k);l.trigger(i);if(i.isDefaultPrevented()||k.isDefaultPrevented()){return}var f=d(g);this.activate(l.closest("li"),h);this.activate(f,f.parent(),function(){j.trigger({type:"hidden.bs.tab",relatedTarget:l[0]});l.trigger({type:"shown.bs.tab",relatedTarget:j[0]})})};b.prototype.activate=function(h,g,k){var f=g.find("> .active");var j=k&&d.support.transition&&(f.length&&f.hasClass("fade")||!!g.find("> .fade").length);function i(){f.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",false);h.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",true);if(j){h[0].offsetWidth;h.addClass("in")}else{h.removeClass("fade")}if(h.parent(".dropdown-menu").length){h.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",true)}k&&k()}f.length&&j?f.one("bsTransitionEnd",i).emulateTransitionEnd(b.TRANSITION_DURATION):i();f.removeClass("in")};function c(f){return this.each(function(){var h=d(this);var g=h.data("bs.tab");if(!g){h.data("bs.tab",(g=new b(this)))}if(typeof f=="string"){g[f]()}})}var a=d.fn.tab;d.fn.tab=c;d.fn.tab.Constructor=b;d.fn.tab.noConflict=function(){d.fn.tab=a;return this};var e=function(f){f.preventDefault();c.call(d(this),"show")};d(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery);+function(d){var c=function(f,e){this.options=d.extend({},c.DEFAULTS,e);this.$target=d(this.options.target).on("scroll.bs.affix.data-api",d.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",d.proxy(this.checkPositionWithEventLoop,this));this.$element=d(f);this.affixed=null;this.unpin=null;this.pinnedOffset=null;this.checkPosition()};c.VERSION="3.3.7";c.RESET="affix affix-top affix-bottom";c.DEFAULTS={offset:0,target:window};c.prototype.getState=function(n,m,f,g){var e=this.$target.scrollTop();var i=this.$element.offset();var j=this.$target.height();if(f!=null&&this.affixed=="top"){return e<f?"top":false}if(this.affixed=="bottom"){if(f!=null){return(e+this.unpin<=i.top)?false:"bottom"}return(e+j<=n-g)?false:"bottom"}var h=this.affixed==null;var l=h?e:i.top;var k=h?j:m;if(f!=null&&e<=f){return"top"}if(g!=null&&(l+k>=n-g)){return"bottom"}return false};c.prototype.getPinnedOffset=function(){if(this.pinnedOffset){return this.pinnedOffset}this.$element.removeClass(c.RESET).addClass("affix");var f=this.$target.scrollTop();var e=this.$element.offset();return(this.pinnedOffset=e.top-f)};c.prototype.checkPositionWithEventLoop=function(){setTimeout(d.proxy(this.checkPosition,this),1)};c.prototype.checkPosition=function(){if(!this.$element.is(":visible")){return}var f=this.$element.height();var l=this.options.offset;var j=l.top;var h=l.bottom;var i=Math.max(d(document).height(),d(document.body).height());if(typeof l!="object"){h=j=l}if(typeof j=="function"){j=l.top(this.$element)}if(typeof h=="function"){h=l.bottom(this.$element)}var g=this.getState(i,f,j,h);if(this.affixed!=g){if(this.unpin!=null){this.$element.css("top","")}var m="affix"+(g?"-"+g:"");var k=d.Event(m+".bs.affix");this.$element.trigger(k);if(k.isDefaultPrevented()){return}this.affixed=g;this.unpin=g=="bottom"?this.getPinnedOffset():null;this.$element.removeClass(c.RESET).addClass(m).trigger(m.replace("affix","affixed")+".bs.affix")}if(g=="bottom"){this.$element.offset({top:i-f-h})}};function b(e){return this.each(function(){var h=d(this);var g=h.data("bs.affix");var f=typeof e=="object"&&e;if(!g){h.data("bs.affix",(g=new c(this,f)))}if(typeof e=="string"){g[e]()}})}var a=d.fn.affix;d.fn.affix=b;d.fn.affix.Constructor=c;d.fn.affix.noConflict=function(){d.fn.affix=a;return this};d(window).on("load",function(){d('[data-spy="affix"]').each(function(){var f=d(this);var e=f.data();e.offset=e.offset||{};if(e.offsetBottom!=null){e.offset.bottom=e.offsetBottom}if(e.offsetTop!=null){e.offset.top=e.offsetTop}b.call(f,e)})})}(jQuery);
WRFILE: bootstrap-datetimepicker.min.js

(function(a){if(typeof define==="function"&&define.amd){define(["jquery"],a)}else{if(typeof exports==="object"){a(require("jquery"))}else{a(jQuery)}}}(function(d,f){if(!("indexOf" in Array.prototype)){Array.prototype.indexOf=function(k,j){if(j===f){j=0}if(j<0){j+=this.length}if(j<0){j=0}for(var l=this.length;j<l;j++){if(j in this&&this[j]===k){return j}}return -1}}function a(){var q,k,p,l,j,n,m,o;k=(new Date()).toString();p=((m=k.split("(")[1])!=null?m.slice(0,-1):0)||k.split(" ");if(p instanceof Array){n=[];for(var l=0,j=p.length;l<j;l++){o=p[l];if((q=(m=o.match(/\b[A-Z]+\b/))!==null)?m[0]:0){n.push(q)}}p=n.pop()}return p}function h(){return new Date(Date.UTC.apply(Date,arguments))}var g=function(k,j){var m=this;this.element=d(k);this.container=j.container||"body";this.language=j.language||this.element.data("date-language")||"en";this.language=this.language in e?this.language:this.language.split("-")[0];this.language=this.language in e?this.language:"en";this.isRTL=e[this.language].rtl||false;this.formatType=j.formatType||this.element.data("format-type")||"standard";this.format=c.parseFormat(j.format||this.element.data("date-format")||e[this.language].format||c.getDefaultFormat(this.formatType,"input"),this.formatType);this.isInline=false;this.isVisible=false;this.isInput=this.element.is("input");this.fontAwesome=j.fontAwesome||this.element.data("font-awesome")||false;this.bootcssVer=j.bootcssVer||(this.isInput?(this.element.is(".form-control")?3:2):(this.bootcssVer=this.element.is(".input-group")?3:2));this.component=this.element.is(".date")?(this.bootcssVer===3?this.element.find(".input-group-addon .glyphicon-th, .input-group-addon .glyphicon-time, .input-group-addon .glyphicon-remove, .input-group-addon .glyphicon-calendar, .input-group-addon .fa-calendar, .input-group-addon .fa-clock-o").parent():this.element.find(".add-on .icon-th, .add-on .icon-time, .add-on .icon-calendar, .add-on .fa-calendar, .add-on .fa-clock-o").parent()):false;this.componentReset=this.element.is(".date")?(this.bootcssVer===3?this.element.find(".input-group-addon .glyphicon-remove, .input-group-addon .fa-times").parent():this.element.find(".add-on .icon-remove, .add-on .fa-times").parent()):false;this.hasInput=this.component&&this.element.find("input").length;if(this.component&&this.component.length===0){this.component=false}this.linkField=j.linkField||this.element.data("link-field")||false;this.linkFormat=c.parseFormat(j.linkFormat||this.element.data("link-format")||c.getDefaultFormat(this.formatType,"link"),this.formatType);this.minuteStep=j.minuteStep||this.element.data("minute-step")||5;this.pickerPosition=j.pickerPosition||this.element.data("picker-position")||"bottom-right";this.showMeridian=j.showMeridian||this.element.data("show-meridian")||false;this.initialDate=j.initialDate||new Date();this.zIndex=j.zIndex||this.element.data("z-index")||f;this.title=typeof j.title==="undefined"?false:j.title;this.timezone=j.timezone||a();this.icons={leftArrow:this.fontAwesome?"fa-arrow-left":(this.bootcssVer===3?"glyphicon-arrow-left":"icon-arrow-left"),rightArrow:this.fontAwesome?"fa-arrow-right":(this.bootcssVer===3?"glyphicon-arrow-right":"icon-arrow-right")};this.icontype=this.fontAwesome?"fa":"glyphicon";this._attachEvents();this.clickedOutside=function(n){if(d(n.target).closest(".datetimepicker").length===0){m.hide()}};this.formatViewType="datetime";if("formatViewType" in j){this.formatViewType=j.formatViewType}else{if("formatViewType" in this.element.data()){this.formatViewType=this.element.data("formatViewType")}}this.minView=0;if("minView" in j){this.minView=j.minView}else{if("minView" in this.element.data()){this.minView=this.element.data("min-view")}}this.minView=c.convertViewMode(this.minView);this.maxView=c.modes.length-1;if("maxView" in j){this.maxView=j.maxView}else{if("maxView" in this.element.data()){this.maxView=this.element.data("max-view")}}this.maxView=c.convertViewMode(this.maxView);this.wheelViewModeNavigation=false;if("wheelViewModeNavigation" in j){this.wheelViewModeNavigation=j.wheelViewModeNavigation}else{if("wheelViewModeNavigation" in this.element.data()){this.wheelViewModeNavigation=this.element.data("view-mode-wheel-navigation")}}this.wheelViewModeNavigationInverseDirection=false;if("wheelViewModeNavigationInverseDirection" in j){this.wheelViewModeNavigationInverseDirection=j.wheelViewModeNavigationInverseDirection}else{if("wheelViewModeNavigationInverseDirection" in this.element.data()){this.wheelViewModeNavigationInverseDirection=this.element.data("view-mode-wheel-navigation-inverse-dir")}}this.wheelViewModeNavigationDelay=100;if("wheelViewModeNavigationDelay" in j){this.wheelViewModeNavigationDelay=j.wheelViewModeNavigationDelay}else{if("wheelViewModeNavigationDelay" in this.element.data()){this.wheelViewModeNavigationDelay=this.element.data("view-mode-wheel-navigation-delay")}}this.startViewMode=2;if("startView" in j){this.startViewMode=j.startView}else{if("startView" in this.element.data()){this.startViewMode=this.element.data("start-view")}}this.startViewMode=c.convertViewMode(this.startViewMode);this.viewMode=this.startViewMode;this.viewSelect=this.minView;if("viewSelect" in j){this.viewSelect=j.viewSelect}else{if("viewSelect" in this.element.data()){this.viewSelect=this.element.data("view-select")}}this.viewSelect=c.convertViewMode(this.viewSelect);this.forceParse=true;if("forceParse" in j){this.forceParse=j.forceParse}else{if("dateForceParse" in this.element.data()){this.forceParse=this.element.data("date-force-parse")}}var l=this.bootcssVer===3?c.templateV3:c.template;while(l.indexOf("{iconType}")!==-1){l=l.replace("{iconType}",this.icontype)}while(l.indexOf("{leftArrow}")!==-1){l=l.replace("{leftArrow}",this.icons.leftArrow)}while(l.indexOf("{rightArrow}")!==-1){l=l.replace("{rightArrow}",this.icons.rightArrow)}this.picker=d(l).appendTo(this.isInline?this.element:this.container).on({click:d.proxy(this.click,this),mousedown:d.proxy(this.mousedown,this)});if(this.wheelViewModeNavigation){if(d.fn.mousewheel){this.picker.on({mousewheel:d.proxy(this.mousewheel,this)})}else{console.log("Mouse Wheel event is not supported. Please include the jQuery Mouse Wheel plugin before enabling this option")}}if(this.isInline){this.picker.addClass("datetimepicker-inline")}else{this.picker.addClass("datetimepicker-dropdown-"+this.pickerPosition+" dropdown-menu")}if(this.isRTL){this.picker.addClass("datetimepicker-rtl");var i=this.bootcssVer===3?".prev span, .next span":".prev i, .next i";this.picker.find(i).toggleClass(this.icons.leftArrow+" "+this.icons.rightArrow)}d(document).on("mousedown touchend",this.clickedOutside);this.autoclose=false;if("autoclose" in j){this.autoclose=j.autoclose}else{if("dateAutoclose" in this.element.data()){this.autoclose=this.element.data("date-autoclose")}}this.keyboardNavigation=true;if("keyboardNavigation" in j){this.keyboardNavigation=j.keyboardNavigation}else{if("dateKeyboardNavigation" in this.element.data()){this.keyboardNavigation=this.element.data("date-keyboard-navigation")}}this.todayBtn=(j.todayBtn||this.element.data("date-today-btn")||false);this.clearBtn=(j.clearBtn||this.element.data("date-clear-btn")||false);this.todayHighlight=(j.todayHighlight||this.element.data("date-today-highlight")||false);this.weekStart=0;if(typeof j.weekStart!=="undefined"){this.weekStart=j.weekStart}else{if(typeof this.element.data("date-weekstart")!=="undefined"){this.weekStart=this.element.data("date-weekstart")}else{if(typeof e[this.language].weekStart!=="undefined"){this.weekStart=e[this.language].weekStart}}}this.weekStart=this.weekStart%7;this.weekEnd=((this.weekStart+6)%7);this.onRenderDay=function(n){var p=(j.onRenderDay||function(){return[]})(n);if(typeof p==="string"){p=[p]}var o=["day"];return o.concat((p?p:[]))};this.onRenderHour=function(n){var p=(j.onRenderHour||function(){return[]})(n);var o=["hour"];if(typeof p==="string"){p=[p]}return o.concat((p?p:[]))};this.onRenderMinute=function(n){var p=(j.onRenderMinute||function(){return[]})(n);var o=["minute"];if(typeof p==="string"){p=[p]}if(n<this.startDate||n>this.endDate){o.push("disabled")}else{if(Math.floor(this.date.getUTCMinutes()/this.minuteStep)===Math.floor(n.getUTCMinutes()/this.minuteStep)){o.push("active")}}return o.concat((p?p:[]))};this.onRenderYear=function(o){var q=(j.onRenderYear||function(){return[]})(o);var p=["year"];if(typeof q==="string"){q=[q]}if(this.date.getUTCFullYear()===o.getUTCFullYear()){p.push("active")}var n=o.getUTCFullYear();var r=this.endDate.getUTCFullYear();if(o<this.startDate||n>r){p.push("disabled")}return p.concat((q?q:[]))};this.onRenderMonth=function(n){var p=(j.onRenderMonth||function(){return[]})(n);var o=["month"];if(typeof p==="string"){p=[p]}return o.concat((p?p:[]))};this.startDate=new Date(-8639968443048000);this.endDate=new Date(8639968443048000);this.datesDisabled=[];this.daysOfWeekDisabled=[];this.setStartDate(j.startDate||this.element.data("date-startdate"));this.setEndDate(j.endDate||this.element.data("date-enddate"));this.setDatesDisabled(j.datesDisabled||this.element.data("date-dates-disabled"));this.setDaysOfWeekDisabled(j.daysOfWeekDisabled||this.element.data("date-days-of-week-disabled"));this.setMinutesDisabled(j.minutesDisabled||this.element.data("date-minute-disabled"));this.setHoursDisabled(j.hoursDisabled||this.element.data("date-hour-disabled"));this.fillDow();this.fillMonths();this.update();this.showMode();if(this.isInline){this.show()}};g.prototype={constructor:g,_events:[],_attachEvents:function(){this._detachEvents();if(this.isInput){this._events=[[this.element,{focus:d.proxy(this.show,this),keyup:d.proxy(this.update,this),keydown:d.proxy(this.keydown,this)}]]}else{if(this.component&&this.hasInput){this._events=[[this.element.find("input"),{focus:d.proxy(this.show,this),keyup:d.proxy(this.update,this),keydown:d.proxy(this.keydown,this)}],[this.component,{click:d.proxy(this.show,this)}]];if(this.componentReset){this._events.push([this.componentReset,{click:d.proxy(this.reset,this)}])}}else{if(this.element.is("div")){this.isInline=true}else{this._events=[[this.element,{click:d.proxy(this.show,this)}]]}}}for(var j=0,k,l;j<this._events.length;j++){k=this._events[j][0];l=this._events[j][1];k.on(l)}},_detachEvents:function(){for(var j=0,k,l;j<this._events.length;j++){k=this._events[j][0];l=this._events[j][1];k.off(l)}this._events=[]},show:function(i){this.picker.show();this.height=this.component?this.component.outerHeight():this.element.outerHeight();if(this.forceParse){this.update()}this.place();d(window).on("resize",d.proxy(this.place,this));if(i){i.stopPropagation();i.preventDefault()}this.isVisible=true;this.element.trigger({type:"show",date:this.date})},hide:function(){if(!this.isVisible){return}if(this.isInline){return}this.picker.hide();d(window).off("resize",this.place);this.viewMode=this.startViewMode;this.showMode();if(!this.isInput){d(document).off("mousedown",this.hide)}if(this.forceParse&&(this.isInput&&this.element.val()||this.hasInput&&this.element.find("input").val())){this.setValue()}this.isVisible=false;this.element.trigger({type:"hide",date:this.date})},remove:function(){this._detachEvents();d(document).off("mousedown",this.clickedOutside);this.picker.remove();delete this.picker;delete this.element.data().datetimepicker},getDate:function(){var i=this.getUTCDate();if(i===null){return null}return new Date(i.getTime()+(i.getTimezoneOffset()*60000))},getUTCDate:function(){return this.date},getInitialDate:function(){return this.initialDate},setInitialDate:function(i){this.initialDate=i},setDate:function(i){this.setUTCDate(new Date(i.getTime()-(i.getTimezoneOffset()*60000)))},setUTCDate:function(i){if(i>=this.startDate&&i<=this.endDate){this.date=i;this.setValue();this.viewDate=this.date;this.fill()}else{this.element.trigger({type:"outOfRange",date:i,startDate:this.startDate,endDate:this.endDate})}},setFormat:function(j){this.format=c.parseFormat(j,this.formatType);var i;if(this.isInput){i=this.element}else{if(this.component){i=this.element.find("input")}}if(i&&i.val()){this.setValue()}},setValue:function(){var i=this.getFormattedDate();if(!this.isInput){if(this.component){this.element.find("input").val(i)}this.element.data("date",i)}else{this.element.val(i)}if(this.linkField){d("#"+this.linkField).val(this.getFormattedDate(this.linkFormat))}},getFormattedDate:function(i){i=i||this.format;return c.formatDate(this.date,i,this.language,this.formatType,this.timezone)},setStartDate:function(i){this.startDate=i||this.startDate;if(this.startDate.valueOf()!==8639968443048000){this.startDate=c.parseDate(this.startDate,this.format,this.language,this.formatType,this.timezone)}this.update();this.updateNavArrows()},setEndDate:function(i){this.endDate=i||this.endDate;if(this.endDate.valueOf()!==8639968443048000){this.endDate=c.parseDate(this.endDate,this.format,this.language,this.formatType,this.timezone)}this.update();this.updateNavArrows()},setDatesDisabled:function(j){this.datesDisabled=j||[];if(!d.isArray(this.datesDisabled)){this.datesDisabled=this.datesDisabled.split(/,\s*/)}var i=this;this.datesDisabled=d.map(this.datesDisabled,function(k){return c.parseDate(k,i.format,i.language,i.formatType,i.timezone).toDateString()});this.update();this.updateNavArrows()},setTitle:function(i,j){return this.picker.find(i).find("th:eq(1)").text(this.title===false?j:this.title)},setDaysOfWeekDisabled:function(i){this.daysOfWeekDisabled=i||[];if(!d.isArray(this.daysOfWeekDisabled)){this.daysOfWeekDisabled=this.daysOfWeekDisabled.split(/,\s*/)}this.daysOfWeekDisabled=d.map(this.daysOfWeekDisabled,function(j){return parseInt(j,10)});this.update();this.updateNavArrows()},setMinutesDisabled:function(i){this.minutesDisabled=i||[];if(!d.isArray(this.minutesDisabled)){this.minutesDisabled=this.minutesDisabled.split(/,\s*/)}this.minutesDisabled=d.map(this.minutesDisabled,function(j){return parseInt(j,10)});this.update();this.updateNavArrows()},setHoursDisabled:function(i){this.hoursDisabled=i||[];if(!d.isArray(this.hoursDisabled)){this.hoursDisabled=this.hoursDisabled.split(/,\s*/)}this.hoursDisabled=d.map(this.hoursDisabled,function(j){return parseInt(j,10)});this.update();this.updateNavArrows()},place:function(){if(this.isInline){return}if(!this.zIndex){var j=0;d("div").each(function(){var o=parseInt(d(this).css("zIndex"),10);if(o>j){j=o}});this.zIndex=j+10}var n,m,l,k;if(this.container instanceof d){k=this.container.offset()}else{k=d(this.container).offset()}if(this.component){n=this.component.offset();l=n.left;if(this.pickerPosition==="bottom-left"||this.pickerPosition==="top-left"){l+=this.component.outerWidth()-this.picker.outerWidth()}}else{n=this.element.offset();l=n.left;if(this.pickerPosition==="bottom-left"||this.pickerPosition==="top-left"){l+=this.element.outerWidth()-this.picker.outerWidth()}}var i=document.body.clientWidth||window.innerWidth;if(l+220>i){l=i-220}if(this.pickerPosition==="top-left"||this.pickerPosition==="top-right"){m=n.top-this.picker.outerHeight()}else{m=n.top+this.height}m=m-k.top;l=l-k.left;this.picker.css({top:m,left:l,zIndex:this.zIndex})},hour_minute:"^([0-9]|0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]",update:function(){var i,j=false;if(arguments&&arguments.length&&(typeof arguments[0]==="string"||arguments[0] instanceof Date)){i=arguments[0];j=true}else{i=(this.isInput?this.element.val():this.element.find("input").val())||this.element.data("date")||this.initialDate;if(typeof i==="string"){i=i.replace(/^\s+|\s+$/g,"")}}if(!i){i=new Date();j=false}if(typeof i==="string"){if(new RegExp(this.hour_minute).test(i)||new RegExp(this.hour_minute+":[0-5][0-9]").test(i)){i=this.getDate()}}this.date=c.parseDate(i,this.format,this.language,this.formatType,this.timezone);if(j){this.setValue()}if(this.date<this.startDate){this.viewDate=new Date(this.startDate)}else{if(this.date>this.endDate){this.viewDate=new Date(this.endDate)}else{this.viewDate=new Date(this.date)}}this.fill()},fillDow:function(){var i=this.weekStart,j="<tr>";while(i<this.weekStart+7){j+='<th class="dow">'+e[this.language].daysMin[(i++)%7]+"</th>"}j+="</tr>";this.picker.find(".datetimepicker-days thead").append(j)},fillMonths:function(){var l="";var m=new Date(this.viewDate);for(var k=0;k<12;k++){m.setUTCMonth(k);var j=this.onRenderMonth(m);l+='<span class="'+j.join(" ")+'">'+e[this.language].monthsShort[k]+"</span>"}this.picker.find(".datetimepicker-months td").html(l)},fill:function(){if(!this.date||!this.viewDate){return}var E=new Date(this.viewDate),t=E.getUTCFullYear(),G=E.getUTCMonth(),n=E.getUTCDate(),A=E.getUTCHours(),w=this.startDate.getUTCFullYear(),B=this.startDate.getUTCMonth(),p=this.endDate.getUTCFullYear(),x=this.endDate.getUTCMonth()+1,q=(new h(this.date.getUTCFullYear(),this.date.getUTCMonth(),this.date.getUTCDate())).valueOf(),D=new Date();this.setTitle(".datetimepicker-days",e[this.language].months[G]+" "+t);if(this.formatViewType==="time"){var k=this.getFormattedDate();this.setTitle(".datetimepicker-hours",k);this.setTitle(".datetimepicker-minutes",k)}else{this.setTitle(".datetimepicker-hours",n+" "+e[this.language].months[G]+" "+t);this.setTitle(".datetimepicker-minutes",n+" "+e[this.language].months[G]+" "+t)}this.picker.find("tfoot th.today").text(e[this.language].today||e.en.today).toggle(this.todayBtn!==false);this.picker.find("tfoot th.clear").text(e[this.language].clear||e.en.clear).toggle(this.clearBtn!==false);this.updateNavArrows();this.fillMonths();var I=h(t,G-1,28,0,0,0,0),z=c.getDaysInMonth(I.getUTCFullYear(),I.getUTCMonth());I.setUTCDate(z);I.setUTCDate(z-(I.getUTCDay()-this.weekStart+7)%7);var j=new Date(I);j.setUTCDate(j.getUTCDate()+42);j=j.valueOf();var r=[];var F;while(I.valueOf()<j){if(I.getUTCDay()===this.weekStart){r.push("<tr>")}F=this.onRenderDay(I);if(I.getUTCFullYear()<t||(I.getUTCFullYear()===t&&I.getUTCMonth()<G)){F.push("old")}else{if(I.getUTCFullYear()>t||(I.getUTCFullYear()===t&&I.getUTCMonth()>G)){F.push("new")}}if(this.todayHighlight&&I.getUTCFullYear()===D.getFullYear()&&I.getUTCMonth()===D.getMonth()&&I.getUTCDate()===D.getDate()){F.push("today")}if(I.valueOf()===q){F.push("active")}if((I.valueOf()+86400000)<=this.startDate||I.valueOf()>this.endDate||d.inArray(I.getUTCDay(),this.daysOfWeekDisabled)!==-1||d.inArray(I.toDateString(),this.datesDisabled)!==-1){F.push("disabled")}r.push('<td class="'+F.join(" ")+'">'+I.getUTCDate()+"</td>");if(I.getUTCDay()===this.weekEnd){r.push("</tr>")}I.setUTCDate(I.getUTCDate()+1)}this.picker.find(".datetimepicker-days tbody").empty().append(r.join(""));r=[];var u="",C="",s="";var l=this.hoursDisabled||[];E=new Date(this.viewDate);for(var y=0;y<24;y++){E.setUTCHours(y);F=this.onRenderHour(E);if(l.indexOf(y)!==-1){F.push("disabled")}var v=h(t,G,n,y);if((v.valueOf()+3600000)<=this.startDate||v.valueOf()>this.endDate){F.push("disabled")}else{if(A===y){F.push("active")}}if(this.showMeridian&&e[this.language].meridiem.length===2){C=(y<12?e[this.language].meridiem[0]:e[this.language].meridiem[1]);if(C!==s){if(s!==""){r.push("</fieldset>")}r.push('<fieldset class="hour"><legend>'+C.toUpperCase()+"</legend>")}s=C;u=(y%12?y%12:12);if(y<12){F.push("hour_am")}else{F.push("hour_pm")}r.push('<span class="'+F.join(" ")+'">'+u+"</span>");if(y===23){r.push("</fieldset>")}}else{u=y+":00";r.push('<span class="'+F.join(" ")+'">'+u+"</span>")}}this.picker.find(".datetimepicker-hours td").html(r.join(""));r=[];u="";C="";s="";var m=this.minutesDisabled||[];E=new Date(this.viewDate);for(var y=0;y<60;y+=this.minuteStep){if(m.indexOf(y)!==-1){continue}E.setUTCMinutes(y);E.setUTCSeconds(0);F=this.onRenderMinute(E);if(this.showMeridian&&e[this.language].meridiem.length===2){C=(A<12?e[this.language].meridiem[0]:e[this.language].meridiem[1]);if(C!==s){if(s!==""){r.push("</fieldset>")}r.push('<fieldset class="minute"><legend>'+C.toUpperCase()+"</legend>")}s=C;u=(A%12?A%12:12);r.push('<span class="'+F.join(" ")+'">'+u+":"+(y<10?"0"+y:y)+"</span>");if(y===59){r.push("</fieldset>")}}else{u=y+":00";r.push('<span class="'+F.join(" ")+'">'+A+":"+(y<10?"0"+y:y)+"</span>")}}this.picker.find(".datetimepicker-minutes td").html(r.join(""));var J=this.date.getUTCFullYear();var o=this.setTitle(".datetimepicker-months",t).end().find(".month").removeClass("active");if(J===t){o.eq(this.date.getUTCMonth()).addClass("active")}if(t<w||t>p){o.addClass("disabled")}if(t===w){o.slice(0,B).addClass("disabled")}if(t===p){o.slice(x).addClass("disabled")}r="";t=parseInt(t/10,10)*10;var H=this.setTitle(".datetimepicker-years",t+"-"+(t+9)).end().find("td");t-=1;E=new Date(this.viewDate);for(var y=-1;y<11;y++){E.setUTCFullYear(t);F=this.onRenderYear(E);if(y===-1||y===10){F.push(b)}r+='<span class="'+F.join(" ")+'">'+t+"</span>";t+=1}H.html(r);this.place()},updateNavArrows:function(){var m=new Date(this.viewDate),k=m.getUTCFullYear(),l=m.getUTCMonth(),j=m.getUTCDate(),i=m.getUTCHours();switch(this.viewMode){case 0:if(k<=this.startDate.getUTCFullYear()&&l<=this.startDate.getUTCMonth()&&j<=this.startDate.getUTCDate()&&i<=this.startDate.getUTCHours()){this.picker.find(".prev").css({visibility:"hidden"})}else{this.picker.find(".prev").css({visibility:"visible"})}if(k>=this.endDate.getUTCFullYear()&&l>=this.endDate.getUTCMonth()&&j>=this.endDate.getUTCDate()&&i>=this.endDate.getUTCHours()){this.picker.find(".next").css({visibility:"hidden"})}else{this.picker.find(".next").css({visibility:"visible"})}break;case 1:if(k<=this.startDate.getUTCFullYear()&&l<=this.startDate.getUTCMonth()&&j<=this.startDate.getUTCDate()){this.picker.find(".prev").css({visibility:"hidden"})}else{this.picker.find(".prev").css({visibility:"visible"})}if(k>=this.endDate.getUTCFullYear()&&l>=this.endDate.getUTCMonth()&&j>=this.endDate.getUTCDate()){this.picker.find(".next").css({visibility:"hidden"})}else{this.picker.find(".next").css({visibility:"visible"})}break;case 2:if(k<=this.startDate.getUTCFullYear()&&l<=this.startDate.getUTCMonth()){this.picker.find(".prev").css({visibility:"hidden"})}else{this.picker.find(".prev").css({visibility:"visible"})}if(k>=this.endDate.getUTCFullYear()&&l>=this.endDate.getUTCMonth()){this.picker.find(".next").css({visibility:"hidden"})}else{this.picker.find(".next").css({visibility:"visible"})}break;case 3:case 4:if(k<=this.startDate.getUTCFullYear()){this.picker.find(".prev").css({visibility:"hidden"})}else{this.picker.find(".prev").css({visibility:"visible"})}if(k>=this.endDate.getUTCFullYear()){this.picker.find(".next").css({visibility:"hidden"})}else{this.picker.find(".next").css({visibility:"visible"})}break}},mousewheel:function(j){j.preventDefault();j.stopPropagation();if(this.wheelPause){return}this.wheelPause=true;var i=j.originalEvent;var l=i.wheelDelta;var k=l>0?1:(l===0)?0:-1;if(this.wheelViewModeNavigationInverseDirection){k=-k}this.showMode(k);setTimeout(d.proxy(function(){this.wheelPause=false},this),this.wheelViewModeNavigationDelay)},click:function(m){m.stopPropagation();m.preventDefault();var n=d(m.target).closest("span, td, th, legend");if(n.is("."+this.icontype)){n=d(n).parent().closest("span, td, th, legend")}if(n.length===1){if(n.is(".disabled")){this.element.trigger({type:"outOfRange",date:this.viewDate,startDate:this.startDate,endDate:this.endDate});return}switch(n[0].nodeName.toLowerCase()){case"th":switch(n[0].className){case"switch":this.showMode(1);break;case"prev":case"next":var i=c.modes[this.viewMode].navStep*(n[0].className==="prev"?-1:1);switch(this.viewMode){case 0:this.viewDate=this.moveHour(this.viewDate,i);break;case 1:this.viewDate=this.moveDate(this.viewDate,i);break;case 2:this.viewDate=this.moveMonth(this.viewDate,i);break;case 3:case 4:this.viewDate=this.moveYear(this.viewDate,i);break}this.fill();this.element.trigger({type:n[0].className+":"+this.convertViewModeText(this.viewMode),date:this.viewDate,startDate:this.startDate,endDate:this.endDate});break;case"clear":this.reset();if(this.autoclose){this.hide()}break;case"today":var j=new Date();j=h(j.getFullYear(),j.getMonth(),j.getDate(),j.getHours(),j.getMinutes(),j.getSeconds(),0);if(j<this.startDate){j=this.startDate}else{if(j>this.endDate){j=this.endDate}}this.viewMode=this.startViewMode;this.showMode(0);this._setDate(j);this.fill();if(this.autoclose){this.hide()}break}break;case"span":if(!n.is(".disabled")){var p=this.viewDate.getUTCFullYear(),o=this.viewDate.getUTCMonth(),q=this.viewDate.getUTCDate(),r=this.viewDate.getUTCHours(),k=this.viewDate.getUTCMinutes(),s=this.viewDate.getUTCSeconds();if(n.is(".month")){this.viewDate.setUTCDate(1);o=n.parent().find("span").index(n);q=this.viewDate.getUTCDate();this.viewDate.setUTCMonth(o);this.element.trigger({type:"changeMonth",date:this.viewDate});if(this.viewSelect>=3){this._setDate(h(p,o,q,r,k,s,0))}}else{if(n.is(".year")){this.viewDate.setUTCDate(1);p=parseInt(n.text(),10)||0;this.viewDate.setUTCFullYear(p);this.element.trigger({type:"changeYear",date:this.viewDate});if(this.viewSelect>=4){this._setDate(h(p,o,q,r,k,s,0))}}else{if(n.is(".hour")){r=parseInt(n.text(),10)||0;if(n.hasClass("hour_am")||n.hasClass("hour_pm")){if(r===12&&n.hasClass("hour_am")){r=0}else{if(r!==12&&n.hasClass("hour_pm")){r+=12}}}this.viewDate.setUTCHours(r);this.element.trigger({type:"changeHour",date:this.viewDate});if(this.viewSelect>=1){this._setDate(h(p,o,q,r,k,s,0))}}else{if(n.is(".minute")){k=parseInt(n.text().substr(n.text().indexOf(":")+1),10)||0;this.viewDate.setUTCMinutes(k);this.element.trigger({type:"changeMinute",date:this.viewDate});if(this.viewSelect>=0){this._setDate(h(p,o,q,r,k,s,0))}}}}}if(this.viewMode!==0){var l=this.viewMode;this.showMode(-1);this.fill();if(l===this.viewMode&&this.autoclose){this.hide()}}else{this.fill();if(this.autoclose){this.hide()}}}break;case"td":if(n.is(".day")&&!n.is(".disabled")){var q=parseInt(n.text(),10)||1;var p=this.viewDate.getUTCFullYear(),o=this.viewDate.getUTCMonth(),r=this.viewDate.getUTCHours(),k=this.viewDate.getUTCMinutes(),s=this.viewDate.getUTCSeconds();if(n.is(".old")){if(o===0){o=11;p-=1}else{o-=1}}else{if(n.is(".new")){if(o===11){o=0;p+=1}else{o+=1}}}this.viewDate.setUTCFullYear(p);this.viewDate.setUTCMonth(o,q);this.element.trigger({type:"changeDay",date:this.viewDate});if(this.viewSelect>=2){this._setDate(h(p,o,q,r,k,s,0))}}var l=this.viewMode;this.showMode(-1);this.fill();if(l===this.viewMode&&this.autoclose){this.hide()}break}}},_setDate:function(i,k){if(!k||k==="date"){this.date=i}if(!k||k==="view"){this.viewDate=i}this.fill();this.setValue();var j;if(this.isInput){j=this.element}else{if(this.component){j=this.element.find("input")}}if(j){j.change()}this.element.trigger({type:"changeDate",date:this.getDate()});if(i===null){this.date=this.viewDate}},moveMinute:function(j,i){if(!i){return j}var k=new Date(j.valueOf());k.setUTCMinutes(k.getUTCMinutes()+(i*this.minuteStep));return k},moveHour:function(j,i){if(!i){return j}var k=new Date(j.valueOf());k.setUTCHours(k.getUTCHours()+i);return k},moveDate:function(j,i){if(!i){return j}var k=new Date(j.valueOf());k.setUTCDate(k.getUTCDate()+i);return k},moveMonth:function(j,k){if(!k){return j}var n=new Date(j.valueOf()),r=n.getUTCDate(),o=n.getUTCMonth(),m=Math.abs(k),q,p;k=k>0?1:-1;if(m===1){p=k===-1?function(){return n.getUTCMonth()===o}:function(){return n.getUTCMonth()!==q};q=o+k;n.setUTCMonth(q);if(q<0||q>11){q=(q+12)%12}}else{for(var l=0;l<m;l++){n=this.moveMonth(n,k)}q=n.getUTCMonth();n.setUTCDate(r);p=function(){return q!==n.getUTCMonth()}}while(p()){n.setUTCDate(--r);n.setUTCMonth(q)}return n},moveYear:function(j,i){return this.moveMonth(j,i*12)},dateWithinRange:function(i){return i>=this.startDate&&i<=this.endDate},keydown:function(o){if(this.picker.is(":not(:visible)")){if(o.keyCode===27){this.show()}return}var k=false,j,i,n;switch(o.keyCode){case 27:this.hide();o.preventDefault();break;case 37:case 39:if(!this.keyboardNavigation){break}j=o.keyCode===37?-1:1;var m=this.viewMode;if(o.ctrlKey){m+=2}else{if(o.shiftKey){m+=1}}if(m===4){i=this.moveYear(this.date,j);n=this.moveYear(this.viewDate,j)}else{if(m===3){i=this.moveMonth(this.date,j);n=this.moveMonth(this.viewDate,j)}else{if(m===2){i=this.moveDate(this.date,j);n=this.moveDate(this.viewDate,j)}else{if(m===1){i=this.moveHour(this.date,j);n=this.moveHour(this.viewDate,j)}else{if(m===0){i=this.moveMinute(this.date,j);n=this.moveMinute(this.viewDate,j)}}}}}if(this.dateWithinRange(i)){this.date=i;this.viewDate=n;this.setValue();this.update();o.preventDefault();k=true}break;case 38:case 40:if(!this.keyboardNavigation){break}j=o.keyCode===38?-1:1;m=this.viewMode;if(o.ctrlKey){m+=2}else{if(o.shiftKey){m+=1}}if(m===4){i=this.moveYear(this.date,j);n=this.moveYear(this.viewDate,j)}else{if(m===3){i=this.moveMonth(this.date,j);n=this.moveMonth(this.viewDate,j)}else{if(m===2){i=this.moveDate(this.date,j*7);n=this.moveDate(this.viewDate,j*7)}else{if(m===1){if(this.showMeridian){i=this.moveHour(this.date,j*6);n=this.moveHour(this.viewDate,j*6)}else{i=this.moveHour(this.date,j*4);n=this.moveHour(this.viewDate,j*4)}}else{if(m===0){i=this.moveMinute(this.date,j*4);n=this.moveMinute(this.viewDate,j*4)}}}}}if(this.dateWithinRange(i)){this.date=i;this.viewDate=n;this.setValue();this.update();o.preventDefault();k=true}break;case 13:if(this.viewMode!==0){var p=this.viewMode;this.showMode(-1);this.fill();if(p===this.viewMode&&this.autoclose){this.hide()}}else{this.fill();if(this.autoclose){this.hide()}}o.preventDefault();break;case 9:this.hide();break}if(k){var l;if(this.isInput){l=this.element}else{if(this.component){l=this.element.find("input")}}if(l){l.change()}this.element.trigger({type:"changeDate",date:this.getDate()})}},showMode:function(i){if(i){var j=Math.max(0,Math.min(c.modes.length-1,this.viewMode+i));if(j>=this.minView&&j<=this.maxView){this.element.trigger({type:"changeMode",date:this.viewDate,oldViewMode:this.viewMode,newViewMode:j});this.viewMode=j}}this.picker.find(">div").hide().filter(".datetimepicker-"+c.modes[this.viewMode].clsName).css("display","block");this.updateNavArrows()},reset:function(){this._setDate(null,"date")},convertViewModeText:function(i){switch(i){case 4:return"decade";case 3:return"year";case 2:return"month";case 1:return"day";case 0:return"hour"}}};var b=d.fn.datetimepicker;d.fn.datetimepicker=function(k){var i=Array.apply(null,arguments);i.shift();var j;this.each(function(){var n=d(this),m=n.data("datetimepicker"),l=typeof k==="object"&&k;if(!m){n.data("datetimepicker",(m=new g(this,d.extend({},d.fn.datetimepicker.defaults,l))))}if(typeof k==="string"&&typeof m[k]==="function"){j=m[k].apply(m,i);if(j!==f){return false}}});if(j!==f){return j}else{return this}};d.fn.datetimepicker.defaults={};d.fn.datetimepicker.Constructor=g;var e=d.fn.datetimepicker.dates={en:{days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],daysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat","Sun"],daysMin:["Su","Mo","Tu","We","Th","Fr","Sa","Su"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],meridiem:["am","pm"],suffix:["st","nd","rd","th"],today:"Today",clear:"Clear"}};var c={modes:[{clsName:"minutes",navFnc:"Hours",navStep:1},{clsName:"hours",navFnc:"Date",navStep:1},{clsName:"days",navFnc:"Month",navStep:1},{clsName:"months",navFnc:"FullYear",navStep:1},{clsName:"years",navFnc:"FullYear",navStep:10}],isLeapYear:function(i){return(((i%4===0)&&(i%100!==0))||(i%400===0))},getDaysInMonth:function(i,j){return[31,(c.isLeapYear(i)?29:28),31,30,31,30,31,31,30,31,30,31][j]},getDefaultFormat:function(i,j){if(i==="standard"){if(j==="input"){return"yyyy-mm-dd hh:ii"}else{return"yyyy-mm-dd hh:ii:ss"}}else{if(i==="php"){if(j==="input"){return"Y-m-d H:i"}else{return"Y-m-d H:i:s"}}else{throw new Error("Invalid format type.")}}},validParts:function(i){if(i==="standard"){return/t|hh?|HH?|p|P|z|Z|ii?|ss?|dd?|DD?|mm?|MM?|yy(?:yy)?/g}else{if(i==="php"){return/[dDjlNwzFmMnStyYaABgGhHis]/g}else{throw new Error("Invalid format type.")}}},nonpunctuation:/[^ -\/:-@\[-`{-~\t\n\rTZ]+/g,parseFormat:function(l,j){var i=l.replace(this.validParts(j),"\0").split("\0"),k=l.match(this.validParts(j));if(!i||!i.length||!k||k.length===0){throw new Error("Invalid date format.")}return{separators:i,parts:k}},parseDate:function(A,y,v,j,r){if(A instanceof Date){var u=new Date(A.valueOf()-A.getTimezoneOffset()*60000);u.setMilliseconds(0);return u}if(/^\d{4}\-\d{1,2}\-\d{1,2}$/.test(A)){y=this.parseFormat("yyyy-mm-dd",j)}if(/^\d{4}\-\d{1,2}\-\d{1,2}[T ]\d{1,2}\:\d{1,2}$/.test(A)){y=this.parseFormat("yyyy-mm-dd hh:ii",j)}if(/^\d{4}\-\d{1,2}\-\d{1,2}[T ]\d{1,2}\:\d{1,2}\:\d{1,2}[Z]{0,1}$/.test(A)){y=this.parseFormat("yyyy-mm-dd hh:ii:ss",j)}if(/^[-+]\d+[dmwy]([\s,]+[-+]\d+[dmwy])*$/.test(A)){var l=/([-+]\d+)([dmwy])/,q=A.match(/([-+]\d+)([dmwy])/g),t,p;A=new Date();for(var x=0;x<q.length;x++){t=l.exec(q[x]);p=parseInt(t[1]);switch(t[2]){case"d":A.setUTCDate(A.getUTCDate()+p);break;case"m":A=g.prototype.moveMonth.call(g.prototype,A,p);break;case"w":A.setUTCDate(A.getUTCDate()+p*7);break;case"y":A=g.prototype.moveYear.call(g.prototype,A,p);break}}return h(A.getUTCFullYear(),A.getUTCMonth(),A.getUTCDate(),A.getUTCHours(),A.getUTCMinutes(),A.getUTCSeconds(),0)}var q=A&&A.toString().match(this.nonpunctuation)||[],A=new Date(0,0,0,0,0,0,0),m={},z=["hh","h","ii","i","ss","s","yyyy","yy","M","MM","m","mm","D","DD","d","dd","H","HH","p","P","z","Z"],o={hh:function(s,i){return s.setUTCHours(i)},h:function(s,i){return s.setUTCHours(i)},HH:function(s,i){return s.setUTCHours(i===12?0:i)},H:function(s,i){return s.setUTCHours(i===12?0:i)},ii:function(s,i){return s.setUTCMinutes(i)},i:function(s,i){return s.setUTCMinutes(i)},ss:function(s,i){return s.setUTCSeconds(i)},s:function(s,i){return s.setUTCSeconds(i)},yyyy:function(s,i){return s.setUTCFullYear(i)},yy:function(s,i){return s.setUTCFullYear(2000+i)},m:function(s,i){i-=1;while(i<0){i+=12}i%=12;s.setUTCMonth(i);while(s.getUTCMonth()!==i){if(isNaN(s.getUTCMonth())){return s}else{s.setUTCDate(s.getUTCDate()-1)}}return s},d:function(s,i){return s.setUTCDate(i)},p:function(s,i){return s.setUTCHours(i===1?s.getUTCHours()+12:s.getUTCHours())},z:function(){return r}},B,k,t;o.M=o.MM=o.mm=o.m;o.dd=o.d;o.P=o.p;o.Z=o.z;A=h(A.getFullYear(),A.getMonth(),A.getDate(),A.getHours(),A.getMinutes(),A.getSeconds());if(q.length===y.parts.length){for(var x=0,w=y.parts.length;x<w;x++){B=parseInt(q[x],10);t=y.parts[x];if(isNaN(B)){switch(t){case"MM":k=d(e[v].months).filter(function(){var i=this.slice(0,q[x].length),s=q[x].slice(0,i.length);return i===s});B=d.inArray(k[0],e[v].months)+1;break;case"M":k=d(e[v].monthsShort).filter(function(){var i=this.slice(0,q[x].length),s=q[x].slice(0,i.length);return i.toLowerCase()===s.toLowerCase()});B=d.inArray(k[0],e[v].monthsShort)+1;break;case"p":case"P":B=d.inArray(q[x].toLowerCase(),e[v].meridiem);break;case"z":case"Z":r;break}}m[t]=B}for(var x=0,n;x<z.length;x++){n=z[x];if(n in m&&!isNaN(m[n])){o[n](A,m[n])}}}return A},formatDate:function(l,q,m,p,o){if(l===null){return""}var k;if(p==="standard"){k={t:l.getTime(),yy:l.getUTCFullYear().toString().substring(2),yyyy:l.getUTCFullYear(),m:l.getUTCMonth()+1,M:e[m].monthsShort[l.getUTCMonth()],MM:e[m].months[l.getUTCMonth()],d:l.getUTCDate(),D:e[m].daysShort[l.getUTCDay()],DD:e[m].days[l.getUTCDay()],p:(e[m].meridiem.length===2?e[m].meridiem[l.getUTCHours()<12?0:1]:""),h:l.getUTCHours(),i:l.getUTCMinutes(),s:l.getUTCSeconds(),z:o};if(e[m].meridiem.length===2){k.H=(k.h%12===0?12:k.h%12)}else{k.H=k.h}k.HH=(k.H<10?"0":"")+k.H;k.P=k.p.toUpperCase();k.Z=k.z;k.hh=(k.h<10?"0":"")+k.h;k.ii=(k.i<10?"0":"")+k.i;k.ss=(k.s<10?"0":"")+k.s;k.dd=(k.d<10?"0":"")+k.d;k.mm=(k.m<10?"0":"")+k.m}else{if(p==="php"){k={y:l.getUTCFullYear().toString().substring(2),Y:l.getUTCFullYear(),F:e[m].months[l.getUTCMonth()],M:e[m].monthsShort[l.getUTCMonth()],n:l.getUTCMonth()+1,t:c.getDaysInMonth(l.getUTCFullYear(),l.getUTCMonth()),j:l.getUTCDate(),l:e[m].days[l.getUTCDay()],D:e[m].daysShort[l.getUTCDay()],w:l.getUTCDay(),N:(l.getUTCDay()===0?7:l.getUTCDay()),S:(l.getUTCDate()%10<=e[m].suffix.length?e[m].suffix[l.getUTCDate()%10-1]:""),a:(e[m].meridiem.length===2?e[m].meridiem[l.getUTCHours()<12?0:1]:""),g:(l.getUTCHours()%12===0?12:l.getUTCHours()%12),G:l.getUTCHours(),i:l.getUTCMinutes(),s:l.getUTCSeconds()};k.m=(k.n<10?"0":"")+k.n;k.d=(k.j<10?"0":"")+k.j;k.A=k.a.toString().toUpperCase();k.h=(k.g<10?"0":"")+k.g;k.H=(k.G<10?"0":"")+k.G;k.i=(k.i<10?"0":"")+k.i;k.s=(k.s<10?"0":"")+k.s}else{throw new Error("Invalid format type.")}}var l=[],r=d.extend([],q.separators);for(var n=0,j=q.parts.length;n<j;n++){if(r.length){l.push(r.shift())}l.push(k[q.parts[n]])}if(r.length){l.push(r.shift())}return l.join("")},convertViewMode:function(i){switch(i){case 4:case"decade":i=4;break;case 3:case"year":i=3;break;case 2:case"month":i=2;break;case 1:case"day":i=1;break;case 0:case"hour":i=0;break}return i},headTemplate:'<thead><tr><th class="prev"><i class="{iconType} {leftArrow}"/></th><th colspan="5" class="switch"></th><th class="next"><i class="{iconType} {rightArrow}"/></th></tr></thead>',headTemplateV3:'<thead><tr><th class="prev"><span class="{iconType} {leftArrow}"></span> </th><th colspan="5" class="switch"></th><th class="next"><span class="{iconType} {rightArrow}"></span> </th></tr></thead>',contTemplate:'<tbody><tr><td colspan="7"></td></tr></tbody>',footTemplate:'<tfoot><tr><th colspan="7" class="today"></th></tr><tr><th colspan="7" class="clear"></th></tr></tfoot>'};c.template='<div class="datetimepicker"><div class="datetimepicker-minutes"><table class=" table-condensed">'+c.headTemplate+c.contTemplate+c.footTemplate+'</table></div><div class="datetimepicker-hours"><table class=" table-condensed">'+c.headTemplate+c.contTemplate+c.footTemplate+'</table></div><div class="datetimepicker-days"><table class=" table-condensed">'+c.headTemplate+"<tbody></tbody>"+c.footTemplate+'</table></div><div class="datetimepicker-months"><table class="table-condensed">'+c.headTemplate+c.contTemplate+c.footTemplate+'</table></div><div class="datetimepicker-years"><table class="table-condensed">'+c.headTemplate+c.contTemplate+c.footTemplate+"</table></div></div>";c.templateV3='<div class="datetimepicker"><div class="datetimepicker-minutes"><table class=" table-condensed">'+c.headTemplateV3+c.contTemplate+c.footTemplate+'</table></div><div class="datetimepicker-hours"><table class=" table-condensed">'+c.headTemplateV3+c.contTemplate+c.footTemplate+'</table></div><div class="datetimepicker-days"><table class=" table-condensed">'+c.headTemplateV3+"<tbody></tbody>"+c.footTemplate+'</table></div><div class="datetimepicker-months"><table class="table-condensed">'+c.headTemplateV3+c.contTemplate+c.footTemplate+'</table></div><div class="datetimepicker-years"><table class="table-condensed">'+c.headTemplateV3+c.contTemplate+c.footTemplate+"</table></div></div>";d.fn.datetimepicker.DPGlobal=c;d.fn.datetimepicker.noConflict=function(){d.fn.datetimepicker=b;return this};d(document).on("focus.datetimepicker.data-api click.datetimepicker.data-api",'[data-provide="datetimepicker"]',function(j){var i=d(this);if(i.data("datetimepicker")){return}j.preventDefault();i.datetimepicker("show")});d(function(){d('[data-provide="datetimepicker-inline"]').datetimepicker()})}));
WRFILE: pgcluu_slide.min.js

jQuery(function(){jQuery(".slide").hide();jQuery(".active-slide").show();var a=location.hash;if(a){a=a.substring(1);var d=document.getElementById(a);var c=jQuery(d).parent().attr("id");if(c!=undefined){var b="#"+c;jQuery("#main-container li.slide").removeClass("active-slide").hide();jQuery(b).addClass("active-slide").fadeIn();window.location.hash="#"+a}}jQuery(".navbar li.dropdown").click(function(){var g=jQuery(this).attr("id");g=g.substring(5);if((g=="home")||(g=="about")||(g=="info")){var e="#"+g+"-slide";var f=jQuery("#main-container .active-slide").attr("id");f="#"+f;if(e!=f){jQuery("#main-container li.slide").removeClass("active-slide").hide();jQuery(e).addClass("active-slide").fadeIn()}}});jQuery(".navbar li ul li").click(function(){var g=jQuery(this).attr("id");var h=g.substring(5);if(h.lastIndexOf("-")>0){var e=document.getElementById(h+"-slide");if(e!=undefined){var f="#"+h+"-slide";jQuery("#main-container li.slide").removeClass("active-slide").hide();jQuery(f).addClass("active-slide").fadeIn()}}})});jQuery(document).ready(function(){jQuery(".sql").dblclick(function(){if(this.style==undefined||this.style.whiteSpace=="pre"){this.style.whiteSpace="normal"}else{this.style.whiteSpace="pre"}});jQuery(".icon-copy").click(function(){var d=$(this).parent()[0];if(window.getSelection){var c=window.getSelection();c.removeAllRanges();var a=document.createRange();a.selectNodeContents(d);c.addRange(a)}else{if(document.selection){var b=document.body.createTextRange();b.moveToElementText(d);b.select()}}})});
WRFILE: pgcluu.min.css

html{overflow-x:hidden}body{padding-top:70px}footer{padding:30px 0}ul#slides li{list-style-type:none}ul#slides{margin:0;padding:0}ul#slides li div div{padding:0 .2em}.mainmenu{height:80px;width:100%}.linegraph{width:900px;height:400px;background:#fff;border:4px double white;padding:0 10px;margin:35px auto}.piegraph{width:500px;height:250px;background:#fff;border:4px double white;padding:0 10px;margin:35px auto}.smallgraph{width:600px;height:150px;background:#fff;border:4px double white;padding:0 10px;margin:35px auto}.dropdown{font-size:1.2em}.dropdown-submenu{position:relative}.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px}.dropdown-submenu:hover>.dropdown-menu{display:block}.dropdown-submenu>a:after{display:block;content:" ";float:right;width:0;height:0;border-color:transparent;border-style:solid;border-width:5px 0 5px 5px;border-left-color:#ccc;margin-top:5px;margin-right:-10px}.dropdown-submenu:hover>a:after{border-left-color:#fff}.dropdown-submenu.pull-left{float:none}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.container{width:90%}.panel{background-color:#f5f5f5}.panel-body{background-color:#fff;font-size:1.2em}.panel-body a{margin:5px}.panel-footer{background-color:#f5f5f5}.panel-height{min-height:300px}.panel-xlheight{min-height:750px}.btn{margin-top:10px};.key-figures ul{margin:0;padding:0}.key-figures li{list-style-type:none;margin-bottom:.5em}.figure{font-weight:bold;font-size:1.0;color:#c43c35}.figure-label{color:#666;font-size:.9em}.figure-date{color:#333;font-size:.8em}.mouse-figures{font-weight:bold;font-size:1.0;margin:0;padding:0}.mfigure{font-weight:bold;font-size:1.2em;color:#d9534f}.mfigure small{font-weight:bold;font-size:.8em;color:#5f5555}.span11{font-size:.8em}@media screen and (max-width:767px){.row-offcanvas{position:relative;-webkit-transition:all .25s ease-out;-moz-transition:all .25s ease-out;transition:all .25s ease-out}.row-offcanvas-right .sidebar-offcanvas{right:-50%}.row-offcanvas-left .sidebar-offcanvas{left:-50%}.row-offcanvas-right.active{right:50%}.row-offcanvas-left.active{left:50%}.sidebar-offcanvas{position:absolute;top:0;width:50%}}.jqplot-graph{color:#ac1316;z-index:99}.jqplot-target{position:relative;color:#333;font-size:.8em}.jqplot-highlighter-tooltip{border:0;font-size:1.0;white-space:nowrap;font-weight:bold;margin:5px;padding:5px;color:#5f5555;background:#f5f5f5;border:1px solid #DCA;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2)}.jqplot-title{font-size:1.1em;text-transform:uppercase;letter-spacing:.1em;margin:0;padding:0;color:#5f5555}#start-date{color:#000}#end-date{color:#000}#pgcluuModal .modal-dialog{height:100%;width:1200px;overflow-y:hidden}.btn-danger{background:#5f5555;color:#f5f5f5;border:1px solid #DCA}
WRFILE: pgcluu.min.js

function create_download_button(a,b){document.writeln('<button type="button" id="download'+a+'" class="btn btn-danger" data-toggle="modal" data-target="#pgcluuModal">Download</button>');document.writeln('<button type="button" id="csv'+a+'" class="btn btn-danger" >CSV export</button>');document.writeln('<a id="acsv'+a+'" href="#"></a>')}$(document).ready(function(){$(".nav li.disabled a").click(function(){return false})});function add_download_button_event(a,c,b){jQuery("#download"+a).click(function(){$("#pgcluuModal img").attr("src",$("#"+c).jqplotToImageStr({}))});jQuery("#csv"+a).click(function(){export_csv(b,a)})}function create_linegraph(f,c,d,a,b,e){return $.jqplot(f,b,{seriesColors:["#6e9dc9","#f4ab3a","#ac7fa8","#8dbd0f","#958c12","#953579","#4b5de4","#d8b83f","#ff5800","#0085cc"],seriesDefaults:{markerOptions:{show:false},lineWidth:1},grid:{borderWidth:1,background:"#ffffff"},title:c,series:a,axes:{xaxis:{renderer:$.jqplot.DateAxisRenderer,tickOptions:{angle:-30,textColor:"#333"}},yaxis:{label:d,renderer:$.jqplot.LogAxisRenderer,labelRenderer:$.jqplot.CanvasAxisLabelRenderer,tickRenderer:$.jqplot.CanvasAxisTickRenderer,tickOptions:{textColor:"#333",formatter:function(h,g){return pretty_print_number(g,0,d)}}}},legend:{show:true,placement:"outside",location:"e"},cursor:{show:true,zoom:true,showTooltip:false,looseZoom:true,followMouse:true},highlighter:{show:true,tooltipContentEditor:function(n,g,k,l){var j=new Date(l.data[g][k][0]);var m="<div>On "+j.toString().substring(0,33)+"<br>"+j.toString().substring(34);for(var h=0;h<l.data.length;h++){m+='<br><span class="mfigure">'+pretty_print_number(l.data[h][k][1],2,l.series[h].label)+" <small>"+l.series[h].label+"</small></span>"}m+="</div>";return m}}})}function create_piechart(c,b,a){return $.jqplot(c,[a],{seriesColors:["#6e9dc9","#f4ab3a","#ac7fa8","#8dbd0f","#958c12","#953579","#4b5de4","#d8b83f","#ff5800","#0085cc","#4bb2c5","#c5b47f","#EAA228","#579575","#839557","#498991","#C08840","#9F9274","#546D61","#646C4A","#6F6621","#6E3F5F","#4F64B0","#A89050","#C45923","#187399","#945381","#959E5C","#C7AF7B","#478396","#907294"],grid:{borderWidth:1,background:"#ffffff"},title:b,seriesDefaults:{renderer:$.jqplot.PieRenderer,rendererOptions:{showDataLabels:true}},legend:{show:true,location:"e"},highlighter:{show:true,tooltipLocation:"sw",useAxesFormatters:false,tooltipContentEditor:function(h,d,e,f){var g="<div>";g+='<span class="mfigure">'+format_number(f.data[0][e][1])+" <small>"+f.data[0][e][0]+"</small></span>";g+="</div>";return g}}})}function create_bargraph(e,d,a,c,b){return $.jqplot(e,c,{grid:{borderWidth:1,background:"#ffffff"},title:d,seriesDefaults:{rendererOptions:{barPadding:4,barMargin:5}},seriesColors:["#6e9dc9","#8dbd0f","#f4ab3a","#ac7fa8","#958c12","#953579","#4b5de4","#d8b83f","#ff5800","#0085cc"],series:[{renderer:$.jqplot.BarRenderer,label:a},{yaxis:"y2axis",label:b,markerOptions:{show:false},lineWidth:1}],axes:{xaxis:{renderer:$.jqplot.CategoryAxisRenderer,drawMajorGridlines:false,drawMajorTickMarks:false,tickRenderer:$.jqplot.CanvasAxisTickRenderer,tickOptions:{angle:-30,textColor:"#333",formatString:"%H:%M",fontFamily:"Helvetica",fontSize:"8pt"}},yaxis:{autoscale:true,labelRenderer:$.jqplot.CanvasAxisLabelRenderer,tickOptions:{textColor:"#333"},tickRenderer:$.jqplot.CanvasAxisTickRenderer,tickOptions:{textColor:"#333",formatter:function(g,f){return pretty_print_number(f,0,a)},fontFamily:"Helvetica",fontSize:"8pt"},label:a},y2axis:{autoscale:true,labelRenderer:$.jqplot.CanvasAxisLabelRenderer,tickRenderer:$.jqplot.CanvasAxisTickRenderer,tickOptions:{textColor:"#8dbd0f",formatter:function(g,f){return pretty_print_number(f,0,b)},fontFamily:"Helvetica",fontSize:"8pt"},rendererOptions:{alignTicks:true},label:b}},highlighter:{show:true,tooltipLocation:"ne",useAxesFormatters:false,tooltipContentEditor:function(l,f,h,j){var k='<div style="z-index: 99;">At '+j.data[0][h][0];for(var g=0;g<j.data.length;g++){k+='<br><span class="mfigure">'+pretty_print_number(j.data[g][h][1],2,j.series[g].label)+" <small>"+j.series[g].label+"</small></span>"}k+="</div>";return k}}})}function pretty_print_number(c,b,a){if((b==undefined)||((b==0)&&(c!=0))){b=1}if(a!=undefined){a=a.toLowerCase();if(a.search("size")>=0){if(Math.abs(c)>=1125899906842624){c=(c/1125899906842624);return c.toFixed(b)+" PiB"}else{if(Math.abs(c)>=1099511627776){c=(c/1099511627776);return c.toFixed(b)+" TiB"}else{if(Math.abs(c)>=1073741824){c=(c/1073741824);return c.toFixed(b)+" GiB"}else{if(Math.abs(c)>=1048576){c=(c/1048576);return c.toFixed(b)+" MiB"}else{if(Math.abs(c)>=1024){c=(c/1024);return c.toFixed(b)+" KiB"}else{return c.toFixed(b)+" B"}}}}}}else{if(a.search("duration")>=0){if(Math.abs(c)>=1000){c=(c/1000);return c.toFixed(b)+" sec"}else{return c+" ms"}}else{if(Math.abs(c)>=1000000000000000){c=(c/1000000000000000);return c.toFixed(b)+" P"}else{if(Math.abs(c)>=1000000000000){c=(c/1000000000000);return c.toFixed(b)+" T"}else{if(Math.abs(c)>=1000000000){c=(c/1000000000);return c.toFixed(b)+" G"}else{if(Math.abs(c)>=1000000){c=(c/1000000);return c.toFixed(b)+" M"}else{if(Math.abs(c)>=1000){c=(c/1000);return c.toFixed(b)+" K"}}}}}}}}return c.toFixed(b)}function format_number(a){var f=2;var h=",";var k=Math.round(Math.pow(10,f)*(Math.abs(a)-Math.floor(Math.abs(a))));a=Math.floor(Math.abs(a));if((f==0)||(k==Math.pow(10,f))){k=0}var c=a+"";var g=c.length;for(var e=1;e<4;e++){if(a>=Math.pow(10,(3*e))){c=c.substring(0,g-(3*e))+h+c.substring(g-(3*e))}}if(f>0){var b="";for(var d=0;d<(f-k.toString().length);d++){b+="0"}k=b+k.toString();if(k>0){c=c+"."+k}}if(parseFloat(a)<0){c="-"+c}return c}function export_csv(c,b){if(jQuery("#acsv"+b).attr("href")=="#"){var a="data:text/csv;charset=utf-8,";if(c.seriesDefaults!=null){a+='"serie","epoch","value"\n'}else{a+='"serie","value"\n'}_.each(c.series[0]._plotValues.x,function(f,e){_.each(c.series,function(h,g){if(c.plugins.lineRenderer!=null){a+='"'+h.label+'",'+h._plotValues.x[e]+","+h._plotValues.y[e]+"\n"}else{a+='"'+h._plotValues.x[e]+'",'+h._plotValues.y[e]+"\n"}})});var d=encodeURI(a);jQuery("#acsv"+b).attr("href",d).attr("download","data.csv")}document.getElementById("acsv"+b).click()};
WRFILE: sorttable.min.js

var stIsIE=
/*@cc_on!@*/
false;sorttable={init:function(){if(arguments.callee.done){return}arguments.callee.done=true;if(_timer){clearInterval(_timer)}if(!document.createElement||!document.getElementsByTagName){return}sorttable.DATE_RE=/^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/;forEach(document.getElementsByTagName("table"),function(a){if(a.className.search(/\bsortable\b/)!=-1){sorttable.makeSortable(a)}})},makeSortable:function(b){if(b.getElementsByTagName("thead").length==0){the=document.createElement("thead");the.appendChild(b.rows[0]);b.insertBefore(the,b.firstChild)}if(b.tHead==null){b.tHead=b.getElementsByTagName("thead")[0]}if(b.tHead.rows.length!=1){return}sortbottomrows=[];for(var a=0;a<b.rows.length;a++){if(b.rows[a].className.search(/\bsortbottom\b/)!=-1){sortbottomrows[sortbottomrows.length]=b.rows[a]}}if(sortbottomrows){if(b.tFoot==null){tfo=document.createElement("tfoot");b.appendChild(tfo)}for(var a=0;a<sortbottomrows.length;a++){tfo.appendChild(sortbottomrows[a])}delete sortbottomrows}headrow=b.tHead.rows[0].cells;for(var a=0;a<headrow.length;a++){if(!headrow[a].className.match(/\bsorttable_nosort\b/)){mtch=headrow[a].className.match(/\bsorttable_([a-z0-9]+)\b/);if(mtch){override=mtch[1]}if(mtch&&typeof sorttable["sort_"+override]=="function"){headrow[a].sorttable_sortfunction=sorttable["sort_"+override]}else{headrow[a].sorttable_sortfunction=sorttable.guessType(b,a)}headrow[a].sorttable_columnindex=a;headrow[a].sorttable_tbody=b.tBodies[0];dean_addEvent(headrow[a],"click",sorttable.innerSortFunction=function(f){if(this.className.search(/\bsorttable_sorted\b/)!=-1){sorttable.reverse(this.sorttable_tbody);this.className=this.className.replace("sorttable_sorted","sorttable_sorted_reverse");this.removeChild(document.getElementById("sorttable_sortfwdind"));sortrevind=document.createElement("span");sortrevind.id="sorttable_sortrevind";sortrevind.innerHTML=stIsIE?'&nbsp<font face="webdings">5</font>':"&nbsp;&#x25B4;";this.appendChild(sortrevind);return}if(this.className.search(/\bsorttable_sorted_reverse\b/)!=-1){sorttable.reverse(this.sorttable_tbody);this.className=this.className.replace("sorttable_sorted_reverse","sorttable_sorted");this.removeChild(document.getElementById("sorttable_sortrevind"));sortfwdind=document.createElement("span");sortfwdind.id="sorttable_sortfwdind";sortfwdind.innerHTML=stIsIE?'&nbsp<font face="webdings">6</font>':"&nbsp;&#x25BE;";this.appendChild(sortfwdind);return}theadrow=this.parentNode;forEach(theadrow.childNodes,function(e){if(e.nodeType==1){e.className=e.className.replace("sorttable_sorted_reverse","");e.className=e.className.replace("sorttable_sorted","")}});sortfwdind=document.getElementById("sorttable_sortfwdind");if(sortfwdind){sortfwdind.parentNode.removeChild(sortfwdind)}sortrevind=document.getElementById("sorttable_sortrevind");if(sortrevind){sortrevind.parentNode.removeChild(sortrevind)}this.className+=" sorttable_sorted";sortfwdind=document.createElement("span");sortfwdind.id="sorttable_sortfwdind";sortfwdind.innerHTML=stIsIE?'&nbsp<font face="webdings">6</font>':"&nbsp;&#x25BE;";this.appendChild(sortfwdind);row_array=[];col=this.sorttable_columnindex;rows=this.sorttable_tbody.rows;for(var c=0;c<rows.length;c++){row_array[row_array.length]=[sorttable.getInnerText(rows[c].cells[col]),rows[c]]}row_array.sort(this.sorttable_sortfunction);row_array.reverse();tb=this.sorttable_tbody;for(var c=0;c<row_array.length;c++){tb.appendChild(row_array[c][1])}delete row_array})}}},guessType:function(c,b){sortfn=sorttable.sort_alpha;for(var a=0;a<c.tBodies[0].rows.length;a++){text=sorttable.getInnerText(c.tBodies[0].rows[a].cells[b]);if(text!=""){if(text.match(/^-?[£$¤]?[\d,.]+\s*[%KMGTP]?[B]?$/)){return sorttable.sort_numeric}possdate=text.match(sorttable.DATE_RE);if(possdate){first=parseInt(possdate[1]);second=parseInt(possdate[2]);if(first>12){return sorttable.sort_ddmm}else{if(second>12){return sorttable.sort_mmdd}else{sortfn=sorttable.sort_ddmm}}}}}return sortfn},getInnerText:function(b){if(!b){return""}hasInputs=(typeof b.getElementsByTagName=="function")&&b.getElementsByTagName("input").length;if(b.getAttribute("sorttable_customkey")!=null){return b.getAttribute("sorttable_customkey")}else{if(typeof b.textContent!="undefined"&&!hasInputs){return b.textContent.replace(/^\s+|\s+$/g,"")}else{if(typeof b.innerText!="undefined"&&!hasInputs){return b.innerText.replace(/^\s+|\s+$/g,"")}else{if(typeof b.text!="undefined"&&!hasInputs){return b.text.replace(/^\s+|\s+$/g,"")}else{switch(b.nodeType){case 3:if(b.nodeName.toLowerCase()=="input"){return b.value.replace(/^\s+|\s+$/g,"")}case 4:return b.nodeValue.replace(/^\s+|\s+$/g,"");break;case 1:case 11:var c="";for(var a=0;a<b.childNodes.length;a++){c+=sorttable.getInnerText(b.childNodes[a])}return c.replace(/^\s+|\s+$/g,"");break;default:return""}}}}}},reverse:function(a){newrows=[];for(var b=0;b<a.rows.length;b++){newrows[newrows.length]=a.rows[b]}for(var b=newrows.length-1;b>=0;b--){a.appendChild(newrows[b])}delete newrows},sort_numeric:function(e,c){am=1;if(e[0].match(/KB/)){am=1000}else{if(e[0].match(/MB/)){am=1000000}else{if(e[0].match(/GB/)){am=1000000000}else{if(e[0].match(/TB/)){am=1000000000000}else{if(e[0].match(/PB/)){am=1000000000000000}}}}}aa=parseFloat(e[0].replace(/[^0-9.-]/g,""));if(isNaN(aa)){aa=0}aa=aa*am;bm=1;if(c[0].match(/KB/)){bm=1000}else{if(c[0].match(/MB/)){bm=1000000}else{if(c[0].match(/GB/)){bm=1000000000}else{if(c[0].match(/TB/)){bm=1000000000000}else{if(c[0].match(/PB/)){bm=1000000000000000}}}}}bb=parseFloat(c[0].replace(/[^0-9.-]/g,""));if(isNaN(bb)){bb=0}bb=bb*bm;return aa-bb},sort_alpha:function(e,c){if(e[0].replace(/ <.*\(.*%\).*/,"")){c[0].replace(/ <.*\(.*%\).*/,"");aa=parseFloat(e[0].replace(/[^0-9.-]/g,""));if(isNaN(aa)){aa=0}bb=parseFloat(c[0].replace(/[^0-9.-]/g,""));if(isNaN(bb)){bb=0}return aa-bb}else{if(e[0]==c[0]){return 0}if(e[0]<c[0]){return -1}}return 1},sort_ddmm:function(e,c){mtch=e[0].match(sorttable.DATE_RE);y=mtch[3];m=mtch[2];d=mtch[1];if(m.length==1){m="0"+m}if(d.length==1){d="0"+d}dt1=y+m+d;mtch=c[0].match(sorttable.DATE_RE);y=mtch[3];m=mtch[2];d=mtch[1];if(m.length==1){m="0"+m}if(d.length==1){d="0"+d}dt2=y+m+d;if(dt1==dt2){return 0}if(dt1<dt2){return -1}return 1},sort_mmdd:function(e,c){mtch=e[0].match(sorttable.DATE_RE);y=mtch[3];d=mtch[2];m=mtch[1];if(m.length==1){m="0"+m}if(d.length==1){d="0"+d}dt1=y+m+d;mtch=c[0].match(sorttable.DATE_RE);y=mtch[3];d=mtch[2];m=mtch[1];if(m.length==1){m="0"+m}if(d.length==1){d="0"+d}dt2=y+m+d;if(dt1==dt2){return 0}if(dt1<dt2){return -1}return 1},shaker_sort:function(h,f){var a=0;var e=h.length-1;var j=true;while(j){j=false;for(var c=a;c<e;++c){if(f(h[c],h[c+1])>0){var g=h[c];h[c]=h[c+1];h[c+1]=g;j=true}}e--;if(!j){break}for(var c=e;c>a;--c){if(f(h[c],h[c-1])<0){var g=h[c];h[c]=h[c-1];h[c-1]=g;j=true}}a++}}};if(document.addEventListener){document.addEventListener("DOMContentLoaded",sorttable.init,false);
/*@cc_on @*/
/*@if (@_win32)
    document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
    var script = document.getElementById("__ie_onload");
    script.onreadystatechange = function() {
        if (this.readyState == "complete") {
            sorttable.init(); // call the onload handler
        }
    };
/*@end @*/
}if(/WebKit/i.test(navigator.userAgent)){var _timer=setInterval(function(){if(/loaded|complete/.test(document.readyState)){sorttable.init()}},10)}window.onload=sorttable.init;function dean_addEvent(b,e,c){if(b.addEventListener){b.addEventListener(e,c,false)}else{if(!c.$$guid){c.$$guid=dean_addEvent.guid++}if(!b.events){b.events={}}var a=b.events[e];if(!a){a=b.events[e]={};if(b["on"+e]){a[0]=b["on"+e]}}a[c.$$guid]=c;b["on"+e]=handleEvent}}dean_addEvent.guid=1;function removeEvent(a,c,b){if(a.removeEventListener){a.removeEventListener(c,b,false)}else{if(a.events&&a.events[c]){delete a.events[c][b.$$guid]}}}function handleEvent(e){var c=true;e=e||fixEvent(((this.ownerDocument||this.document||this).parentWindow||window).event);var a=this.events[e.type];for(var b in a){this.$$handleEvent=a[b];if(this.$$handleEvent(e)===false){c=false}}return c}function fixEvent(a){a.preventDefault=fixEvent.preventDefault;a.stopPropagation=fixEvent.stopPropagation;return a}fixEvent.preventDefault=function(){this.returnValue=false};fixEvent.stopPropagation=function(){this.cancelBubble=true};if(!Array.forEach){Array.forEach=function(e,c,b){for(var a=0;a<e.length;a++){c.call(b,e[a],a,e)}}}Function.prototype.forEach=function(a,e,c){for(var b in a){if(typeof this.prototype[b]=="undefined"){e.call(c,a[b],b,a)}}};String.forEach=function(a,c,b){Array.forEach(a.split(""),function(f,e){c.call(b,f,e,a)})};var forEach=function(a,e,b){if(a){var c=Object;if(a instanceof Function){c=Function}else{if(a.forEach instanceof Function){a.forEach(e,b);return}else{if(typeof a=="string"){c=String}else{if(typeof a.length=="number"){c=Array}}}}c.forEach(a,e,b)}};
WRFILE: w3.min.js

"use strict";var w3={};w3.hide=function(a){w3.hideElements(w3.getElements(a))};w3.hideElements=function(c){var b,a=c.length;for(b=0;b<a;b++){w3.hideElement(c[b])}};w3.hideElement=function(a){w3.styleElement(a,"display","none")};w3.show=function(d,b){var c=w3.getElements(d);if(b){w3.hideElements(c)}w3.showElements(c)};w3.showElements=function(c){var b,a=c.length;for(b=0;b<a;b++){w3.showElement(c[b])}};w3.showElement=function(a){w3.styleElement(a,"display","block")};w3.addStyle=function(a,c,b){w3.styleElements(w3.getElements(a),c,b)};w3.styleElements=function(c,e,d){var b,a=c.length;for(b=0;b<a;b++){w3.styleElement(c[b],e,d)}};w3.styleElement=function(a,c,b){a.style.setProperty(c,b)};w3.toggleShow=function(d){var c,a=w3.getElements(d),b=a.length;for(c=0;c<b;c++){if(a[c].style.display=="none"){w3.styleElement(a[c],"display","block")}else{w3.styleElement(a[c],"display","none")}}};w3.addClass=function(b,a){w3.addClassElements(w3.getElements(b),a)};w3.addClassElements=function(d,b){var c,a=d.length;for(c=0;c<a;c++){w3.addClassElement(d[c],b)}};w3.addClassElement=function(e,c){var d,b,a;b=e.className.split(" ");a=c.split(" ");for(d=0;d<a.length;d++){if(b.indexOf(a[d])==-1){e.className+=" "+a[d]}}};w3.removeClass=function(b,a){w3.removeClassElements(w3.getElements(b),a)};w3.removeClassElements=function(g,e){var f,a=g.length,d,b,c;for(f=0;f<a;f++){w3.removeClassElement(g[f],e)}};w3.removeClassElement=function(e,c){var d,b,a;b=e.className.split(" ");a=c.split(" ");for(d=0;d<a.length;d++){while(b.indexOf(a[d])>-1){b.splice(b.indexOf(a[d]),1)}}e.className=b.join(" ")};w3.toggleClass=function(c,b,a){w3.toggleClassElements(w3.getElements(c),b,a)};w3.toggleClassElements=function(e,d,c){var b,a=e.length;for(b=0;b<a;b++){w3.toggleClassElement(e[b],d,c)}};w3.toggleClassElement=function(f,e,a){var i,h,k,b,c,g,d;i=(e||"");h=(a||"");k=i.split(" ");b=h.split(" ");g=f.className.split(" ");if(b.length==0){d=true;for(c=0;c<k.length;c++){if(g.indexOf(k[c])==-1){d=false}}if(d){w3.removeClassElement(f,i)}else{w3.addClassElement(f,i)}}else{d=true;for(c=0;c<k.length;c++){if(g.indexOf(k[c])==-1){d=false}}if(d){w3.removeClassElement(f,i);w3.addClassElement(f,h)}else{w3.removeClassElement(f,h);w3.addClassElement(f,i)}}};w3.getElements=function(a){if(typeof a=="object"){return[a]}else{return document.querySelectorAll(a)}};w3.filterHTML=function(e,g,f){var m,l,j,h,n,k,d;m=w3.getElements(e);for(h=0;h<m.length;h++){l=w3.getElements(g);for(n=0;n<l.length;n++){d=0;if(l[n].innerHTML.toUpperCase().indexOf(f.toUpperCase())>-1){d=1}j=l[n].getElementsByTagName("*");for(k=0;k<j.length;k++){if(j[k].innerHTML.toUpperCase().indexOf(f.toUpperCase())>-1){d=1}}if(d==1){l[n].style.display=""}else{l[n].style.display="none"}}}};w3.sortHTML=function(c,d,e){var o,m,k,q,l,g,p,n,f,h;o=w3.getElements(c);for(k=0;k<o.length;k++){for(h=0;h<2;h++){f=0;l=1;while(l==1){l=0;m=o[k].querySelectorAll(d);for(q=0;q<(m.length-1);q++){g=0;if(e){p=m[q].querySelector(e).innerHTML.toLowerCase();n=m[q+1].querySelector(e).innerHTML.toLowerCase()}else{p=m[q].innerHTML.toLowerCase();n=m[q+1].innerHTML.toLowerCase()}if((h==0&&(p>n))||(h==1&&(p<n))){g=1;break}}if(g==1){m[q].parentNode.insertBefore(m[q+1],m[q]);l=1;f++}}if(f>0){break}}}};w3.slideshow=function(g,c,f){var e,d,a=w3.getElements(g),b=a.length;d={};d.current=1;d.x=a;d.ondisplaychange=f;if(!isNaN(c)||c==0){d.milliseconds=c}else{d.milliseconds=1000}d.start=function(){d.display(d.current);if(d.ondisplaychange){d.ondisplaychange()}if(d.milliseconds>0){window.clearTimeout(d.timeout);d.timeout=window.setTimeout(d.next,d.milliseconds)}};d.next=function(){d.current+=1;if(d.current>d.x.length){d.current=1}d.start()};d.previous=function(){d.current-=1;if(d.current<1){d.current=d.x.length}d.start()};d.display=function(h){w3.styleElements(d.x,"display","none");w3.styleElement(d.x[h-1],"display","block")};d.start();return d};w3.includeHTML=function(a){var f,d,c,b,e;f=document.getElementsByTagName("*");for(d=0;d<f.length;d++){c=f[d];b=c.getAttribute("w3-include-html");if(b){e=new XMLHttpRequest();e.onreadystatechange=function(){if(this.readyState==4){if(this.status==200){c.innerHTML=this.responseText}if(this.status==404){c.innerHTML="Page not found."}c.removeAttribute("w3-include-html");w3.includeHTML(a)}};e.open("GET",b,true);e.send();return}}if(a){a()}};w3.getHttpData=function(a,b){w3.http(a,function(){if(this.readyState==4&&this.status==200){b(this.responseText)}})};w3.getHttpObject=function(a,b){w3.http(a,function(){if(this.readyState==4&&this.status==200){b(JSON.parse(this.responseText))}})};w3.displayHttp=function(b,a){w3.http(a,function(){if(this.readyState==4&&this.status==200){w3.displayObject(b,JSON.parse(this.responseText))}})};w3.http=function(d,a,b,e){var c;if(!e){e="GET"}if(window.XMLHttpRequest){c=new XMLHttpRequest()}else{if(window.ActiveXObject){c=new ActiveXObject("Microsoft.XMLHTTP")}}if(c){if(a){c.onreadystatechange=a}c.open(e,d,true);c.send(b)}};w3.getElementsByAttribute=function(b,d){var a=[],h=-1,e,c,g=b.getElementsByTagName("*"),f=d.toUpperCase();c=g.length;for(e=-1;e<c;e+=1){if(e==-1){g[e]=b}if(g[e].getAttribute(f)!==null){h+=1;a[h]=g[e]}}return a};w3.dataObject={},w3.displayObject=function(o,w){var e,c,k,b=[],v,p,y,h,q,r,m,n,g,t,u="";e=document.getElementById(o);c=f(o,e);k=c.cloneNode(true);b=w3.getElementsByAttribute(k,"w3-repeat");p=b.length;for(q=(p-1);q>=0;q-=1){n=b[q].getAttribute("w3-repeat").split(" ");if(n.length==1){g=n[0]}else{u=n[0];g=n[2]}b[q].removeAttribute("w3-repeat");t=w[g];if(t&&typeof t=="object"&&t.length!="undefined"){r=0;for(h in t){r+=1;y=b[q];y=s(y,"element",u,t[h]);v=y.attributes;for(m=0;m<v.length;m+=1){v[m].value=s(v[m],"attribute",u,t[h]).value}(r===t.length)?b[q].parentNode.replaceChild(y,b[q]):b[q].parentNode.insertBefore(y,b[q])}}else{console.log("w3-repeat must be an array. "+g+" is not an array.");continue}}k=s(k,"element");e.parentNode.replaceChild(k,e);function f(j,i){var a;a=i.cloneNode(true);if(w3.dataObject.hasOwnProperty(j)){return w3.dataObject[j]}w3.dataObject[j]=a;return a}function s(A,l,D,G){var I,J,F,E,C,H,B=[],z,j,a;J=A.cloneNode(true);F=0;while(F>-1){C=(l=="attribute")?J.value:J.innerHTML;F=C.indexOf("{{",F);if(F===-1){break}E=C.indexOf("}}",F+1);H=C.substring(F+2,E);B=H.split("||");I=undefined;for(z=0;z<B.length;z+=1){B[z]=B[z].replace(/^\s+|\s+$/gm,"");if(G){I=G[B[z]]}if(I==undefined&&w){I=w[B[z]]}if(I==undefined){j=B[z].split(".");if(j[0]==D){I=G[j[1]]}}if(I==undefined){if(B[z]==D){I=G}}if(I==undefined){if(B[z].substr(0,1)=='"'){I=B[z].replace(/"/g,"")}else{if(B[z].substr(0,1)=="'"){I=B[z].replace(/'/g,"")}}}if(I!=undefined){break}}if(I!=undefined){a="{{"+H+"}}";if(l=="attribute"){J.value=J.value.replace(a,I)}else{d(J,a,I)}}F=F+1}return J}function d(D,G,B){var A,C,F,D,z,E;if(D.hasAttributes()){A=D.attributes;C=A.length;for(F=0;F<C;F+=1){if(A[F].value.indexOf(G)>-1){A[F].value=A[F].value.replace(G,B)}}}z=D.getElementsByTagName("*");C=z.length;D.innerHTML=D.innerHTML.replace(G,B)}};
