Server : LiteSpeed
System : Linux server51.dnsbootclub.com 4.18.0-553.62.1.lve.el8.x86_64 #1 SMP Mon Jul 21 17:50:35 UTC 2025 x86_64
User : nandedex ( 1060)
PHP Version : 8.1.33
Disable Function : NONE
Directory :  /home/nandedex/www/s.nandedexpress.com/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]


Current File : /home/nandedex/www/s.nandedexpress.com/live-news-lite.tar
admin/view/help.php000064400000002660151213253510010251 0ustar00<?php
/**
 * The Help Page in the admin menu.
 */

if ( ! current_user_can( 'manage_options' ) ) {
	wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', $this->shared->get( 'text_domain' ) ) );
}

?>

<!-- output -->

<div class="wrap">

	<h2><?php esc_html_e( 'Live News - Help', $this->shared->get( 'text_domain' ) ); ?></h2>

	<div id="daext-menu-wrapper">

		<p><?php esc_html_e( 'Visit the resources below to find your answers or to ask questions directly to the plugin developers.', $this->shared->get( 'text_domain' ) ); ?></p>
		<ul>
			<li><a href="https://daext.com/doc/live-news/"><?php esc_html_e( 'Plugin Documentation', $this->shared->get( 'text_domain' ) ); ?></a></li>
			<li><a href="https://daext.com/support/"><?php esc_html_e( 'Support Conditions', $this->shared->get( 'text_domain' ) ); ?></li>
			<li><a href="https://daext.com"><?php esc_html_e( 'Developer Website', $this->shared->get( 'text_domain' ) ); ?></a></li>
			<li><a href="https://daext.com/live-news/"><?php esc_html_e( 'Pro Version', $this->shared->get( 'text_domain' ) ); ?></a></li>
			<li><a href="https://wordpress.org/plugins/live-news-lite/"><?php esc_html_e( 'WordPress.org Plugin Page', $this->shared->get( 'text_domain' ) ); ?></a></li>
			<li><a href="https://wordpress.org/support/plugin/live-news-lite/"><?php esc_html_e( 'WordPress.org Support Forum', $this->shared->get( 'text_domain' ) ); ?></a></li>
		</ul>
		<p>

	</div>

admin/view/sliding.php000064400000100547151213253510010755 0ustar00<?php
/**
 * The "Sliding News" menu of the plugin.
 *
 * @package live-news-lite
 */

if ( ! current_user_can( get_option( $this->shared->get( 'slug' ) . '_sliding_menu_capability' ) ) ) {
	wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', $this->shared->get( 'text_domain' ) ) );
}

?>

		<!-- process data -->

		<?php

		// Initialize variables -------------------------------------------------------------------------------------------------.
		$dismissible_notice_a = array();

		// Preliminary operations -----------------------------------------------------------------------------------------------.
		global $wpdb;

		// Sanitization ---------------------------------------------------------------------------------------------.

		// Actions
		$data['edit_id']        = isset( $_GET['edit_id'] ) ? intval( $_GET['edit_id'], 10 ) : null;
		$data['delete_id']      = isset( $_POST['delete_id'] ) ? intval( $_POST['delete_id'], 10 ) : null;
		$data['update_id']      = isset( $_POST['update_id'] ) ? intval( $_POST['update_id'], 10 ) : null;
		$data['form_submitted'] = isset( $_POST['form_submitted'] ) ? intval( $_POST['form_submitted'], 10 ) : null;

		// Filter and search data.
		$data['s']  = isset( $_GET['s'] ) ? sanitize_text_field( $_GET['s'] ) : null;
		$data['cf'] = isset( $_GET['cf'] ) ? sanitize_text_field( $_GET['cf'] ) : null;

		if ( ! is_null( $data['update_id'] ) or ! is_null( $data['form_submitted'] ) ) {

			// Nonce verification.
			check_admin_referer( 'daextlnl_create_update_sliding_news', 'daextlnl_create_update_sliding_news_nonce' );

			// Sanitization -----------------------------------------------------------------------------------------------------
			$news_title               = isset( $_POST['news_title'] ) ? sanitize_text_field( $_POST['news_title'] ) : null;
			$url                      = isset( $_POST['url'] ) ? esc_url_raw( $_POST['url'] ) : null;
			$ticker_id                = isset( $_POST['ticker_id'] ) ? intval( $_POST['ticker_id'], 10 ) : null;
			$text_color               = isset( $_POST['text_color'] ) ? sanitize_text_field( $_POST['text_color'] ) : null;
			$text_color_hover         = isset( $_POST['text_color_hover'] ) ? sanitize_text_field( $_POST['text_color_hover'] ) : null;
			$background_color         = isset( $_POST['background_color'] ) ? sanitize_text_field( $_POST['background_color'] ) : null;
			$background_color_opacity = isset( $_POST['background_color_opacity'] ) ? floatval( $_POST['background_color_opacity'] ) : null;
			$image_before             = isset( $_POST['image_before'] ) ? esc_url_raw( $_POST['image_before'] ) : null;
			$image_after              = isset( $_POST['image_after'] ) ? esc_url_raw( $_POST['image_after'] ) : null;

			// Validation -------------------------------------------------------------------------------------------------------.
			$invalid_data_message = '';

			// validation on "Title"
			if ( mb_strlen( trim( $news_title ) ) == 0 or mb_strlen( $news_title ) > 1000 ) {
				$dismissible_notice_a[] = array(
					'message' => __( 'Please enter a valid value in the "Title" field.', $this->shared->get( 'text_domain' ) ),
					'class'   => 'error',
				);
				$invalid_data           = true;
			}

			// validation on "URL".
			if ( mb_strlen( $url ) > 2083 ) {
				$dismissible_notice_a[] = array(
					'message' => __( 'Please enter a valid URL in the "URL" field.', $this->shared->get( 'text_domain' ) ),
					'class'   => 'error',
				);
				$invalid_data           = true;
			}

			// validation on "Text Color".
			if ( ! preg_match( $this->shared->hex_rgb_regex, $text_color ) ) {
				$dismissible_notice_a[] = array(
					'message' => __( 'Please enter a valid color in the "Text Color" field.', $this->shared->get( 'text_domain' ) ),
					'class'   => 'error',
				);
				$invalid_data           = true;
			}

			// validation on "Text Color Hover"
			if ( ! preg_match( $this->shared->hex_rgb_regex, $text_color_hover ) ) {
				$dismissible_notice_a[] = array(
					'message' => __( 'Please enter a valid color in the "Text Color Hover" field.', $this->shared->get( 'text_domain' ) ),
					'class'   => 'error',
				);
				$invalid_data           = true;
			}

			// validation on "Background Color".
			if ( ! preg_match( $this->shared->hex_rgb_regex, $background_color ) ) {
				$dismissible_notice_a[] = array(
					'message' => __( 'Please enter a valid color in the "Background Color" field.', $this->shared->get( 'text_domain' ) ),
					'class'   => 'error',
				);
				$invalid_data           = true;
			}

			// validation on "Background Color Opacity".
			if ( $background_color_opacity < 0 or $background_color_opacity > 1 ) {
				$dismissible_notice_a[] = array(
					'message' => __( 'Please enter a value included between 0 and 1 in the "Background Color Opacity" field.', $this->shared->get( 'text_domain' ) ),
					'class'   => 'error',
				);
				$invalid_data           = true;
			}

			// validation on "Image Before".
			if ( mb_strlen( $image_before ) > 2083 ) {
				$dismissible_notice_a[] = array(
					'message' => __( 'Please enter a valid URL in the "Image Left" field.', $this->shared->get( 'text_domain' ) ),
					'class'   => 'error',
				);
				$invalid_data           = true;
			}

			// validation on "Image After".
			if ( mb_strlen( $image_after ) > 2083 ) {
				$dismissible_notice_a[] = array(
					'message' => __( 'Please enter a valid URL in the "Image Right" field.', $this->shared->get( 'text_domain' ) ),
					'class'   => 'error',
				);
				$invalid_data           = true;
			}
		}

		// update ---------------------------------------------------------------.
		if ( ! is_null( $data['update_id'] ) and ! isset( $invalid_data ) ) {

			// update the database.
			$table_name = $wpdb->prefix . $this->shared->get( 'slug' ) . '_sliding_news';
			$safe_sql   = $wpdb->prepare(
				"UPDATE $table_name SET
                news_title = %s,
                url = %s,
                ticker_id = %d,
                text_color = %s,
                text_color_hover = %s,
                background_color = %s,
                background_color_opacity = %f,
                image_before = %s,
                image_after = %s
                WHERE id = %d",
				$news_title,
				$url,
				$ticker_id,
				$text_color,
				$text_color_hover,
				$background_color,
				$background_color_opacity,
				$image_before,
				$image_after,
				$data['update_id']
			);

			$query_result = $wpdb->query( $safe_sql );

			if ( $query_result !== false ) {
				$dismissible_notice_a[] = array(
					'message' => __( 'The sliding news has been successfully updated.', $this->shared->get( 'text_domain' ) ),
					'class'   => 'updated',
				);
			}
		} else {

			// add ------------------------------------------------------------------.
			if ( ! is_null( $data['form_submitted'] ) and ! isset( $invalid_data ) ) {

				// insert into the database
				$table_name = $wpdb->prefix . $this->shared->get( 'slug' ) . '_sliding_news';
				$safe_sql   = $wpdb->prepare(
					"INSERT INTO $table_name SET
                    news_title = %s,
                    url = %s,
                    ticker_id = %d,
                    text_color = %s,
                    text_color_hover = %s,
                    background_color = %s,
                    background_color_opacity = %f,
                    image_before = %s,
                    image_after = %s",
					$news_title,
					$url,
					$ticker_id,
					$text_color,
					$text_color_hover,
					$background_color,
					$background_color_opacity,
					$image_before,
					$image_after
				);

				$query_result = $wpdb->query( $safe_sql );

				if ( $query_result !== false ) {
					$dismissible_notice_a[] = array(
						'message' => __( 'The sliding news has been successfully added.', $this->shared->get( 'text_domain' ) ),
						'class'   => 'updated',
					);
				}
			}
		}

		// delete a sliding news.
		if ( ! is_null( $data['delete_id'] ) ) {

			// Nonce verification.
			check_admin_referer( 'daextlnl_delete_sliding_news_' . $data['delete_id'], 'daextlnl_delete_sliding_news_nonce' );

			// delete this game.
			$table_name = $wpdb->prefix . $this->shared->get( 'slug' ) . '_sliding_news';
			$safe_sql   = $wpdb->prepare( "DELETE FROM $table_name WHERE id = %d ", $data['delete_id'] );

			$query_result = $wpdb->query( $safe_sql );

			if ( $query_result !== false ) {
				$dismissible_notice_a[] = array(
					'message' => __( 'The sliding news has been successfully deleted.', $this->shared->get( 'text_domain' ) ),
					'class'   => 'updated',
				);
			}
		}

		// get the sliding news data.
		$display_form = true;
		if ( ! is_null( $data['edit_id'] ) ) {
			$table_name       = $wpdb->prefix . $this->shared->get( 'slug' ) . '_sliding_news';
			$safe_sql         = $wpdb->prepare( "SELECT * FROM $table_name WHERE id = %d ", $data['edit_id'] );
			$sliding_news_obj = $wpdb->get_row( $safe_sql );
			if ( $sliding_news_obj === null ) {
				$display_form = false;
			}
		}

		// Get the value of the custom filter.
		if ( $data['cf'] !== null ) {
			if ( $data['cf'] !== 'all' ) {
				$ticker_id_in_cf = intval( $data['cf'], 10 );
			} else {
				$ticker_id_in_cf = false;
			}
		} else {
			$ticker_id_in_cf = false;
		}

		?>
		
		<!-- output -->

		<div class="wrap">

			<?php if ( $this->shared->get_number_of_sliding_news() > 0 ) : ?>

				<div id="daext-header-wrapper" class="daext-clearfix">

					<h2><?php esc_html_e( 'Live News - Sliding News', $this->shared->get( 'text_domain' ) ); ?></h2>

					<!-- Search Form -->

					<form action="admin.php" method="get" id="daext-search-form">

						<input type="hidden" name="page" value="daextlnl-sliding">

						<p><?php esc_html_e( 'Perform your Search', $this->shared->get( 'text_domain' ) ); ?></p>

						<?php
						if ( ! is_null( $data['s'] ) ) {
							if ( mb_strlen( trim( $data['s'] ) ) > 0 ) {
								$search_string = $data['s'];
							} else {
								$search_string = '';
							}
						} else {
							$search_string = '';
						}

						// Custom Filter.
						if ( $ticker_id_in_cf !== false ) {
							echo '<input type="hidden" name="cf" value="' . esc_attr( $ticker_id_in_cf ) . '">';
						}

						?>

						<input type="text" name="s" name="s"
								value="<?php echo esc_attr( stripslashes( $search_string ) ); ?>" autocomplete="off" maxlength="255">
						<input type="submit" value="">

					</form>

					<!-- Filter Form -->

					<form method="GET" action="admin.php" id="daext-filter-form">

						<input type="hidden" name="page" value="<?php echo esc_attr( $this->shared->get( 'slug' ) ); ?>-sliding">

						<p><?php esc_html_e( 'Filter by News Ticker', $this->shared->get( 'text_domain' ) ); ?></p>

						<select id="cf" name="cf" class="daext-display-none">

							<option value="all" 
							<?php
							if ( $data['cf'] !== null ) {
								selected( $data['cf'], 'all' );}
							?>
							><?php esc_html_e( 'All', $this->shared->get( 'text_domain' ) ); ?></option>

							<?php

							$table_name = $wpdb->prefix . $this->shared->get( 'slug' ) . '_tickers';
							$safe_sql   = "SELECT id, name FROM $table_name ORDER BY id DESC";
							$tickers_a  = $wpdb->get_results( $safe_sql, ARRAY_A );

							foreach ( $tickers_a as $key => $ticker ) {

								if ( $data['cf'] !== null ) {
									echo '<option value="' . esc_attr( $ticker['id'] ) . '" ' . selected( $data['cf'], $ticker['id'], false ) . '>' . esc_html( stripslashes( $ticker['name'] ) ) . '</option>';
								} else {
									echo '<option value="' . esc_attr( $ticker['id'] ) . '">' . esc_html( stripslashes( $ticker['name'] ) ) . '</option>';

								}
							}

							?>

						</select>

					</form>

				</div>

			<?php else : ?>

				<div id="daext-header-wrapper" class="daext-clearfix">

					<h2><?php esc_attr_e( 'Live News - Sliding News', $this->shared->get( 'text_domain' ) ); ?></h2>

				</div>

			<?php endif; ?>

			<?php

			// do not display the menu if in the 'cf' url parameter is applied a filter based on a ticker that doesn't exist.
			if ( $data['cf'] !== null ) {
				if ( $data['cf'] !== 'all' and ! $this->shared->ticker_exists( $data['cf'] ) ) {
					echo '<p>' . esc_html__( "The filter can't be applied because this sliding news doesn't exist.", $this->shared->get( 'text_domain' ) ) . '</p>';
					return;
				}
			}

			// retrieve the url parameter that should be used in the linked URLs.
			if ( $this->shared->ticker_exists( $data['cf'] ) ) {
				$ticker_url_parameter = '&cf=' . intval( $data['cf'], 10 );
			} else {
				$ticker_url_parameter = '';
			}

			// display a message and not the menu if there are no tickers
			if ( $this->shared->get_number_of_tickers() == 0 ) {
				echo '<p>' . esc_html__( 'There are no news tickers at the moment, please create at least one news ticker with the', $this->shared->get( 'text_domain' ) ) . ' ' . '<a href="admin.php?page=daextlnl-tickers">' . esc_html__( 'News Tickers', $this->shared->get( 'text_domain' ) ) . '</a> menu.' . '</p>';
				return;
			}

			?>

		<div id="daext-menu-wrapper">

			<?php $this->dismissible_notice( $dismissible_notice_a ); ?>
			
			<!-- table -->

			<?php

			// custom filter.
			if ( $ticker_id_in_cf === false ) {
				$filter = '';
			} else {
				$filter = $wpdb->prepare( 'WHERE ticker_id = %d', $ticker_id_in_cf );
			}

			// create the query part used to filter the results when a search is performed.
			if ( ! is_null( $data['s'] ) ) {

				if ( mb_strlen( trim( $data['s'] ) ) > 0 ) {

					if ( strlen( trim( $filter ) ) > 0 ) {
						$filter .= $wpdb->prepare( ' AND (news_title LIKE %s OR url LIKE %s)', '%' . $data['s'] . '%', '%' . $data['s'] . '%' );
					} else {
						$filter = $wpdb->prepare( 'WHERE (news_title LIKE %s OR url LIKE %s)', '%' . $data['s'] . '%', '%' . $data['s'] . '%' );
					}
				}
			}

			// retrieve the total number of sliding news.
			$table_name  = $wpdb->prefix . $this->shared->get( 'slug' ) . '_sliding_news';
			$total_items = $wpdb->get_var( "SELECT COUNT(*) FROM $table_name $filter" );

			// Initialize the pagination class.
			require_once $this->shared->get( 'dir' ) . '/admin/inc/class-daextlnl-pagination.php';
			$pag = new daextlnl_pagination();
			$pag->set_total_items( $total_items );// Set the total number of items.
			$pag->set_record_per_page( 10 ); // Set records per page.
			$pag->set_target_page( 'admin.php?page=' . $this->shared->get( 'slug' ) . '-sliding' );// Set target page.
			$pag->set_current_page();// set the current page number.

			?>

			<!-- Query the database -->
			<?php
			$query_limit = $pag->query_limit();
			$results     = $wpdb->get_results( "SELECT * FROM $table_name $filter ORDER BY id DESC $query_limit ", ARRAY_A );
			?>

			<?php if ( count( $results ) > 0 ) : ?>

			<div class="daext-items-container">

				<!-- list of tables -->
				<table class="daext-items">
					<thead>
						<tr>
							<th>
								<div><?php esc_html_e( 'Title', $this->shared->get( 'text_domain' ) ); ?></div>
								<div class="help-icon" title="<?php esc_attr_e( 'The title of the sliding news.', $this->shared->get( 'text_domain' ) ); ?>"></div>
							</th>
							<th>
								<div><?php esc_html_e( 'Ticker', $this->shared->get( 'text_domain' ) ); ?></div>
								<div class="help-icon" title="<?php esc_attr_e( 'The news ticker associated with the sliding news.', $this->shared->get( 'text_domain' ) ); ?>"></div>
							</th>
							<th></th>
						</tr>
					</thead>
					<tbody>

					<?php foreach ( $results as $result ) : ?>
						<tr>
							<td><?php echo esc_html( stripslashes( $result['news_title'] ) ); ?></td>
							<td><?php echo '<a href="admin.php?page=daextlnl-tickers&edit_id=' . esc_attr( $result['ticker_id'] ) . '">' . esc_html( stripslashes( $this->shared->get_textual_ticker( $result['ticker_id'] ) ) ) . '</a>'; ?></td>
							<td class="icons-container">

								<a class="menu-icon edit" href="admin.php?page=<?php echo esc_attr( $this->shared->get( 'slug' ) ); ?>-sliding&edit_id=<?php echo esc_attr( $result['id'] ); ?><?php echo esc_html( $ticker_url_parameter ); ?>"></a>
								<form method="POST" action="admin.php?page=<?php echo esc_attr( $this->shared->get( 'slug' ) ); ?>-sliding">
									<?php wp_nonce_field( 'daextlnl_delete_sliding_news_' . $result['id'], 'daextlnl_delete_sliding_news_nonce' ); ?>
									<input type="hidden" value="<?php echo esc_attr( $result['id'] ); ?>" name="delete_id" >
									<input class="menu-icon delete" type="submit" value="">
								</form>
							</td>
						</tr>
					<?php endforeach; ?>

					</tbody>

				</table>

			</div>

				<!-- Display the pagination -->
				<?php if ( $pag->total_items > 0 ) : ?>
					<div class="daext-tablenav daext-clearfix">
						<div class="daext-tablenav-pages">
							<span class="daext-displaying-num"><?php echo esc_html( $pag->total_items ); ?> <?php esc_html_e( 'items', $this->shared->get( 'text_domain' ) ); ?></span>
							<?php $pag->show(); ?>
						</div>
					</div>
				<?php endif; ?>

			<?php else : ?>

				<?php

				if ( strlen( trim( $filter ) ) > 0 ) {
					echo '<div class="error settings-error notice is-dismissible below-h2"><p>' . esc_html__( 'There are no results that match your filter.', $this->shared->get( 'text_domain' ) ) . '</p></div>';
				}

				?>

			<?php endif; ?>

			<div id="sliding-news-form-container">

				<?php if ( $display_form ) : ?>

					<form method="POST" action="admin.php?page=<?php echo esc_attr( $this->shared->get( 'slug' ) ); ?>-sliding<?php echo esc_attr( $ticker_url_parameter ); ?>" autocomplete="off">

						<input type="hidden" value="1" name="form_submitted">
						<?php wp_nonce_field( 'daextlnl_create_update_sliding_news', 'daextlnl_create_update_sliding_news_nonce' ); ?>

						<?php if ( ! is_null( $data['edit_id'] ) ) : ?>

							<!-- Edit a sliding news -->

							<div class="daext-form-container">

								<h3 class="daext-form-title"><?php esc_html_e( 'Edit Sliding News', $this->shared->get( 'text_domain' ) ); ?> <?php echo esc_html( $sliding_news_obj->id ); ?></h3>

								<table class="daext-form">

									<input type="hidden" name="update_id" id="update-id" value="<?php echo esc_html( $sliding_news_obj->id ); ?>" />

									<!-- title -->
									<tr valign="top">
										<th scope="row"><label for="news-title"><?php esc_html_e( 'Title', $this->shared->get( 'text_domain' ) ); ?></label></th>
										<td>
											<input value="<?php echo esc_attr( stripslashes( $sliding_news_obj->news_title ) ); ?>" type="text" id="news-title" maxlength="1000" size="30" name="news_title" />
											<div class="help-icon" title="<?php esc_attr_e( 'Enter the title of the sliding news.', $this->shared->get( 'text_domain' ) ); ?>"></div>
										</td>
									</tr>

									<!-- URL -->
									<tr valign="top">
										<th scope="row"><label for="url"><?php esc_html_e( 'URL', $this->shared->get( 'text_domain' ) ); ?></label></th>
										<td>
											<input value="<?php echo esc_attr( stripslashes( $sliding_news_obj->url ) ); ?>" type="text" id="url" maxlength="2083" size="30" name="url" />
											<div class="help-icon" title="<?php esc_attr_e( 'Enter the URL of the sliding news.', $this->shared->get( 'text_domain' ) ); ?>"></div>
										</td>
									</tr>

									<!-- Ticker -->
									<tr>
										<th scope="row"><?php esc_html_e( 'Ticker', $this->shared->get( 'text_domain' ) ); ?></th>
										<td>
											<select id="ticker-id" name="ticker_id" class="daext-display-none">

												<?php

												$table_name = $wpdb->prefix . $this->shared->get( 'slug' ) . '_tickers';
												$safe_sql   = "SELECT id, name FROM $table_name ORDER BY id DESC";
												$tickers_a  = $wpdb->get_results( $safe_sql, ARRAY_A );

												foreach ( $tickers_a as $key => $ticker ) {

													echo '<option value="' . esc_attr( $ticker['id'] ) . '" ' . selected( $sliding_news_obj->ticker_id, $ticker['id'] ) . '>' . esc_html( stripslashes( $ticker['name'] ) ) . '</option>';

												}

												?>

											</select>
											<div class="help-icon" title='<?php esc_attr_e( 'Select the news ticker associated with this sliding news.', $this->shared->get( 'text_domain' ) ); ?>'></div>
										</td>
									</tr>

									<!-- Text Color -->
									<tr valign="top">
										<th scope="row"><label for="text-color"><?php esc_html_e( 'Text Color', $this->shared->get( 'text_domain' ) ); ?></label></th>
										<td>
											<input value="<?php echo esc_attr( stripslashes( $sliding_news_obj->text_color ) ); ?>" class="wp-color-picker" type="text" id="text-color" maxlength="7" size="30" name="text_color"/>
											<div class="help-icon" title="<?php esc_attr_e( 'Select the color used to display the text of this sliding news.', $this->shared->get( 'text_domain' ) ); ?>"></div>
										</td>
									</tr>

									<!-- Text Color Hover -->
									<tr valign="top">
										<th scope="row"><label for="text-color-hover"><?php esc_html_e( 'Text Color Hover', $this->shared->get( 'text_domain' ) ); ?></label></th>
										<td>
											<input value="<?php echo esc_attr( stripslashes( $sliding_news_obj->text_color_hover ) ); ?>" class="wp-color-picker" type="text" id="text-color-hover" maxlength="7" size="30" name="text_color_hover"/>
											<div class="help-icon" title="<?php esc_attr_e( 'Select the color used to display the text of this sliding news in hover state.', $this->shared->get( 'text_domain' ) ); ?>"></div>
										</td>
									</tr>

									<!-- Background Color -->
									<tr valign="top">
										<th scope="row"><label for="background-color"><?php esc_html_e( 'Background Color', $this->shared->get( 'text_domain' ) ); ?></label></th>
										<td>
											<input value="<?php echo esc_attr( stripslashes( $sliding_news_obj->background_color ) ); ?>" class="wp-color-picker" type="text" id="background-color" maxlength="7" size="30" name="background_color"/>
											<div class="help-icon" title="<?php esc_attr_e( 'Select the background color of this sliding news.', $this->shared->get( 'text_domain' ) ); ?>"></div>
										</td>
									</tr>

									<!-- Background Color Opacity -->
									<tr>
										<th scope="row"><label for="background-color-opacity"><?php esc_html_e( 'Background Color Opacity', $this->shared->get( 'text_domain' ) ); ?></label></th>
										<td>
											<input value="<?php echo floatval( $sliding_news_obj->background_color_opacity ); ?>" type="text" id="background-color-opacity" maxlength="3" size="30" name="background_color_opacity" />
											<div class="help-icon" title="<?php esc_attr_e( 'The background color opacity of this sliding news.', $this->shared->get( 'text_domain' ) ); ?>"></div>
										</td>
									</tr>

									<!-- Image Before -->
									<tr>
										<th scope="row"><label for="image-before"><?php esc_html_e( 'Image Left', $this->shared->get( 'text_domain' ) ); ?></label></th>
										<td>

											<div class="image-uploader">
												<img class="selected-image" src="<?php echo esc_attr( stripslashes( $sliding_news_obj->image_before ) ); ?>" <?php echo mb_strlen( trim( $sliding_news_obj->image_before ) ) == 0 ? 'style="display: none;"' : ''; ?>>
												<input value="<?php echo esc_attr( stripslashes( $sliding_news_obj->image_before ) ); ?>" type="hidden" id="image-before" maxlength="2083" name="image_before">
												<a class="button_add_media" data-set-remove="<?php echo mb_strlen( trim( $sliding_news_obj->image_before ) ) == 0 ? 'set' : 'remove'; ?>" data-set="<?php esc_attr_e( 'Set image', $this->shared->get( 'text_domain' ) ); ?>" data-remove="<?php esc_attr_e( 'Remove Image', $this->shared->get( 'text_domain' ) ); ?>"><?php echo mb_strlen( trim( $sliding_news_obj->image_before ) ) == 0 ? esc_attr__( 'Set image', $this->shared->get( 'text_domain' ) ) : esc_attr__( 'Remove Image', $this->shared->get( 'text_domain' ) ); ?></a>
												<p class="description"><?php esc_html_e( "Select the image displayed on the left of the sliding news. It's recommended to use an image with an height of 40 pixels.", $this->shared->get( 'text_domain' ) ); ?></p>
											</div>

										</td>
									</tr>

									<!-- Image After -->
									<tr>
										<th scope="row"><label for="image-after"><?php esc_html_e( 'Image Right', $this->shared->get( 'text_domain' ) ); ?></label></th>
										<td>

											<div class="image-uploader">
												<img class="selected-image" src="<?php echo esc_attr( stripslashes( $sliding_news_obj->image_after ) ); ?>" <?php echo mb_strlen( trim( $sliding_news_obj->image_after ) ) == 0 ? 'style="display: none;"' : ''; ?>>
												<input value="<?php echo esc_attr( stripslashes( $sliding_news_obj->image_after ) ); ?>" type="hidden" id="image-after" maxlength="2083" name="image_after">
												<a class="button_add_media" data-set-remove="<?php echo mb_strlen( trim( $sliding_news_obj->image_after ) ) == 0 ? 'set' : 'remove'; ?>" data-set="<?php esc_attr_e( 'Set image', $this->shared->get( 'text_domain' ) ); ?>" data-remove="<?php esc_attr_e( 'Remove Image', $this->shared->get( 'text_domain' ) ); ?>"><?php echo mb_strlen( trim( $sliding_news_obj->image_after ) ) == 0 ? esc_attr__( 'Set image', $this->shared->get( 'text_domain' ) ) : esc_attr__( 'Remove Image', $this->shared->get( 'text_domain' ) ); ?></a>
												<p class="description"><?php esc_html_e( "Select the image displayed on the right of the sliding news. It's recommended to use an image with an height of 40 pixels.", $this->shared->get( 'text_domain' ) ); ?></p>
											</div>

										</td>
									</tr>

								</table>

								<!-- submit button -->
								<div class="daext-form-action">
									<input class="button" type="submit" value="<?php esc_attr_e( 'Update Sliding News', $this->shared->get( 'text_domain' ) ); ?>" >
								</div>

						<?php else : ?>

							<!-- Create New Sliding News -->

							<div class="daext-form-container">

								<div class="daext-form-title"><?php esc_html_e( 'Create a Sliding News', $this->shared->get( 'text_domain' ) ); ?></div>

									<table class="daext-form">

										<!-- Title -->
										<tr valign="top">
											<th scope="row"><label for="news-title"><?php esc_html_e( 'Title', $this->shared->get( 'text_domain' ) ); ?></label></th>
											<td>
												<input type="text" id="news-title" maxlength="1000" size="30" name="news_title" />
												<div class="help-icon" title="<?php esc_attr_e( 'Enter the title of the sliding news.', $this->shared->get( 'text_domain' ) ); ?>"></div>
											</td>
										</tr>

										<!-- URL -->
										<tr valign="top">
											<th scope="row"><label for="url"><?php esc_html_e( 'URL', $this->shared->get( 'text_domain' ) ); ?></label></th>
											<td>
												<input type="text" id="url" maxlength="2083" size="30" name="url" />
												<div class="help-icon" title="<?php esc_attr_e( 'Enter the URL of the sliding news.', $this->shared->get( 'text_domain' ) ); ?>"></div>
											</td>
										</tr>

										<!-- Ticker -->
										<tr>
											<th scope="row"><?php esc_html_e( 'Ticker', $this->shared->get( 'text_domain' ) ); ?></th>
											<td>
												<select id="ticker-id" name="ticker_id" class="daext-display-none">

													<?php

													$table_name = $wpdb->prefix . $this->shared->get( 'slug' ) . '_tickers';
													$safe_sql   = "SELECT id, name FROM $table_name ORDER BY id DESC";
													$tickers_a  = $wpdb->get_results( $safe_sql, ARRAY_A );

													if ( $ticker_id_in_cf === false ) {

														foreach ( $tickers_a as $key => $ticker ) {
															echo '<option value="' . esc_attr( $ticker['id'] ) . '">' . esc_html( stripslashes( $ticker['name'] ) ) . '</option>';
														}
													} else {

														foreach ( $tickers_a as $key => $ticker ) {
															echo '<option value="' . esc_attr( $ticker['id'] ) . '" ' . selected( $ticker_id_in_cf, $ticker['id'], false ) . '>' . esc_html( stripslashes( $ticker['name'] ) ) . '</option>';
														}
													}

													?>

												</select>
												<div class="help-icon" title='<?php esc_attr_e( 'Select the news ticker associated with this sliding news.', $this->shared->get( 'text_domain' ) ); ?>'></div>
											</td>
										</tr>

										<!-- Text Color -->
										<tr valign="top">
											<th scope="row"><label for="text-color"><?php esc_html_e( 'Text Color', $this->shared->get( 'text_domain' ) ); ?></label></th>
											<td>
												<input class="wp-color-picker" type="text" id="text-color" maxlength="7" size="30" name="text_color"/>
												<div class="help-icon" title="<?php esc_attr_e( 'Select the color used to display the text of this sliding news.', $this->shared->get( 'text_domain' ) ); ?>"></div>
											</td>
										</tr>

										<!-- Text Color Hover -->
										<tr valign="top">
											<th scope="row"><label for="text-color-hover"><?php esc_html_e( 'Text Color Hover', $this->shared->get( 'text_domain' ) ); ?></label></th>
											<td>
												<input class="wp-color-picker" type="text" id="text-color-hover" maxlength="7" size="30" name="text_color_hover"/>
												<div class="help-icon" title="<?php esc_attr_e( 'Select the color used to display the text of this sliding news in hover state.', $this->shared->get( 'text_domain' ) ); ?>"></div>
											</td>
										</tr>

										<!-- Background Color -->
										<tr valign="top">
											<th scope="row"><label for="background-color"><?php esc_html_e( 'Background Color', $this->shared->get( 'text_domain' ) ); ?></label></th>
											<td>
												<input class="wp-color-picker" type="text" id="background-color" maxlength="7" size="30" name="background_color"/>
												<div class="help-icon" title="<?php esc_attr_e( 'Select the background color of this sliding news.', $this->shared->get( 'text_domain' ) ); ?>"></div>
											</td>
										</tr>

										<!-- Background Color Opacity -->
										<tr>
											<th scope="row"><label for="background-color-opacity"><?php esc_html_e( 'Background Color Opacity', $this->shared->get( 'text_domain' ) ); ?></label></th>
											<td>
												<input value="1" type="text" id="background-color-opacity" maxlength="3" size="30" name="background_color_opacity" />
												<div class="help-icon" title="<?php esc_attr_e( 'The background color opacity of this sliding news.', $this->shared->get( 'text_domain' ) ); ?>"></div>
											</td>
										</tr>

										<!-- Image Before -->
										<tr>
											<th scope="row"><label for="image-before"><?php esc_html_e( 'Image Left', $this->shared->get( 'text_domain' ) ); ?></label></th>
											<td>

												<div class="image-uploader">
													<img class="selected-image" src="" style="display: none">
													<input type="hidden" id="image-before" maxlength="2083" name="image_before">
													<a class="button_add_media" data-set-remove="set" data-set="<?php esc_attr_e( 'Set image', $this->shared->get( 'text_domain' ) ); ?>" data-remove="<?php esc_attr_e( 'Remove Image', $this->shared->get( 'text_domain' ) ); ?>"><?php esc_html_e( 'Set image', $this->shared->get( 'text_domain' ) ); ?></a>
													<p class="description"><?php esc_html_e( "Select the image displayed on the left of the sliding news. It's recommended to use an image with an height of 40 pixels.", $this->shared->get( 'text_domain' ) ); ?></p>
												</div>

											</td>
										</tr>

										<!-- Image After -->
										<tr>
											<th scope="row"><label for="image-after"><?php esc_html_e( 'Image Right', $this->shared->get( 'text_domain' ) ); ?></label></th>
											<td>

												<div class="image-uploader">
													<img class="selected-image" src="" style="display: none">
													<input type="hidden" id="image-after" maxlength="2083" name="image_after">
													<a class="button_add_media" data-set-remove="set" data-set="<?php esc_attr_e( 'Set image', $this->shared->get( 'text_domain' ) ); ?>" data-remove="<?php esc_attr_e( 'Remove Image', $this->shared->get( 'text_domain' ) ); ?>"><?php esc_html_e( 'Set image', $this->shared->get( 'text_domain' ) ); ?></a>
													<p class="description"><?php esc_attr_e( "Select the image displayed on the right of the sliding news. It's recommended to use an image with an height of 40 pixels.", $this->shared->get( 'text_domain' ) ); ?></p>
												</div>

											</td>
										</tr>

									</table>

									<!-- submit button -->
									<div class="daext-form-action">
										<input class="button" type="submit" value="<?php esc_attr_e( 'Add Sliding News', $this->shared->get( 'text_domain' ) ); ?>" >
									</div>

								<?php endif; ?>

							</div>

					</form>

				<?php endif; ?>

			</div>

		</div>

	</div>admin/view/tickers.php000064400000306336151213253510010774 0ustar00<?php
/**
 * The "Tickers" menu page.
 *
 * @package live-news-lite
 */

if ( ! current_user_can( get_option( $this->shared->get( 'slug' ) . '_tickers_menu_capability' ) ) ) {
	wp_die( esc_attr__( 'You do not have sufficient permissions to access this page.', $this->shared->get( 'text_domain' ) ) );
}

?>

<!-- process data -->

<?php

// Initialize variables -------------------------------------------------------------------------------------------------.
$dismissible_notice_a = array();

// Preliminary operations -----------------------------------------------------------------------------------------------.
global $wpdb;

// Sanitization ---------------------------------------------------------------------------------------------------------.
$data['edit_id']             = isset( $_GET['edit_id'] ) ? intval( $_GET['edit_id'], 10 ) : null;
$data['delete_id']           = isset( $_POST['delete_id'] ) ? intval( $_POST['delete_id'], 10 ) : null;
$data['update_id']           = isset( $_POST['update_id'] ) ? intval( $_POST['update_id'], 10 ) : null;
$data['form_submitted']      = isset( $_POST['form_submitted'] ) ? intval( $_POST['form_submitted'], 10 ) : null;
$data['delete_transient_id'] = isset( $_POST['delete_transient_id'] ) ? intval( $_POST['delete_transient_id'], 10 ) : null;

// Filter and search data.
$data['s'] = isset( $_GET['s'] ) ? sanitize_text_field( $_GET['s'] ) : null;

if ( ! is_null( $data['update_id'] ) or ! is_null( $data['form_submitted'] ) ) {

	// Nonce verification.
	check_admin_referer( 'daextlnl_create_update_ticker', 'daextlnl_create_update_ticker_nonce' );

	// Sanitization -----------------------------------------------------------------------------------------------------.
	$name          = isset( $_POST['name'] ) ? sanitize_text_field( $_POST['name'] ) : null;
	$target        = isset( $_POST['target'] ) ? intval( $_POST['target'], 10 ) : null;
	$url           = isset( $_POST['url'] ) ? sanitize_textarea_field( $_POST['url'] ) : null;
	$enable_ticker = isset( $_POST['enable_ticker'] ) ? intval( $_POST['enable_ticker'], 10 ) : null;

	$clock_source = isset( $_POST['clock_source'] ) ? intval( $_POST['clock_source'], 10 ) : null;
	$clock_offset = isset( $_POST['clock_offset'] ) ? intval( $_POST['clock_offset'], 10 ) : null;
	$clock_format = isset( $_POST['clock_format'] ) ? sanitize_text_field( $_POST['clock_format'] ) : null;

	$enable_rtl_layout          = isset( $_POST['enable_rtl_layout'] ) ? intval( $_POST['enable_rtl_layout'], 10 ) : null;
	$enable_with_mobile_devices = isset( $_POST['enable_with_mobile_devices'] ) ? intval( $_POST['enable_with_mobile_devices'], 10 ) : null;
	$hide_featured_news         = isset( $_POST['hide_featured_news'] ) ? intval( $_POST['hide_featured_news'], 10 ) : null;
	$open_news_as_default       = isset( $_POST['open_news_as_default'] ) ? intval( $_POST['open_news_as_default'], 10 ) : null;
	$enable_links               = isset( $_POST['enable_links'] ) ? intval( $_POST['enable_links'], 10 ) : null;
	$open_links_new_tab         = isset( $_POST['open_links_new_tab'] ) ? intval( $_POST['open_links_new_tab'], 10 ) : null;
	$hide_clock                 = isset( $_POST['hide_clock'] ) ? intval( $_POST['hide_clock'], 10 ) : null;
	$clock_autoupdate           = isset( $_POST['clock_autoupdate'] ) ? intval( $_POST['clock_autoupdate'], 10 ) : null;
	$clock_autoupdate_time      = isset( $_POST['clock_autoupdate_time'] ) ? intval( $_POST['clock_autoupdate_time'], 10 ) : null;
	$number_of_sliding_news     = isset( $_POST['number_of_sliding_news'] ) ? intval( $_POST['number_of_sliding_news'], 10 ) : null;

	$cached_cycles        = isset( $_POST['cached_cycles'] ) ? intval( $_POST['cached_cycles'], 10 ) : null;
	$transient_expiration = isset( $_POST['transient_expiration'] ) ? intval( $_POST['transient_expiration'], 10 ) : null;

	$featured_title_maximum_length          = isset( $_POST['featured_title_maximum_length'] ) ? intval( $_POST['featured_title_maximum_length'], 10 ) : null;
	$featured_excerpt_maximum_length        = isset( $_POST['featured_excerpt_maximum_length'] ) ? intval( $_POST['featured_excerpt_maximum_length'], 10 ) : null;
	$sliding_news_maximum_length            = isset( $_POST['sliding_news_maximum_length'] ) ? intval( $_POST['sliding_news_maximum_length'], 10 ) : null;
	$featured_title_font_size               = isset( $_POST['featured_title_font_size'] ) ? intval( $_POST['featured_title_font_size'], 10 ) : null;
	$featured_excerpt_font_size             = isset( $_POST['featured_excerpt_font_size'] ) ? intval( $_POST['featured_excerpt_font_size'], 10 ) : null;
	$sliding_news_font_size                 = isset( $_POST['featured_excerpt_font_size'] ) ? intval( $_POST['sliding_news_font_size'], 10 ) : null;
	$clock_font_size                        = isset( $_POST['clock_font_size'] ) ? intval( $_POST['clock_font_size'], 10 ) : null;
	$sliding_news_margin                    = isset( $_POST['sliding_news_margin'] ) ? intval( $_POST['sliding_news_margin'], 10 ) : null;
	$sliding_news_padding                   = isset( $_POST['sliding_news_padding'] ) ? intval( $_POST['sliding_news_padding'], 10 ) : null;
	$font_family                            = isset( $_POST['font_family'] ) ? sanitize_text_field( $_POST['font_family'] ) : null;
	$google_font                            = isset( $_POST['google_font'] ) ? esc_url_raw( $_POST['google_font'] ) : null;
	$featured_news_title_color              = isset( $_POST['featured_news_title_color'] ) ? sanitize_text_field( $_POST['featured_news_title_color'] ) : null;
	$featured_news_title_color_hover        = isset( $_POST['featured_news_title_color_hover'] ) ? sanitize_text_field( $_POST['featured_news_title_color_hover'] ) : null;
	$featured_news_excerpt_color            = isset( $_POST['featured_news_excerpt_color'] ) ? sanitize_text_field( $_POST['featured_news_excerpt_color'] ) : null;
	$sliding_news_color                     = isset( $_POST['sliding_news_color'] ) ? sanitize_text_field( $_POST['sliding_news_color'] ) : null;
	$sliding_news_color_hover               = isset( $_POST['sliding_news_color_hover'] ) ? sanitize_text_field( $_POST['sliding_news_color_hover'] ) : null;
	$clock_text_color                       = isset( $_POST['clock_text_color'] ) ? sanitize_text_field( $_POST['clock_text_color'] ) : null;
	$featured_news_background_color         = isset( $_POST['featured_news_background_color'] ) ? sanitize_text_field( $_POST['featured_news_background_color'] ) : null;
	$featured_news_background_color_opacity = isset( $_POST['featured_news_background_color_opacity'] ) ? floatval( $_POST['featured_news_background_color_opacity'] ) : null;
	$sliding_news_background_color          = isset( $_POST['sliding_news_background_color'] ) ? sanitize_text_field( $_POST['sliding_news_background_color'] ) : null;
	$sliding_news_background_color_opacity  = isset( $_POST['sliding_news_background_color_opacity'] ) ? floatval( $_POST['sliding_news_background_color_opacity'] ) : null;
	$open_button_image                      = isset( $_POST['open_button_image'] ) ? esc_url_raw( $_POST['open_button_image'] ) : null;
	$close_button_image                     = isset( $_POST['close_button_image'] ) ? esc_url_raw( $_POST['close_button_image'] ) : null;
	$clock_background_image                 = isset( $_POST['clock_background_image'] ) ? esc_url_raw( $_POST['clock_background_image'] ) : null;

	$url_mode = isset( $_POST['url_mode'] ) ? intval( $_POST['url_mode'], 10 ) : null;

	// Validation -------------------------------------------------------------------------------------------------------.

	$invalid_data_message = '';

	// validation on "Name".
	if ( mb_strlen( trim( $name ) ) == 0 or mb_strlen( $name ) > 100 ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'Please enter a valid value in the "Name" field.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'error',
		);
		$invalid_data           = true;
	}

	// validation on "Featured Title Maximum Length".
	if ( intval( $featured_title_maximum_length, 10 ) < 1 or intval( $featured_title_maximum_length, 10 ) > 1000 ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'Please enter a value included between 1 and 1000 in the "Featured Title Maximum Length" field.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'error',
		);
		$invalid_data           = true;
	}

	// validation on "Featured Excerpt Maximum Length".
	if ( intval( $featured_excerpt_maximum_length, 10 ) < 1 or intval( $featured_excerpt_maximum_length, 10 ) > 1000 ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'Please enter a value included between 1 and 1000 in the "Featured Excerpt Maximum Length" field.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'error',
		);
		$invalid_data           = true;
	}

	// validation on "Sliding News Maximum Length".
	if ( intval( $sliding_news_maximum_length, 10 ) < 1 or intval( $sliding_news_maximum_length, 10 ) > 1000 ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'Please enter a value included between 1 and 1000 in the "Sliding News Maximum Length" field.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'error',
		);
		$invalid_data           = true;
	}

	// validation on "Featured News Title Font Size".
	if ( intval( $featured_title_font_size, 10 ) < 1 or intval( $featured_title_font_size, 10 ) > 38 ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'Please enter a value included between 1 and 38 in the "Featured News Title Font Size" field.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'error',
		);
	}

	// validation on "Featured News Excerpt Font Size".
	if ( intval( $featured_excerpt_font_size, 10 ) < 1 or intval( $featured_excerpt_font_size, 10 ) > 28 ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'Please enter a value included between 1 and 28 in the "Featured News Excerpt Font Size" field.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'error',
		);
		$invalid_data           = true;
	}

	// validation on "Sliding News Font Size"
	if ( intval( $sliding_news_font_size, 10 ) < 1 or intval( $sliding_news_font_size, 10 ) > 28 ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'Please enter a value included between 1 and 28 in the "Sliding News Font Size" field.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'error',
		);
		$invalid_data           = true;
	}

	// validation on "Clock Font Size".
	if ( intval( $clock_font_size, 10 ) < 1 or intval( $clock_font_size, 10 ) > 28 ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'Please enter a value included between 1 and 28 in the "Clock Font Size" field.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'error',
		);
		$invalid_data           = true;
	}

	// validation on "Sliding News Margin".
	if ( intval( $sliding_news_margin, 10 ) < 0 or intval( $sliding_news_margin, 10 ) > 999 ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'Please enter a value included between 0 and 999 in the "Sliding News Margin" field.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'error',
		);
		$invalid_data           = true;
	}

	// validation on "Sliding News Padding".
	if ( intval( $sliding_news_padding, 10 ) < 0 or intval( $sliding_news_padding, 10 ) > 999 ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'Please enter a value included between 0 and 999 in the "Sliding News Padding" field.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'error',
		);
		$invalid_data           = true;
	}

	// validation on "Cached Cycles".
	if ( intval( $cached_cycles, 10 ) < 0 or intval( $cached_cycles, 10 ) > 1000000000 ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'Please enter a value included between 0 and 1000000000 in the "Cached Cycles" field.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'error',
		);
		$invalid_data           = true;
	}

	// validation on "Transient Expiration".
	if ( intval( $transient_expiration, 10 ) < 0 or intval( $transient_expiration, 10 ) > 1000000000 ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'Please enter a value included between 0 and 1000000000 in the "Transient Expiration" field.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'error',
		);
		$invalid_data           = true;
	}

	// validation on "Featured News Background Color".
	if ( ! preg_match( $this->shared->hex_rgb_regex, $featured_news_background_color ) ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'Please enter a valid color in the "Featured News Background Color" field.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'error',
		);
		$invalid_data           = true;
	}

	// validation on "Sliding News Background Color".
	if ( ! preg_match( $this->shared->hex_rgb_regex, $sliding_news_background_color ) ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'Please enter a valid color in the "Sliding News Background Color" field.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'error',
		);
		$invalid_data           = true;
	}

	// validation on "Sliding News Background Color Opacity".
	if ( $sliding_news_background_color_opacity < 0 or $sliding_news_background_color_opacity > 1 ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'Please enter a value included between 0 and 1 in the "Sliding News Background Color Opacity" field.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'error',
		);
		$invalid_data           = true;
	}

	// validation on "Font Family".
	if ( ! preg_match( $this->shared->font_family_regex, stripslashes( $font_family ) ) ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'Please enter a valid value in the "Font Family" field.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'error',
		);
		$invalid_data           = true;
	}

	// validation on "Google Font".
	if ( mb_strlen( $google_font ) > 2083 ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'Please enter a valid value in the "Google Font" field.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'error',
		);
		$invalid_data           = true;
	}

	// validation on "Open Button Image".
	if ( mb_strlen( $open_button_image ) > 2083 ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'Please enter a valid URL in the "Open Button Image" field.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'error',
		);
		$invalid_data           = true;
	}

	// validation on "Close Button Image".
	if ( mb_strlen( $close_button_image ) > 2083 ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'Please enter a valid URL in the "Close Button Image" field.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'error',
		);
		$invalid_data           = true;
	}

	// validation on "Clock Background Image".
	if ( mb_strlen( $clock_background_image ) > 2083 ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'Please enter a valid URL in the "Clock Background Image" field.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'error',
		);
		$invalid_data           = true;
	}

	// validation on "Featured News Title Color".
	if ( ! preg_match( $this->shared->hex_rgb_regex, $featured_news_title_color ) ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'Please enter a valid color in the "Featured News Title Color" field.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'error',
		);
		$invalid_data           = true;
	}

	// validation on "Featured News Title Color Hover".
	if ( ! preg_match( $this->shared->hex_rgb_regex, $featured_news_title_color_hover ) ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'Please enter a valid color in the "Featured News Title Color Hover" field.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'error',
		);
		$invalid_data           = true;
	}

	// validation on "Featured News Excerpt Color".
	if ( ! preg_match( $this->shared->hex_rgb_regex, $featured_news_excerpt_color ) ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'Please enter a valid color in the "Featured News Excerpt Color" field.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'error',
		);
		$invalid_data           = true;
	}

	// validation on "Sliding News Color".
	if ( ! preg_match( $this->shared->hex_rgb_regex, $sliding_news_color ) ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'Please enter a valid color in the "Sliding News Color" field.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'error',
		);
		$invalid_data           = true;
	}

	// validation on "Sliding News Color Hover".
	if ( ! preg_match( $this->shared->hex_rgb_regex, $sliding_news_color_hover ) ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'Please enter a valid color in the "Sliding News Color Hover" field.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'error',
		);
		$invalid_data           = true;
	}

	// validation on "Clock Text Color".
	if ( ! preg_match( $this->shared->hex_rgb_regex, $clock_text_color ) ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'Please enter a valid color in the "Clock Text Color" field.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'error',
		);
		$invalid_data           = true;
	}

	// validation on "Featured News Background Color Opacity".
	if ( $featured_news_background_color_opacity < 0 or $featured_news_background_color_opacity > 1 ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'Please enter a value included between 0 and 1 in the "Featured News Background Color Opacity" field.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'error',
		);
		$invalid_data           = true;
	}

	// do not save (and leave an error message) if a ticker with "Website" as a target already exists.
	if ( $target == 1 ) {

		$table_name = $wpdb->prefix . $this->shared->get( 'slug' ) . '_tickers';
		$row_obj    = $wpdb->get_row( "SELECT * from $table_name WHERE target = 1" );
		if ( $row_obj !== null ) {

			if ( is_null( $data['update_id'] ) or ( ! is_null( $data['update_id'] ) and intval( $row_obj->id, 10 ) !== $data['update_id'] ) ) {
				$dismissible_notice_a[] = array(
					'message' => __( 'A news ticker with "Website" as a target already exists.', $this->shared->get( 'text_domain' ) ),
					'class'   => 'error',
				);
				$invalid_data           = true;
			}
		}
	}
}

// update ---------------------------------------------------------------.
if ( ! is_null( $data['update_id'] ) and ! isset( $invalid_data ) ) {

	// update the database
	$table_name = $wpdb->prefix . $this->shared->get( 'slug' ) . '_tickers';
	$safe_sql   = $wpdb->prepare(
		"UPDATE $table_name SET
                name = %s,
                target = %d,
                url = %s,
                open_links_new_tab = %d,
                clock_offset = %d,
                clock_format = %s,
                clock_source = %d,
                clock_autoupdate = %d,
                clock_autoupdate_time = %d,
                number_of_sliding_news = %d,
                featured_title_maximum_length = %d,
                featured_excerpt_maximum_length = %d,
                sliding_news_maximum_length = %d,
                open_news_as_default = %d,
                hide_featured_news = %d,
                hide_clock = %d,
                enable_rtl_layout = %d,
                cached_cycles = %d,
                featured_news_background_color = %s,
                sliding_news_background_color = %s,
                sliding_news_background_color_opacity = %f,
                font_family = %s,
                google_font = %s,
                featured_title_font_size = %d,
				featured_excerpt_font_size = %d,
				sliding_news_font_size = %d,
				clock_font_size = %d,
				sliding_news_margin = %d,
				sliding_news_padding = %d,
                enable_with_mobile_devices = %d,
                open_button_image = %s,
                close_button_image = %s,
                clock_background_image = %s,
                featured_news_title_color = %s,
                featured_news_title_color_hover = %s,
                featured_news_excerpt_color = %s,
                sliding_news_color = %s,
                sliding_news_color_hover = %s,
                clock_text_color = %s,
                featured_news_background_color_opacity = %s,
                enable_ticker = %d,
                enable_links = %d,
                transient_expiration = %d,
                url_mode = %d
                WHERE id = %d",
		$name,
		$target,
		$url,
		$open_links_new_tab,
		$clock_offset,
		$clock_format,
		$clock_source,
		$clock_autoupdate,
		$clock_autoupdate_time,
		$number_of_sliding_news,
		$featured_title_maximum_length,
		$featured_excerpt_maximum_length,
		$sliding_news_maximum_length,
		$open_news_as_default,
		$hide_featured_news,
		$hide_clock,
		$enable_rtl_layout,
		$cached_cycles,
		$featured_news_background_color,
		$sliding_news_background_color,
		$sliding_news_background_color_opacity,
		$font_family,
		$google_font,
		$featured_title_font_size,
		$featured_excerpt_font_size,
		$sliding_news_font_size,
		$clock_font_size,
		$sliding_news_margin,
		$sliding_news_padding,
		$enable_with_mobile_devices,
		$open_button_image,
		$close_button_image,
		$clock_background_image,
		$featured_news_title_color,
		$featured_news_title_color_hover,
		$featured_news_excerpt_color,
		$sliding_news_color,
		$sliding_news_color_hover,
		$clock_text_color,
		$featured_news_background_color_opacity,
		$enable_ticker,
		$enable_links,
		$transient_expiration,
		$url_mode,
		$data['update_id']
	);

	$query_result = $wpdb->query( $safe_sql );

	if ( $query_result !== false ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'The news ticker has been successfully updated.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'updated',
		);
	}
} else {

	// add ------------------------------------------------------------------.
	if ( ! is_null( $data['form_submitted'] ) and ! isset( $invalid_data ) ) {

		// insert into the database
		$table_name = $wpdb->prefix . $this->shared->get( 'slug' ) . '_tickers';
		$safe_sql   = $wpdb->prepare(
			"INSERT INTO $table_name SET
                    name = %s,
                    target = %d,
                    url = %s,
                    open_links_new_tab = %d,
                    clock_offset = %d,
                    clock_format = %s,
                    clock_source = %d,
                    clock_autoupdate = %d,
                    clock_autoupdate_time = %d,
                    number_of_sliding_news = %d,
                    featured_title_maximum_length = %d,
                    featured_excerpt_maximum_length = %d,
                    sliding_news_maximum_length = %d,
                    open_news_as_default = %d,
                    hide_featured_news = %d,
                    hide_clock = %d,
                    enable_rtl_layout = %d,
                    cached_cycles = %d,
                    featured_news_background_color = %s,
                    sliding_news_background_color = %s,
                    sliding_news_background_color_opacity = %f,
                    font_family = %s,
                    google_font = %s,
					featured_title_font_size = %d,
					featured_excerpt_font_size = %d,
					sliding_news_font_size = %d,
					clock_font_size = %d,
					sliding_news_margin = %d,
					sliding_news_padding = %d,
                    enable_with_mobile_devices = %d,
                    open_button_image = %s,
                    close_button_image = %s,
                    clock_background_image = %s,
                    featured_news_title_color = %s,
                    featured_news_title_color_hover = %s,
                    featured_news_excerpt_color = %s,
                    sliding_news_color = %s,
                    sliding_news_color_hover = %s,
                    clock_text_color = %s,
                    featured_news_background_color_opacity = %s,
                    enable_ticker = %d,
                    enable_links = %d,
                    transient_expiration = %d,
                    url_mode = %d",
			$name,
			$target,
			$url,
			$open_links_new_tab,
			$clock_offset,
			$clock_format,
			$clock_source,
			$clock_autoupdate,
			$clock_autoupdate_time,
			$number_of_sliding_news,
			$featured_title_maximum_length,
			$featured_excerpt_maximum_length,
			$sliding_news_maximum_length,
			$open_news_as_default,
			$hide_featured_news,
			$hide_clock,
			$enable_rtl_layout,
			$cached_cycles,
			$featured_news_background_color,
			$sliding_news_background_color,
			$sliding_news_background_color_opacity,
			$font_family,
			$google_font,
			$featured_title_font_size,
			$featured_excerpt_font_size,
			$sliding_news_font_size,
			$clock_font_size,
			$sliding_news_margin,
			$sliding_news_padding,
			$enable_with_mobile_devices,
			$open_button_image,
			$close_button_image,
			$clock_background_image,
			$featured_news_title_color,
			$featured_news_title_color_hover,
			$featured_news_excerpt_color,
			$sliding_news_color,
			$sliding_news_color_hover,
			$clock_text_color,
			$featured_news_background_color_opacity,
			$enable_ticker,
			$enable_links,
			$transient_expiration,
			$url_mode
		);

		$query_result = $wpdb->query( $safe_sql );

		if ( $query_result !== false ) {
			$dismissible_notice_a[] = array(
				'message' => __( 'The news ticker has been successfully added.', $this->shared->get( 'text_domain' ) ),
				'class'   => 'updated',
			);
		}
	}
}

// delete a transient.
if ( ! is_null( $data['delete_transient_id'] ) ) {

	// Nonce verification.
	check_admin_referer(
		'daextlnl_delete_ticker_transient_' . $data['delete_transient_id'],
		'daextlnl_delete_ticker_transient_nonce'
	);

	$deletion_result = delete_transient( 'daextlnl_ticker_' . intval( $data['delete_transient_id'], 10 ) );

	if ( $deletion_result !== false ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'The transient has been successfully deleted.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'updated',
		);
	}
}

// delete a ticker.
if ( ! is_null( $data['delete_id'] ) ) {

	// Nonce verification.
	check_admin_referer(
		'daextlnl_delete_ticker_' . $data['delete_id'],
		'daextlnl_delete_ticker_nonce'
	);

	// delete the ticker only if it's not used by sliding news or featured news.
	if ( $this->shared->ticker_is_used( $data['delete_id'] ) ) {

		$dismissible_notice_a[] = array(
			'message' => __( "This news ticker is associated with one or more news and can't be deleted.", $this->shared->get( 'text_domain' ) ),
			'class'   => 'error',
		);

	} else {

		// delete the transient of the ticker.
		delete_transient( 'daextlnl_ticker_' . $data['delete_id'] );

		// delete this ticker.
		$table_name = $wpdb->prefix . $this->shared->get( 'slug' ) . '_tickers';
		$safe_sql   = $wpdb->prepare( "DELETE FROM $table_name WHERE id = %d ", $data['delete_id'] );

		$query_result = $wpdb->query( $safe_sql );

		if ( $query_result !== false ) {

			$dismissible_notice_a[] = array(
				'message' => __( 'The news ticker has been successfully deleted.', $this->shared->get( 'text_domain' ) ),
				'class'   => 'updated',
			);

		}
	}
}

// get the tickers data.
$display_form = true;
if ( ! is_null( $data['edit_id'] ) ) {
	$table_name = $wpdb->prefix . $this->shared->get( 'slug' ) . '_tickers';
	$safe_sql   = $wpdb->prepare( "SELECT * FROM $table_name WHERE id = %d ", $data['edit_id'] );
	$ticker_obj = $wpdb->get_row( $safe_sql );
	if ( $ticker_obj === null ) {
		$display_form = false;
	}
}

?>

<!-- output -->

<div class="wrap">

	<?php if ( $this->shared->get_number_of_tickers() > 0 ) : ?>

		<div id="daext-header-wrapper" class="daext-clearfix">

			<h2><?php esc_html_e( 'Live News - News Tickers', $this->shared->get( 'text_domain' ) ); ?></h2>

			<!-- Search Form -->

			<form action="admin.php" method="get" id="daext-search-form">

				<input type="hidden" name="page" value="daextlnl-tickers">

				<p><?php esc_html_e( 'Perform your Search', $this->shared->get( 'text_domain' ) ); ?></p>

				<?php
				if ( ! is_null( $data['s'] ) ) {
					if ( mb_strlen( trim( $data['s'] ) ) > 0 ) {
						$search_string = $data['s'];
					} else {
						$search_string = '';
					}
				} else {
					$search_string = '';
				}

				?>

				<input type="text" name="s" name="s"
						value="<?php echo esc_attr( stripslashes( $search_string ) ); ?>" autocomplete="off" maxlength="255">
				<input type="submit" value="">

			</form>

		</div>

	<?php else : ?>

		<div id="daext-header-wrapper" class="daext-clearfix">

			<h2><?php esc_html_e( 'Live News - News Tickers', $this->shared->get( 'text_domain' ) ); ?></h2>

		</div>

	<?php endif; ?>

	<div id="daext-menu-wrapper">

		<?php $this->dismissible_notice( $dismissible_notice_a ); ?>

		<!-- table -->

		<?php

		// create the query part used to filter the results when a search is performed.
		if ( ! is_null( $data['s'] ) ) {
			if ( mb_strlen( trim( $data['s'] ) ) > 0 ) {
				$filter = $wpdb->prepare( 'WHERE (name LIKE %s)', '%' . $data['s'] . '%' );
			} else {
				$filter = '';
			}
		} else {
			$filter = '';
		}

		// retrieve the total number of sliding news.
		$table_name  = $wpdb->prefix . $this->shared->get( 'slug' ) . '_tickers';
		$total_items = $wpdb->get_var( "SELECT COUNT(*) FROM $table_name $filter" );

		// Initialize the pagination class.
		require_once $this->shared->get( 'dir' ) . '/admin/inc/class-daextlnl-pagination.php';
		$pag = new daextlnl_pagination();
		$pag->set_total_items( $total_items );// Set the total number of items
		$pag->set_record_per_page( 10 ); // Set records per page
		$pag->set_target_page( 'admin.php?page=' . $this->shared->get( 'slug' ) . '-tickers' );// Set target page
		$pag->set_current_page();// set the current page number

		?>

		<!-- Query the database -->
		<?php
		$query_limit = $pag->query_limit();
		$results     = $wpdb->get_results( "SELECT * FROM $table_name $filter ORDER BY id DESC $query_limit ", ARRAY_A );
		?>

		<?php if ( count( $results ) > 0 ) : ?>

			<div class="daext-items-container">

				<!-- list of tables -->
				<table class="daext-items">
					<thead>
					<tr>
						<th>
							<div><?php esc_html_e( 'Name', $this->shared->get( 'text_domain' ) ); ?></div>
							<div class="help-icon" title="<?php esc_attr_e( 'The name of the news ticker.', $this->shared->get( 'text_domain' ) ); ?>"></div>
						</th>
						<th>
							<div><?php esc_html_e( 'Target', $this->shared->get( 'text_domain' ) ); ?></div>
							<div class="help-icon" title="<?php esc_attr_e( 'The target of the news ticker.', $this->shared->get( 'text_domain' ) ); ?>"></div>
						</th>
						<th></th>
					</tr>
					</thead>
					<tbody>

					<?php foreach ( $results as $result ) : ?>
						<tr>
							<td><?php echo esc_html( stripslashes( $result['name'] ) ); ?></td>
							<td><?php echo esc_html( $this->shared->get_textual_target( $result['target'] ) ); ?></td>
							<td class="icons-container">
								<?php if ( get_transient( 'daextlnl_ticker_' . $result['id'] ) !== false ) : ?>
									<form method="POST" action="admin.php?page=<?php echo esc_attr( $this->shared->get( 'slug' ) ); ?>-tickers">
										<?php
										wp_nonce_field(
											'daextlnl_delete_ticker_transient_' . $result['id'],
											'daextlnl_delete_ticker_transient_nonce'
										);
										?>
										<input type="hidden" value="<?php echo esc_attr( $result['id'] ); ?>" name="delete_transient_id" >
										<input class="menu-icon update" type="submit" value="">
									</form>
								<?php else : ?>
									<div class="empty-icon-container"></div>
								<?php endif; ?>
								<a class="menu-icon edit" href="admin.php?page=<?php echo esc_attr( $this->shared->get( 'slug' ) ); ?>-tickers&edit_id=<?php echo esc_attr( $result['id'] ); ?>"></a>
								<form method="POST" action="admin.php?page=<?php echo esc_attr( $this->shared->get( 'slug' ) ); ?>-tickers">
									<?php wp_nonce_field( 'daextlnl_delete_ticker_' . $result['id'], 'daextlnl_delete_ticker_nonce' ); ?>
									<input type="hidden" value="<?php echo esc_attr( $result['id'] ); ?>" name="delete_id" >
									<input class="menu-icon delete" type="submit" value="">
								</form>
							</td>
						</tr>
					<?php endforeach; ?>

					</tbody>

				</table>

			</div>

			<!-- Display the pagination -->
			<?php if ( $pag->total_items > 0 ) : ?>
				<div class="daext-tablenav daext-clearfix">
					<div class="daext-tablenav-pages">
						<span class="daext-displaying-num"><?php echo esc_html( $pag->total_items ); ?> <?php esc_html_e( 'items', $this->shared->get( 'text_domain' ) ); ?></span>
						<?php $pag->show(); ?>
					</div>
				</div>
			<?php endif; ?>

		<?php endif; ?>

		<?php if ( $display_form ) : ?>

			<form method="POST" action="admin.php?page=<?php echo esc_attr( $this->shared->get( 'slug' ) ); ?>-tickers" autocomplete="off">

				<input type="hidden" value="1" name="form_submitted">
				<?php wp_nonce_field( 'daextlnl_create_update_ticker', 'daextlnl_create_update_ticker_nonce' ); ?>

				<?php if ( ! is_null( $data['edit_id'] ) ) : ?>

				<!-- Edit a Ticker -->

				<div class="daext-form-container">

					<h3 class="daext-form-title"><?php esc_html_e( 'Edit News Ticker', $this->shared->get( 'text_domain' ) ); ?> <?php echo esc_html( $ticker_obj->id ); ?></h3>

					<table class="daext-form">

						<input type="hidden" name="update_id" value="<?php echo esc_attr( $ticker_obj->id ); ?>" />

						<!-- Name -->
						<tr valign="top">
							<th scope="row"><label for="name"><?php esc_html_e( 'Name', $this->shared->get( 'text_domain' ) ); ?></label></th>
							<td>
								<input value="<?php echo esc_attr( stripslashes( $ticker_obj->name ) ); ?>" type="text" id="name" maxlength="100" size="30" name="name"/>
								<div class="help-icon" title="<?php esc_attr_e( 'The name of the news ticker.', $this->shared->get( 'text_domain' ) ); ?>"></div>
							</td>
						</tr>

						<!-- Target -->
						<tr valign="top">
							<th scope="row"><label for="target"><?php esc_html_e( 'Target', $this->shared->get( 'text_domain' ) ); ?></label></th>
							<td>
								<select id="target" name="target" class="daext-display-none">
									<option value="1" <?php selected( $ticker_obj->target, 1 ); ?>><?php esc_html_e( 'Website', $this->shared->get( 'text_domain' ) ); ?></option>
									<option value="2" <?php selected( $ticker_obj->target, 2 ); ?>><?php esc_html_e( 'URL', $this->shared->get( 'text_domain' ) ); ?></option>
								</select>
								<div class="help-icon" title='<?php esc_attr_e( 'This selection determines if the news ticker should be applied to the entire website or to a specific URL. Note that a news ticker associated with an URL has the priority over the news ticker associated with the entire website.', $this->shared->get( 'text_domain' ) ); ?>'></div>
							</td>
						</tr>

						<!-- URL -->
						<tr valign="top">
							<th scope="row"><label for="url"><?php esc_html_e( 'Target URL', $this->shared->get( 'text_domain' ) ); ?></label></th>
							<td>
								<textarea type="text" id="url" maxlength="20830000" size="30" name="url"><?php echo esc_html( stripslashes( $ticker_obj->url ) ); ?></textarea>
								<div class="help-icon" title="<?php esc_attr_e( 'Enter one or more URLs. (one URL per line) This option is used only if the target of the news ticker is "URL".', $this->shared->get( 'text_domain' ) ); ?>"></div>
							</td>
						</tr>

						<!-- Enable Ticker -->
						<tr>
							<th scope="row"><?php esc_html_e( 'Enable Ticker', $this->shared->get( 'text_domain' ) ); ?></th>
							<td>
								<select id="enable-ticker" name="enable_ticker" class="daext-display-none">
									<option value="0" <?php selected( $ticker_obj->enable_ticker, 0 ); ?>><?php esc_html_e( 'No', $this->shared->get( 'text_domain' ) ); ?></option>
									<option value="1" <?php selected( $ticker_obj->enable_ticker, 1 ); ?>><?php esc_html_e( 'Yes', $this->shared->get( 'text_domain' ) ); ?></option>
								</select>
								<div class="help-icon" title='<?php esc_attr_e( 'Use this option to enable or disable the news ticker on the front-end.', $this->shared->get( 'text_domain' ) ); ?>'></div>
							</td>
						</tr>

						<tr class="group-trigger" data-trigger-target="source-chart-configuration">
							<th scope="row" class="group-title"><?php esc_html_e( 'Source', $this->shared->get( 'text_domain' ) ); ?></th>
							<td>
								<div class="expand-icon"></div>
							</td>
						</tr>

						<!-- Clock Source -->
						<tr class="source-chart-configuration">
							<th scope="row"><?php esc_html_e( 'Clock Source', $this->shared->get( 'text_domain' ) ); ?></th>
							<td>
								<select id="clock-source" name="clock_source">
									<option value="1" <?php selected( $ticker_obj->clock_source, 1 ); ?>><?php esc_html_e( 'Server Time', $this->shared->get( 'text_domain' ) ); ?></option>
									<option value="2" <?php selected( $ticker_obj->clock_source, 2 ); ?>><?php esc_html_e( 'User Time', $this->shared->get( 'text_domain' ) ); ?></option>
								</select>
								<div class="help-icon" title='<?php esc_attr_e( 'Select if the time should be based on the server time or on the user time.', $this->shared->get( 'text_domain' ) ); ?>'></div>
							</td>
						</tr>

						<!-- Clock Offset -->
						<tr class="source-chart-configuration">
							<th scope="row"><label for="clock-offset"><?php esc_html_e( 'Clock Offset', $this->shared->get( 'text_domain' ) ); ?></label></th>
							<td>
								<input value="<?php echo intval( $ticker_obj->clock_offset, 10 ); ?>" type="text" id="clock-offset" maxlength="6" size="30" name="clock_offset" />
								<div class="help-icon" title="<?php esc_attr_e( 'The clock offset in seconds. Positive or negative values are allowed.', $this->shared->get( 'text_domain' ) ); ?>"></div>
							</td>
						</tr>

						<!-- Clock Format -->
						<tr class="source-chart-configuration">
							<th scope="row"><label for="clock-format"><?php esc_html_e( 'Clock Format', $this->shared->get( 'text_domain' ) ); ?></label></th>
							<td>
								<input value="<?php echo esc_attr( stripslashes( $ticker_obj->clock_format ) ); ?>" type="text" id="clock-format" maxlength="40" size="30" name="clock_format" />
								<div class="help-icon" title="<?php esc_attr_e( 'Use this field to specify the clock format. The tokens supported by Moment.js should be used.', $this->shared->get( 'text_domain' ) ); ?>"></div>
							</td>
						</tr>

						<tr class="group-trigger" data-trigger-target="behavior-chart-configuration">
							<th scope="row" class="group-title"><?php esc_html_e( 'Behavior', $this->shared->get( 'text_domain' ) ); ?></th>
							<td>
								<div class="expand-icon"></div>
							</td>
						</tr>

						<!-- Enable RTL Layout -->
						<tr class="behavior-chart-configuration">
							<th scope="row"><?php esc_html_e( 'Enable RTL Layout', $this->shared->get( 'text_domain' ) ); ?></th>
							<td>
								<select id="enable-rtl-layout" name="enable_rtl_layout">
									<option value="0" <?php selected( $ticker_obj->enable_rtl_layout, 0 ); ?>><?php esc_html_e( 'No', $this->shared->get( 'text_domain' ) ); ?></option>
									<option value="1" <?php selected( $ticker_obj->enable_rtl_layout, 1 ); ?>><?php esc_html_e( 'Yes', $this->shared->get( 'text_domain' ) ); ?></option>
								</select>
								<div class="help-icon" title='<?php esc_attr_e( 'Select whether to enable or not the RTL layout.', $this->shared->get( 'text_domain' ) ); ?>'></div>
							</td>
						</tr>

						<!-- Enable with Mobile Devices -->
						<tr class="behavior-chart-configuration">
							<th scope="row"><?php esc_html_e( 'Enable with Mobile Devices', $this->shared->get( 'text_domain' ) ); ?></th>
							<td>
								<select id="enable-with-mobile-devices" name="enable_with_mobile_devices">
									<option value="0" <?php selected( $ticker_obj->enable_with_mobile_devices, 0 ); ?>><?php esc_html_e( 'No', $this->shared->get( 'text_domain' ) ); ?></option>
									<option value="1" <?php selected( $ticker_obj->enable_with_mobile_devices, 1 ); ?>><?php esc_html_e( 'Yes', $this->shared->get( 'text_domain' ) ); ?></option>
								</select>
								<div class="help-icon" title='<?php esc_attr_e( 'Select whether to display or not the news ticker with mobile devices. The user-agent string combined with specific HTTP headers are used to determine the device.', $this->shared->get( 'text_domain' ) ); ?>'></div>
							</td>
						</tr>

						<!-- Hide Featured News -->
						<tr class="behavior-chart-configuration">
							<th scope="row"><?php esc_html_e( 'Hide Featured News', $this->shared->get( 'text_domain' ) ); ?></th>
							<td>
								<select id="hide-featured-news" name="hide_featured_news">
									<option value="1" <?php selected( $ticker_obj->hide_featured_news, 1 ); ?>><?php esc_html_e( 'No', $this->shared->get( 'text_domain' ) ); ?></option>
									<option value="2" <?php selected( $ticker_obj->hide_featured_news, 2 ); ?>><?php esc_html_e( 'Yes', $this->shared->get( 'text_domain' ) ); ?></option>
									<option value="3" <?php selected( $ticker_obj->hide_featured_news, 3 ); ?>><?php esc_html_e( 'Only with Mobile Devices', $this->shared->get( 'text_domain' ) ); ?></option>
								</select>
								<div class="help-icon" title='<?php esc_attr_e( 'Select if the featured news area of the news ticker should be displayed.', $this->shared->get( 'text_domain' ) ); ?>'></div>
							</td>
						</tr>

						<!-- Open News as Default -->
						<tr class="behavior-chart-configuration">
							<th scope="row"><?php esc_html_e( 'Open News as Default', $this->shared->get( 'text_domain' ) ); ?></th>
							<td>
								<select id="open-news-as-default" name="open_news_as_default">
									<option value="0" <?php selected( $ticker_obj->open_news_as_default, 0 ); ?>><?php esc_html_e( 'No', $this->shared->get( 'text_domain' ) ); ?></option>
									<option value="1" <?php selected( $ticker_obj->open_news_as_default, 1 ); ?>><?php esc_html_e( 'Yes', $this->shared->get( 'text_domain' ) ); ?></option>
								</select>
								<div class="help-icon" title='<?php esc_attr_e( 'Select if the news ticker should be presented in the open status (with the featured news area visible) to the users. If the user opens or closes the news ticker the new status will be saved in a cookie and used to determine the default status of the news ticker for that specific user.', $this->shared->get( 'text_domain' ) ); ?>'></div>
							</td>
						</tr>

						<!-- Enable Links -->
						<tr class="behavior-chart-configuration">
							<th scope="row"><?php esc_html_e( 'Enable Links', $this->shared->get( 'text_domain' ) ); ?></th>
							<td>
								<select id="enable-links" name="enable_links">
									<option value="0" <?php selected( $ticker_obj->enable_links, 0 ); ?>><?php esc_html_e( 'No', $this->shared->get( 'text_domain' ) ); ?></option>
									<option value="1" <?php selected( $ticker_obj->enable_links, 1 ); ?>><?php esc_html_e( 'Yes', $this->shared->get( 'text_domain' ) ); ?></option>
								</select>
								<div class="help-icon" title='<?php esc_attr_e( 'Whether to apply or not the links associated with the news on the featured news title and on the sliding news.', $this->shared->get( 'text_domain' ) ); ?>'></div>
							</td>
						</tr>

						<!-- Open Links New Tab -->
						<tr class="behavior-chart-configuration">
							<th scope="row"><?php esc_html_e( 'Open Links in New Tab', $this->shared->get( 'text_domain' ) ); ?></th>
							<td>
								<select id="open-links-new-tab" name="open_links_new_tab">
									<option value="0" <?php selected( $ticker_obj->open_links_new_tab, 0 ); ?>><?php esc_html_e( 'No', $this->shared->get( 'text_domain' ) ); ?></option>
									<option value="1" <?php selected( $ticker_obj->open_links_new_tab, 1 ); ?>><?php esc_html_e( 'Yes', $this->shared->get( 'text_domain' ) ); ?></option>
								</select>
								<div class="help-icon" title='<?php esc_attr_e( 'Select if the links availble in the news ticker should be opened in a new tab.', $this->shared->get( 'text_domain' ) ); ?>'></div>
							</td>
						</tr>

						<!-- Hide Clock -->
						<tr class="behavior-chart-configuration">
							<th scope="row"><?php esc_html_e( 'Hide Clock', $this->shared->get( 'text_domain' ) ); ?></th>
							<td>
								<select id="hide-clock" name="hide_clock">
									<option value="0" <?php selected( $ticker_obj->hide_clock, 0 ); ?>><?php esc_html_e( 'No', $this->shared->get( 'text_domain' ) ); ?></option>
									<option value="1" <?php selected( $ticker_obj->hide_clock, 1 ); ?>><?php esc_html_e( 'Yes', $this->shared->get( 'text_domain' ) ); ?></option>
								</select>
								<div class="help-icon" title='<?php esc_attr_e( 'Select whether to display or not the clock.', $this->shared->get( 'text_domain' ) ); ?>'></div>
							</td>
						</tr>

						<!-- Clock Autoupdate -->
						<tr class="behavior-chart-configuration">
							<th scope="row"><?php esc_html_e( 'Clock Autoupdate', $this->shared->get( 'text_domain' ) ); ?></th>
							<td>
								<select id="clock-autoupdate" name="clock_autoupdate">
									<option value="0" <?php selected( $ticker_obj->clock_autoupdate, 0 ); ?>><?php esc_html_e( 'No', $this->shared->get( 'text_domain' ) ); ?></option>
									<option value="1" <?php selected( $ticker_obj->clock_autoupdate, 1 ); ?>><?php esc_html_e( 'Yes', $this->shared->get( 'text_domain' ) ); ?></option>
								</select>
								<div class="help-icon" title='<?php esc_attr_e( 'Select whether to autoupdate or not the clock independently from the cycles of news received. This option is applied only if the source of the clock is "User Time".', $this->shared->get( 'text_domain' ) ); ?>'></div>
							</td>
						</tr>

						<!-- Clock Autoupdate Time -->
						<tr class="behavior-chart-configuration">
							<th scope="row"><label for="clock-autoupdate-time"><?php esc_html_e( 'Clock Autoupdate Time', $this->shared->get( 'text_domain' ) ); ?></label></th>
							<td>
								<input value="<?php echo intval( $ticker_obj->clock_autoupdate_time, 10 ); ?>" type="text" id="clock-autoupdate-time" maxlength="10" size="30" name="clock_autoupdate_time" />
								<div class="help-icon" title="<?php esc_attr_e( 'This option determines how frequent should be the clock autoupdate in seconds.', $this->shared->get( 'text_domain' ) ); ?>"></div>
							</td>
						</tr>

						<!-- Number of Sliding News -->
						<tr class="behavior-chart-configuration">
							<th scope="row"><label for="number-of-sliding-news"><?php esc_html_e( 'Number of Sliding News', $this->shared->get( 'text_domain' ) ); ?></label></th>
							<td>
								<input value="<?php echo abs( intval( $ticker_obj->number_of_sliding_news, 10 ) ); ?>" type="text" id="number-of-sliding-news" maxlength="2" size="30" name="number_of_sliding_news" />
								<div class="help-icon" title="<?php esc_attr_e( 'Enter the number of sliding news that you want to display in a single cycle of news.', $this->shared->get( 'text_domain' ) ); ?>"></div>
							</td>
						</tr>

						<tr class="group-trigger" data-trigger-target="performance-chart-configuration">
							<th scope="row" class="group-title"><?php esc_html_e( 'Performance', $this->shared->get( 'text_domain' ) ); ?></th>
							<td>
								<div class="expand-icon"></div>
							</td>
						</tr>

						<!-- Cached Cycled -->
						<tr class="performance-chart-configuration">
							<th scope="row"><label for="cached-cycles"><?php esc_html_e( 'Cached Cycles', $this->shared->get( 'text_domain' ) ); ?></label></th>
							<td>
								<input value="<?php echo abs( intval( $ticker_obj->cached_cycles, 10 ) ); ?>" type="text" id="cached-cycles" maxlength="10" size="30" name="cached_cycles" />
								<div class="help-icon" title="<?php esc_attr_e( 'This value determines the number of cycles performed by the news ticker without updating the news. Set an high value to improve the news ticker performance and to avoid an excessive load on the web server. Set a low value to have frequent updates of the news. Set 0 to update the news at every cycle.', $this->shared->get( 'text_domain' ) ); ?>"></div>
							</td>
						</tr>

						<!-- Transient Expiration -->
						<tr class="performance-chart-configuration">
							<th scope="row"><label for="clock-background-image"><?php esc_html_e( 'Transient Expiration', $this->shared->get( 'text_domain' ) ); ?></label></th>
							<td>
								<input value="<?php echo intval( $ticker_obj->transient_expiration, 10 ); ?>" type="text" id="transient-expiration" maxlength="10" size="30" name="transient_expiration"/>
								<div class="help-icon" title="<?php esc_attr_e( 'Enter the transient expiration in seconds. Set an high value to improve the news ticker performance and to avoid an excessive load on the web server. Set a low value to have frequent updates of the news. Set 0 to not use a transient.', $this->shared->get( 'text_domain' ) ); ?>"></div>
							</td>
						</tr>

						<tr class="group-trigger" data-trigger-target="style-chart-configuration">
							<th scope="row" class="group-title"><?php esc_html_e( 'Style', $this->shared->get( 'text_domain' ) ); ?></th>
							<td>
								<div class="expand-icon"></div>
							</td>
						</tr>

						<!-- Featured Title Maximum Length -->
						<tr class="style-chart-configuration">
							<th scope="row"><label for="featured-title-maximum-length"><?php esc_html_e( 'Featured News Title Maximum Length', $this->shared->get( 'text_domain' ) ); ?></label></th>
							<td>
								<input value="<?php echo abs( intval( $ticker_obj->featured_title_maximum_length, 10 ) ); ?>" type="text" id="featured-title-maximum-length" maxlength="4" size="30" name="featured_title_maximum_length" />
								<div class="help-icon" title="<?php esc_attr_e( 'The maximum length of the featured news title.', $this->shared->get( 'text_domain' ) ); ?>"></div>
							</td>
						</tr>

						<!-- Featured Excerpt Maximum Length -->
						<tr class="style-chart-configuration">
							<th scope="row"><label for="featured-excerpt-maximum-length"><?php esc_html_e( 'Featured News Excerpt Maximum Length', $this->shared->get( 'text_domain' ) ); ?></label></th>
							<td>
								<input value="<?php echo abs( intval( $ticker_obj->featured_excerpt_maximum_length, 10 ) ); ?>" type="text" id="featured-excerpt-maximum-length" maxlength="4" size="30" name="featured_excerpt_maximum_length" />
								<div class="help-icon" title="<?php esc_attr_e( 'The maximum length of the featured news excerpt.', $this->shared->get( 'text_domain' ) ); ?>"></div>
							</td>
						</tr>

						<!-- Sliding News Maximum Length -->
						<tr class="style-chart-configuration">
							<th scope="row"><label for="sliding-news-maximum-length"><?php esc_html_e( 'Sliding News Maximum Length', $this->shared->get( 'text_domain' ) ); ?></label></th>
							<td>
								<input value="<?php echo abs( intval( $ticker_obj->sliding_news_maximum_length, 10 ) ); ?>" type="text" id="sliding-news-maximum-length" maxlength="4" size="30" name="sliding_news_maximum_length" />
								<div class="help-icon" title="<?php esc_attr_e( 'The maximum length of the sliding news.', $this->shared->get( 'text_domain' ) ); ?>"></div>
							</td>
						</tr>

						<!-- Featured Title Font Size -->
						<tr class="style-chart-configuration">
							<th scope="row"><label for="featured-title-font-size"><?php esc_html_e( 'Featured News Title Font Size', $this->shared->get( 'text_domain' ) ); ?></label></th>
							<td>
								<input value="<?php echo abs( intval( $ticker_obj->featured_title_font_size, 10 ) ); ?>" type="text" id="featured-title-font-size" maxlength="2" size="30" name="featured_title_font_size" />
								<div class="help-icon" title="<?php esc_attr_e( 'The font size of the featured news title.', $this->shared->get( 'text_domain' ) ); ?>"></div>
							</td>
						</tr>

						<!-- Featured Excerpt Font Size -->
						<tr class="style-chart-configuration">
							<th scope="row"><label for="featured-excerpt-font-size"><?php esc_html_e( 'Featured News Excerpt Font Size', $this->shared->get( 'text_domain' ) ); ?></label></th>
							<td>
								<input value="<?php echo abs( intval( $ticker_obj->featured_excerpt_font_size, 10 ) ); ?>" type="text" id="featured-excerpt-font-size" maxlength="2" size="30" name="featured_excerpt_font_size" />
								<div class="help-icon" title="<?php esc_attr_e( 'The font size of the featured news excerpt.', $this->shared->get( 'text_domain' ) ); ?>"></div>
							</td>
						</tr>

						<!-- Sliding News Font Size -->
						<tr class="style-chart-configuration">
							<th scope="row"><label for="sliding-news-font-size"><?php esc_html_e( 'Sliding News Font Size', $this->shared->get( 'text_domain' ) ); ?></label></th>
							<td>
								<input value="<?php echo abs( intval( $ticker_obj->sliding_news_font_size, 10 ) ); ?>" type="text" id="sliding-news-font-size" maxlength="2" size="30" name="sliding_news_font_size" />
								<div class="help-icon" title="<?php esc_attr_e( 'The font size of the sliding news.', $this->shared->get( 'text_domain' ) ); ?>"></div>
							</td>
						</tr>

						<!-- Clock Font Size -->
						<tr class="style-chart-configuration">
							<th scope="row"><label for="clock-font-size"><?php esc_html_e( 'Clock Font Size', $this->shared->get( 'text_domain' ) ); ?></label></th>
							<td>
								<input value="<?php echo abs( intval( $ticker_obj->clock_font_size, 10 ) ); ?>" type="text" id="clock-font-size" maxlength="2" size="30" name="clock_font_size" />
								<div class="help-icon" title="<?php esc_attr_e( 'The font size of the text in the clock.', $this->shared->get( 'text_domain' ) ); ?>"></div>
							</td>
						</tr>

						<!-- Sliding News Margin -->
						<tr class="style-chart-configuration">
							<th scope="row"><label for="sliding-news-margin"><?php esc_html_e( 'Sliding News Margin', $this->shared->get( 'text_domain' ) ); ?></label></th>
							<td>
								<input value="<?php echo abs( intval( $ticker_obj->sliding_news_margin, 10 ) ); ?>" type="text" id="sliding-news-margin" maxlength="3" size="30" name="sliding_news_margin" />
								<div class="help-icon" title="<?php esc_attr_e( 'The margin between the sliding news.', $this->shared->get( 'text_domain' ) ); ?>"></div>
							</td>
						</tr>

						<!-- Sliding News Padding -->
						<tr class="style-chart-configuration">
							<th scope="row"><label for="sliding-news-padding"><?php esc_html_e( 'Sliding News Padding', $this->shared->get( 'text_domain' ) ); ?></label></th>
							<td>
								<input value="<?php echo abs( intval( $ticker_obj->sliding_news_padding, 10 ) ); ?>" type="text" id="sliding-news-padding" maxlength="3" size="30" name="sliding_news_padding" />
								<div class="help-icon" title="<?php esc_attr_e( 'This option determines the padding on the left and on the right of each sliding news and also the distance between the sliding news text and the sliding news left and right images.', $this->shared->get( 'text_domain' ) ); ?>"></div>
							</td>
						</tr>

						<!-- Font Family -->
						<tr class="style-chart-configuration">
							<th scope="row"><label for="font-family"><?php esc_html_e( 'Font Family', $this->shared->get( 'text_domain' ) ); ?></label></th>
							<td>
								<input value="<?php echo esc_attr( stripslashes( $ticker_obj->font_family ) ); ?>" type="text" id="font-family" maxlength="255" size="30" name="font_family" />
								<div class="help-icon" title="<?php esc_attr_e( 'The font family used for all the text displayed in the news ticker.', $this->shared->get( 'text_domain' ) ); ?>"></div>
							</td>
						</tr>

						<!-- Google Font -->
						<tr class="style-chart-configuration">
							<th scope="row"><label for="google-font"><?php esc_html_e( 'Google Font', $this->shared->get( 'text_domain' ) ); ?></label></th>
							<td>
								<input value="<?php echo esc_url( stripslashes( $ticker_obj->google_font ) ); ?>" type="text" id="google-font" maxlength="255" size="30" name="google_font" />
								<div class="help-icon" title="<?php esc_attr_e( 'This option allows you to load a specific Google Font.', $this->shared->get( 'text_domain' ) ); ?>"></div>
							</td>
						</tr>

						<!-- Featured News Title Color -->
						<tr class="style-chart-configuration">
							<th scope="row"><label for="featured-news-title-color"><?php esc_html_e( 'Featured News Title Color', $this->shared->get( 'text_domain' ) ); ?></label></th>
							<td>
								<input value="<?php echo esc_attr( stripslashes( $ticker_obj->featured_news_title_color ) ); ?>" class="wp-color-picker" type="text" id="featured-news-title-color" maxlength="7" size="30" name="featured_news_title_color" />
								<div class="help-icon" title="<?php esc_attr_e( 'The color of the featured news title.', $this->shared->get( 'text_domain' ) ); ?>"></div>
							</td>
						</tr>

						<!-- Featured News Title Color Hover -->
						<tr class="style-chart-configuration">
							<th scope="row"><label for="featured-news-title-color-hover"><?php esc_html_e( 'Featured News Title Color Hover', $this->shared->get( 'text_domain' ) ); ?></label></th>
							<td>
								<input value="<?php echo esc_attr( stripslashes( $ticker_obj->featured_news_title_color_hover ) ); ?>" class="wp-color-picker" type="text" id="featured-news-title-color-hover" maxlength="7" size="30" name="featured_news_title_color_hover" />
								<div class="help-icon" title="<?php esc_attr_e( 'The color of the featured news title in hover status.', $this->shared->get( 'text_domain' ) ); ?>"></div>
							</td>
						</tr>

						<!-- Featured News Excerpt Color -->
						<tr class="style-chart-configuration">
							<th scope="row"><label for="featured-news-excerpt-color"><?php esc_html_e( 'Featured News Excerpt Color', $this->shared->get( 'text_domain' ) ); ?></label></th>
							<td>
								<input value="<?php echo esc_attr( stripslashes( $ticker_obj->featured_news_excerpt_color ) ); ?>" class="wp-color-picker" type="text" id="featured-news-excerpt-color" maxlength="7" size="30" name="featured_news_excerpt_color" />
								<div class="help-icon" title="<?php esc_attr_e( 'The color of the featured news excerpt.', $this->shared->get( 'text_domain' ) ); ?>"></div>
							</td>
						</tr>

						<!-- Sliding News Color -->
						<tr class="style-chart-configuration">
							<th scope="row"><label for="sliding-news-color"><?php esc_html_e( 'Sliding News Color', $this->shared->get( 'text_domain' ) ); ?></label></th>
							<td>
								<input value="<?php echo esc_attr( stripslashes( $ticker_obj->sliding_news_color ) ); ?>" class="wp-color-picker" type="text" id="sliding-news-color" maxlength="7" size="30" name="sliding_news_color" />
								<div class="help-icon" title="<?php esc_attr_e( 'The color of the sliding news.', $this->shared->get( 'text_domain' ) ); ?>"></div>
							</td>
						</tr>

						<!-- Sliding News Color Hover -->
						<tr class="style-chart-configuration">
							<th scope="row"><label for="sliding-news-color-hover"><?php esc_html_e( 'Sliding News Color Hover', $this->shared->get( 'text_domain' ) ); ?></label></th>
							<td>
								<input value="<?php echo esc_attr( stripslashes( $ticker_obj->sliding_news_color_hover ) ); ?>" class="wp-color-picker" type="text" id="sliding-news-color-hover" maxlength="7" size="30" name="sliding_news_color_hover" />
								<div class="help-icon" title="<?php esc_attr_e( 'The color of the sliding news in hover status.', $this->shared->get( 'text_domain' ) ); ?>"></div>
							</td>
						</tr>

						<!-- Clock Text Color -->
						<tr class="style-chart-configuration">
							<th scope="row"><label for="clock-text-color"><?php esc_html_e( 'Clock Text Color', $this->shared->get( 'text_domain' ) ); ?></label></th>
							<td>
								<input value="<?php echo esc_attr( stripslashes( $ticker_obj->clock_text_color ) ); ?>" class="wp-color-picker" type="text" id="clock-text-color" maxlength="7" size="30" name="clock_text_color" />
								<div class="help-icon" title="<?php esc_attr_e( 'The color of the text displayed in the clock.', $this->shared->get( 'text_domain' ) ); ?>"></div>
							</td>
						</tr>

						<!-- Featured News Background Color -->
						<tr class="style-chart-configuration">
							<th scope="row"><label for="featured-news-background-color"><?php esc_html_e( 'Featured News Background Color', $this->shared->get( 'text_domain' ) ); ?></label></th>
							<td>
								<input value="<?php echo esc_attr( stripslashes( $ticker_obj->featured_news_background_color ) ); ?>" class="wp-color-picker" type="text" id="featured-news-background-color" maxlength="7" size="30" name="featured_news_background_color" />
								<div class="help-icon" title="<?php esc_attr_e( 'The background color of the featured news area.', $this->shared->get( 'text_domain' ) ); ?>"></div>
							</td>
						</tr>

						<!-- Featured News Background Color Opacity -->
						<tr class="style-chart-configuration">
							<th scope="row"><label for="featured-news-background-color-opacity"><?php esc_html_e( 'Featured News Background Color Opacity', $this->shared->get( 'text_domain' ) ); ?></label></th>
							<td>
								<input value="<?php echo floatval( $ticker_obj->featured_news_background_color_opacity ); ?>" type="text" id="featured-news-background-color-opacity" maxlength="3" size="30" name="featured_news_background_color_opacity" />
								<div class="help-icon" title="<?php esc_attr_e( 'The background color opacity of the featured news area.', $this->shared->get( 'text_domain' ) ); ?>"></div>
							</td>
						</tr>

						<!-- Sliding News Background Color -->
						<tr class="style-chart-configuration">
							<th scope="row"><label for="sliding-news-background-color"><?php esc_html_e( 'Sliding News Background Color', $this->shared->get( 'text_domain' ) ); ?></label></th>
							<td>
								<input value="<?php echo esc_attr( stripslashes( $ticker_obj->sliding_news_background_color ) ); ?>" class="wp-color-picker" type="text" id="sliding-news-background-color" maxlength="7" size="30" name="sliding_news_background_color" />
								<div class="help-icon" title="<?php esc_attr_e( 'The background color of the sliding news area.', $this->shared->get( 'text_domain' ) ); ?>"></div>
							</td>
						</tr>

						<!-- Sliding News Background Color Opacity -->
						<tr class="style-chart-configuration">
							<th scope="row"><label for="sliding-news-background-color-opacity"><?php esc_html_e( 'Sliding News Background Color Opacity', $this->shared->get( 'text_domain' ) ); ?></label></th>
							<td>
								<input value="<?php echo floatval( stripslashes( $ticker_obj->sliding_news_background_color_opacity ) ); ?>" type="text" id="sliding-news-background-color-opacity" maxlength="3" size="30" name="sliding_news_background_color_opacity" />
								<div class="help-icon" title="<?php esc_attr_e( 'The background color opacity of the sliding news area.', $this->shared->get( 'text_domain' ) ); ?>"></div>
							</td>
						</tr>

						<!-- Open Button Image -->
						<tr class="style-chart-configuration">
							<th scope="row"><label for="open-button-image"><?php esc_html_e( 'Open Button Image', $this->shared->get( 'text_domain' ) ); ?></label></th>
							<td>

								<div class="image-uploader">
									<img class="selected-image" src="<?php echo esc_attr( stripslashes( $ticker_obj->open_button_image ) ); ?>" <?php echo mb_strlen( trim( $ticker_obj->open_button_image ) ) == 0 ? 'style="display: none;"' : ''; ?>>
									<input value="<?php echo esc_attr( stripslashes( $ticker_obj->open_button_image ) ); ?>" type="hidden" id="open-button-image" maxlength="2083" name="open_button_image">
									<a class="button_add_media" data-set-remove="<?php echo mb_strlen( trim( $ticker_obj->open_button_image ) ) == 0 ? 'set' : 'remove'; ?>" data-set="<?php esc_attr_e( 'Set image', $this->shared->get( 'text_domain' ) ); ?>" data-remove="<?php esc_attr_e( 'Remove Image', $this->shared->get( 'text_domain' ) ); ?>"><?php echo mb_strlen( trim( $ticker_obj->open_button_image ) ) == 0 ? esc_attr__( 'Set image', $this->shared->get( 'text_domain' ) ) : esc_attr__( 'Remove Image', $this->shared->get( 'text_domain' ) ); ?></a>
									<p class="description"><?php esc_attr_e( "Select the image of the button used to open the news ticker. It's recommended to use an image with a width of 80 pixels and a height of 40 pixels.", $this->shared->get( 'text_domain' ) ); ?></p>
								</div>

							</td>
						</tr>

						<!-- Close Button Image -->
						<tr class="style-chart-configuration">
							<th scope="row"><label for="open-button-image"><?php esc_html_e( 'Close Button Image', $this->shared->get( 'text_domain' ) ); ?></label></th>
							<td>

								<div class="image-uploader">
									<img class="selected-image" src="<?php echo esc_attr( stripslashes( $ticker_obj->close_button_image ) ); ?>" <?php echo mb_strlen( trim( $ticker_obj->close_button_image ) ) == 0 ? 'style="display: none;"' : ''; ?>>
									<input value="<?php echo esc_attr( stripslashes( $ticker_obj->close_button_image ) ); ?>" type="hidden" id="close-button-image" maxlength="2083" name="close_button_image">
									<a class="button_add_media" data-set-remove="<?php echo mb_strlen( trim( $ticker_obj->close_button_image ) ) == 0 ? 'set' : 'remove'; ?>" data-set="<?php esc_attr_e( 'Set image', $this->shared->get( 'text_domain' ) ); ?>" data-remove="<?php esc_attr_e( 'Remove Image', $this->shared->get( 'text_domain' ) ); ?>"><?php echo mb_strlen( trim( $ticker_obj->close_button_image ) ) == 0 ? esc_attr__( 'Set image', $this->shared->get( 'text_domain' ) ) : esc_attr__( 'Remove Image', $this->shared->get( 'text_domain' ) ); ?></a>
									<p class="description"><?php esc_attr_e( "Select the image of the button used to close the news ticker. It's recommended to use an image with a width of 80 pixels and a height of 40 pixels.", $this->shared->get( 'text_domain' ) ); ?></p>
								</div>

							</td>
						</tr>

						<!-- Clock Background Image -->
						<tr class="style-chart-configuration">
							<th scope="row"><label for="clock-background-image"><?php esc_html_e( 'Clock Background Image', $this->shared->get( 'text_domain' ) ); ?></label></th>
							<td>

								<div class="image-uploader">
									<img class="selected-image" src="<?php echo esc_attr( stripslashes( $ticker_obj->clock_background_image ) ); ?>" <?php echo mb_strlen( trim( $ticker_obj->clock_background_image ) ) == 0 ? 'style="display: none;"' : ''; ?>>
									<input value="<?php echo esc_attr( stripslashes( $ticker_obj->clock_background_image ) ); ?>" type="hidden" id="clock-background-image" maxlength="2083" name="clock_background_image">
									<a class="button_add_media" data-set-remove="<?php echo mb_strlen( trim( $ticker_obj->clock_background_image ) ) == 0 ? 'set' : 'remove'; ?>" data-set="<?php esc_attr_e( 'Set image', $this->shared->get( 'text_domain' ) ); ?>" data-remove="<?php esc_attr_e( 'Remove Image', $this->shared->get( 'text_domain' ) ); ?>"><?php echo mb_strlen( trim( $ticker_obj->clock_background_image ) ) == 0 ? esc_attr__( 'Set image', $this->shared->get( 'text_domain' ) ) : esc_attr__( 'Remove Image', $this->shared->get( 'text_domain' ) ); ?></a>
									<p class="description"><?php esc_attr_e( "Select the background image of the clock. It's recommended to use an image with a width of 80 pixels and a height of 40 pixels.", $this->shared->get( 'text_domain' ) ); ?></p>
								</div>

							</td>
						</tr>

						<tr class="group-trigger" data-trigger-target="section-advanced">
							<th scope="row" class="group-title"><?php esc_html_e( 'Advanced', $this->shared->get( 'text_domain' ) ); ?></th>
							<td>
								<div class="expand-icon"></div>
							</td>
						</tr>

						<!-- Target URL Mode -->
						<tr class="section-advanced">
							<th scope="row"><?php esc_html_e( 'Target URL Mode', $this->shared->get( 'text_domain' ) ); ?></th>
							<td>
								<select id="url-mode" name="url_mode">
									<option value="0" <?php selected( $ticker_obj->url_mode, 0 ); ?>><?php esc_html_e( 'Include', $this->shared->get( 'text_domain' ) ); ?></option>
									<option value="1" <?php selected( $ticker_obj->url_mode, 1 ); ?>><?php esc_html_e( 'Exclude', $this->shared->get( 'text_domain' ) ); ?></option>
								</select>
								<div class="help-icon" title='<?php esc_attr_e( 'Select whether to include or exclude the URLs defined with the "Target URL" option.', $this->shared->get( 'text_domain' ) ); ?>'></div>
							</td>
						</tr>

					</table>

					<!-- submit button -->
					<div class="daext-form-action">
						<input class="button" type="submit" value="<?php esc_attr_e( 'Update News Ticker', $this->shared->get( 'text_domain' ) ); ?>" >
					</div>

					<?php else : ?>

					<!-- Create New Ticker -->

					<div class="daext-form-container">

						<div class="daext-form-title"><?php esc_html_e( 'Create a News Ticker', $this->shared->get( 'text_domain' ) ); ?></div>

						<table class="daext-form">

							<!-- Name -->
							<tr valign="top">
								<th scope="row"><label for="name"><?php esc_html_e( 'Name', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<input type="text" id="name" maxlength="100" size="30" name="name" />
									<div class="help-icon" title="<?php esc_attr_e( 'The name of the news ticker.', $this->shared->get( 'text_domain' ) ); ?>"></div>
								</td>
							</tr>

							<!-- Target -->
							<tr valign="top">
								<th scope="row"><label for="target"><?php esc_html_e( 'Target', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<select id="target" name="target" class="daext-display-none">
										<option value="1"><?php esc_html_e( 'Website', $this->shared->get( 'text_domain' ) ); ?></option>
										<option value="2"><?php esc_html_e( 'URL', $this->shared->get( 'text_domain' ) ); ?></option>
									</select>
									<div class="help-icon" title='<?php esc_attr_e( 'This selection determines if the news ticker should be applied to the entire website or to a specific URL. Note that a news ticker associated with an URL has the priority over the news ticker associated with the entire website.', $this->shared->get( 'text_domain' ) ); ?>'></div>
								</td>
							</tr>

							<!-- URL -->
							<tr valign="top">
								<th scope="row"><label for="url"><?php esc_html_e( ' Target URL', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<textarea type="text" id="url" maxlength="20830000" size="30" name="url"></textarea>
									<div class="help-icon" title="<?php esc_attr_e( 'Enter one or more URLs. (one URL per line) This option is used only if the target of the news ticker is "URL".', $this->shared->get( 'text_domain' ) ); ?>"></div>
								</td>
							</tr>

							<!-- Enable Ticker -->
							<tr>
								<th scope="row"><?php esc_html_e( 'Enable Ticker', $this->shared->get( 'text_domain' ) ); ?></th>
								<td>
									<select id="enable-ticker" name="enable_ticker" class="daext-display-none">
										<option value="0"><?php esc_html_e( 'No', $this->shared->get( 'text_domain' ) ); ?></option>
										<option value="1" selected="selected"><?php esc_html_e( 'Yes', $this->shared->get( 'text_domain' ) ); ?></option>
									</select>
									<div class="help-icon" title='<?php esc_attr_e( 'Use this option to enable or disable the news ticker on the front-end.', $this->shared->get( 'text_domain' ) ); ?>'></div>
								</td>
							</tr>

							<tr class="group-trigger" data-trigger-target="source-chart-configuration">
								<th scope="row" class="group-title"><?php esc_html_e( 'Source', $this->shared->get( 'text_domain' ) ); ?></th>
								<td>
									<div class="expand-icon"></div>
								</td>
							</tr>

							<!-- Clock Source -->
							<tr class="source-chart-configuration">
								<th scope="row"><?php esc_html_e( 'Clock Source', $this->shared->get( 'text_domain' ) ); ?></th>
								<td>
									<select id="clock-source" name="clock_source">
										<option value="1"><?php esc_html_e( 'Server Time', $this->shared->get( 'text_domain' ) ); ?></option>
										<option value="2" selected="selected"><?php esc_html_e( 'User Time', $this->shared->get( 'text_domain' ) ); ?></option>
									</select>
									<div class="help-icon" title='<?php esc_attr_e( 'Select if the time should be based on the server time or on the user time. Please note that by selecting "Server Time" the clock will be updated only when the news are retrieved from the server, therefore this option should not be used if you are caching cycles of news or if you are using transients.', $this->shared->get( 'text_domain' ) ); ?>'></div>
								</td>
							</tr>

							<!-- Clock Offset -->
							<tr class="source-chart-configuration">
								<th scope="row"><label for="clock-offset"><?php esc_html_e( 'Clock Offset', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<input value="0" type="text" id="clock-offset" maxlength="6" size="30" name="clock_offset" />
									<div class="help-icon" title="<?php esc_attr_e( 'The clock offset in seconds. Positive or negative values are allowed.', $this->shared->get( 'text_domain' ) ); ?>"></div>
								</td>
							</tr>

							<!-- Clock Format -->
							<tr class="source-chart-configuration">
								<th scope="row"><label for="clock-format"><?php esc_html_e( 'Clock Format', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<input value="HH:mm" type="text" id="clock-format" maxlength="40" size="30" name="clock_format" />
									<div class="help-icon" title="<?php esc_attr_e( 'Use this field to specify the clock format. The tokens supported by Moment.js should be used.', $this->shared->get( 'text_domain' ) ); ?>"></div>
								</td>
							</tr>

							<tr class="group-trigger" data-trigger-target="behavior-chart-configuration">
								<th scope="row" class="group-title"><?php esc_html_e( 'Behavior', $this->shared->get( 'text_domain' ) ); ?></th>
								<td>
									<div class="expand-icon"></div>
								</td>
							</tr>

							<!-- Enable RTL Layout -->
							<tr class="behavior-chart-configuration">
								<th scope="row"><?php esc_html_e( 'Enable RTL Layout', $this->shared->get( 'text_domain' ) ); ?></th>
								<td>
									<select id="enable-rtl-layout" name="enable_rtl_layout">
										<option value="0"><?php esc_html_e( 'No', $this->shared->get( 'text_domain' ) ); ?></option>
										<option value="1"><?php esc_html_e( 'Yes', $this->shared->get( 'text_domain' ) ); ?></option>
									</select>
									<div class="help-icon" title='<?php esc_attr_e( 'Select whether to enable or not the RTL layout.', $this->shared->get( 'text_domain' ) ); ?>'></div>
								</td>
							</tr>

							<!-- Enable with Mobile Devices -->
							<tr class="behavior-chart-configuration">
								<th scope="row"><?php esc_html_e( 'Enable with Mobile Devices', $this->shared->get( 'text_domain' ) ); ?></th>
								<td>
									<select id="enable-with-mobile-devices" name="enable_with_mobile_devices">
										<option value="0"><?php esc_html_e( 'No', $this->shared->get( 'text_domain' ) ); ?></option>
										<option value="1"><?php esc_html_e( 'Yes', $this->shared->get( 'text_domain' ) ); ?></option>
									</select>
									<div class="help-icon" title='<?php esc_attr_e( 'Select whether to display or not the news ticker with mobile devices. The user-agent string combined with specific HTTP headers are used to determine the device.', $this->shared->get( 'text_domain' ) ); ?>'></div>
								</td>
							</tr>

							<!-- Hide Featured News -->
							<tr class="behavior-chart-configuration">
								<th scope="row"><?php esc_html_e( 'Hide Featured News', $this->shared->get( 'text_domain' ) ); ?></th>
								<td>
									<select id="hide-featured-news" name="hide_featured_news">
										<option value="1"><?php esc_html_e( 'No', $this->shared->get( 'text_domain' ) ); ?></option>
										<option value="2"><?php esc_html_e( 'Yes', $this->shared->get( 'text_domain' ) ); ?></option>
										<option value="3"><?php esc_html_e( 'Only with Mobile Devices', $this->shared->get( 'text_domain' ) ); ?></option>
									</select>
									<div class="help-icon" title='<?php esc_attr_e( 'Select if the featured news area of the news ticker should be displayed.', $this->shared->get( 'text_domain' ) ); ?>'></div>
								</td>
							</tr>

							<!-- Open News as Default -->
							<tr class="behavior-chart-configuration">
								<th scope="row"><?php esc_html_e( 'Open News as Default', $this->shared->get( 'text_domain' ) ); ?></th>
								<td>
									<select id="open-news-as-default" name="open_news_as_default">
										<option value="0"><?php esc_html_e( 'No', $this->shared->get( 'text_domain' ) ); ?></option>
										<option value="1" selected="selected"><?php esc_html_e( 'Yes', $this->shared->get( 'text_domain' ) ); ?></option>
									</select>
									<div class="help-icon" title='<?php esc_attr_e( 'Select if the news ticker should be presented in the open status (with the featured news area visible) to the users. If the user opens or closes the news ticker the new status will be saved in a cookie and used to determine the default status of the news ticker for that specific user.', $this->shared->get( 'text_domain' ) ); ?>'></div>
								</td>
							</tr>

							<!-- Enable Links -->
							<tr class="behavior-chart-configuration">
								<th scope="row"><?php esc_html_e( 'Enable Links', $this->shared->get( 'text_domain' ) ); ?></th>
								<td>
									<select id="enable-links" name="enable_links">
										<option value="0"><?php esc_html_e( 'No', $this->shared->get( 'text_domain' ) ); ?></option>
										<option value="1" selected="selected"><?php esc_html_e( 'Yes', $this->shared->get( 'text_domain' ) ); ?></option>
									</select>
									<div class="help-icon" title='<?php esc_attr_e( 'Whether to apply or not the links associated with the news on the featured news title and on the sliding news.', $this->shared->get( 'text_domain' ) ); ?>'></div>
								</td>
							</tr>

							<!-- Open Links New Tab -->
							<tr class="behavior-chart-configuration">
								<th scope="row"><?php esc_html_e( 'Open Links in New Tab', $this->shared->get( 'text_domain' ) ); ?></th>
								<td>
									<select id="open-links-new-tab" name="open_links_new_tab">
										<option value="0"><?php esc_html_e( 'No', $this->shared->get( 'text_domain' ) ); ?></option>
										<option value="1"><?php esc_html_e( 'Yes', $this->shared->get( 'text_domain' ) ); ?></option>
									</select>
									<div class="help-icon" title='<?php esc_attr_e( 'Select if the links availble in the news ticker should be opened in a new tab.', $this->shared->get( 'text_domain' ) ); ?>'></div>
								</td>
							</tr>

							<!-- Hide Clock -->
							<tr class="behavior-chart-configuration">
								<th scope="row"><?php esc_html_e( 'Hide Clock', $this->shared->get( 'text_domain' ) ); ?></th>
								<td>
									<select id="hide-clock" name="hide_clock">
										<option value="0"><?php esc_html_e( 'No', $this->shared->get( 'text_domain' ) ); ?></option>
										<option value="1"><?php esc_html_e( 'Yes', $this->shared->get( 'text_domain' ) ); ?></option>
									</select>
									<div class="help-icon" title='<?php esc_attr_e( 'Select whether to display or not the clock.', $this->shared->get( 'text_domain' ) ); ?>'></div>
								</td>
							</tr>

							<!-- Clock Autoupdate -->
							<tr class="behavior-chart-configuration">
								<th scope="row"><?php esc_html_e( 'Clock Autoupdate', $this->shared->get( 'text_domain' ) ); ?></th>
								<td>
									<select id="clock-autoupdate" name="clock_autoupdate">
										<option value="0"><?php esc_html_e( 'No', $this->shared->get( 'text_domain' ) ); ?></option>
										<option value="1" selected="selected"><?php esc_html_e( 'Yes', $this->shared->get( 'text_domain' ) ); ?></option>
									</select>
									<div class="help-icon" title='<?php esc_attr_e( 'Select whether to autoupdate or not the clock independently from the cycles of news received. This option is applied only if the source of the clock is "User Time".', $this->shared->get( 'text_domain' ) ); ?>'></div>
								</td>
							</tr>

							<!-- Clock Autoupdate Time -->
							<tr class="behavior-chart-configuration">
								<th scope="row"><label for="clock-autoupdate-time"><?php esc_html_e( 'Clock Autoupdate Time', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<input value="10" type="text" id="clock-autoupdate-time" maxlength="10" size="30" name="clock_autoupdate_time" />
									<div class="help-icon" title="<?php esc_attr_e( 'This option determines how frequent should be the clock autoupdate in seconds.', $this->shared->get( 'text_domain' ) ); ?>"></div>
								</td>
							</tr>

							<!-- Number of Sliding News -->
							<tr class="behavior-chart-configuration">
								<th scope="row"><label for="number-of-sliding-news"><?php esc_html_e( 'Number of Sliding News', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<input value="10" type="text" id="number-of-sliding-news" maxlength="2" size="30" name="number_of_sliding_news" />
									<div class="help-icon" title="<?php esc_attr_e( 'Enter the number of sliding news that you want to display in a single cycle of news.', $this->shared->get( 'text_domain' ) ); ?>"></div>
								</td>
							</tr>

							<tr class="group-trigger" data-trigger-target="performance-chart-configuration">
								<th scope="row" class="group-title"><?php esc_html_e( 'Performance', $this->shared->get( 'text_domain' ) ); ?></th>
								<td>
									<div class="expand-icon"></div>
								</td>
							</tr>

							<!-- Cached Cycles -->
							<tr class="performance-chart-configuration">
								<th scope="row"><label for="cached-cycles"><?php esc_html_e( 'Cached Cycles', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<input value="5" type="text" id="cached-cycles" maxlength="10" size="30" name="cached_cycles" />
									<div class="help-icon" title="<?php esc_attr_e( 'This value determines the number of cycles performed by the news ticker without updating the news. Set an high value to improve the news ticker performance and to avoid an excessive load on the web server. Set a low value to have frequent updates of the news. Set 0 to update the news at every cycle.', $this->shared->get( 'text_domain' ) ); ?>"></div>
								</td>
							</tr>

							<!-- Transient Expiration -->
							<tr class="performance-chart-configuration">
								<th scope="row"><label for="transient-expiration"><?php esc_html_e( 'Transient Expiration', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<input value="0" type="text" id="transient-expiration" maxlength="10" size="30" name="transient_expiration"/>
									<div class="help-icon" title="<?php esc_attr_e( 'Enter the transient expiration in seconds. Set an high value to improve the news ticker performance and to avoid an excessive load on the web server. Set a low value to have frequent updates of the news. Set 0 to not use a transient.', $this->shared->get( 'text_domain' ) ); ?>"></div>
								</td>
							</tr>

							<tr class="group-trigger" data-trigger-target="style-chart-configuration">
								<th scope="row" class="group-title"><?php esc_html_e( 'Style', $this->shared->get( 'text_domain' ) ); ?></th>
								<td>
									<div class="expand-icon"></div>
								</td>
							</tr>

							<!-- Featured Title Maximum Length -->
							<tr class="style-chart-configuration">
								<th scope="row"><label for="featured-title-maximum-length"><?php esc_html_e( 'Featured News Title Maximum Length', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<input value="280" type="text" id="featured-title-maximum-length" maxlength="4" size="30" name="featured_title_maximum_length" />
									<div class="help-icon" title="<?php esc_attr_e( 'The maximum length of the featured news title.', $this->shared->get( 'text_domain' ) ); ?>"></div>
								</td>
							</tr>

							<!-- Featured Excerpt Maximum Length -->
							<tr class="style-chart-configuration">
								<th scope="row"><label for="featured-excerpt-maximum-length"><?php esc_html_e( 'Featured News Excerpt Maximum Length', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<input value="280" type="text" id="featured-excerpt-maximum-length" maxlength="4" size="30" name="featured_excerpt_maximum_length" />
									<div class="help-icon" title="<?php esc_attr_e( 'The maximum length of the featured news excerpt.', $this->shared->get( 'text_domain' ) ); ?>"></div>
								</td>
							</tr>

							<!-- Sliding News Maximum Length -->
							<tr class="style-chart-configuration">
								<th scope="row"><label for="sliding-news-maximum-length"><?php esc_html_e( 'Sliding News Maximum Length', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<input value="280" type="text" id="sliding-news-maximum-length" maxlength="4" size="30" name="sliding_news_maximum_length" />
									<div class="help-icon" title="<?php esc_attr_e( 'The maximum length of the sliding news.', $this->shared->get( 'text_domain' ) ); ?>"></div>
								</td>
							</tr>

							<!-- Featured Title Font Size -->
							<tr class="style-chart-configuration">
								<th scope="row"><label for="featured-title-font-size"><?php esc_html_e( 'Featured News Title Font Size', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<input value="38" type="text" id="featured-title-font-size" maxlength="2" size="30" name="featured_title_font_size" />
									<div class="help-icon" title="<?php esc_attr_e( 'The font size of the featured news title.', $this->shared->get( 'text_domain' ) ); ?>"></div>
								</td>
							</tr>

							<!-- Featured Excerpt Font Size -->
							<tr class="style-chart-configuration">
								<th scope="row"><label for="featured-excerpt-font-size"><?php esc_html_e( 'Featured News Excerpt Font Size', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<input value="28" type="text" id="featured-excerpt-font-size" maxlength="2" size="30" name="featured_excerpt_font_size" />
									<div class="help-icon" title="<?php esc_attr_e( 'The font size of the featured news excerpt.', $this->shared->get( 'text_domain' ) ); ?>"></div>
								</td>
							</tr>

							<!-- Sliding News Font Size -->
							<tr class="style-chart-configuration">
								<th scope="row"><label for="sliding-news-font-size"><?php esc_html_e( 'Sliding News Font Size', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<input value="28" type="text" id="sliding-news-font-size" maxlength="2" size="30" name="sliding_news_font_size" />
									<div class="help-icon" title="<?php esc_attr_e( 'The font size of the sliding news.', $this->shared->get( 'text_domain' ) ); ?>"></div>
								</td>
							</tr>

							<!-- Clock Font Size -->
							<tr class="style-chart-configuration">
								<th scope="row"><label for="clock-font-size"><?php esc_html_e( 'Clock Font Size', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<input value="28" type="text" id="clock-font-size" maxlength="2" size="30" name="clock_font_size" />
									<div class="help-icon" title="<?php esc_attr_e( 'The font size of the text in the clock.', $this->shared->get( 'text_domain' ) ); ?>"></div>
								</td>
							</tr>

							<!-- Sliding News Margin -->
							<tr class="style-chart-configuration">
								<th scope="row"><label for="sliding-news-margin"><?php esc_html_e( 'Sliding News Margin', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<input value="84" type="text" id="sliding-news-margin" maxlength="3" size="30" name="sliding_news_margin" />
									<div class="help-icon" title="<?php esc_attr_e( 'The margin between the sliding news.', $this->shared->get( 'text_domain' ) ); ?>"></div>
								</td>
							</tr>

							<!-- Sliding News Padding -->
							<tr class="style-chart-configuration">
								<th scope="row"><label for="sliding-news-padding"><?php esc_html_e( 'Sliding News Padding', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<input value="28" type="text" id="sliding-news-padding" maxlength="3" size="30" name="sliding_news_padding" />
									<div class="help-icon" title="<?php esc_attr_e( 'This option determines the padding on the left and on the right of each sliding news and also the distance between the sliding news text and the sliding news left and right images.', $this->shared->get( 'text_domain' ) ); ?>"></div>
								</td>
							</tr>

							<!-- Font Family -->
							<tr class="style-chart-configuration">
								<th scope="row"><label for="font-family"><?php esc_html_e( 'Font Family', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<input value="'Open Sans', sans-serif" type="text" id="font-family" maxlength="255" size="30" name="font_family" />
									<div class="help-icon" title="<?php esc_attr_e( 'The font family used for all the text displayed in the news ticker.', $this->shared->get( 'text_domain' ) ); ?>"></div>
								</td>
							</tr>

							<!-- Google Font -->
							<tr class="style-chart-configuration">
								<th scope="row"><label for="google-font"><?php esc_html_e( 'Google Font', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<input value="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600;700&display=swap" type="text" id="google-font" maxlength="255" size="30" name="google_font" />
									<div class="help-icon" title="<?php esc_attr_e( 'This option allows you to load a specific Google Font.', $this->shared->get( 'text_domain' ) ); ?>"></div>
								</td>
							</tr>

							<!-- Featured News Title Color -->
							<tr class="style-chart-configuration">
								<th scope="row"><label for="featured-news-title-color"><?php esc_html_e( 'Featured News Title Color', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<input value="#eee" class="wp-color-picker" type="text" id="featured-news-title-color" maxlength="7" size="30" name="featured_news_title_color" />
									<div class="help-icon" title="<?php esc_attr_e( 'The color of the featured news title.', $this->shared->get( 'text_domain' ) ); ?>"></div>
								</td>
							</tr>

							<!-- Featured News Title Color Hover -->
							<tr class="style-chart-configuration">
								<th scope="row"><label for="featured-news-title-color-hover"><?php esc_html_e( 'Featured News Title Color Hover', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<input value="#111" class="wp-color-picker" type="text" id="featured-news-title-color-hover" maxlength="7" size="30" name="featured_news_title_color_hover" />
									<div class="help-icon" title="<?php esc_attr_e( 'The color of the featured news title in hover status.', $this->shared->get( 'text_domain' ) ); ?>"></div>
								</td>
							</tr>

							<!-- Featured News Excerpt Color -->
							<tr class="style-chart-configuration">
								<th scope="row"><label for="featured-news-excerpt-color"><?php esc_html_e( 'Featured News Excerpt Color', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<input value="#eee" class="wp-color-picker" type="text" id="featured-news-excerpt-color" maxlength="7" size="30" name="featured_news_excerpt_color" />
									<div class="help-icon" title="<?php esc_attr_e( 'The color of the featured news excerpt.', $this->shared->get( 'text_domain' ) ); ?>"></div>
								</td>
							</tr>

							<!-- Sliding News Color -->
							<tr class="style-chart-configuration">
								<th scope="row"><label for="sliding-news-color"><?php esc_html_e( 'Sliding News Color', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<input value="#eee" class="wp-color-picker" type="text" id="sliding-news-color" maxlength="7" size="30" name="sliding_news_color" />
									<div class="help-icon" title="<?php esc_attr_e( 'The color of the sliding news.', $this->shared->get( 'text_domain' ) ); ?>"></div>
								</td>
							</tr>

							<!-- Sliding News Color Hover -->
							<tr class="style-chart-configuration">
								<th scope="row"><label for="sliding-news-color-hover"><?php esc_html_e( 'Sliding News Color Hover', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<input value="#aaa" class="wp-color-picker" type="text" id="sliding-news-color-hover" maxlength="7" size="30" name="sliding_news_color_hover" />
									<div class="help-icon" title="<?php esc_attr_e( 'The color of the sliding news in hover status.', $this->shared->get( 'text_domain' ) ); ?>"></div>
								</td>
							</tr>

							<!-- Clock Text Color -->
							<tr class="style-chart-configuration">
								<th scope="row"><label for="clock-text-color"><?php esc_html_e( 'Clock Text Color', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<input value="#111" class="wp-color-picker" type="text" id="clock-text-color" maxlength="7" size="30" name="clock_text_color" />
									<div class="help-icon" title="<?php esc_attr_e( 'The color of the text displayed in the clock.', $this->shared->get( 'text_domain' ) ); ?>"></div>
								</td>
							</tr>

							<!-- Featured News Background Color -->
							<tr class="style-chart-configuration">
								<th scope="row"><label for="featured-news-background-color"><?php esc_html_e( 'Featured News Background Color', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<input value="#C90016" class="wp-color-picker" type="text" id="featured-news-background-color" maxlength="7" size="30" name="featured_news_background_color" />
									<div class="help-icon" title="<?php esc_attr_e( 'The background color of the featured news area.', $this->shared->get( 'text_domain' ) ); ?>"></div>
								</td>
							</tr>

							<!-- Featured News Background Color Opacity -->
							<tr class="style-chart-configuration">
								<th scope="row"><label for="featured-news-background-color-opacity"><?php esc_html_e( 'Featured News Background Color Opacity', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<input value="1" type="text" id="featured-news-background-color-opacity" maxlength="3" size="30" name="featured_news_background_color_opacity" />
									<div class="help-icon" title="<?php esc_attr_e( 'The background color opacity of the featured news area.', $this->shared->get( 'text_domain' ) ); ?>"></div>
								</td>
							</tr>

							<!-- Sliding News Background Color -->
							<tr class="style-chart-configuration">
								<th scope="row"><label for="sliding-news-background-color"><?php esc_html_e( 'Sliding News Background Color', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<input value="#000000" class="wp-color-picker" type="text" id="sliding-news-background-color" maxlength="7" size="30" name="sliding_news_background_color" />
									<div class="help-icon" title="<?php esc_attr_e( 'The background color of the sliding news area.', $this->shared->get( 'text_domain' ) ); ?>"></div>
								</td>
							</tr>

							<!-- Sliding News Background Color Opacity -->
							<tr class="style-chart-configuration">
								<th scope="row"><label for="sliding-news-background-color-opacity"><?php esc_html_e( 'Sliding News Background Color Opacity', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<input value="1" type="text" id="sliding-news-background-color-opacity" maxlength="3" size="30" name="sliding_news_background_color_opacity" />
									<div class="help-icon" title="<?php esc_attr_e( 'The background color opacity of the sliding news area.', $this->shared->get( 'text_domain' ) ); ?>"></div>
								</td>
							</tr>

							<!-- Open Button Image -->
							<tr class="style-chart-configuration">
								<th scope="row"><label for="open-button-image"><?php esc_html_e( 'Open Button Image', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>

									<div class="image-uploader">
										<img class="selected-image" src="<?php echo esc_url( $this->shared->get( 'url' ) . 'public/assets/img/open-button.png' ); ?>" >
										<input value="<?php echo esc_url( $this->shared->get( 'url' ) . 'public/assets/img/open-button.png' ); ?>" type="hidden" id="open-button-image" maxlength="2083" name="open_button_image">
										<a class="button_add_media" data-set-remove="remove" data-set="<?php esc_attr_e( 'Set image', $this->shared->get( 'text_domain' ) ); ?>" data-remove="<?php esc_attr_e( 'Remove Image', $this->shared->get( 'text_domain' ) ); ?>"><?php esc_attr_e( 'Remove image', $this->shared->get( 'text_domain' ) ); ?></a>
										<p class="description"><?php esc_html_e( "Select the image of the button used to open the news ticker. It's recommended to use an image with a width of 80 pixels and a height of 40 pixels.", $this->shared->get( 'text_domain' ) ); ?></p>
									</div>

								</td>
							</tr>

							<!-- Close Button Image -->
							<tr class="style-chart-configuration">
								<th scope="row"><label for="close-button-image"><?php esc_html_e( 'Close Button Image', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>

									<div class="image-uploader">
										<img class="selected-image" src="<?php echo esc_url( $this->shared->get( 'url' ) . 'public/assets/img/close-button.png' ); ?>" >
										<input value="<?php echo esc_url( $this->shared->get( 'url' ) . 'public/assets/img/close-button.png' ); ?>" type="hidden" id="close-button-image" maxlength="2083" name="close_button_image">
										<a class="button_add_media" data-set-remove="remove" data-set="<?php esc_attr_e( 'Set image', $this->shared->get( 'text_domain' ) ); ?>" data-remove="<?php esc_attr_e( 'Remove Image', $this->shared->get( 'text_domain' ) ); ?>"><?php esc_html_e( 'Remove image', $this->shared->get( 'text_domain' ) ); ?></a>
										<p class="description"><?php esc_html_e( "Select the image of the button used to close the news ticker. It's recommended to use an image with a width of 80 pixels and a height of 40 pixels.", $this->shared->get( 'text_domain' ) ); ?></p>
									</div>

								</td>
							</tr>

							<!-- Clock Background Image -->
							<tr class="style-chart-configuration">
								<th scope="row"><label for="clock-background-image"><?php esc_html_e( 'Clock Background Image', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>

									<div class="image-uploader">
										<img class="selected-image" src="<?php echo esc_url( $this->shared->get( 'url' ) . 'public/assets/img/clock.png' ); ?>" >
										<input value="<?php echo esc_url( $this->shared->get( 'url' ) . 'public/assets/img/clock.png' ); ?>" type="hidden" id="clock-background-image" maxlength="2083" name="clock_background_image">
										<a class="button_add_media" data-set-remove="remove" data-set="<?php esc_attr_e( 'Set image', $this->shared->get( 'text_domain' ) ); ?>" data-remove="<?php esc_attr_e( 'Remove Image', $this->shared->get( 'text_domain' ) ); ?>"><?php esc_html_e( 'Remove image', $this->shared->get( 'text_domain' ) ); ?></a>
										<p class="description"><?php esc_html_e( "Select the background image of the clock. It's recommended to use an image with a width of 80 pixels and a height of 40 pixels.", $this->shared->get( 'text_domain' ) ); ?></p>
									</div>

								</td>
							</tr>

							<tr class="group-trigger" data-trigger-target="section-advanced">
								<th scope="row" class="group-title"><?php esc_html_e( 'Advanced', $this->shared->get( 'text_domain' ) ); ?></th>
								<td>
									<div class="expand-icon"></div>
								</td>
							</tr>

							<!-- Target URL Mode -->
							<tr class="section-advanced">
								<th scope="row"><?php esc_html_e( 'Target URL Mode', $this->shared->get( 'text_domain' ) ); ?></th>
								<td>
									<select id="url-mode" name="url_mode">
										<option value="0"><?php esc_html_e( 'Include', $this->shared->get( 'text_domain' ) ); ?></option>
										<option value="1"><?php esc_html_e( 'Exclude', $this->shared->get( 'text_domain' ) ); ?></option>
									</select>
									<div class="help-icon" title='<?php esc_attr_e( 'Select whether to include or exclude the URLs defined with the "Target URL" option.', $this->shared->get( 'text_domain' ) ); ?>'></div>
								</td>
							</tr>

						</table>

						<!-- submit button -->
						<div class="daext-form-action">
							<input class="button" type="submit" value="<?php esc_attr_e( 'Add News Ticker', $this->shared->get( 'text_domain' ) ); ?>" >
						</div>

						<?php endif; ?>

					</div>

			</form>

		<?php endif; ?>

	</div>

</div>admin/view/export_to_pro.php000064400000002644151213253520012227 0ustar00<?php
/**
 * The view for the Export to Pro page.
 *
 * @package live-news-lite
 */

if ( ! current_user_can( 'manage_options' ) ) {
	wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', $this->shared->get( 'text_domain' ) ) );
}

?>

<!-- output -->

<div class="wrap">

	<h2><?php esc_html_e( 'Live News - Export to Pro', $this->shared->get( 'text_domain' ) ); ?></h2>

	<div id="daext-menu-wrapper">

		<p><?php esc_html_e( 'Click the Export button to generate an XML file that includes all the plugin data.', $this->shared->get( 'text_domain' ) ); ?></p>
		<p><?php esc_html_e( 'Note that you can import the resulting file in the Import menu of the ', $this->shared->get( 'text_domain' ) ); ?>
			<a href="https://daext.com/live-news/"><?php esc_html_e( 'Pro Version', $this->shared->get( 'text_domain' ) ); ?></a>.</p>

		<!-- the data sent through this form are handled by the export_xml_controller() method called with the WordPress init action -->
		<form method="POST" action="admin.php?page=daextlnl_export_to_pro">

			<div class="daext-widget-submit">
				<input name="daextlnl_export" class="button button-primary" type="submit"
						value="<?php esc_attr_e( 'Export', $this->shared->get( 'text_domain' ) ); ?>" 
												<?php
												if ( ! $this->shared->plugin_has_data() ) {
													echo 'disabled="disabled"';
												}
												?>
				>
			</div>

		</form>

	</div>

</div>admin/view/options.php000064400000003125151213253520011012 0ustar00<?php
/**
 * Options page.
 *
 * @package live-news-lite
 */

if ( ! current_user_can( 'manage_options' ) ) {
	wp_die( esc_html__( 'You do not have sufficient capabilities to access this page.', $this->shared->get( 'text_domain' ) ) );
}

// Sanitization -------------------------------------------------------------------------------------------------
$data['settings_updated'] = isset( $_GET['settings-updated'] ) ? sanitize_key( $_GET['settings-updated'], 10 ) : null;
$data['active_tab']       = isset( $_GET['tab'] ) ? sanitize_key( $_GET['tab'] ) : 'general';

?>

<div class="wrap">

	<h2><?php esc_html_e( 'Live News - Options', $this->shared->get( 'text_domain' ) ); ?></h2>

	<?php

	// settings errors.
	if ( ! is_null( $data['settings_updated'] ) and $data['settings_updated'] == 'true' ) {
		settings_errors();
	}

	?>

	<div id="daext-options-wrapper">

		<div class="nav-tab-wrapper">
			<a href="?page=daextlnl-options&tab=general"
				class="nav-tab <?php echo $data['active_tab'] === 'general' ? 'nav-tab-active' : ''; ?>"><?php esc_html_e( 'General', $this->shared->get( 'text_domain' ) ); ?></a>
		</div>

		<form method='post' action='options.php'>

			<?php

			if ( $data['active_tab'] === 'general' ) {

				settings_fields( $this->shared->get( 'slug' ) . '_general_options' );
				do_settings_sections( $this->shared->get( 'slug' ) . '_general_options' );

			}

			?>

			<div class="daext-options-action">
				<input type="submit" name="submit" id="submit" class="button" value="<?php esc_attr_e( 'Save Changes', $this->shared->get( 'text_domain' ) ); ?>">
			</div>

		</form>

	</div>

</div>admin/view/featured.php000064400000051211151213253520011115 0ustar00<?php
/**
 * The admin featured news page.
 *
 * @package live-news-lite
 */

if ( ! current_user_can( get_option( $this->shared->get( 'slug' ) . '_featured_menu_capability' ) ) ) {
	wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', $this->shared->get( 'text_domain' ) ) );
}

?>

<!-- process data -->

<?php

// Initialize variables -----------------------------------------------------------------------------------------------.
$dismissible_notice_a = array();

// Preliminary operations ---------------------------------------------------------------------------------------------.
global $wpdb;

// Sanitization ---------------------------------------------------------------------------------------------.

// Actions
$data['edit_id']        = isset( $_GET['edit_id'] ) ? intval( $_GET['edit_id'], 10 ) : null;
$data['delete_id']      = isset( $_POST['delete_id'] ) ? intval( $_POST['delete_id'], 10 ) : null;
$data['update_id']      = isset( $_POST['update_id'] ) ? intval( $_POST['update_id'], 10 ) : null;
$data['form_submitted'] = isset( $_POST['form_submitted'] ) ? intval( $_POST['form_submitted'], 10 ) : null;

// Filter and search data.
$data['s']  = isset( $_GET['s'] ) ? sanitize_text_field( $_GET['s'] ) : null;
$data['cf'] = isset( $_GET['cf'] ) ? sanitize_text_field( $_GET['cf'] ) : null;

// Form data.
if ( ! is_null( $data['update_id'] ) or ! is_null( $data['form_submitted'] ) ) {

	// Nonce verification.
	check_admin_referer( 'daextlnl_create_update_featured_news', 'daextlnl_create_update_featured_news_nonce' );

	// Sanitization ---------------------------------------------------------------------------------------------------.
	$news_title   = isset( $_POST['news_title'] ) ? sanitize_text_field( $_POST['news_title'] ) : null;
	$news_excerpt = isset( $_POST['news_excerpt'] ) ? sanitize_text_field( $_POST['news_excerpt'] ) : null;
	$url          = isset( $_POST['url'] ) ? esc_url_raw( $_POST['url'] ) : null;
	$ticker_id    = isset( $_POST['ticker_id'] ) ? intval( $_POST['ticker_id'], 10 ) : null;

	// Validation -----------------------------------------------------------------------------------------------------.
	$invalid_data_message = '';

	// validation on "Title".
	if ( mb_strlen( trim( $news_title ) ) == 0 or mb_strlen( $news_title ) > 1000 ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'Please enter a valid value in the "Title" field.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'error',
		);
		$invalid_data           = true;
	}

	// validation on "Excerpt".
	if ( mb_strlen( trim( $news_excerpt ) ) == 0 or mb_strlen( $news_excerpt ) > 1000 ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'Please enter a valid value in the "Excerpt" field.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'error',
		);
		$invalid_data           = true;
	}

	// validation on "URL".
	if ( mb_strlen( $url ) > 2083 ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'Please enter a valid URL in the "URL" field.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'error',
		);
		$invalid_data           = true;
	}
}

// update ---------------------------------------------------------------.
if ( ! is_null( $data['update_id'] ) and ! isset( $invalid_data ) ) {

	// update the database.
	$table_name = $wpdb->prefix . $this->shared->get( 'slug' ) . '_featured_news';
	$safe_sql   = $wpdb->prepare(
		"UPDATE $table_name SET
                news_title = %s,
                news_excerpt = %s,
                url = %s,
                ticker_id = %d
                WHERE id = %d",
		$news_title,
		$news_excerpt,
		$url,
		$ticker_id,
		$data['update_id']
	);

	$query_result = $wpdb->query( $safe_sql );

	if ( $query_result !== false ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'The featured news has been successfully updated.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'updated',
		);
	}
} else {

	// add ------------------------------------------------------------------.
	if ( ! is_null( $data['form_submitted'] ) and ! isset( $invalid_data ) ) {

		// insert into the database
		$table_name = $wpdb->prefix . $this->shared->get( 'slug' ) . '_featured_news';
		$safe_sql   = $wpdb->prepare(
			"INSERT INTO $table_name SET
                    news_title = %s,
                    news_excerpt = %s,
                    url = %s,
                    ticker_id = %d",
			$news_title,
			$news_excerpt,
			$url,
			$ticker_id
		);

		$query_result = $wpdb->query( $safe_sql );

		if ( $query_result !== false ) {
			$dismissible_notice_a[] = array(
				'message' => __( 'The featured news has been successfully added.', $this->shared->get( 'text_domain' ) ),
				'class'   => 'updated',
			);
		}
	}
}

// delete a featured news.
if ( ! is_null( $data['delete_id'] ) ) {

	// Nonce verification.
	check_admin_referer( 'daextlnl_delete_featured_news_' . $data['delete_id'], 'daextlnl_delete_featured_news_nonce' );

	// delete this featured news.
	$table_name = $wpdb->prefix . $this->shared->get( 'slug' ) . '_featured_news';
	$safe_sql   = $wpdb->prepare( "DELETE FROM $table_name WHERE id = %d ", $data['delete_id'] );

	$query_result = $wpdb->query( $safe_sql );

	if ( $query_result !== false ) {
		$dismissible_notice_a[] = array(
			'message' => __( 'The featured news has been successfully deleted.', $this->shared->get( 'text_domain' ) ),
			'class'   => 'updated',
		);
	}
}

// get the featured news data.
$display_form = true;
if ( ! is_null( $data['edit_id'] ) ) {
	$table_name        = $wpdb->prefix . $this->shared->get( 'slug' ) . '_featured_news';
	$safe_sql          = $wpdb->prepare( "SELECT * FROM $table_name WHERE id = %d ", $data['edit_id'] );
	$featured_news_obj = $wpdb->get_row( $safe_sql );
	if ( $featured_news_obj === null ) {
		$display_form = false;
	}
}

// Get the value of the custom filter.
if ( $data['cf'] !== null ) {
	if ( $data['cf'] !== 'all' ) {
		$ticker_id_in_cf = intval( $data['cf'], 10 );
	} else {
		$ticker_id_in_cf = false;
	}
} else {
	$ticker_id_in_cf = false;
}

?>

<!-- output -->

<div class="wrap">

	<?php if ( $this->shared->get_number_of_featured_news() > 0 ) : ?>

		<div id="daext-header-wrapper" class="daext-clearfix">

			<h2><?php esc_html_e( 'Live News - Featured News', $this->shared->get( 'text_domain' ) ); ?></h2>

			<!-- Search Form -->

			<form action="admin.php" method="get" id="daext-search-form">

				<input type="hidden" name="page" value="daextlnl-featured">

				<p><?php esc_attr_e( 'Perform your Search', $this->shared->get( 'text_domain' ) ); ?></p>

				<?php
				if ( ! is_null( $data['s'] ) ) {
					if ( mb_strlen( trim( $data['s'] ) ) > 0 ) {
						$search_string = $data['s'];
					} else {
						$search_string = '';
					}
				} else {
					$search_string = '';
				}

				// Custom Filter.
				if ( $ticker_id_in_cf !== false ) {
					echo '<input type="hidden" name="cf" value="' . esc_attr( $ticker_id_in_cf ) . '">';
				}

				?>

				<input type="text" name="s" name="s"
						value="<?php echo esc_attr( stripslashes( $search_string ) ); ?>" autocomplete="off" maxlength="255">
				<input type="submit" value="">

			</form>

			<!-- Filter Form -->

			<form method="GET" action="admin.php" id="daext-filter-form">

				<input type="hidden" name="page" value="<?php echo esc_attr( $this->shared->get( 'slug' ) ); ?>-featured">

				<p><?php esc_html_e( 'Filter by News Ticker', $this->shared->get( 'text_domain' ) ); ?></p>

				<select id="cf" name="cf" class="daext-display-none">

					<option value="all" 
					<?php
					if ( $data['cf'] !== null ) {
						selected( $data['cf'], 'all' );}
					?>
					><?php esc_html_e( 'All', $this->shared->get( 'text_domain' ) ); ?></option>

					<?php

					$table_name = $wpdb->prefix . $this->shared->get( 'slug' ) . '_tickers';
					$safe_sql   = "SELECT id, name FROM $table_name ORDER BY id DESC";
					$tickers_a  = $wpdb->get_results( $safe_sql, ARRAY_A );

					foreach ( $tickers_a as $key => $ticker ) {

						if ( $data['cf'] !== null ) {
							echo '<option value="' . esc_attr( $ticker['id'] ) . '" ' . selected( $data['cf'], $ticker['id'], false ) . '>' . esc_html( stripslashes( $ticker['name'] ) ) . '</option>';
						} else {
							echo '<option value="' . esc_attr( $ticker['id'] ) . '">' . esc_html( stripslashes( $ticker['name'] ) ) . '</option>';

						}
					}

					?>

				</select>

			</form>

		</div>

	<?php else : ?>

		<div id="daext-header-wrapper" class="daext-clearfix">

			<h2><?php esc_html_e( 'Live News - Featured News', $this->shared->get( 'text_domain' ) ); ?></h2>

		</div>

	<?php endif; ?>

	<?php

	// do not display the menu if in the 'cf' url parameter is applied a filter based on a ticker that doesn't existm
	if ( $data['cf'] !== null ) {
		if ( $data['cf'] !== 'all' and ! $this->shared->ticker_exists( $data['cf'] ) ) {
			echo '<p>' . esc_html__( "The filter can't be applied because this featured news doesn't exist.", $this->shared->get( 'text_domain' ) ) . '</p>';
			return;
		}
	}

	// retrieve the url parameter that should be used in the linked URLs
	if ( $data['cf'] !== null ) {
		if ( $data['cf'] !== 'all' and $this->shared->ticker_exists( $data['cf'] ) ) {
			$ticker_url_parameter = '&cf=' . intval( $data['cf'], 10 );
		} else {
			$ticker_url_parameter = '';
		}
	} else {
		$ticker_url_parameter = '';
	}

	// display a message and not the menu if there are no tickers
	if ( $this->shared->get_number_of_tickers() == 0 ) {
		echo '<p>' . esc_html__( 'There are no news tickers at the moment, please create at least one news ticker with the', $this->shared->get( 'text_domain' ) ) . ' ' . '<a href="admin.php?page=daextlnl-tickers">' . esc_html__( 'News Tickers', $this->shared->get( 'text_domain' ) ) . '</a> menu.' . '</p>';
		return;
	}

	?>

	<div id="daext-menu-wrapper">

		<?php $this->dismissible_notice( $dismissible_notice_a ); ?>

		<!-- table -->

		<?php

		// custom filter.
		if ( $ticker_id_in_cf === false ) {
			$filter = '';
		} else {
			$filter = $wpdb->prepare( 'WHERE ticker_id = %d', $ticker_id_in_cf );
		}

		// create the query part used to filter the results when a search is performed.
		if ( ! is_null( $data['s'] ) ) {

			if ( mb_strlen( trim( $data['s'] ) ) > 0 ) {

				if ( strlen( trim( $filter ) ) > 0 ) {
					$filter .= $wpdb->prepare( ' AND (news_title LIKE %s OR news_excerpt LIKE %s OR url LIKE %s)', '%' . $data['s'] . '%', '%' . $data['s'] . '%', '%' . $data['s'] . '%' );
				} else {
					$filter = $wpdb->prepare( 'WHERE (news_title LIKE %s OR news_excerpt LIKE %s OR url LIKE %s)', '%' . $data['s'] . '%', '%' . $data['s'] . '%', '%' . $data['s'] . '%' );
				}
			}
		}

		// retrieve the total number of featured news.
		$table_name  = $wpdb->prefix . $this->shared->get( 'slug' ) . '_featured_news';
		$total_items = $wpdb->get_var( "SELECT COUNT(*) FROM $table_name $filter" );

		// Initialize the pagination class.
		require_once $this->shared->get( 'dir' ) . '/admin/inc/class-daextlnl-pagination.php';
		$pag = new daextlnl_pagination();
		$pag->set_total_items( $total_items );// Set the total number of items
		$pag->set_record_per_page( 10 ); // Set records per page
		$pag->set_target_page( 'admin.php?page=' . $this->shared->get( 'slug' ) . '-featured' );// Set target page
		$pag->set_current_page();// set the current page number

		?>

		<!-- Query the database -->
		<?php
		$query_limit = $pag->query_limit();
		$results     = $wpdb->get_results( "SELECT * FROM $table_name $filter ORDER BY id DESC $query_limit ", ARRAY_A );
		?>

		<?php if ( count( $results ) > 0 ) : ?>

			<div class="daext-items-container">

				<!-- list of tables -->
				<table class="daext-items">
					<thead>
					<tr>
						<th>
							<div><?php esc_html_e( 'Title', $this->shared->get( 'text_domain' ) ); ?></div>
							<div class="help-icon" title="<?php esc_attr_e( 'The title of the featured news.', $this->shared->get( 'text_domain' ) ); ?>"></div>
						</th>
						<th>
							<div><?php esc_html_e( 'Ticker', $this->shared->get( 'text_domain' ) ); ?></div>
							<div class="help-icon" title="<?php esc_attr_e( 'The news ticker associated with the featured news.', $this->shared->get( 'text_domain' ) ); ?>"></div>
						</th>
						<th></th>
					</tr>
					</thead>
					<tbody>

					<?php foreach ( $results as $result ) : ?>
						<tr>
							<td><?php echo esc_attr( stripslashes( $result['news_title'] ) ); ?></td>
							<td><?php echo '<a href="admin.php?page=daextlnl-tickers&edit_id=' . esc_attr( $result['ticker_id'] ) . '">' . esc_html( stripslashes( $this->shared->get_textual_ticker( $result['ticker_id'] ) ) ) . '</a>'; ?></td>
							<td class="icons-container">
								<a class="menu-icon edit" href="admin.php?page=<?php echo esc_attr( $this->shared->get( 'slug' ) ); ?>-featured&edit_id=<?php echo esc_attr( $result['id'] ); ?><?php echo esc_html( $ticker_url_parameter ); ?>"></a>
								<form method="POST" action="admin.php?page=<?php echo $this->shared->get( 'slug' ); ?>-featured">
									<?php wp_nonce_field( 'daextlnl_delete_featured_news_' . intval( $result['id'], 10 ), 'daextlnl_delete_featured_news_nonce' ); ?>
									<input type="hidden" value="<?php echo esc_attr( $result['id'] ); ?>" name="delete_id" >
									<input class="menu-icon delete" type="submit" value="">
								</form>
							</td>
						</tr>
					<?php endforeach; ?>

					</tbody>

				</table>

			</div>

			<!-- Display the pagination -->
			<?php if ( $pag->total_items > 0 ) : ?>
				<div class="daext-tablenav daext-clearfix">
					<div class="daext-tablenav-pages">
						<span class="daext-displaying-num"><?php echo esc_html( $pag->total_items ); ?> <?php esc_html_e( 'items', $this->shared->get( 'text_domain' ) ); ?></span>
						<?php $pag->show(); ?>
					</div>
				</div>
			<?php endif; ?>

		<?php else : ?>

			<?php

			if ( strlen( trim( $filter ) ) > 0 ) {
				echo '<div class="error settings-error notice is-dismissible below-h2"><p>' . esc_html__( 'There are no results that match your filter.', $this->shared->get( 'text_domain' ) ) . '</p></div>';
			}

			?>

		<?php endif; ?>

		<div id="featured-news-form-container">

			<?php if ( $display_form ) : ?>

				<form method="POST" action="admin.php?page=<?php echo esc_attr( $this->shared->get( 'slug' ) ); ?>-featured<?php echo esc_attr( $ticker_url_parameter ); ?>" autocomplete="off">

					<input type="hidden" value="1" name="form_submitted">
					<?php wp_nonce_field( 'daextlnl_create_update_featured_news', 'daextlnl_create_update_featured_news_nonce' ); ?>

					<?php if ( ! is_null( $data['edit_id'] ) ) : ?>

					<!-- Edit a featured news -->

					<div class="daext-form-container">

						<h3 class="daext-form-title"><?php esc_attr_e( 'Edit Featured News', $this->shared->get( 'text_domain' ) ); ?> <?php echo esc_html( $featured_news_obj->id ); ?></h3>

						<table class="daext-form">

							<input type="hidden" name="update_id" value="<?php echo esc_attr( $featured_news_obj->id ); ?>" />

							<!-- title -->
							<tr valign="top">
								<th scope="row"><label for="news-title"><?php esc_html_e( 'Title', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<input value="<?php echo esc_attr( stripslashes( $featured_news_obj->news_title ) ); ?>" type="text" id="news-title" maxlength="1000" size="30" name="news_title" />
									<div class="help-icon" title="<?php esc_attr_e( 'Enter the title of the featured news.', $this->shared->get( 'text_domain' ) ); ?>"></div>
								</td>
							</tr>

							<!-- excerpt -->
							<tr valign="top">
								<th scope="row"><label for="news-excerpt"><?php esc_html_e( 'Excerpt', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<input value="<?php echo esc_attr( stripslashes( $featured_news_obj->news_excerpt ) ); ?>" type="text" id="news-excerpt" maxlength="1000" size="30" name="news_excerpt" />
									<div class="help-icon" title="<?php esc_attr_e( 'Enter the excerpt of the featured news.', $this->shared->get( 'text_domain' ) ); ?>"></div>
								</td>
							</tr>

							<!-- URL -->
							<tr valign="top">
								<th scope="row"><label for="url"><?php esc_html_e( 'URL', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<input value="<?php echo esc_attr( stripslashes( $featured_news_obj->url ) ); ?>" type="text" id="url" maxlength="2083" size="30" name="url" />
									<div class="help-icon" title="<?php esc_attr_e( 'Enter the URL of the featured news.', $this->shared->get( 'text_domain' ) ); ?>"></div>
								</td>
							</tr>

							<!-- Ticker -->
							<tr>
								<th scope="row"><label for="ticker-id"><?php esc_html_e( 'Ticker', $this->shared->get( 'text_domain' ) ); ?></label></th>
								<td>
									<select id="ticker-id" name="ticker_id" class="daext-display-none">

										<?php

										$table_name = $wpdb->prefix . $this->shared->get( 'slug' ) . '_tickers';
										$safe_sql   = "SELECT id, name FROM $table_name ORDER BY id DESC";
										$tickers_a  = $wpdb->get_results( $safe_sql, ARRAY_A );

										foreach ( $tickers_a as $key => $ticker ) {
											echo '<option value="' . esc_attr( $ticker['id'] ) . '" ' . selected( $featured_news_obj->ticker_id, $ticker['id'] ) . '>' . esc_html( stripslashes( $ticker['name'] ) ) . '</option>';
										}

										?>

									</select>
									<div class="help-icon" title='<?php esc_attr_e( 'The news ticker associated with this featured news.', $this->shared->get( 'text_domain' ) ); ?>'></div>
								</td>
							</tr>

						</table>

						<!-- submit button -->
						<div class="daext-form-action">
							<input class="button" type="submit" value="<?php esc_attr_e( 'Update Featured News', $this->shared->get( 'text_domain' ) ); ?>" >
						</div>

						<?php else : ?>

						<!-- Create New featured News -->

						<div class="daext-form-container">

							<div class="daext-form-title"><?php esc_html_e( 'Create a Featured News', $this->shared->get( 'text_domain' ) ); ?></div>

							<table class="daext-form">

								<!-- Title -->
								<tr valign="top">
									<th scope="row"><label for="news-title"><?php esc_html_e( 'Title', $this->shared->get( 'text_domain' ) ); ?></label></th>
									<td>
										<input type="text" id="news-title" maxlength="1000" size="30" name="news_title" />
										<div class="help-icon" title="<?php esc_attr_e( 'Enter the title of the featured news.', $this->shared->get( 'text_domain' ) ); ?>"></div>
									</td>
								</tr>

								<!-- Excerpt -->
								<tr valign="top">
									<th scope="row"><label for="news-excerpt"><?php esc_html_e( 'Excerpt', $this->shared->get( 'text_domain' ) ); ?></label></th>
									<td>
										<input type="text" id="news-excerpt" maxlength="1000" size="30" name="news_excerpt" />
										<div class="help-icon" title="<?php esc_attr_e( 'Enter the excerpt of the featured news.', $this->shared->get( 'text_domain' ) ); ?>"></div>
									</td>
								</tr>

								<!-- URL -->
								<tr valign="top">
									<th scope="row"><label for="url"><?php esc_html_e( 'URL', $this->shared->get( 'text_domain' ) ); ?></label></th>
									<td>
										<input type="text" id="url" maxlength="2083" size="30" name="url" />
										<div class="help-icon" title="<?php esc_attr_e( 'Enter the URL of the featured news.', $this->shared->get( 'text_domain' ) ); ?>"></div>
									</td>
								</tr>

								<!-- Ticker -->
								<tr>
									<th scope="row"><label for="ticker-id"><?php esc_html_e( 'Ticker', $this->shared->get( 'text_domain' ) ); ?></label></th>
									<td>
										<select id="ticker-id" name="ticker_id" class="daext-display-none">

											<?php

											$table_name = $wpdb->prefix . $this->shared->get( 'slug' ) . '_tickers';
											$safe_sql   = "SELECT id, name FROM $table_name ORDER BY id DESC";
											$tickers_a  = $wpdb->get_results( $safe_sql, ARRAY_A );

											if ( $ticker_id_in_cf === false ) {

												foreach ( $tickers_a as $key => $ticker ) {
													echo '<option value="' . esc_attr( $ticker['id'] ) . '">' . esc_html( stripslashes( $ticker['name'] ) ) . '</option>';
												}
											} else {

												foreach ( $tickers_a as $key => $ticker ) {
													echo '<option value="' . esc_attr( $ticker['id'] ) . '" ' . selected( $ticker_id_in_cf, $ticker['id'], false ) . '>' . esc_html( stripslashes( $ticker['name'] ) ) . '</option>';
												}
											}

											?>

										</select>
										<div class="help-icon" title='<?php esc_attr_e( 'The news ticker associated with this featured news', $this->shared->get( 'text_domain' ) ); ?>'></div>
									</td>
								</tr>

							</table>

							<!-- submit button -->
							<div class="daext-form-action">
								<input class="button" type="submit" value="<?php esc_attr_e( 'Add Featured News', $this->shared->get( 'text_domain' ) ); ?>" >
							</div>

							<?php endif; ?>

						</div>

				</form>

			<?php endif; ?>

		</div>

	</div>

</div>admin/view/pro_version.php000064400000004754151213253520011675 0ustar00<?php
/**
 * The "Pro Version" menu page.
 *
 * @package live-news-lite
 */

if ( ! current_user_can( 'manage_options' ) ) {
	wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', $this->shared->get( 'text_domain' ) ) );
}

?>

<!-- output -->

<div class="wrap">

	<h2><?php esc_html_e( 'Live News - Pro Version', $this->shared->get( 'text_domain' ) ); ?></h2>

	<div id="daext-menu-wrapper">

		<p><?php echo esc_html__( 'For professional users, we distribute a', $this->shared->get( 'text_domain' ) ) . ' <a href="https://daext.com/live-news/">' . esc_html__( 'Pro Version', $this->shared->get( 'text_domain' ) ) . '</a> ' . esc_html__( 'of this plugin.', $this->shared->get( 'text_domain' ) ) . '</p>'; ?>
		<h2><?php esc_html_e( 'Additional Features Included in the Pro Version', $this->shared->get( 'text_domain' ) ); ?></h2>
		<ul>
			<li><?php esc_html_e( 'Automatically generate news based on your posts', $this->shared->get( 'text_domain' ) ); ?></li>
			<li><?php esc_html_e( 'Automatically generate the news based on a specified RSS feed (E.g. Your own RSS feed, the RSS feed of a tv channel, the RSS feed of a radio station.)', $this->shared->get( 'text_domain' ) ); ?></li>
			<li><?php esc_html_e( 'Automatically generate the news based on a specified Twitter account', $this->shared->get( 'text_domain' ) ); ?></li>
			<li><?php esc_html_e( 'Control the speed and the delay of the sliding news with advanced options of the news ticker', $this->shared->get( 'text_domain' ) ); ?></li>
		</ul>
		<h2><?php esc_html_e( 'Additional Benefits of the Pro Version', $this->shared->get( 'text_domain' ) ); ?></h2>
		<ul>
			<li><?php esc_html_e( '24 hours support provided seven days a week', $this->shared->get( 'text_domain' ) ); ?></li>
			<li><?php echo esc_html__( '30 day money back guarantee (more information is available on the', $this->shared->get( 'text_domain' ) ) . ' <a href="https://daext.com/refund-policy/">' . esc_html__( 'Refund Policy', $this->shared->get( 'text_domain' ) ) . '</a> ' . esc_html__( 'page', $this->shared->get( 'text_domain' ) ) . ')'; ?></li>
		</ul>
		<h2><?php esc_html_e( 'Get Started', $this->shared->get( 'text_domain' ) ); ?></h2>
		<p><?php echo esc_html__( 'Download the', $this->shared->get( 'text_domain' ) ) . ' <a href="https://daext.com/live-news/">' . esc_html__( 'Pro Version', $this->shared->get( 'text_domain' ) ) . '</a> ' . esc_html__( 'now by selecting one of the available licenses.', $this->shared->get( 'text_domain' ) ); ?></p>
	</div>

</div>admin/inc/class-daextlnl-pagination.php000064400000020462151213253520014166 0ustar00<?php
/**
 * This file is used to handle the pagination in the back-end menus.
 */

/**
 * Handles the pagination on the back-end menus by returning the HTML content useful to represent the elements of the
 *  pagination.
 */
class Daextlnl_Pagination {

	/**
	 * Total number of items.
	 *
	 * @var null
	 */
	public $total_items = null;

	/**
	 * Number of records to display per page.
	 *
	 * @var int
	 */
	private $record_per_page = 10;

	/**
	 * Target page url.
	 *
	 * @var string
	 */
	private $target_page = '';

	/**
	 * Store the current page value, this is set through the set_current_page() method.
	 *
	 * @var int
	 */
	private $current_page = 0;

	/**
	 * Store the number of adjacent pages to show on each side of the current page inside the pagination.
	 *
	 * @var int
	 */
	private $adjacents = 2;

	/**
	 * Store the $_GET parameter to use.
	 *
	 * @var string
	 */
	private $parameter_name = 'p';

	/**
	 * Set the total number of items.
	 *
	 * @param $value
	 */
	public function set_total_items( $value ) {
		$this->total_items = intval( $value, 10 );
	}

	/**
	 * Set the number of items to show per page.
	 *
	 * @param $value
	 */
	public function set_record_per_page( $value ) {
		$this->record_per_page = intval( $value, 10 );
	}

	/**
	 * Set the page url
	 *
	 * @param $value
	 */
	public function set_target_page( $value ) {
		$this->target_page = $value;
	}

	/**
	 * Set the current page parameter by getting it from $_GET['p'], if it's not set or it's not > than 0 then set
	 * it to 1.
	 */
	public function set_current_page() {

		if ( isset( $_GET[ $this->parameter_name ] ) ) {

			$page_number = intval( $_GET[ $this->parameter_name ], 10 );

			if ( $page_number > 0 and $page_number <= ceil( $this->total_items / $this->record_per_page ) ) {
				$this->current_page = $page_number;
			} else {
				$this->current_page = 1;
			}
		} else {

			$this->current_page = 1;

		}
	}

	/**
	 * Set the number of adjacent pages to show on each side of the current page inside the pagination.
	 *
	 * @param int $value
	 *
	 * @return void
	 */
	public function set_adjacents( $value ) {
		$this->adjacents = intval( $value, 10 );
	}

	// Assing a different $_GET parameter instead of p
	public function set_parameter_name( $value = '' ) {
		$this->parameter_name = $value;
	}

	/**
	 * Calculate and echo the pagination.
	 */
	public function show() {

		// Setup page vars for display.
		$prev      = $this->current_page - 1;// previous page
		$next      = $this->current_page + 1;// next page
		$last_page = intval( ceil( $this->total_items / $this->record_per_page ), 10 );// last page
		$lpm1      = $last_page - 1;// last page minus 1

		// Generate the pagination if there is more than one page.
		if ( $last_page > 1 ) {

			// Generate the "Previous" button.
			if ( $this->current_page ) {

				if ( $this->current_page > 1 ) {

					// If the current page is > 1 the "Previous" button is clickable.
					$this->display_link( '&#171', $this->get_pagenum_link( $prev ) );

				} else {

					// If the current page is not > 1 the previous button is not clickable.
					$this->display_link( '&#171' );

				}
			}

			// Generate the buttons of all the pages.
			if ( $last_page < 7 + ( $this->adjacents * 2 ) ) {

				// Not enough pages to bother breaking it up

				for ( $counter = 1; $counter <= $last_page; $counter++ ) {
					if ( $counter === $this->current_page ) {
						$this->display_link( $counter );
					} else {
						$this->display_link( $counter, $this->get_pagenum_link( $counter ) );
					}
				}
			} else {

				// Enough pages to hide some.

				if ( $this->current_page < 1 + ( $this->adjacents * 2 ) ) {

					// When the selected page is near the beginning hide pages at the end.

					for ( $counter = 1; $counter < 4 + ( $this->adjacents * 2 ); $counter++ ) {

						if ( $counter === $this->current_page ) {
							$this->display_link( $counter );
						} else {
							$this->display_link( $counter, $this->get_pagenum_link( $counter ) );
						}
					}

					echo '<span>...</span>';
					$this->display_link( $lpm1, $this->get_pagenum_link( $lpm1 ) );
					$this->display_link( $last_page, $this->get_pagenum_link( $last_page ) );

				} elseif ( $last_page - ( $this->adjacents * 2 ) > $this->current_page && $this->current_page > ( $this->adjacents * 2 ) ) {

					// When the selected page is in the middle hide some pages form the front and some page from the back.

					$this->display_link( '1', $this->get_pagenum_link( 1 ) );
					$this->display_link( '2', $this->get_pagenum_link( 2 ) );
					echo '<span>...</span>';

					for ( $counter = $this->current_page - $this->adjacents; $counter <= $this->current_page + $this->adjacents; $counter++ ) {

						if ( $counter === $this->current_page ) {
							$this->display_link( $counter );
						} else {
							$this->display_link( $counter, $this->get_pagenum_link( $counter ) );
						}
					}

					echo '<span>...</span>';
					$this->display_link( $lpm1, $this->get_pagenum_link( $lpm1 ) );
					$this->display_link( $last_page, $this->get_pagenum_link( $last_page ) );

				} else {

					// When the selected page is near the end hide pages at the beginning.

					$this->display_link( '1', $this->get_pagenum_link( 1 ) );
					$this->display_link( '2', $this->get_pagenum_link( 2 ) );
					echo '<span>...</span>';
					for ( $counter = $last_page - ( 2 + ( $this->adjacents * 2 ) ); $counter <= $last_page; $counter++ ) {

						if ( $counter === $this->current_page ) {
							$this->display_link( $counter );
						} else {
							$this->display_link( $counter, $this->get_pagenum_link( $counter ) );
						}
					}
				}
			}

			// Generate the "Next" button.
			if ( $this->current_page ) {

				if ( $this->current_page < $counter - 1 ) {

					// If the current page is not the last page the "Next" button is clickable.
					$this->display_link( '&#187', $this->get_pagenum_link( $next ) );

				} else {

					// If the current page is the last page the "Next" button is not clickable.
					$this->display_link( '&#187' );

				}
			}
		}
	}

	/**
	 * Return the complete url associated with this page id.
	 *
	 * @param $id The page id.
	 *
	 * @return string The URL associated with the id.
	 */
	private function get_pagenum_link( $id ) {

		// search: s ----------------------------------------------------------------------------------------------------
		if ( isset( $_GET['s'] ) ) {
			$s      = sanitize_text_field( $_GET['s'] );
			$filter = '&s=' . $s;
		} else {
			$filter = '';
		}

		// filter cf
		if ( isset( $_GET['cf'] ) ) {
			$cf = sanitize_text_field( $_GET['cf'] );
			if ( $cf !== 'all' ) {
				$filter .= '&cf=' . intval( $_GET['cf'], 10 );
			}
		}

		if ( false === strpos( $this->target_page, '?' ) ) {
			return $this->target_page . '?' . $this->parameter_name . '=' . $id . $filter;
		} else {
			return $this->target_page . '&' . $this->parameter_name . '=' . $id . $filter;
		}
	}

	/**
	 * Generate the query string to use inside the SQL query.
	 *
	 * @return string
	 */
	public function query_limit() {

		// Calculate the $list_start position.
		$list_start = ( $this->current_page - 1 ) * $this->record_per_page;

		// Start of the list should be less than pagination count.
		if ( $list_start >= $this->total_items ) {
			$list_start = ( $this->total_items - $this->record_per_page );
		}

		// List start can't be negative.
		if ( $list_start < 0 ) {
			$list_start = 0;
		}

		return 'LIMIT ' . intval( $list_start, 10 ) . ', ' . intval( $this->record_per_page, 10 );
	}

	/**
	 * Display the pagination link based on the provided link text and url.
	 *
	 * @param string $text The text of the link.
	 * @param null   $url The url of the link.
	 */
	private function display_link( $text, $url = null ) {

		if ( null === $url ) {

			// Non-clickable and disabled links.

			if ( '&#171' === $text ) {
				echo '<a href="javascript: void(0)" class="disabled">&#171</a>';
			} elseif ( '&#187' === $text ) {
				echo '<a href="javascript: void(0)" class="disabled">&#187</a>';
			} else {
				echo '<a href="javascript: void(0)" class="disabled">' . esc_html( $text ) . '</a>';
			}
		} else {

			// Clickable and active links.

			if ( '&#171' === $text ) {
				echo '<a href="' . esc_url( $url ) . '">&#171</a>';
			} elseif ( '&#187' === $text ) {
				echo '<a href="' . esc_url( $url ) . '">&#187</a>';
			} else {
				echo '<a href="' . esc_url( $url ) . '">' . esc_html( $text ) . '</a>';
			}
		}
	}
}
admin/assets/js/menu-featured.js000064400000000355151213253520012653 0ustar00(function($) {

  'use strict';

  $(document).ready(function() {

    'use strict';

    $('#daext-filter-form select').on('change', function() {

      'use strict';

      $('#daext-filter-form').submit();

    });

  });

}(jQuery));admin/assets/js/chosen-init-options.js000064400000000231151213253520014014 0ustar00jQuery(document).ready(function($) {

  'use strict';

  jQuery('#daextlnl-detect-url-mode').chosen();
  jQuery('#daextlnl-load-momentjs').chosen();

});admin/assets/js/menu-sliding.js000064400000003032151213253520012500 0ustar00jQuery(document).ready(function($) {

    'use strict';

    //Handle changes of the news ticker filter
    $('#daext-filter-form select').on('change', function() {

        'use strict';

        $('#daext-filter-form').submit();

    });

    //do not set the default values if we are editing an existing sliding news
    if ( $( "#update-id" ).length ){return;}

    daextlnl_update_default_colors();

    $('#ticker-id').change(function(){

        'use strict';

        daextlnl_update_default_colors();

    });

    /*
     * Update the default 'Text Color', 'Text Color Hover' and 'Background Color' based on the values available on the
     * related ticker
     */
    function daextlnl_update_default_colors(){

        'use strict';

        //When the menu doesn't have the #ticker-id field available return
        if(!$('#ticker-id').length){return;}

        let ticker_id = parseInt($('#ticker-id').val(), 10);

        //prepare input for the ajax request
        let data = {
            "action": "update_default_colors",
            "security": daextlnl_nonce,
            "ticker_id": ticker_id
        };

        //ajax
        $.post(daextlnl_ajax_url, data, function(result_json) {

            'use strict';

            let data_obj = JSON.parse(result_json);

            $('#text-color').iris('color', data_obj.sliding_news_color);
            $('#text-color-hover').iris('color', data_obj.sliding_news_color_hover);
            $('#background-color').iris('color', data_obj.sliding_news_background_color);

        });

    }

});admin/assets/js/chosen-init-featured.js000064400000000145151213253520014124 0ustar00jQuery(document).ready(function($) {

    'use strict';

    jQuery('#ticker-id, #cf').chosen();

});admin/assets/js/chosen-init-sliding.js000064400000000145151213253520013756 0ustar00jQuery(document).ready(function($) {

    'use strict';

    jQuery('#ticker-id, #cf').chosen();

});admin/assets/js/chosen-init-tickers.js000064400000000450151213253520013770 0ustar00jQuery(document).ready(function($) {

    'use strict';

    jQuery('#target, #open-links-new-tab, #open-news-as-default, #hide-featured-news, #hide-clock, #clock-autoupdate, #enable-rtl-layout, #enable-ticker, #clock-source, #enable-with-mobile-devices, #enable-links, #url-mode').chosen();

});admin/assets/js/media-uploader.js000064400000004753151213253520013010 0ustar00jQuery(document).ready(function($) {

  'use strict';

    //.button_add_media click event handler
    $(document.body).on('click', '.button_add_media' , function( event ){

      'use strict';

      //will be used to store the wp.media object
      let file_frame;

        //prevent the default behavior of this event
        event.preventDefault();

        //save this in a variable
        let da_media_button = $(this);

        if($(this).attr('data-set-remove') == "set"){

            //reopen the media frame if already exists
            if ( file_frame ) {
                file_frame.open();
                return;
            }

            //extend the wp.media object
            file_frame = wp.media.frames.file_frame = wp.media({
                title: $( this ).data( 'Insert image' ),
                button: {
                  text: $( this ).data( 'Insert image' ),
                },
                multiple: false//false -> allows single file | true -> allows multiple files
            });

            //run a callback when an image is selected
            file_frame.on( 'select', function() {

              'use strict';

              //get the attachment from the uploader
              let attachment = file_frame.state().get('selection').first().toJSON();

              //change the da_media_button label
              da_media_button.text(da_media_button.attr('data-remove'));

              //change the da_media_button current status
              da_media_button.attr('data-set-remove', 'remove');

              //assign the attachment.url ( or attachment.id ) to the DOM element ( an input text ) that comes just before the "Add Media" button
              da_media_button.prev().val(attachment.url);

              //assign the attachment.url to the src of the image two times before the "Add Media" button
              da_media_button.prev().prev().attr("src",attachment.url);

              //show the image
              da_media_button.prev().prev().show();

            });

            //open the modal window
            file_frame.open();

        }else{

            //change the da_media_button label
            da_media_button.html(da_media_button.attr('data-set'))

            //change the da_media_button current status
            da_media_button.attr('data-set-remove', 'set');

            //hide the game image
            da_media_button.prev().prev().hide();

            //set empty to the hidden field
            da_media_button.prev().val("");

        }

    });

});admin/assets/js/jquery-ui-tooltip-init.js000064400000000170151213253520014470 0ustar00jQuery(document).ready(function($) {

    'use strict';

    $( '.help-icon' ).tooltip({show: false, hide: false});

});admin/assets/js/wp-color-picker-init.js000064400000000233151213253520014063 0ustar00/*
 * initialization of the wp color picker
 */
jQuery(document).ready(function($){

    'use strict';

    $('.wp-color-picker').wpColorPicker();
    
});admin/assets/js/menu-tickers.js000064400000001377151213253520012525 0ustar00jQuery(document).ready(function($) {

    remove_border_last_cell_chart();

    //.group-trigger -> click - EVENT LISTENER
    $(document.body).on('click', '.group-trigger' , function(){

        //open and close the various sections of the chart area
        let target = $(this).attr('data-trigger-target');
        $('.' + target).toggle(0);
        $(this).find('.expand-icon').toggleClass('arrow-down');

        remove_border_last_cell_chart();

    });

    /*
     Remove the bottom border on the cells of the last row of the chart section
     */
    function remove_border_last_cell_chart(){
        $('table.daext-form tr > *').css('border-bottom-width', '1px');
        $('table.daext-form tr:visible:last > *').css('border-bottom-width', '0');
    }

});admin/assets/img/trash-hover.png000064400000002212151213253520012656 0ustar00�PNG


IHDR�ZtEXtSoftwareAdobe ImageReadyq�e<�iTXtXML:com.adobe.xmp<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c014 79.156797, 2014/08/20-09:53:02        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmpMM:OriginalDocumentID="xmp.did:1fc19e20-5f81-8447-88b8-1c526769ad72" xmpMM:DocumentID="xmp.did:71749E26ECE411E4935FEAE867B912DF" xmpMM:InstanceID="xmp.iid:71749E25ECE411E4935FEAE867B912DF" xmp:CreatorTool="Adobe Photoshop CC 2014 (Windows)"> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:abdfe499-e7f4-aa42-aa27-0f51114cbf86" stRef:documentID="adobe:docid:photoshop:624f098a-ece3-11e4-a23a-de087bd57efa"/> </rdf:Description> </rdf:RDF> </x:xmpmeta> <?xpacket end="r"?>!���IDATx�b���/������]�����w�`���`!�L��W��CY�Y��1e��O^ఙ��V?	�A�����B�$0l�v�aO���6�)
�睋�U�S�q4VقZQń�x�6��&�Q��֋�`೙K��`U�����g��<��)�HIEND�B`�admin/assets/img/update-hover.png000064400000036753151213253520013040 0ustar00�PNG


IHDR�Z	pHYs��;tiTXtXML:com.adobe.xmp<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c132 79.159284, 2016/04/19-13:13:40        ">
   <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
      <rdf:Description rdf:about=""
            xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"
            xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#"
            xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#"
            xmlns:xmp="http://ns.adobe.com/xap/1.0/"
            xmlns:dc="http://purl.org/dc/elements/1.1/"
            xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/"
            xmlns:tiff="http://ns.adobe.com/tiff/1.0/"
            xmlns:exif="http://ns.adobe.com/exif/1.0/">
         <xmpMM:OriginalDocumentID>xmp.did:1fc19e20-5f81-8447-88b8-1c526769ad72</xmpMM:OriginalDocumentID>
         <xmpMM:DocumentID>adobe:docid:photoshop:c6803d97-b6df-11e6-b4ca-cf667453ff9b</xmpMM:DocumentID>
         <xmpMM:InstanceID>xmp.iid:ee9d9ad2-99fe-3741-bc39-12f3b42f1999</xmpMM:InstanceID>
         <xmpMM:DerivedFrom rdf:parseType="Resource">
            <stRef:instanceID>xmp.iid:F1FE7681ECDA11E4AE18BDE587F855DB</stRef:instanceID>
            <stRef:documentID>xmp.did:F1FE7682ECDA11E4AE18BDE587F855DB</stRef:documentID>
         </xmpMM:DerivedFrom>
         <xmpMM:History>
            <rdf:Seq>
               <rdf:li rdf:parseType="Resource">
                  <stEvt:action>saved</stEvt:action>
                  <stEvt:instanceID>xmp.iid:700f37b2-2785-d345-a435-d18e3bf32180</stEvt:instanceID>
                  <stEvt:when>2016-11-30T10:31:40+01:00</stEvt:when>
                  <stEvt:softwareAgent>Adobe Photoshop CC 2015.5 (Windows)</stEvt:softwareAgent>
                  <stEvt:changed>/</stEvt:changed>
               </rdf:li>
               <rdf:li rdf:parseType="Resource">
                  <stEvt:action>saved</stEvt:action>
                  <stEvt:instanceID>xmp.iid:ee9d9ad2-99fe-3741-bc39-12f3b42f1999</stEvt:instanceID>
                  <stEvt:when>2016-11-30T10:31:40+01:00</stEvt:when>
                  <stEvt:softwareAgent>Adobe Photoshop CC 2015.5 (Windows)</stEvt:softwareAgent>
                  <stEvt:changed>/</stEvt:changed>
               </rdf:li>
            </rdf:Seq>
         </xmpMM:History>
         <xmp:CreatorTool>Adobe Photoshop CC 2015.5 (Windows)</xmp:CreatorTool>
         <xmp:CreateDate>2016-11-28T08:56:08+01:00</xmp:CreateDate>
         <xmp:ModifyDate>2016-11-30T10:31:40+01:00</xmp:ModifyDate>
         <xmp:MetadataDate>2016-11-30T10:31:40+01:00</xmp:MetadataDate>
         <dc:format>image/png</dc:format>
         <photoshop:ColorMode>3</photoshop:ColorMode>
         <tiff:Orientation>1</tiff:Orientation>
         <tiff:XResolution>720000/10000</tiff:XResolution>
         <tiff:YResolution>720000/10000</tiff:YResolution>
         <tiff:ResolutionUnit>2</tiff:ResolutionUnit>
         <exif:ColorSpace>65535</exif:ColorSpace>
         <exif:PixelXDimension>20</exif:PixelXDimension>
         <exif:PixelYDimension>20</exif:PixelYDimension>
      </rdf:Description>
   </rdf:RDF>
</x:xmpmeta>
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                            
<?xpacket end="w"?>�$�D cHRMz%������u0�`:�o�_�F�IDATx�b���/����0p�Y��{{��Nj�~o�����"� �,����=�~}ܱ�Y֛QՉ����ʄ+s��iú�_�y&Ff����bl3T(��ª�/�/��8���k����+�߯7�>Mz��$�Vo5!�?��u���� �򝀂��\��t��I}q�sn�(����]��?N����	�N�:>����^@q�Ӈ�����	��ns�B��Ɓ�Y/�2����:�'�4E&�_�������q&F��2�F��M�A���������?�ts9
6��_O\�����Wi̘��~�gQ?P��„�E>}�x��ί70�{
�1��RT}yZ���$�4y�vkX��{����m�
�j�l��	$��C���H�ܼ��$�$�wV��2�7���E�9KK��O��?<x��֏_~~`c�����b�D�+I�ў`��IEND�B`�admin/assets/img/arrow-down-f7f7f7.png000064400000036323151213253520013531 0ustar00�PNG


IHDR��
	pHYs��;�iTXtXML:com.adobe.xmp<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c132 79.159284, 2016/04/19-13:13:40        ">
   <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
      <rdf:Description rdf:about=""
            xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"
            xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#"
            xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#"
            xmlns:xmp="http://ns.adobe.com/xap/1.0/"
            xmlns:dc="http://purl.org/dc/elements/1.1/"
            xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/"
            xmlns:tiff="http://ns.adobe.com/tiff/1.0/"
            xmlns:exif="http://ns.adobe.com/exif/1.0/">
         <xmpMM:OriginalDocumentID>xmp.did:1fc19e20-5f81-8447-88b8-1c526769ad72</xmpMM:OriginalDocumentID>
         <xmpMM:DocumentID>adobe:docid:photoshop:8539bf25-56f5-11e6-987b-fc45e1ca408c</xmpMM:DocumentID>
         <xmpMM:InstanceID>xmp.iid:86854044-7971-5c40-bdab-f2d668ef80cb</xmpMM:InstanceID>
         <xmpMM:DerivedFrom rdf:parseType="Resource">
            <stRef:instanceID>xmp.iid:abdfe499-e7f4-aa42-aa27-0f51114cbf86</stRef:instanceID>
            <stRef:documentID>adobe:docid:photoshop:624f098a-ece3-11e4-a23a-de087bd57efa</stRef:documentID>
         </xmpMM:DerivedFrom>
         <xmpMM:History>
            <rdf:Seq>
               <rdf:li rdf:parseType="Resource">
                  <stEvt:action>saved</stEvt:action>
                  <stEvt:instanceID>xmp.iid:1cd6ecbe-4b4a-2d43-b164-54a5e5304408</stEvt:instanceID>
                  <stEvt:when>2015-09-04T15:23:19+02:00</stEvt:when>
                  <stEvt:softwareAgent>Adobe Photoshop CC 2015 (Windows)</stEvt:softwareAgent>
                  <stEvt:changed>/</stEvt:changed>
               </rdf:li>
               <rdf:li rdf:parseType="Resource">
                  <stEvt:action>saved</stEvt:action>
                  <stEvt:instanceID>xmp.iid:86854044-7971-5c40-bdab-f2d668ef80cb</stEvt:instanceID>
                  <stEvt:when>2016-07-31T10:05:49+02:00</stEvt:when>
                  <stEvt:softwareAgent>Adobe Photoshop CC 2015.5 (Windows)</stEvt:softwareAgent>
                  <stEvt:changed>/</stEvt:changed>
               </rdf:li>
            </rdf:Seq>
         </xmpMM:History>
         <xmp:CreatorTool>Adobe Photoshop CC 2015.5 (Windows)</xmp:CreatorTool>
         <xmp:CreateDate>2015-09-04T09:15:20+02:00</xmp:CreateDate>
         <xmp:ModifyDate>2016-07-31T10:05:49+02:00</xmp:ModifyDate>
         <xmp:MetadataDate>2016-07-31T10:05:49+02:00</xmp:MetadataDate>
         <dc:format>image/png</dc:format>
         <photoshop:ColorMode>3</photoshop:ColorMode>
         <tiff:Orientation>1</tiff:Orientation>
         <tiff:XResolution>720000/10000</tiff:XResolution>
         <tiff:YResolution>720000/10000</tiff:YResolution>
         <tiff:ResolutionUnit>2</tiff:ResolutionUnit>
         <exif:ColorSpace>65535</exif:ColorSpace>
         <exif:PixelXDimension>20</exif:PixelXDimension>
         <exif:PixelYDimension>20</exif:PixelYDimension>
      </rdf:Description>
   </rdf:RDF>
</x:xmpmeta>
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                            
<?xpacket end="w"?>�� cHRMz%������u0�`:�o�_�F�IDATx�b����*&*�Q�l�����G1Tn{NP��m�Q�K�?���w�0�;���p[4C1C�o+f�n;����<�%�ߡJ~���?2��6뿥��cc�Yk�'U�@|��������r
�['~1�1�W-e(a�A�zIb
F|Ya(�7�`����eXZe�F�a]��D&1�1�0�hG��70��D1��3IEND�B`�admin/assets/img/arrow-up-f7f7f7.png000064400000036272151213253520013211 0ustar00�PNG


IHDR��
	pHYs��;�iTXtXML:com.adobe.xmp<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c132 79.159284, 2016/04/19-13:13:40        ">
   <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
      <rdf:Description rdf:about=""
            xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"
            xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#"
            xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#"
            xmlns:xmp="http://ns.adobe.com/xap/1.0/"
            xmlns:dc="http://purl.org/dc/elements/1.1/"
            xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/"
            xmlns:tiff="http://ns.adobe.com/tiff/1.0/"
            xmlns:exif="http://ns.adobe.com/exif/1.0/">
         <xmpMM:OriginalDocumentID>xmp.did:1fc19e20-5f81-8447-88b8-1c526769ad72</xmpMM:OriginalDocumentID>
         <xmpMM:DocumentID>adobe:docid:photoshop:9a9f8acc-56f5-11e6-987b-fc45e1ca408c</xmpMM:DocumentID>
         <xmpMM:InstanceID>xmp.iid:f9c035f6-f314-a049-90d1-54992f565534</xmpMM:InstanceID>
         <xmpMM:DerivedFrom rdf:parseType="Resource">
            <stRef:instanceID>xmp.iid:abdfe499-e7f4-aa42-aa27-0f51114cbf86</stRef:instanceID>
            <stRef:documentID>adobe:docid:photoshop:624f098a-ece3-11e4-a23a-de087bd57efa</stRef:documentID>
         </xmpMM:DerivedFrom>
         <xmpMM:History>
            <rdf:Seq>
               <rdf:li rdf:parseType="Resource">
                  <stEvt:action>saved</stEvt:action>
                  <stEvt:instanceID>xmp.iid:1cd6ecbe-4b4a-2d43-b164-54a5e5304408</stEvt:instanceID>
                  <stEvt:when>2015-09-04T15:23:19+02:00</stEvt:when>
                  <stEvt:softwareAgent>Adobe Photoshop CC 2015 (Windows)</stEvt:softwareAgent>
                  <stEvt:changed>/</stEvt:changed>
               </rdf:li>
               <rdf:li rdf:parseType="Resource">
                  <stEvt:action>saved</stEvt:action>
                  <stEvt:instanceID>xmp.iid:f9c035f6-f314-a049-90d1-54992f565534</stEvt:instanceID>
                  <stEvt:when>2016-07-31T10:06:11+02:00</stEvt:when>
                  <stEvt:softwareAgent>Adobe Photoshop CC 2015.5 (Windows)</stEvt:softwareAgent>
                  <stEvt:changed>/</stEvt:changed>
               </rdf:li>
            </rdf:Seq>
         </xmpMM:History>
         <xmp:CreatorTool>Adobe Photoshop CC 2015.5 (Windows)</xmp:CreatorTool>
         <xmp:CreateDate>2015-09-04T09:15:20+02:00</xmp:CreateDate>
         <xmp:ModifyDate>2016-07-31T10:06:11+02:00</xmp:ModifyDate>
         <xmp:MetadataDate>2016-07-31T10:06:11+02:00</xmp:MetadataDate>
         <dc:format>image/png</dc:format>
         <photoshop:ColorMode>3</photoshop:ColorMode>
         <tiff:Orientation>1</tiff:Orientation>
         <tiff:XResolution>720000/10000</tiff:XResolution>
         <tiff:YResolution>720000/10000</tiff:YResolution>
         <tiff:ResolutionUnit>2</tiff:ResolutionUnit>
         <exif:ColorSpace>65535</exif:ColorSpace>
         <exif:PixelXDimension>20</exif:PixelXDimension>
         <exif:PixelYDimension>20</exif:PixelYDimension>
      </rdf:Description>
   </rdf:RDF>
</x:xmpmeta>
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                            
<?xpacket end="w"?>�Z�� cHRMz%������u0�`:�o�_�F�IDATx�b����*&*�Q�d��m��۞e aÊ��N2�b8�P̰���K�|"c```��p�-����K���`^��au�91�~���?:��6뿥��cc�Yk�G��F�<)��Q��B�1I���:�2��MI�^����{�b�P�GK�` `�s��~w�IEND�B`�admin/assets/img/edit-hover.png000064400000002464151213253530012474 0ustar00�PNG


IHDR�ZtEXtSoftwareAdobe ImageReadyq�e<�iTXtXML:com.adobe.xmp<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c014 79.156797, 2014/08/20-09:53:02        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmpMM:OriginalDocumentID="xmp.did:1fc19e20-5f81-8447-88b8-1c526769ad72" xmpMM:DocumentID="xmp.did:8A698CFCECE411E4A525FD53B109EA24" xmpMM:InstanceID="xmp.iid:8A698CFBECE411E4A525FD53B109EA24" xmp:CreatorTool="Adobe Photoshop CC 2014 (Windows)"> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:abdfe499-e7f4-aa42-aa27-0f51114cbf86" stRef:documentID="adobe:docid:photoshop:624f098a-ece3-11e4-a23a-de087bd57efa"/> </rdf:Description> </rdf:RDF> </x:xmpmeta> <?xpacket end="r"?>�/][FIDATx�b���/����0�5y޹�Ԋ�'���00��-�~C,�8�l�C���:����(�3��9��g�<�8���_��y,H�A�'���_����f$�
ߟw��vL�R��瘏�N�_^N�������Mɀ����@:��lH��"����^_q��w �Iߺ�g?�
�d͟���İ�X�i!:_�[�]'� ���O@���+�^~7w�����/*��y�����<	�����n�K �T��'����-�������3>�@�p�����������O'��~1�	�;�s��
hHp���$0���*E��IEND�B`�admin/assets/img/help-fdfdfd.png000064400000037022151213253530012567 0ustar00�PNG


IHDR��
	pHYs��;�iTXtXML:com.adobe.xmp<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c067 79.157747, 2015/03/30-23:40:42        ">
   <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
      <rdf:Description rdf:about=""
            xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"
            xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#"
            xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#"
            xmlns:xmp="http://ns.adobe.com/xap/1.0/"
            xmlns:dc="http://purl.org/dc/elements/1.1/"
            xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/"
            xmlns:tiff="http://ns.adobe.com/tiff/1.0/"
            xmlns:exif="http://ns.adobe.com/exif/1.0/">
         <xmpMM:OriginalDocumentID>xmp.did:1fc19e20-5f81-8447-88b8-1c526769ad72</xmpMM:OriginalDocumentID>
         <xmpMM:DocumentID>adobe:docid:photoshop:7ca342f9-53a2-11e5-9437-a138aa861b2d</xmpMM:DocumentID>
         <xmpMM:InstanceID>xmp.iid:17d02260-2f52-1748-b97c-306edf822c4a</xmpMM:InstanceID>
         <xmpMM:DerivedFrom rdf:parseType="Resource">
            <stRef:instanceID>xmp.iid:abdfe499-e7f4-aa42-aa27-0f51114cbf86</stRef:instanceID>
            <stRef:documentID>adobe:docid:photoshop:624f098a-ece3-11e4-a23a-de087bd57efa</stRef:documentID>
         </xmpMM:DerivedFrom>
         <xmpMM:History>
            <rdf:Seq>
               <rdf:li rdf:parseType="Resource">
                  <stEvt:action>saved</stEvt:action>
                  <stEvt:instanceID>xmp.iid:1cd6ecbe-4b4a-2d43-b164-54a5e5304408</stEvt:instanceID>
                  <stEvt:when>2015-09-04T15:23:19+02:00</stEvt:when>
                  <stEvt:softwareAgent>Adobe Photoshop CC 2015 (Windows)</stEvt:softwareAgent>
                  <stEvt:changed>/</stEvt:changed>
               </rdf:li>
               <rdf:li rdf:parseType="Resource">
                  <stEvt:action>saved</stEvt:action>
                  <stEvt:instanceID>xmp.iid:17d02260-2f52-1748-b97c-306edf822c4a</stEvt:instanceID>
                  <stEvt:when>2015-09-05T09:49:14+02:00</stEvt:when>
                  <stEvt:softwareAgent>Adobe Photoshop CC 2015 (Windows)</stEvt:softwareAgent>
                  <stEvt:changed>/</stEvt:changed>
               </rdf:li>
            </rdf:Seq>
         </xmpMM:History>
         <xmp:CreatorTool>Adobe Photoshop CC 2015 (Windows)</xmp:CreatorTool>
         <xmp:CreateDate>2015-09-04T09:15:20+02:00</xmp:CreateDate>
         <xmp:ModifyDate>2015-09-05T09:49:14+02:00</xmp:ModifyDate>
         <xmp:MetadataDate>2015-09-05T09:49:14+02:00</xmp:MetadataDate>
         <dc:format>image/png</dc:format>
         <photoshop:ColorMode>3</photoshop:ColorMode>
         <tiff:Orientation>1</tiff:Orientation>
         <tiff:XResolution>720000/10000</tiff:XResolution>
         <tiff:YResolution>720000/10000</tiff:YResolution>
         <tiff:ResolutionUnit>2</tiff:ResolutionUnit>
         <exif:ColorSpace>65535</exif:ColorSpace>
         <exif:PixelXDimension>20</exif:PixelXDimension>
         <exif:PixelYDimension>20</exif:PixelYDimension>
      </rdf:Description>
   </rdf:RDF>
</x:xmpmeta>
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                            
<?xpacket end="w"?>�A�| cHRMz%������u0�`:�o�_�FIDATxڼ�?hQ�?O�\��-^�ti/Kn�.�A:�.������E7��R,Ht*�k�$:�R��Yz.u�C��s�spy5i��E��?8��}��w�����!�#y
��hh�Ug���\���c&��Y�S�c�0�����7��x!�):ӏ����	[\�f����b���k�X�@�qٽ'J��K�����/���&�!
�O>�_�-��NH��6'�N�,ȵ����}C�W)��f�D�CnMMpf�￷9y6K����,V�aCqqV���ػ�������9��p3�~��q���y��#�7V��g�1{�zp�"d�1��i���ܻ:Ky+@*��q��*�TKE���@2�Z�ST��pieT% �'
�0�i��}���$�sy2}�M3��	[�}Y�•Ҟ�Q��eIP�z簧�(�-�?� ZO~:Kܼ�x��.��%T��/#�kP�<���G�M5f��Lq9�@SdY8a�W�х�H@J��W\ɡ=���u��^'��IEND�B`�admin/assets/img/search-hover.png000064400000000323151213253530013004 0ustar00�PNG


IHDRY �0PLTE&����4������w��O�׮���\�څ��j�ݠ��A�������
�6^IDATx�c`���g�
��9�=��l6���(�E���YƑ�`G(#���̴��~�0�����"���700!9OY��dN
�x�9A�#IEND�B`�admin/assets/img/search.png000064400000000323151213253530011663 0ustar00�PNG


IHDRY �0PLTEq����*z����q��G������U����c�œ��8��������26^IDATx�c`���g�
��9�=��l6���(�E���YƑ�`G(#���̴��~�0�����"���700!9OY��dN
�x�9A�#IEND�B`�admin/assets/img/update.png000064400000036745151213253530011721 0ustar00�PNG


IHDR�Z	pHYs��;tiTXtXML:com.adobe.xmp<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c132 79.159284, 2016/04/19-13:13:40        ">
   <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
      <rdf:Description rdf:about=""
            xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"
            xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#"
            xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#"
            xmlns:xmp="http://ns.adobe.com/xap/1.0/"
            xmlns:dc="http://purl.org/dc/elements/1.1/"
            xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/"
            xmlns:tiff="http://ns.adobe.com/tiff/1.0/"
            xmlns:exif="http://ns.adobe.com/exif/1.0/">
         <xmpMM:OriginalDocumentID>xmp.did:1fc19e20-5f81-8447-88b8-1c526769ad72</xmpMM:OriginalDocumentID>
         <xmpMM:DocumentID>adobe:docid:photoshop:db179c40-b6df-11e6-b4ca-cf667453ff9b</xmpMM:DocumentID>
         <xmpMM:InstanceID>xmp.iid:a99f2b47-1252-264a-8b7c-530b703502d4</xmpMM:InstanceID>
         <xmpMM:DerivedFrom rdf:parseType="Resource">
            <stRef:instanceID>xmp.iid:F1FE7681ECDA11E4AE18BDE587F855DB</stRef:instanceID>
            <stRef:documentID>xmp.did:F1FE7682ECDA11E4AE18BDE587F855DB</stRef:documentID>
         </xmpMM:DerivedFrom>
         <xmpMM:History>
            <rdf:Seq>
               <rdf:li rdf:parseType="Resource">
                  <stEvt:action>saved</stEvt:action>
                  <stEvt:instanceID>xmp.iid:8b68ec71-35b0-8b4d-ac06-349d140af2c2</stEvt:instanceID>
                  <stEvt:when>2016-11-30T10:32:15+01:00</stEvt:when>
                  <stEvt:softwareAgent>Adobe Photoshop CC 2015.5 (Windows)</stEvt:softwareAgent>
                  <stEvt:changed>/</stEvt:changed>
               </rdf:li>
               <rdf:li rdf:parseType="Resource">
                  <stEvt:action>saved</stEvt:action>
                  <stEvt:instanceID>xmp.iid:a99f2b47-1252-264a-8b7c-530b703502d4</stEvt:instanceID>
                  <stEvt:when>2016-11-30T10:32:15+01:00</stEvt:when>
                  <stEvt:softwareAgent>Adobe Photoshop CC 2015.5 (Windows)</stEvt:softwareAgent>
                  <stEvt:changed>/</stEvt:changed>
               </rdf:li>
            </rdf:Seq>
         </xmpMM:History>
         <xmp:CreatorTool>Adobe Photoshop CC 2015.5 (Windows)</xmp:CreatorTool>
         <xmp:CreateDate>2016-11-28T08:56:08+01:00</xmp:CreateDate>
         <xmp:ModifyDate>2016-11-30T10:32:15+01:00</xmp:ModifyDate>
         <xmp:MetadataDate>2016-11-30T10:32:15+01:00</xmp:MetadataDate>
         <dc:format>image/png</dc:format>
         <photoshop:ColorMode>3</photoshop:ColorMode>
         <tiff:Orientation>1</tiff:Orientation>
         <tiff:XResolution>720000/10000</tiff:XResolution>
         <tiff:YResolution>720000/10000</tiff:YResolution>
         <tiff:ResolutionUnit>2</tiff:ResolutionUnit>
         <exif:ColorSpace>65535</exif:ColorSpace>
         <exif:PixelXDimension>20</exif:PixelXDimension>
         <exif:PixelYDimension>20</exif:PixelYDimension>
      </rdf:Description>
   </rdf:RDF>
</x:xmpmeta>
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                            
<?xpacket end="w"?>���� cHRMz%������u0�`:�o�_�F�IDATx�b���/����0p�Y�~|��Ëw?o���/�%o��,����=�~�ޱ�x���QՉ����ۄ�s��zC����P�<���_��bm�s.��ƪ�/�o�79-z�BRr]��/�7�K��$��ZO^�?��wZ��Wi'�챀����\����I}c�s�J(����~�E�N�x4��N�:%��W_@q����=OV��̵u�ū#�uc�ެ�~�>�����A��U�WdZ�����|��$	U&��737=@��M�ϮM�/D'��/L����?ߛXw������},Q�be�Ѩ�(aOa��L��M��3�ܸ������[HQ��ba��ILi��펰`�|o��Iϙ�����YXٰ'H���+ǟ������B	<���Ó��L���nwm�yQ����6ï�o<��«�x�-���M�5x�g��g��rП���IEND�B`�admin/assets/img/trash.png000064400000002164151213253530011544 0ustar00�PNG


IHDR�ZtEXtSoftwareAdobe ImageReadyq�e<niTXtXML:com.adobe.xmp<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c014 79.156797, 2014/08/20-09:53:02        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmpMM:OriginalDocumentID="xmp.did:1fc19e20-5f81-8447-88b8-1c526769ad72" xmpMM:DocumentID="xmp.did:B479422CECE211E49DC79110D7C6CF73" xmpMM:InstanceID="xmp.iid:B479422BECE211E49DC79110D7C6CF73" xmp:CreatorTool="Adobe Photoshop CC 2014 (Windows)"> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:F1FE7681ECDA11E4AE18BDE587F855DB" stRef:documentID="xmp.did:F1FE7682ECDA11E4AE18BDE587F855DB"/> </rdf:Description> </rdf:RDF> </x:xmpmeta> <?xpacket end="r"?>#x��IDATx�b���/������]��͉s�u��' *2/��B��x�_��{퇫�.�c����y��fF��_o�?���;�%���H`���sž|���l6S`7;ˮT�S,t��тZQń�x�6��&�Q��w�e�p0��,�.�?W�*��Ut�3@��z>���IEND�B`�admin/assets/img/edit.png000064400000002442151213253530011347 0ustar00�PNG


IHDR�ZtEXtSoftwareAdobe ImageReadyq�e<�iTXtXML:com.adobe.xmp<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c014 79.156797, 2014/08/20-09:53:02        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmpMM:OriginalDocumentID="xmp.did:1fc19e20-5f81-8447-88b8-1c526769ad72" xmpMM:DocumentID="xmp.did:84EE53D9ECE411E4BCD2D48ED6954F54" xmpMM:InstanceID="xmp.iid:84EE53D8ECE411E4BCD2D48ED6954F54" xmp:CreatorTool="Adobe Photoshop CC 2014 (Windows)"> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:abdfe499-e7f4-aa42-aa27-0f51114cbf86" stRef:documentID="adobe:docid:photoshop:624f098a-ece3-11e4-a23a-de087bd57efa"/> </rdf:Description> </rdf:RDF> </x:xmpmeta> <?xpacket end="r"?>+E�4IDATx�b���/����0�5��ٴV�i����2����J�0�C�h��'�6#����Q�g¯s"��^vq$�SN� ���X����|<\�8'+>�H:����+}�9��tJ�K7�������kY%�s�� �Z��}g��
"<:�&ģM�ۭSW1t�=m&D��y=�u�__�$�l�z[��K�h�g��d�ܗa���?�=|{D�.Zv醾!�N+
N�q�Ha�o^�
&��/��>�@�p��{ߐ���ܗ�O'���޳�i8h��+Iiq���$0@
m�{$IEND�B`�admin/assets/img/help-f7f7f7.png000064400000037562151213253530012371 0ustar00�PNG


IHDR��
	pHYs��<�iTXtXML:com.adobe.xmp<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c067 79.157747, 2015/03/30-23:40:42        ">
   <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
      <rdf:Description rdf:about=""
            xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"
            xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#"
            xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#"
            xmlns:xmp="http://ns.adobe.com/xap/1.0/"
            xmlns:dc="http://purl.org/dc/elements/1.1/"
            xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/"
            xmlns:tiff="http://ns.adobe.com/tiff/1.0/"
            xmlns:exif="http://ns.adobe.com/exif/1.0/">
         <xmpMM:OriginalDocumentID>xmp.did:1fc19e20-5f81-8447-88b8-1c526769ad72</xmpMM:OriginalDocumentID>
         <xmpMM:DocumentID>adobe:docid:photoshop:150a3d9b-5308-11e5-bacc-9c4d6e71be1e</xmpMM:DocumentID>
         <xmpMM:InstanceID>xmp.iid:4d5c2728-619d-c74d-a2d2-fa9b5a09ca29</xmpMM:InstanceID>
         <xmpMM:DerivedFrom rdf:parseType="Resource">
            <stRef:instanceID>xmp.iid:abdfe499-e7f4-aa42-aa27-0f51114cbf86</stRef:instanceID>
            <stRef:documentID>adobe:docid:photoshop:624f098a-ece3-11e4-a23a-de087bd57efa</stRef:documentID>
         </xmpMM:DerivedFrom>
         <xmpMM:History>
            <rdf:Seq>
               <rdf:li rdf:parseType="Resource">
                  <stEvt:action>saved</stEvt:action>
                  <stEvt:instanceID>xmp.iid:1cd6ecbe-4b4a-2d43-b164-54a5e5304408</stEvt:instanceID>
                  <stEvt:when>2015-09-04T15:23:19+02:00</stEvt:when>
                  <stEvt:softwareAgent>Adobe Photoshop CC 2015 (Windows)</stEvt:softwareAgent>
                  <stEvt:changed>/</stEvt:changed>
               </rdf:li>
               <rdf:li rdf:parseType="Resource">
                  <stEvt:action>saved</stEvt:action>
                  <stEvt:instanceID>xmp.iid:4d5c2728-619d-c74d-a2d2-fa9b5a09ca29</stEvt:instanceID>
                  <stEvt:when>2015-09-04T15:23:19+02:00</stEvt:when>
                  <stEvt:softwareAgent>Adobe Photoshop CC 2015 (Windows)</stEvt:softwareAgent>
                  <stEvt:changed>/</stEvt:changed>
               </rdf:li>
            </rdf:Seq>
         </xmpMM:History>
         <xmp:CreatorTool>Adobe Photoshop CC 2015 (Windows)</xmp:CreatorTool>
         <xmp:CreateDate>2015-09-04T09:15:20+02:00</xmp:CreateDate>
         <xmp:ModifyDate>2015-09-04T15:23:19+02:00</xmp:ModifyDate>
         <xmp:MetadataDate>2015-09-04T15:23:19+02:00</xmp:MetadataDate>
         <dc:format>image/png</dc:format>
         <photoshop:ColorMode>3</photoshop:ColorMode>
         <photoshop:TextLayers>
            <rdf:Bag>
               <rdf:li rdf:parseType="Resource">
                  <photoshop:LayerName></photoshop:LayerName>
                  <photoshop:LayerText></photoshop:LayerText>
               </rdf:li>
            </rdf:Bag>
         </photoshop:TextLayers>
         <tiff:Orientation>1</tiff:Orientation>
         <tiff:XResolution>720000/10000</tiff:XResolution>
         <tiff:YResolution>720000/10000</tiff:YResolution>
         <tiff:ResolutionUnit>2</tiff:ResolutionUnit>
         <exif:ColorSpace>65535</exif:ColorSpace>
         <exif:PixelXDimension>20</exif:PixelXDimension>
         <exif:PixelYDimension>20</exif:PixelYDimension>
      </rdf:Description>
   </rdf:RDF>
</x:xmpmeta>
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                            
<?xpacket end="w"?>W�; cHRMz%������u0�`:�o�_�F.IDATx�ĔMH�q����%������a���CM�Atp8ȶ�̠<��(1w�[Be�֡.-BW�J�>Fl*g^��"\+���;�1m�k��ӟ�?���2����"Se�:�lh�&y7=A8��Wr(l۽���t7c��Iz5L'&� �3�8�2™��?��qz��,����mmE�A��S�ϥ(Ʊ�y����l�Qw�H)3�8��9Q�@�$���G�NJP������MI��0�G!��]�����a�|ʲ��q<%{.Bp&iԔ���*'</>��h�VX�HDߓ:l��2�/��
z��d?�X"r�"�u1Y���h$����KFz<^��a��P��><@�g�1�ӳ�0����o�VT������K(:V���}�F]{/�
/�~�!?���z�m�C3�C�W���R���M�r:Ay��t'9�Vl�lQ�9�������ʩk��o�!������قE��۩ۄ� �1E��F'.�	N{Z�iγ��!��8H���dF�$dY**�@��|� ��|�B�|!��������IEND�B`�admin/assets/css/menu-tickers.css000064400000002456151213253530013055 0ustar00table.daext-items .icons-container{
    width: 76px !important;
    min-width: 76px !important;
}

.display-none{
    display: none;
}

table.daext-items .menu-icon.update{
    margin-right: 8px !important;
}

table.daext-items .update{
    background: url("../img/update.png") 0 0 no-repeat !important;
}

table.daext-items .update:hover{
    background: url("../img/update-hover.png") 0 0 no-repeat !important;
}

.empty-icon-container{
    width: 20px !important;
    height: 20px !important;
    float: left !important;
    margin: 4px 8px 4px 0 !important;
}

table.daext-form .image-uploader .selected-image{
    width: auto !important;
    height: 40px !important;
}

.expand-icon{
    background: url("../img/arrow-down-f7f7f7.png") 0 0 no-repeat !important;
    width: 20px !important;
    height: 20px !important;
    float: right;
    margin: 2px 0;
    cursor: pointer;
}

.group-trigger{
    background: #f7f7f7;
    cursor: pointer;
}

.group-title{
    font-weight: 600 !important;
    color: #333 !important;
    text-align: left !important;
}

.expand-icon.arrow-down{
    background: url("../img/arrow-up-f7f7f7.png") 0 0 no-repeat !important;
}

.source-chart-configuration,
.behavior-chart-configuration,
.style-chart-configuration,
.performance-chart-configuration,
.section-advanced{
    display: none;
}admin/assets/css/framework/options.css000064400000006550151213253530014136 0ustar00/* Utility */

.daext-display-none{display: none;}

/* General */

#daext-options-wrapper{
    margin-top: 23px;
}

#daext-options-wrapper *{
    font-size: 12px;
    font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
}

#daext-options-wrapper .nav-tab-wrapper{
    border-bottom: 0;
}

#daext-options-wrapper tbody th{
    color: #333;
    font-weight: normal;
    text-align: right;
    height: 24px;
    line-height: 24px;
}

#daext-options-wrapper tbody th,
#daext-options-wrapper tbody td {
    padding: 8px;
}

#daext-options-wrapper tbody tr:not(:last-child) > th, #daext-options-wrapper tbody tr:not(:last-child) > td {
    border-bottom: 1px solid #e3e3e3;
}

#daext-options-wrapper input[type="text"]{
    height: 24px;
    line-height: 16px;
    box-shadow: none;
    padding: 3px 5px;
    margin: 0 !important;
    width: 217px;
    color: #333 !important;
    border-color: #dddddd;
    border-radius: 0;
    min-height: auto;
}

#daext-options-wrapper input[type="text"]:focus{
    border-color: #5b9dd9;
}

#daext-options-wrapper select{
    height: 24px;
    line-height: 16px;
    box-shadow: none;
    padding: 3px 5px;
    margin: 0 !important;
}

#daext-options-wrapper textarea{
    width: 100%;
    font-size: 12px;
    box-shadow: none;
    border: 1px solid #ddd;
    min-height: 60px;
    color: #999;
    margin: 0 !important;
    overflow: auto;
    padding: 3px 5px;
    line-height: 1.4;
    color: #333;
    display: block;
}

.submit > input[type="submit"]{
    box-shadow: none !important;
    font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif !important;
    font-size: 12px !important;
}

.nav-tab{
    background: #f7f7f7;
    border: 1px solid #dfdfdf;
    padding: 3px 10px;
    line-height: 28px;
    font-weight: 600;
    height: 28px;
    color: #333;
}

.nav-tab:hover{
    background: #f7f7f7;
}

.nav-tab-active{
    background: #fff;
    border-bottom-color: #fff;
}

.nav-tab-active:hover{
    background: #fff !important;
    border-bottom-color: #fff;
}

#daext-options-wrapper .form-table{
    border-left: 1px solid #dfdfdf;
    border-right: 1px solid #dfdfdf;
    margin: 0;
    background: #fdfdfd;
    border-top: 1px solid #dfdfdf;
}

.form-table th{
    width: 260px !important;
}

#daext-options-wrapper{
    width: 800px;
}

.daext-options-action{
    line-height: 28px;
    height: 28px;
    font-size: 12px;
    color: #333;
    font-weight: 600;
    font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
    padding: 8px 10px;
    text-align: left;
    background: #f7f7f7;
    text-shadow: #fff 0px 1px 0px;
    border: 1px solid #dfdfdf;
    border-radius: 0 0 3px 3px;
}

.daext-options-action > input.button{
    -webkit-box-shadow: none !important;
    -moz-box-shadow: none !important;
    box-shadow: none !important;
    font-weight: normal;
    color: #555 !important;
    border-color: #cccccc !important;
    background: #f7f7f7;
}

.daext-options-action > input.button:hover{
    background: #fafafa;
    border-color: #979797 !important;
}

#daext-options-wrapper .wp-color-result{
    margin: 0;
    box-shadow: none;
}

#daext-options-wrapper .wp-picker-clear{
    box-shadow: none;
}

.chosen-container-single input{
    width: 100% !important;
}admin/assets/css/framework/menu.css000064400000033035151213253530013405 0ustar00/*

index:

- utility
- general
- daext-items //The table that lists all the items
- daext-items icons //Icons for the daext-items table
- daext-tablenav //The pagination of the daext-items table
- daext-form //The form used to create and edit items
- daext-widget //The sidebar widget
- wp-picker-container //The color picker

*/

/* utility */

.daext-clearfix:after{
    visibility: hidden !important;
    display: block !important;
    font-size: 0 !important;
    content: " " !important;
    clear: both !important;
    height: 0 !important;
}
.daext-clearfix { display: inline-block !important; }
* html .daext-clearfix { height: 1% !important; }
.daext-clearfix { display: block !important; }

.daext-display-none{display: none;}

/* general */

#daext-menu-wrapper{
    margin-top: 19px !important;
}

.display-none{
    display: none;
}

/* daext-items */

.daext-items-container{
    border: 1px solid #dfdfdf;
    border-radius: 3px;
}

table.daext-items{
    width: 100%;
    border-collapse: collapse;
}

table.daext-items > thead{
    background: #f7f7f7;
}

table.daext-items > tbody > tr{
    background: #fdfdfd !important;
}

table.daext-items > thead > tr > th{
    padding: 0;
    line-height: 28px;
    height: 28px;
    font-size: 12px;
    color: #333;
    font-weight: 600;
    font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
    padding: 3px 10px;
    text-align: left;
    border-bottom: 1px solid #dfdfdf;
    text-shadow: #fff 0px 1px 0px;
}

table.daext-items > tbody > tr > td{
    padding: 0;
    line-height: 28px;
    height: 28px;
    font-size: 12px;
    color: #555;
    font-weight: normal;
    font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
    padding: 3px 10px;
    text-align: left;
}

table.daext-items > thead > tr > th:not(:nth-of-type(1)){
    border-left: 1px solid #dfdfdf !important;
}

table.daext-items > tbody > tr > td:not(:nth-of-type(1)){
    border-left: 1px solid #e3e3e3 !important;
}

table.daext-items .shortcode{
    font-size: 11px !important;
    font-family: monospace !important;
    color: #fff;
    padding: 3px;
    background: #0073aa;
}

table.daext-items > tbody > tr:not(:last-child) > td{
    border-bottom: 1px solid #e3e3e3;
    background: #fdfdfd;
}

table.daext-items > tbody > tr > td > a{
    text-decoration: none;
}

table.daext-items .menu-icon{
    width: 20px !important;
    height: 20px !important;
    border: none !important;
    margin: 0 !important;
    padding: 0 !important;
    cursor: pointer !important;
    float: left !important;
    margin-top: 4px !important;
    margin-bottom: 4px !important;
}

table.daext-items .menu-icon.empty-icon{
    cursor: default !important;
}

table.daext-items .icons-container .menu-icon:not(:last-child){
    margin-right: 8px !important;
}

table.daext-items .edit{
    background: url("../../img/edit.png") 0 0 no-repeat !important;
}

table.daext-items .edit:hover{
    background: url("../../img/edit-hover.png") 0 0 no-repeat !important;
}

table.daext-items .delete{
    background: url("../../img/trash.png") 0 0 no-repeat !important;
}

table.daext-items .delete:hover{
    background: url("../../img/trash-hover.png") 0 0 no-repeat !important;
}

table.daext-items input[type="checkbox"]{
    border: 1px solid #ddd;
    box-shadow: none;
}

/* daext-header-wrapper */

#daext-header-wrapper h2{
    font-size: 23px;
    font-weight: 400;
    margin: 0;
    padding: 9px 0 4px;
    line-height: 29px;
    float: left;
}

#daext-search-form{
    float: right;
}

#daext-search-form p{
    margin: 14px 8px 6px 0;
    height: 22px;
    float: left;
    text-align: right;
    font-size: 12px;
    line-height: 22px;
    font-style: italic;
    color: #777;
}

#daext-search-form input[type="text"]{
    height: 24px;
    line-height: 16px;
    box-shadow: none;
    padding: 3px 5px;
    margin: 13px 0 5px;
    color: #333333 !important;
    font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
    font-weight: normal;
    font-size: 12px !important;
    border-width: 1px 0 1px 1px;
    border-color: #dddddd;
    border-radius: 0;
    min-height: auto;
}

#daext-search-form input[type="text"]:focus{
    border-color: #5b9dd9;
}

#daext-search-form input[type="submit"]{
    background: url('../../img/search.png') 0 0 no-repeat !important;
    background-color: #1c71a6;
    height: 24px;
    box-shadow: none;
    display: block;
    width: 24px;
    float: right;
    padding: 0;
    border: 0;
    margin: 13px 0 5px;
    cursor: pointer;
}

#daext-search-form input[type="submit"]:hover{
    background: url('../../img/search-hover.png') 0 0 no-repeat !important;
}

#daext-filter-form{
    float: right;
    position: relative;
    margin-right: 8px;
}

#daext-filter-form p{
    margin: 14px 8px 6px 0;
    height: 22px;
    text-align: right;
    font-size: 12px;
    position: absolute;
    width: 180px;
    line-height: 22px;
    right: 180px;
    top: 0;
    font-style: italic;
    color: #777;
}

#daext-filter-form .chosen-container{
    margin: 13px 0 5px;
    min-width: 180px;
    max-width: 180px;
}

/* daext-tablenav */

.daext-tablenav-pages > *:not(:first-child){
    margin: 0 0 0 4px;
}

.daext-tablenav-pages > a{
    font-size: 12px !important;
    color: #888 !important;
    line-height: 25px;
    display: inline-block;
    padding: 0 10px !important;
    background: #f7f7f7;
    text-decoration: none;
}

.daext-tablenav-pages > a:not(.disabled):hover{
    color: #fff !important;
    background: #00a0d2;
}

.daext-tablenav-pages > .disabled{
    cursor: default;
    color: #ccc !important;
}

.daext-tablenav{
    margin-top: 11px;
    margin-bottom: 36px;
}

.daext-tablenav-pages{
    float: right;
    display: block;
    height: 30px;
}

.daext-tablenav .daext-displaying-num{
    margin-right: 2px;
    color: #777;
    font-size: 12px;
    font-style: italic;
}

/* daext-form */

.daext-form-container{
    border: 1px solid #dfdfdf;
    border-radius: 3px;
    width: 800px;
}

.daext-form-container *{
    font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
    font-weight: normal;
    font-size: 12px !important;
}

.daext-form-container input[type="text"]{
    height: 24px;
    line-height: 16px;
    box-shadow: none;
    padding: 3px 5px;
    margin: 0 !important;
    width: 217px;
    border-color: #dddddd;
    border-radius: 0;
    min-height: auto;
}

.daext-form-container input[type="text"]:focus{
    border-color: #5b9dd9;
}

.daext-form-container input[type="text"],
.daext-form-container select,
.daext-form-container textarea {
    color: #333 !important;
}

.daext-form-container #date{
    background: #fff;
    color: #333;
}

.daext-form-container textarea {
    width: 100%;
    font-size: 12px;
    box-shadow: none;
    border: 1px solid #ddd;
    min-height: 60px;
    color: #999;
    margin: 0 !important;
    overflow: auto;
    padding: 3px 5px;
    line-height: 1.4;
    color: #333;
    display: block;
    border-radius: 0;
    width: 217px;
    float: left;
}

.daext-form-container textarea, .daext-form-container select{
    box-shadow: none;
    margin: 0 !important;
}
.daext-form-container select{
    height: 24px;
    line-height: 24px;
}


.daext-form-title{
    line-height: 28px;
    height: 28px;
    font-size: 12px;
    color: #333;
    font-weight: 600;
    font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
    padding: 3px 10px;
    margin: 0;
    text-align: left;
    background: #f7f7f7;
    border-bottom: 1px solid #dfdfdf;
    text-shadow: #fff 0px 1px 0px;
}

.daext-form-action{
    line-height: 28px;
    height: 28px;
    font-size: 12px;
    color: #333;
    font-weight: 600;
    font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
    padding: 8px 10px;
    text-align: left;
    border-top: 1px solid #dedede;
    background: #f7f7f7;
    text-shadow: #fff 0px 1px 0px;
}

.daext-form-action > input.button{
    -webkit-box-shadow: none !important;
    -moz-box-shadow: none !important;
    box-shadow: none !important;
    color: #555 !important;
    border-color: #cccccc !important;
    background: #f7f7f7;
}

.daext-form-action > input.button:hover{
    background: #fafafa;
    border-color: #979797 !important;
}

table.daext-form{
    border-collapse: collapse;
    background: #fdfdfd;
    width: 100%;
}

table.daext-form > tbody > tr > th {
    width: 260px !important;
}

table.daext-form > tbody > tr > td, table.daext-form > tbody > tr > th{
    padding: 8px;

}

table.daext-form > tbody > tr:not(:last-child) > td, table.daext-form > tbody > tr:not(:last-child) > th{
    border-bottom: 1px solid #e3e3e3;
}


table.daext-form > tbody > tr > th{
    text-align: right;
    padding-right: 8px;
    font-size: 12px;
    color: #555;
    position: relative;
}

table.daext-form > tbody > tr > th > label{
    height: 24px;
    line-height: 24px;
    display: block;
    overflow: hidden;
    position: absolute;
    right: 8px;
    top: 8px;
}

table.daext-form .image-uploader{
    max-width: 280px;
    padding: 8px;
    border: 1px solid #e5e5e5;
    background: #fff;
}

table.daext-form .image-uploader .selected-image{
    width: 100%;
    margin-bottom: 8px;
}

table.daext-form .image-uploader .button_add_media{
    display: block;
    cursor: pointer;
    text-decoration: underline;
}

table.daext-form .image-uploader p.description{
    margin: 0 !important;
    color: #777;
}

table.daext-form input[disabled], table.daext-form select[disabled]{
    color: #ccc !important;
    background: #f7f7f7 !important;
}

/* daext-widget */

.daext-widget *{
    font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
}

.daext-widget h3{
    color: #333;
}

.daext-widget label{
    color: #555;
}

.daext-widget{
    border: 1px solid #dfdfdf;
    margin-bottom: 20px;
}

.daext-widget-title{
    padding: 3px 10px;
    line-height: 28px;
    height: 28px;
    font-size: 12px;
    color: #333;
    font-weight: 600;
    border-bottom: 1px solid #dfdfdf;
    margin: 0;
    background: #f7f7f7;
    text-shadow: #fff 0px 1px 0px;
}

.daext-widget-content{
    padding: 8px 10px;
    background: #fff;
    font-size: 12px;
    background: #fdfdfd;
}

.daext-widget-content > h3{
    font-size: 12px;
    margin: 10px 0;
}

.daext-widget-content > h3:not(:nth-of-type(1)){
    margin-top: 18px;
}

.daext-widget-content > ul{
    margin: 10px 0 0 !important;
}

.daext-widget-content > ul > li{
    margin: 0;
    color: #555;
}

.daext-widget-content textarea{
    font-size: 12px;
    width: 100% !important;
    box-shadow: none;
    border: 1px solid #ddd;
    min-height: 60px;
    color: #999;
    margin: 10px 0 0 !important;
    overflow: auto;
    padding: 2px 6px;
    line-height: 1.4;
    color: #333;
    display: block;
}

.daext-widget-content input[type="text"]{
    display: block;
    margin-bottom: 10px;
    font-size: 12px;
    height: 24px;
    line-height: 16px;
    box-shadow: none;
    padding: 3px 5px;
    color: #333;
    border: 1px solid #ddd;
    width: 70px;
}

.daext-widget-content select{
    display: block;
    margin-bottom: 10px;
    font-size: 12px;
    height: 24px;
    line-height: 16px;
    box-shadow: none;
    padding: 3px 5px;
    color: #333;
    border: 1px solid #ddd;
    width: 140px;
}

.daext-widget-content > p{
    font-size: 12px;
    margin: 10px 0 9px;
    line-height: 18px;
}

.daext-widget-content > p:nth-of-type(6){
    margin-bottom: 14px;
}

.daext-widget-content > .separator{
    height: 10px;
    width: 100%;
}

.daext-widget-content > .separator-line{
    margin: 20px 0;
    border-bottom: 1px solid #f1f1f1;
    width: 100%;
}

.daext-widget-content input[type="checkbox"]{
    border-color: #e5e5e5;
    box-shadow: none;
    border: 1px solid #ddd;
}

.daext-widget-submit{
    background: #fff;
    padding: 8px 10px;
    border-top: 1px solid #dedede;
    background: #f7f7f7;
    padding: 8px 10px;
    line-height: 28px;
    height: 28px;
}

.daext-widget-submit input[type="submit"],
.daext-widget-submit input[type="button"]{
    box-shadow: none;
    font-size: 12px;
}

.daext-widget-content table td{
    padding: 0;
}

.daext-widget-content > table > tbody > tr > td:first-child{
    padding-right: 10px;
}

/* Color Picker adaptation to the interface style */
.wp-picker-container{
    display: inline-block !important;
}

.wp-picker-container > button{
    margin: 0 !important;
    box-shadow: none !important;
}

.wp-picker-container .wp-picker-clear{
    box-shadow: none !important;
}

/* wp-picker-container */
.wp-picker-container .wp-color-result.button{
    height: 24px;
    border-color: #dddddd;
    min-height: auto;
}

.wp-picker-container .wp-color-result.button:hover{
    border-color: #979797 !important;
}

.wp-picker-container .wp-color-result.button:focus{
    border-color: #5b9dd9 !important;
}

.wp-picker-container .wp-color-result-text{
    line-height: 22px;
}

.wp-picker-container .wp-color-result-text:hover{
    background: #fafafa;
}

.wp-picker-container label input[type="text"].wp-color-picker{
    min-height: auto;
    margin-left: 6px !important;
}

.wp-picker-container input[type="button"].button{
    color: #555 !important;
    border-color: #cccccc !important;
    background: #f7f7f7;
    line-height: 22px;
    margin-left: 6px;
}

.wp-picker-container input[type="button"].button:hover{
    background: #fafafa;
    border-color: #979797 !important;
}admin/assets/css/menu-sliding.css000064400000001152151213253530013032 0ustar00table.daext-items .icons-container{
    width: 48px !important;
    min-width: 48px !important;
}

.sidebar-container {
    margin-left: 20px;
    float: right;
    width: 280px;
}

#sliding-news-form-container {
    width: calc(100% - 300px);
    float: left;
}

.daext-form-container {
    width: 100%;
}

table.daext-form .image-uploader .selected-image{
    width: auto !important;
    height: 20px !important;
}

@media all and (max-width: 1322px) {
    #sliding-news-form-container{
        float: none;
    }
    .sidebar-container{
        float: none;
        margin-left: 0;
        margin-top: 19px;
    }
}admin/assets/css/menu-help.css000064400000000110151213253530012322 0ustar00#daext-menu-wrapper li{
    list-style: square;
    margin-left: 16px;
}admin/assets/css/menu-featured.css000064400000000776151213253530013213 0ustar00table.daext-items .icons-container{
    width: 48px !important;
    min-width: 48px !important;
}

.sidebar-container {
    margin-left: 20px;
    float: right;
    width: 280px;
}

#featured-news-form-container {
    width: calc(100% - 300px);
    float: left;
}

.daext-form-container {
    width: 100%;
}

@media all and (max-width: 1322px) {
    #featured-news-form-container{
        float: none;
    }
    .sidebar-container{
        float: none;
        margin-left: 0;
        margin-top: 19px;
    }
}admin/assets/css/jquery-ui-tooltip.css000064400000003313151213253530014062 0ustar00/* general tooltip style ---------------------------------------------------- */
.ui-widget-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}

.ui-tooltip {
    background: #fff;
    padding: 13px 15px;
    position: absolute;
    z-index: 9999;
    max-width: 240px;
    -webkit-box-shadow: 0 3px 6px rgba(0,0,0,.075);
    box-shadow: 0 3px 6px rgba(0,0,0,.075);
    border: 1px solid #dfdfdf;
    font-size: 12px;
    color: #444;
    line-height: 18px;
    font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif !important;
}

body .ui-tooltip {
    border-width: 1px;
}

/* style for the help icon on the table .daext-items th ---------------------- */
table.daext-items > thead > tr > th > div.help-icon{
    background: url("../img/help-f7f7f7.png") 0 0 no-repeat !important;
    width: 20px !important;
    height: 20px !important;
    margin: 4px 0 4px 4px;
    display: inline-block;
}

table.daext-items > thead > tr > th > div:not(.help-icon){
    float: left;
}

table.daext-items > thead > tr > th > div.help-icon{
    float: right;
}

/* style for the .daext-form table td --------------------------------------- */
table.daext-form td > div.help-icon{
    background: url("../img/help-fdfdfd.png") 0 0 no-repeat !important;
    width: 20px !important;
    height: 20px !important;
    float: right;
    margin: 2px 0;
}

/* style for the #daext-options-wrapper td ---------------------------------- */
#daext-options-wrapper td > div.help-icon{
    background: url("../img/help-fdfdfd.png") 0 0 no-repeat !important;
    width: 20px !important;
    height: 20px !important;
    float: right;
    margin: 2px 0;
}


admin/assets/css/menu-pro-version.css000064400000000426151213253540013670 0ustar00#daext-menu-wrapper li{
    list-style: square;
    margin-left: 16px;
}

#daext-menu-wrapper li strong{
    text-decoration: underline;
}

#daext-menu-wrapper a.product-image-link{
    display: inline-block;
    margin: 0;
    width: 540px;
    padding: 0;
    height: 276px;
}admin/assets/css/chosen-custom.css000064400000002206151213253540013230 0ustar00.chosen-container,
.chosen-container-single,
.chosen-container-active,
.chosen-default,
.chosen-drop,
.chosen-single,
.chosen-search,
.chosen-results{
    font-size: 12px !important;
    background: #fff !important;
    border-color: #ddd !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    color: #333 !important;
}

.chosen-container-single .chosen-search input[type=text]{
    min-height: auto;
}

.chosen-container-single .chosen-search input[type=text]:focus{
    outline: none;
    box-shadow: none;
}

.chosen-container .chosen-results li.highlighted{
    background: #0075a5 !important;
    color: #fff !important;
}

.chosen-container-single .chosen-default{
    border-color: #ddd !important;
    height: 24px;
    line-height: 22px !important;
}

.chosen-container-single .chosen-single{
    height: 24px !important;
}

.chosen-container-single .chosen-single span{
    line-height: 22px;
}

.chosen-container .chosen-results{
    max-height: 200px !important;
}

.chosen-container{
    min-width: 217px;
    max-width: 217px;
}

#daext-options-wrapper .chosen-container{
    min-width: 217px;
    max-width: 217px;
}admin/assets/inc/chosen/chosen-sprite@2x.png000064400000001342151213253540015032 0ustar00�PNG


IHDRhJ�q��IDATh�횿o�@�#�P	� �����?!d�ԅ�sft⇿'R�J0�#[���Ɉ��+��������P����{R�W%����ދ��1�e,�J4�h��'�Y�2�Ny�H%?��/�4��
L�j�[��	-�85H�q���H�����qȱ�s���6�C+�%0��`QW�X����O�5��
�]:ڿ��h���Ig���7�oi����
1n� ���f���Hn�'
�!-��
hjh؝l�n��zH���A��oj��Q�FEæ�����hH
'��wԲt�c �8�H۪�/�4��
L�j��`$�8�� q�iD�S %N��9 �J�1Sp̶�;X�k}\kN[�[�t���������k�%��s�F<Uk��}dvǢ�W���b��?�O/n&�
�0p)/��Pyf'��~�|��|+a�C�˒�bKq��SB>��p��3�K�X��R~����C�gY�Ƭ��,�9���A%w;8Q�h�H�,�]n�p��Y��>�$�c
��)�ƒ�K�hw~��S�ʼn�q��P�*�w�Ҷ�����X�y{$���u�%�&�Z����'������(�8�؜��֜�b��ҍ၊�5R6�emP�0�<�F�-F��
i��#�	��z�H�|��Y��JZ�\N��IEND�B`�admin/assets/inc/chosen/LICENSE.md000064400000002277151213253540012603 0ustar00#### Chosen
- by Patrick Filler for [Harvest](http://getharvest.com)
- Copyright (c) 2011-2014 by Harvest

Available for use under the [MIT License](http://en.wikipedia.org/wiki/MIT_License)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
admin/assets/inc/chosen/chosen-sprite.png000064400000001032151213253540014454 0ustar00�PNG


IHDR4%��^�IDATH�헱kSQƯ
.-����=�$�b�o�$((T�Hw��*����"nupA�@ P�Apq�J$p!P��M1��.�����;���=��\D�.Y�n0��@}�DMF���>Fb��1���
�c�	!6�1r��b�%G���I��J(v��fFy�O����H4B c�1�}��^��4��5Fo��G�X�ٝv�U�n�(�R�s�p����v��*��8sP���*�c�O�TQWŬ���j1Q�H}����T��+���}��֕d�/���L�Lc�F�6�˔�7��,9ʼ1IkJ�(�dJj��Lc�^��z*"Hu�j)�׿���,?<��._1�a�������°x�	/b�}�T!�����i?O�u�	oc\������eN��c:�99�\@�s� uZ���q��|yp�k�a�����6��B|���1��G����gq�u����p�+���[�*y���IEND�B`�admin/assets/inc/chosen/chosen.js000064400000124073151213253540013013 0ustar00/*!
Chosen, a Select Box Enhancer for jQuery and Prototype
by Patrick Filler for Harvest, http://getharvest.com

Version 1.2.0
Full source at https://github.com/harvesthq/chosen
Copyright (c) 2011-2014 Harvest http://getharvest.com

MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
This file is generated by `grunt build`, do not edit it by hand.
*/

(function() {
  var $, AbstractChosen, Chosen, SelectParser, _ref,
    __hasProp = {}.hasOwnProperty,
    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };

  SelectParser = (function() {
    function SelectParser() {
      this.options_index = 0;
      this.parsed = [];
    }

    SelectParser.prototype.add_node = function(child) {
      if (child.nodeName.toUpperCase() === "OPTGROUP") {
        return this.add_group(child);
      } else {
        return this.add_option(child);
      }
    };

    SelectParser.prototype.add_group = function(group) {
      var group_position, option, _i, _len, _ref, _results;
      group_position = this.parsed.length;
      this.parsed.push({
        array_index: group_position,
        group: true,
        label: this.escapeExpression(group.label),
        children: 0,
        disabled: group.disabled
      });
      _ref = group.childNodes;
      _results = [];
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        option = _ref[_i];
        _results.push(this.add_option(option, group_position, group.disabled));
      }
      return _results;
    };

    SelectParser.prototype.add_option = function(option, group_position, group_disabled) {
      if (option.nodeName.toUpperCase() === "OPTION") {
        if (option.text !== "") {
          if (group_position != null) {
            this.parsed[group_position].children += 1;
          }
          this.parsed.push({
            array_index: this.parsed.length,
            options_index: this.options_index,
            value: option.value,
            text: option.text,
            html: option.innerHTML,
            selected: option.selected,
            disabled: group_disabled === true ? group_disabled : option.disabled,
            group_array_index: group_position,
            classes: option.className,
            style: option.style.cssText
          });
        } else {
          this.parsed.push({
            array_index: this.parsed.length,
            options_index: this.options_index,
            empty: true
          });
        }
        return this.options_index += 1;
      }
    };

    SelectParser.prototype.escapeExpression = function(text) {
      var map, unsafe_chars;
      if ((text == null) || text === false) {
        return "";
      }
      if (!/[\&\<\>\"\'\`]/.test(text)) {
        return text;
      }
      map = {
        "<": "&lt;",
        ">": "&gt;",
        '"': "&quot;",
        "'": "&#x27;",
        "`": "&#x60;"
      };
      unsafe_chars = /&(?!\w+;)|[\<\>\"\'\`]/g;
      return text.replace(unsafe_chars, function(chr) {
        return map[chr] || "&amp;";
      });
    };

    return SelectParser;

  })();

  SelectParser.select_to_array = function(select) {
    var child, parser, _i, _len, _ref;
    parser = new SelectParser();
    _ref = select.childNodes;
    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
      child = _ref[_i];
      parser.add_node(child);
    }
    return parser.parsed;
  };

  AbstractChosen = (function() {
    function AbstractChosen(form_field, options) {
      this.form_field = form_field;
      this.options = options != null ? options : {};
      if (!AbstractChosen.browser_is_supported()) {
        return;
      }
      this.is_multiple = this.form_field.multiple;
      this.set_default_text();
      this.set_default_values();
      this.setup();
      this.set_up_html();
      this.register_observers();
    }

    AbstractChosen.prototype.set_default_values = function() {
      var _this = this;
      this.click_test_action = function(evt) {
        return _this.test_active_click(evt);
      };
      this.activate_action = function(evt) {
        return _this.activate_field(evt);
      };
      this.active_field = false;
      this.mouse_on_container = false;
      this.results_showing = false;
      this.result_highlighted = null;
      this.allow_single_deselect = (this.options.allow_single_deselect != null) && (this.form_field.options[0] != null) && this.form_field.options[0].text === "" ? this.options.allow_single_deselect : false;
      this.disable_search_threshold = this.options.disable_search_threshold || 0;
      this.disable_search = this.options.disable_search || false;
      this.enable_split_word_search = this.options.enable_split_word_search != null ? this.options.enable_split_word_search : true;
      this.group_search = this.options.group_search != null ? this.options.group_search : true;
      this.search_contains = this.options.search_contains || false;
      this.single_backstroke_delete = this.options.single_backstroke_delete != null ? this.options.single_backstroke_delete : true;
      this.max_selected_options = this.options.max_selected_options || Infinity;
      this.inherit_select_classes = this.options.inherit_select_classes || false;
      this.display_selected_options = this.options.display_selected_options != null ? this.options.display_selected_options : true;
      return this.display_disabled_options = this.options.display_disabled_options != null ? this.options.display_disabled_options : true;
    };

    AbstractChosen.prototype.set_default_text = function() {
      if (this.form_field.getAttribute("data-placeholder")) {
        this.default_text = this.form_field.getAttribute("data-placeholder");
      } else if (this.is_multiple) {
        this.default_text = this.options.placeholder_text_multiple || this.options.placeholder_text || AbstractChosen.default_multiple_text;
      } else {
        this.default_text = this.options.placeholder_text_single || this.options.placeholder_text || AbstractChosen.default_single_text;
      }
      return this.results_none_found = this.form_field.getAttribute("data-no_results_text") || this.options.no_results_text || AbstractChosen.default_no_result_text;
    };

    AbstractChosen.prototype.mouse_enter = function() {
      return this.mouse_on_container = true;
    };

    AbstractChosen.prototype.mouse_leave = function() {
      return this.mouse_on_container = false;
    };

    AbstractChosen.prototype.input_focus = function(evt) {
      var _this = this;
      if (this.is_multiple) {
        if (!this.active_field) {
          return setTimeout((function() {
            return _this.container_mousedown();
          }), 50);
        }
      } else {
        if (!this.active_field) {
          return this.activate_field();
        }
      }
    };

    AbstractChosen.prototype.input_blur = function(evt) {
      var _this = this;
      if (!this.mouse_on_container) {
        this.active_field = false;
        return setTimeout((function() {
          return _this.blur_test();
        }), 100);
      }
    };

    AbstractChosen.prototype.results_option_build = function(options) {
      var content, data, _i, _len, _ref;
      content = '';
      _ref = this.results_data;
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        data = _ref[_i];
        if (data.group) {
          content += this.result_add_group(data);
        } else {
          content += this.result_add_option(data);
        }
        if (options != null ? options.first : void 0) {
          if (data.selected && this.is_multiple) {
            this.choice_build(data);
          } else if (data.selected && !this.is_multiple) {
            this.single_set_selected_text(data.text);
          }
        }
      }
      return content;
    };

    AbstractChosen.prototype.result_add_option = function(option) {
      var classes, option_el;
      if (!option.search_match) {
        return '';
      }
      if (!this.include_option_in_results(option)) {
        return '';
      }
      classes = [];
      if (!option.disabled && !(option.selected && this.is_multiple)) {
        classes.push("active-result");
      }
      if (option.disabled && !(option.selected && this.is_multiple)) {
        classes.push("disabled-result");
      }
      if (option.selected) {
        classes.push("result-selected");
      }
      if (option.group_array_index != null) {
        classes.push("group-option");
      }
      if (option.classes !== "") {
        classes.push(option.classes);
      }
      option_el = document.createElement("li");
      option_el.className = classes.join(" ");
      option_el.style.cssText = option.style;
      option_el.setAttribute("data-option-array-index", option.array_index);
      option_el.innerHTML = option.search_text;
      return this.outerHTML(option_el);
    };

    AbstractChosen.prototype.result_add_group = function(group) {
      var group_el;
      if (!(group.search_match || group.group_match)) {
        return '';
      }
      if (!(group.active_options > 0)) {
        return '';
      }
      group_el = document.createElement("li");
      group_el.className = "group-result";
      group_el.innerHTML = group.search_text;
      return this.outerHTML(group_el);
    };

    AbstractChosen.prototype.results_update_field = function() {
      this.set_default_text();
      if (!this.is_multiple) {
        this.results_reset_cleanup();
      }
      this.result_clear_highlight();
      this.results_build();
      if (this.results_showing) {
        return this.winnow_results();
      }
    };

    AbstractChosen.prototype.reset_single_select_options = function() {
      var result, _i, _len, _ref, _results;
      _ref = this.results_data;
      _results = [];
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        result = _ref[_i];
        if (result.selected) {
          _results.push(result.selected = false);
        } else {
          _results.push(void 0);
        }
      }
      return _results;
    };

    AbstractChosen.prototype.results_toggle = function() {
      if (this.results_showing) {
        return this.results_hide();
      } else {
        return this.results_show();
      }
    };

    AbstractChosen.prototype.results_search = function(evt) {
      if (this.results_showing) {
        return this.winnow_results();
      } else {
        return this.results_show();
      }
    };

    AbstractChosen.prototype.winnow_results = function() {
      var escapedSearchText, option, regex, results, results_group, searchText, startpos, text, zregex, _i, _len, _ref;
      this.no_results_clear();
      results = 0;
      searchText = this.get_search_text();
      escapedSearchText = searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
      zregex = new RegExp(escapedSearchText, 'i');
      regex = this.get_search_regex(escapedSearchText);
      _ref = this.results_data;
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        option = _ref[_i];
        option.search_match = false;
        results_group = null;
        if (this.include_option_in_results(option)) {
          if (option.group) {
            option.group_match = false;
            option.active_options = 0;
          }
          if ((option.group_array_index != null) && this.results_data[option.group_array_index]) {
            results_group = this.results_data[option.group_array_index];
            if (results_group.active_options === 0 && results_group.search_match) {
              results += 1;
            }
            results_group.active_options += 1;
          }
          if (!(option.group && !this.group_search)) {
            option.search_text = option.group ? option.label : option.text;
            option.search_match = this.search_string_match(option.search_text, regex);
            if (option.search_match && !option.group) {
              results += 1;
            }
            if (option.search_match) {
              if (searchText.length) {
                startpos = option.search_text.search(zregex);
                text = option.search_text.substr(0, startpos + searchText.length) + '</em>' + option.search_text.substr(startpos + searchText.length);
                option.search_text = text.substr(0, startpos) + '<em>' + text.substr(startpos);
              }
              if (results_group != null) {
                results_group.group_match = true;
              }
            } else if ((option.group_array_index != null) && this.results_data[option.group_array_index].search_match) {
              option.search_match = true;
            }
          }
        }
      }
      this.result_clear_highlight();
      if (results < 1 && searchText.length) {
        this.update_results_content("");
        return this.no_results(searchText);
      } else {
        this.update_results_content(this.results_option_build());
        return this.winnow_results_set_highlight();
      }
    };

    AbstractChosen.prototype.get_search_regex = function(escaped_search_string) {
      var regex_anchor;
      regex_anchor = this.search_contains ? "" : "^";
      return new RegExp(regex_anchor + escaped_search_string, 'i');
    };

    AbstractChosen.prototype.search_string_match = function(search_string, regex) {
      var part, parts, _i, _len;
      if (regex.test(search_string)) {
        return true;
      } else if (this.enable_split_word_search && (search_string.indexOf(" ") >= 0 || search_string.indexOf("[") === 0)) {
        parts = search_string.replace(/\[|\]/g, "").split(" ");
        if (parts.length) {
          for (_i = 0, _len = parts.length; _i < _len; _i++) {
            part = parts[_i];
            if (regex.test(part)) {
              return true;
            }
          }
        }
      }
    };

    AbstractChosen.prototype.choices_count = function() {
      var option, _i, _len, _ref;
      if (this.selected_option_count != null) {
        return this.selected_option_count;
      }
      this.selected_option_count = 0;
      _ref = this.form_field.options;
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        option = _ref[_i];
        if (option.selected) {
          this.selected_option_count += 1;
        }
      }
      return this.selected_option_count;
    };

    AbstractChosen.prototype.choices_click = function(evt) {
      evt.preventDefault();
      if (!(this.results_showing || this.is_disabled)) {
        return this.results_show();
      }
    };

    AbstractChosen.prototype.keyup_checker = function(evt) {
      var stroke, _ref;
      stroke = (_ref = evt.which) != null ? _ref : evt.keyCode;
      this.search_field_scale();
      switch (stroke) {
        case 8:
          if (this.is_multiple && this.backstroke_length < 1 && this.choices_count() > 0) {
            return this.keydown_backstroke();
          } else if (!this.pending_backstroke) {
            this.result_clear_highlight();
            return this.results_search();
          }
          break;
        case 13:
          evt.preventDefault();
          if (this.results_showing) {
            return this.result_select(evt);
          }
          break;
        case 27:
          if (this.results_showing) {
            this.results_hide();
          }
          return true;
        case 9:
        case 38:
        case 40:
        case 16:
        case 91:
        case 17:
          break;
        default:
          return this.results_search();
      }
    };

    AbstractChosen.prototype.clipboard_event_checker = function(evt) {
      var _this = this;
      return setTimeout((function() {
        return _this.results_search();
      }), 50);
    };

    AbstractChosen.prototype.container_width = function() {
      if (this.options.width != null) {
        return this.options.width;
      } else {
        return "" + this.form_field.offsetWidth + "px";
      }
    };

    AbstractChosen.prototype.include_option_in_results = function(option) {
      if (this.is_multiple && (!this.display_selected_options && option.selected)) {
        return false;
      }
      if (!this.display_disabled_options && option.disabled) {
        return false;
      }
      if (option.empty) {
        return false;
      }
      return true;
    };

    AbstractChosen.prototype.search_results_touchstart = function(evt) {
      this.touch_started = true;
      return this.search_results_mouseover(evt);
    };

    AbstractChosen.prototype.search_results_touchmove = function(evt) {
      this.touch_started = false;
      return this.search_results_mouseout(evt);
    };

    AbstractChosen.prototype.search_results_touchend = function(evt) {
      if (this.touch_started) {
        return this.search_results_mouseup(evt);
      }
    };

    AbstractChosen.prototype.outerHTML = function(element) {
      var tmp;
      if (element.outerHTML) {
        return element.outerHTML;
      }
      tmp = document.createElement("div");
      tmp.appendChild(element);
      return tmp.innerHTML;
    };

    AbstractChosen.browser_is_supported = function() {
      if (window.navigator.appName === "Microsoft Internet Explorer") {
        return document.documentMode >= 8;
      }
      if (/iP(od|hone)/i.test(window.navigator.userAgent)) {
        return false;
      }
      if (/Android/i.test(window.navigator.userAgent)) {
        if (/Mobile/i.test(window.navigator.userAgent)) {
          return false;
        }
      }
      return true;
    };

    AbstractChosen.default_multiple_text = "Select Some Options";

    AbstractChosen.default_single_text = "Select an Option";

    AbstractChosen.default_no_result_text = "No results match";

    return AbstractChosen;

  })();

  $ = jQuery;

  $.fn.extend({
    chosen: function(options) {
      if (!AbstractChosen.browser_is_supported()) {
        return this;
      }
      return this.each(function(input_field) {
        var $this, chosen;
        $this = $(this);
        chosen = $this.data('chosen');
        if (options === 'destroy' && chosen instanceof Chosen) {
          chosen.destroy();
        } else if (!(chosen instanceof Chosen)) {
          $this.data('chosen', new Chosen(this, options));
        }
      });
    }
  });

  Chosen = (function(_super) {
    __extends(Chosen, _super);

    function Chosen() {
      _ref = Chosen.__super__.constructor.apply(this, arguments);
      return _ref;
    }

    Chosen.prototype.setup = function() {
      this.form_field_jq = $(this.form_field);
      this.current_selectedIndex = this.form_field.selectedIndex;
      return this.is_rtl = this.form_field_jq.hasClass("chosen-rtl");
    };

    Chosen.prototype.set_up_html = function() {
      var container_classes, container_props;
      container_classes = ["chosen-container"];
      container_classes.push("chosen-container-" + (this.is_multiple ? "multi" : "single"));
      if (this.inherit_select_classes && this.form_field.className) {
        container_classes.push(this.form_field.className);
      }
      if (this.is_rtl) {
        container_classes.push("chosen-rtl");
      }
      container_props = {
        'class': container_classes.join(' '),
        'style': "width: " + (this.container_width()) + ";",
        'title': this.form_field.title
      };
      if (this.form_field.id.length) {
        container_props.id = this.form_field.id.replace(/[^\w]/g, '_') + "_chosen";
      }
      this.container = $("<div />", container_props);
      if (this.is_multiple) {
        this.container.html('<ul class="chosen-choices"><li class="search-field"><input type="text" value="' + this.default_text + '" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chosen-drop"><ul class="chosen-results"></ul></div>');
      } else {
        this.container.html('<a class="chosen-single chosen-default" tabindex="-1"><span>' + this.default_text + '</span><div><b></b></div></a><div class="chosen-drop"><div class="chosen-search"><input type="text" autocomplete="off" /></div><ul class="chosen-results"></ul></div>');
      }
      this.form_field_jq.hide().after(this.container);
      this.dropdown = this.container.find('div.chosen-drop').first();
      this.search_field = this.container.find('input').first();
      this.search_results = this.container.find('ul.chosen-results').first();
      this.search_field_scale();
      this.search_no_results = this.container.find('li.no-results').first();
      if (this.is_multiple) {
        this.search_choices = this.container.find('ul.chosen-choices').first();
        this.search_container = this.container.find('li.search-field').first();
      } else {
        this.search_container = this.container.find('div.chosen-search').first();
        this.selected_item = this.container.find('.chosen-single').first();
      }
      this.results_build();
      this.set_tab_index();
      this.set_label_behavior();
      return this.form_field_jq.trigger("chosen:ready", {
        chosen: this
      });
    };

    Chosen.prototype.register_observers = function() {
      var _this = this;
      this.container.bind('touchstart.chosen', function(evt) {
        _this.container_mousedown(evt);
      });
      this.container.bind('touchend.chosen', function(evt) {
        _this.container_mouseup(evt);
      });
      this.container.bind('mousedown.chosen', function(evt) {
        _this.container_mousedown(evt);
      });
      this.container.bind('mouseup.chosen', function(evt) {
        _this.container_mouseup(evt);
      });
      this.container.bind('mouseenter.chosen', function(evt) {
        _this.mouse_enter(evt);
      });
      this.container.bind('mouseleave.chosen', function(evt) {
        _this.mouse_leave(evt);
      });
      this.search_results.bind('mouseup.chosen', function(evt) {
        _this.search_results_mouseup(evt);
      });
      this.search_results.bind('mouseover.chosen', function(evt) {
        _this.search_results_mouseover(evt);
      });
      this.search_results.bind('mouseout.chosen', function(evt) {
        _this.search_results_mouseout(evt);
      });
      this.search_results.bind('mousewheel.chosen DOMMouseScroll.chosen', function(evt) {
        _this.search_results_mousewheel(evt);
      });
      this.search_results.bind('touchstart.chosen', function(evt) {
        _this.search_results_touchstart(evt);
      });
      this.search_results.bind('touchmove.chosen', function(evt) {
        _this.search_results_touchmove(evt);
      });
      this.search_results.bind('touchend.chosen', function(evt) {
        _this.search_results_touchend(evt);
      });
      this.form_field_jq.bind("chosen:updated.chosen", function(evt) {
        _this.results_update_field(evt);
      });
      this.form_field_jq.bind("chosen:activate.chosen", function(evt) {
        _this.activate_field(evt);
      });
      this.form_field_jq.bind("chosen:open.chosen", function(evt) {
        _this.container_mousedown(evt);
      });
      this.form_field_jq.bind("chosen:close.chosen", function(evt) {
        _this.input_blur(evt);
      });
      this.search_field.bind('blur.chosen', function(evt) {
        _this.input_blur(evt);
      });
      this.search_field.bind('keyup.chosen', function(evt) {
        _this.keyup_checker(evt);
      });
      this.search_field.bind('keydown.chosen', function(evt) {
        _this.keydown_checker(evt);
      });
      this.search_field.bind('focus.chosen', function(evt) {
        _this.input_focus(evt);
      });
      this.search_field.bind('cut.chosen', function(evt) {
        _this.clipboard_event_checker(evt);
      });
      this.search_field.bind('paste.chosen', function(evt) {
        _this.clipboard_event_checker(evt);
      });
      if (this.is_multiple) {
        return this.search_choices.bind('click.chosen', function(evt) {
          _this.choices_click(evt);
        });
      } else {
        return this.container.bind('click.chosen', function(evt) {
          evt.preventDefault();
        });
      }
    };

    Chosen.prototype.destroy = function() {
      $(this.container[0].ownerDocument).unbind("click.chosen", this.click_test_action);
      if (this.search_field[0].tabIndex) {
        this.form_field_jq[0].tabIndex = this.search_field[0].tabIndex;
      }
      this.container.remove();
      this.form_field_jq.removeData('chosen');
      return this.form_field_jq.show();
    };

    Chosen.prototype.search_field_disabled = function() {
      this.is_disabled = this.form_field_jq[0].disabled;
      if (this.is_disabled) {
        this.container.addClass('chosen-disabled');
        this.search_field[0].disabled = true;
        if (!this.is_multiple) {
          this.selected_item.unbind("focus.chosen", this.activate_action);
        }
        return this.close_field();
      } else {
        this.container.removeClass('chosen-disabled');
        this.search_field[0].disabled = false;
        if (!this.is_multiple) {
          return this.selected_item.bind("focus.chosen", this.activate_action);
        }
      }
    };

    Chosen.prototype.container_mousedown = function(evt) {
      if (!this.is_disabled) {
        if (evt && evt.type === "mousedown" && !this.results_showing) {
          evt.preventDefault();
        }
        if (!((evt != null) && ($(evt.target)).hasClass("search-choice-close"))) {
          if (!this.active_field) {
            if (this.is_multiple) {
              this.search_field.val("");
            }
            $(this.container[0].ownerDocument).bind('click.chosen', this.click_test_action);
            this.results_show();
          } else if (!this.is_multiple && evt && (($(evt.target)[0] === this.selected_item[0]) || $(evt.target).parents("a.chosen-single").length)) {
            evt.preventDefault();
            this.results_toggle();
          }
          return this.activate_field();
        }
      }
    };

    Chosen.prototype.container_mouseup = function(evt) {
      if (evt.target.nodeName === "ABBR" && !this.is_disabled) {
        return this.results_reset(evt);
      }
    };

    Chosen.prototype.search_results_mousewheel = function(evt) {
      var delta;
      if (evt.originalEvent) {
        delta = evt.originalEvent.deltaY || -evt.originalEvent.wheelDelta || evt.originalEvent.detail;
      }
      if (delta != null) {
        evt.preventDefault();
        if (evt.type === 'DOMMouseScroll') {
          delta = delta * 40;
        }
        return this.search_results.scrollTop(delta + this.search_results.scrollTop());
      }
    };

    Chosen.prototype.blur_test = function(evt) {
      if (!this.active_field && this.container.hasClass("chosen-container-active")) {
        return this.close_field();
      }
    };

    Chosen.prototype.close_field = function() {
      $(this.container[0].ownerDocument).unbind("click.chosen", this.click_test_action);
      this.active_field = false;
      this.results_hide();
      this.container.removeClass("chosen-container-active");
      this.clear_backstroke();
      this.show_search_field_default();
      return this.search_field_scale();
    };

    Chosen.prototype.activate_field = function() {
      this.container.addClass("chosen-container-active");
      this.active_field = true;
      this.search_field.val(this.search_field.val());
      return this.search_field.focus();
    };

    Chosen.prototype.test_active_click = function(evt) {
      var active_container;
      active_container = $(evt.target).closest('.chosen-container');
      if (active_container.length && this.container[0] === active_container[0]) {
        return this.active_field = true;
      } else {
        return this.close_field();
      }
    };

    Chosen.prototype.results_build = function() {
      this.parsing = true;
      this.selected_option_count = null;
      this.results_data = SelectParser.select_to_array(this.form_field);
      if (this.is_multiple) {
        this.search_choices.find("li.search-choice").remove();
      } else if (!this.is_multiple) {
        this.single_set_selected_text();
        if (this.disable_search || this.form_field.options.length <= this.disable_search_threshold) {
          this.search_field[0].readOnly = true;
          this.container.addClass("chosen-container-single-nosearch");
        } else {
          this.search_field[0].readOnly = false;
          this.container.removeClass("chosen-container-single-nosearch");
        }
      }
      this.update_results_content(this.results_option_build({
        first: true
      }));
      this.search_field_disabled();
      this.show_search_field_default();
      this.search_field_scale();
      return this.parsing = false;
    };

    Chosen.prototype.result_do_highlight = function(el) {
      var high_bottom, high_top, maxHeight, visible_bottom, visible_top;
      if (el.length) {
        this.result_clear_highlight();
        this.result_highlight = el;
        this.result_highlight.addClass("highlighted");
        maxHeight = parseInt(this.search_results.css("maxHeight"), 10);
        visible_top = this.search_results.scrollTop();
        visible_bottom = maxHeight + visible_top;
        high_top = this.result_highlight.position().top + this.search_results.scrollTop();
        high_bottom = high_top + this.result_highlight.outerHeight();
        if (high_bottom >= visible_bottom) {
          return this.search_results.scrollTop((high_bottom - maxHeight) > 0 ? high_bottom - maxHeight : 0);
        } else if (high_top < visible_top) {
          return this.search_results.scrollTop(high_top);
        }
      }
    };

    Chosen.prototype.result_clear_highlight = function() {
      if (this.result_highlight) {
        this.result_highlight.removeClass("highlighted");
      }
      return this.result_highlight = null;
    };

    Chosen.prototype.results_show = function() {
      if (this.is_multiple && this.max_selected_options <= this.choices_count()) {
        this.form_field_jq.trigger("chosen:maxselected", {
          chosen: this
        });
        return false;
      }
      this.container.addClass("chosen-with-drop");
      this.results_showing = true;
      this.search_field.focus();
      this.search_field.val(this.search_field.val());
      this.winnow_results();
      return this.form_field_jq.trigger("chosen:showing_dropdown", {
        chosen: this
      });
    };

    Chosen.prototype.update_results_content = function(content) {
      return this.search_results.html(content);
    };

    Chosen.prototype.results_hide = function() {
      if (this.results_showing) {
        this.result_clear_highlight();
        this.container.removeClass("chosen-with-drop");
        this.form_field_jq.trigger("chosen:hiding_dropdown", {
          chosen: this
        });
      }
      return this.results_showing = false;
    };

    Chosen.prototype.set_tab_index = function(el) {
      var ti;
      if (this.form_field.tabIndex) {
        ti = this.form_field.tabIndex;
        this.form_field.tabIndex = -1;
        return this.search_field[0].tabIndex = ti;
      }
    };

    Chosen.prototype.set_label_behavior = function() {
      var _this = this;
      this.form_field_label = this.form_field_jq.parents("label");
      if (!this.form_field_label.length && this.form_field.id.length) {
        this.form_field_label = $("label[for='" + this.form_field.id + "']");
      }
      if (this.form_field_label.length > 0) {
        return this.form_field_label.bind('click.chosen', function(evt) {
          if (_this.is_multiple) {
            return _this.container_mousedown(evt);
          } else {
            return _this.activate_field();
          }
        });
      }
    };

    Chosen.prototype.show_search_field_default = function() {
      if (this.is_multiple && this.choices_count() < 1 && !this.active_field) {
        this.search_field.val(this.default_text);
        return this.search_field.addClass("default");
      } else {
        this.search_field.val("");
        return this.search_field.removeClass("default");
      }
    };

    Chosen.prototype.search_results_mouseup = function(evt) {
      var target;
      target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first();
      if (target.length) {
        this.result_highlight = target;
        this.result_select(evt);
        return this.search_field.focus();
      }
    };

    Chosen.prototype.search_results_mouseover = function(evt) {
      var target;
      target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first();
      if (target) {
        return this.result_do_highlight(target);
      }
    };

    Chosen.prototype.search_results_mouseout = function(evt) {
      if ($(evt.target).hasClass("active-result" || $(evt.target).parents('.active-result').first())) {
        return this.result_clear_highlight();
      }
    };

    Chosen.prototype.choice_build = function(item) {
      var choice, close_link,
        _this = this;
      choice = $('<li />', {
        "class": "search-choice"
      }).html("<span>" + item.html + "</span>");
      if (item.disabled) {
        choice.addClass('search-choice-disabled');
      } else {
        close_link = $('<a />', {
          "class": 'search-choice-close',
          'data-option-array-index': item.array_index
        });
        close_link.bind('click.chosen', function(evt) {
          return _this.choice_destroy_link_click(evt);
        });
        choice.append(close_link);
      }
      return this.search_container.before(choice);
    };

    Chosen.prototype.choice_destroy_link_click = function(evt) {
      evt.preventDefault();
      evt.stopPropagation();
      if (!this.is_disabled) {
        return this.choice_destroy($(evt.target));
      }
    };

    Chosen.prototype.choice_destroy = function(link) {
      if (this.result_deselect(link[0].getAttribute("data-option-array-index"))) {
        this.show_search_field_default();
        if (this.is_multiple && this.choices_count() > 0 && this.search_field.val().length < 1) {
          this.results_hide();
        }
        link.parents('li').first().remove();
        return this.search_field_scale();
      }
    };

    Chosen.prototype.results_reset = function() {
      this.reset_single_select_options();
      this.form_field.options[0].selected = true;
      this.single_set_selected_text();
      this.show_search_field_default();
      this.results_reset_cleanup();
      this.form_field_jq.trigger("change");
      if (this.active_field) {
        return this.results_hide();
      }
    };

    Chosen.prototype.results_reset_cleanup = function() {
      this.current_selectedIndex = this.form_field.selectedIndex;
      return this.selected_item.find("abbr").remove();
    };

    Chosen.prototype.result_select = function(evt) {
      var high, item;
      if (this.result_highlight) {
        high = this.result_highlight;
        this.result_clear_highlight();
        if (this.is_multiple && this.max_selected_options <= this.choices_count()) {
          this.form_field_jq.trigger("chosen:maxselected", {
            chosen: this
          });
          return false;
        }
        if (this.is_multiple) {
          high.removeClass("active-result");
        } else {
          this.reset_single_select_options();
        }
        item = this.results_data[high[0].getAttribute("data-option-array-index")];
        item.selected = true;
        this.form_field.options[item.options_index].selected = true;
        this.selected_option_count = null;
        if (this.is_multiple) {
          this.choice_build(item);
        } else {
          this.single_set_selected_text(item.text);
        }
        if (!((evt.metaKey || evt.ctrlKey) && this.is_multiple)) {
          this.results_hide();
        }
        this.search_field.val("");
        if (this.is_multiple || this.form_field.selectedIndex !== this.current_selectedIndex) {
          this.form_field_jq.trigger("change", {
            'selected': this.form_field.options[item.options_index].value
          });
        }
        this.current_selectedIndex = this.form_field.selectedIndex;
        return this.search_field_scale();
      }
    };

    Chosen.prototype.single_set_selected_text = function(text) {
      if (text == null) {
        text = this.default_text;
      }
      if (text === this.default_text) {
        this.selected_item.addClass("chosen-default");
      } else {
        this.single_deselect_control_build();
        this.selected_item.removeClass("chosen-default");
      }
      return this.selected_item.find("span").text(text);
    };

    Chosen.prototype.result_deselect = function(pos) {
      var result_data;
      result_data = this.results_data[pos];
      if (!this.form_field.options[result_data.options_index].disabled) {
        result_data.selected = false;
        this.form_field.options[result_data.options_index].selected = false;
        this.selected_option_count = null;
        this.result_clear_highlight();
        if (this.results_showing) {
          this.winnow_results();
        }
        this.form_field_jq.trigger("change", {
          deselected: this.form_field.options[result_data.options_index].value
        });
        this.search_field_scale();
        return true;
      } else {
        return false;
      }
    };

    Chosen.prototype.single_deselect_control_build = function() {
      if (!this.allow_single_deselect) {
        return;
      }
      if (!this.selected_item.find("abbr").length) {
        this.selected_item.find("span").first().after("<abbr class=\"search-choice-close\"></abbr>");
      }
      return this.selected_item.addClass("chosen-single-with-deselect");
    };

    Chosen.prototype.get_search_text = function() {
      if (this.search_field.val() === this.default_text) {
        return "";
      } else {
        return $('<div/>').text($.trim(this.search_field.val())).html();
      }
    };

    Chosen.prototype.winnow_results_set_highlight = function() {
      var do_high, selected_results;
      selected_results = !this.is_multiple ? this.search_results.find(".result-selected.active-result") : [];
      do_high = selected_results.length ? selected_results.first() : this.search_results.find(".active-result").first();
      if (do_high != null) {
        return this.result_do_highlight(do_high);
      }
    };

    Chosen.prototype.no_results = function(terms) {
      var no_results_html;
      no_results_html = $('<li class="no-results">' + this.results_none_found + ' "<span></span>"</li>');
      no_results_html.find("span").first().html(terms);
      this.search_results.append(no_results_html);
      return this.form_field_jq.trigger("chosen:no_results", {
        chosen: this
      });
    };

    Chosen.prototype.no_results_clear = function() {
      return this.search_results.find(".no-results").remove();
    };

    Chosen.prototype.keydown_arrow = function() {
      var next_sib;
      if (this.results_showing && this.result_highlight) {
        next_sib = this.result_highlight.nextAll("li.active-result").first();
        if (next_sib) {
          return this.result_do_highlight(next_sib);
        }
      } else {
        return this.results_show();
      }
    };

    Chosen.prototype.keyup_arrow = function() {
      var prev_sibs;
      if (!this.results_showing && !this.is_multiple) {
        return this.results_show();
      } else if (this.result_highlight) {
        prev_sibs = this.result_highlight.prevAll("li.active-result");
        if (prev_sibs.length) {
          return this.result_do_highlight(prev_sibs.first());
        } else {
          if (this.choices_count() > 0) {
            this.results_hide();
          }
          return this.result_clear_highlight();
        }
      }
    };

    Chosen.prototype.keydown_backstroke = function() {
      var next_available_destroy;
      if (this.pending_backstroke) {
        this.choice_destroy(this.pending_backstroke.find("a").first());
        return this.clear_backstroke();
      } else {
        next_available_destroy = this.search_container.siblings("li.search-choice").last();
        if (next_available_destroy.length && !next_available_destroy.hasClass("search-choice-disabled")) {
          this.pending_backstroke = next_available_destroy;
          if (this.single_backstroke_delete) {
            return this.keydown_backstroke();
          } else {
            return this.pending_backstroke.addClass("search-choice-focus");
          }
        }
      }
    };

    Chosen.prototype.clear_backstroke = function() {
      if (this.pending_backstroke) {
        this.pending_backstroke.removeClass("search-choice-focus");
      }
      return this.pending_backstroke = null;
    };

    Chosen.prototype.keydown_checker = function(evt) {
      var stroke, _ref1;
      stroke = (_ref1 = evt.which) != null ? _ref1 : evt.keyCode;
      this.search_field_scale();
      if (stroke !== 8 && this.pending_backstroke) {
        this.clear_backstroke();
      }
      switch (stroke) {
        case 8:
          this.backstroke_length = this.search_field.val().length;
          break;
        case 9:
          if (this.results_showing && !this.is_multiple) {
            this.result_select(evt);
          }
          this.mouse_on_container = false;
          break;
        case 13:
          if (this.results_showing) {
            evt.preventDefault();
          }
          break;
        case 32:
          if (this.disable_search) {
            evt.preventDefault();
          }
          break;
        case 38:
          evt.preventDefault();
          this.keyup_arrow();
          break;
        case 40:
          evt.preventDefault();
          this.keydown_arrow();
          break;
      }
    };

    Chosen.prototype.search_field_scale = function() {
      var div, f_width, h, style, style_block, styles, w, _i, _len;
      if (this.is_multiple) {
        h = 0;
        w = 0;
        style_block = "position:absolute; left: -1000px; top: -1000px; display:none;";
        styles = ['font-size', 'font-style', 'font-weight', 'font-family', 'line-height', 'text-transform', 'letter-spacing'];
        for (_i = 0, _len = styles.length; _i < _len; _i++) {
          style = styles[_i];
          style_block += style + ":" + this.search_field.css(style) + ";";
        }
        div = $('<div />', {
          'style': style_block
        });
        div.text(this.search_field.val());
        $('body').append(div);
        w = div.width() + 25;
        div.remove();
        f_width = this.container.outerWidth();
        if (w > f_width - 10) {
          w = f_width - 10;
        }
        return this.search_field.css({
          'width': w + 'px'
        });
      }
    };

    return Chosen;

  })(AbstractChosen);

}).call(this);
admin/assets/inc/chosen/chosen.css000064400000031177151213253540013171 0ustar00/*!
Chosen, a Select Box Enhancer for jQuery and Prototype
by Patrick Filler for Harvest, http://getharvest.com

Version 1.2.0
Full source at https://github.com/harvesthq/chosen
Copyright (c) 2011-2014 Harvest http://getharvest.com

MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
This file is generated by `grunt build`, do not edit it by hand.
*/

/* @group Base */
.chosen-container {
  position: relative;
  display: inline-block;
  vertical-align: middle;
  font-size: 13px;
  zoom: 1;
  *display: inline;
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;
}
.chosen-container * {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}
.chosen-container .chosen-drop {
  position: absolute;
  top: 100%;
  left: -9999px;
  z-index: 1010;
  width: 100%;
  border: 1px solid #aaa;
  border-top: 0;
  background: #fff;
  box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15);
}
.chosen-container.chosen-with-drop .chosen-drop {
  left: 0;
}
.chosen-container a {
  cursor: pointer;
}

/* @end */
/* @group Single Chosen */
.chosen-container-single .chosen-single {
  position: relative;
  display: block;
  overflow: hidden;
  padding: 0 0 0 8px;
  height: 25px;
  border: 1px solid #aaa;
  border-radius: 5px;
  background-color: #fff;
  background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #ffffff), color-stop(50%, #f6f6f6), color-stop(52%, #eeeeee), color-stop(100%, #f4f4f4));
  background: -webkit-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
  background: -moz-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
  background: -o-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
  background: linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
  background-clip: padding-box;
  box-shadow: 0 0 3px white inset, 0 1px 1px rgba(0, 0, 0, 0.1);
  color: #444;
  text-decoration: none;
  white-space: nowrap;
  line-height: 24px;
}
.chosen-container-single .chosen-default {
  color: #999;
}
.chosen-container-single .chosen-single span {
  display: block;
  overflow: hidden;
  margin-right: 26px;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.chosen-container-single .chosen-single-with-deselect span {
  margin-right: 38px;
}
.chosen-container-single .chosen-single abbr {
  position: absolute;
  top: 6px;
  right: 26px;
  display: block;
  width: 12px;
  height: 12px;
  background: url('chosen-sprite.png') -42px 1px no-repeat;
  font-size: 1px;
}
.chosen-container-single .chosen-single abbr:hover {
  background-position: -42px -10px;
}
.chosen-container-single.chosen-disabled .chosen-single abbr:hover {
  background-position: -42px -10px;
}
.chosen-container-single .chosen-single div {
  position: absolute;
  top: 0;
  right: 0;
  display: block;
  width: 18px;
  height: 100%;
}
.chosen-container-single .chosen-single div b {
  display: block;
  width: 100%;
  height: 100%;
  background: url('chosen-sprite.png') no-repeat 0px 2px;
}
.chosen-container-single .chosen-search {
  position: relative;
  z-index: 1010;
  margin: 0;
  padding: 3px 4px;
  white-space: nowrap;
}
.chosen-container-single .chosen-search input[type="text"] {
  margin: 1px 0;
  padding: 4px 20px 4px 5px;
  width: 100%;
  height: auto;
  outline: 0;
  border: 1px solid #aaa;
  background: white url('chosen-sprite.png') no-repeat 100% -20px;
  background: url('chosen-sprite.png') no-repeat 100% -20px;
  font-size: 1em;
  font-family: sans-serif;
  line-height: normal;
  border-radius: 0;
}
.chosen-container-single .chosen-drop {
  margin-top: -1px;
  border-radius: 0 0 4px 4px;
  background-clip: padding-box;
}
.chosen-container-single.chosen-container-single-nosearch .chosen-search {
  position: absolute;
  left: -9999px;
}

/* @end */
/* @group Results */
.chosen-container .chosen-results {
  color: #444;
  position: relative;
  overflow-x: hidden;
  overflow-y: auto;
  margin: 0 4px 4px 0;
  padding: 0 0 0 4px;
  max-height: 240px;
  -webkit-overflow-scrolling: touch;
}
.chosen-container .chosen-results li {
  display: none;
  margin: 0;
  padding: 5px 6px;
  list-style: none;
  line-height: 15px;
  word-wrap: break-word;
  -webkit-touch-callout: none;
}
.chosen-container .chosen-results li.active-result {
  display: list-item;
  cursor: pointer;
}
.chosen-container .chosen-results li.disabled-result {
  display: list-item;
  color: #ccc;
  cursor: default;
}
.chosen-container .chosen-results li.highlighted {
  background-color: #3875d7;
  background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #3875d7), color-stop(90%, #2a62bc));
  background-image: -webkit-linear-gradient(#3875d7 20%, #2a62bc 90%);
  background-image: -moz-linear-gradient(#3875d7 20%, #2a62bc 90%);
  background-image: -o-linear-gradient(#3875d7 20%, #2a62bc 90%);
  background-image: linear-gradient(#3875d7 20%, #2a62bc 90%);
  color: #fff;
}
.chosen-container .chosen-results li.no-results {
  color: #777;
  display: list-item;
  background: #f4f4f4;
}
.chosen-container .chosen-results li.group-result {
  display: list-item;
  font-weight: bold;
  cursor: default;
}
.chosen-container .chosen-results li.group-option {
  padding-left: 15px;
}
.chosen-container .chosen-results li em {
  font-style: normal;
  text-decoration: underline;
}

/* @end */
/* @group Multi Chosen */
.chosen-container-multi .chosen-choices {
  position: relative;
  overflow: hidden;
  margin: 0;
  padding: 0 5px;
  width: 100%;
  height: auto !important;
  height: 1%;
  border: 1px solid #aaa;
  background-color: #fff;
  background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
  background-image: -webkit-linear-gradient(#eeeeee 1%, #ffffff 15%);
  background-image: -moz-linear-gradient(#eeeeee 1%, #ffffff 15%);
  background-image: -o-linear-gradient(#eeeeee 1%, #ffffff 15%);
  background-image: linear-gradient(#eeeeee 1%, #ffffff 15%);
  cursor: text;
}
.chosen-container-multi .chosen-choices li {
  float: left;
  list-style: none;
}
.chosen-container-multi .chosen-choices li.search-field {
  margin: 0;
  padding: 0;
  white-space: nowrap;
}
.chosen-container-multi .chosen-choices li.search-field input[type="text"] {
  margin: 1px 0;
  padding: 0;
  height: 25px;
  outline: 0;
  border: 0 !important;
  background: transparent !important;
  box-shadow: none;
  color: #999;
  font-size: 100%;
  font-family: sans-serif;
  line-height: normal;
  border-radius: 0;
}
.chosen-container-multi .chosen-choices li.search-choice {
  position: relative;
  margin: 3px 5px 3px 0;
  padding: 3px 20px 3px 5px;
  border: 1px solid #aaa;
  max-width: 100%;
  border-radius: 3px;
  background-color: #eeeeee;
  background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
  background-image: -webkit-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
  background-image: -moz-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
  background-image: -o-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
  background-image: linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
  background-size: 100% 19px;
  background-repeat: repeat-x;
  background-clip: padding-box;
  box-shadow: 0 0 2px white inset, 0 1px 0 rgba(0, 0, 0, 0.05);
  color: #333;
  line-height: 13px;
  cursor: default;
}
.chosen-container-multi .chosen-choices li.search-choice span {
  word-wrap: break-word;
}
.chosen-container-multi .chosen-choices li.search-choice .search-choice-close {
  position: absolute;
  top: 4px;
  right: 3px;
  display: block;
  width: 12px;
  height: 12px;
  background: url('chosen-sprite.png') -42px 1px no-repeat;
  font-size: 1px;
}
.chosen-container-multi .chosen-choices li.search-choice .search-choice-close:hover {
  background-position: -42px -10px;
}
.chosen-container-multi .chosen-choices li.search-choice-disabled {
  padding-right: 5px;
  border: 1px solid #ccc;
  background-color: #e4e4e4;
  background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
  background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
  background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
  background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
  background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
  color: #666;
}
.chosen-container-multi .chosen-choices li.search-choice-focus {
  background: #d4d4d4;
}
.chosen-container-multi .chosen-choices li.search-choice-focus .search-choice-close {
  background-position: -42px -10px;
}
.chosen-container-multi .chosen-results {
  margin: 0;
  padding: 0;
}
.chosen-container-multi .chosen-drop .result-selected {
  display: list-item;
  color: #ccc;
  cursor: default;
}

/* @end */
/* @group Active  */
.chosen-container-active .chosen-single {
  border: 1px solid #5897fb;
  box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
}
.chosen-container-active.chosen-with-drop .chosen-single {
  border: 1px solid #aaa;
  -moz-border-radius-bottomright: 0;
  border-bottom-right-radius: 0;
  -moz-border-radius-bottomleft: 0;
  border-bottom-left-radius: 0;
  background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #eeeeee), color-stop(80%, #ffffff));
  background-image: -webkit-linear-gradient(#eeeeee 20%, #ffffff 80%);
  background-image: -moz-linear-gradient(#eeeeee 20%, #ffffff 80%);
  background-image: -o-linear-gradient(#eeeeee 20%, #ffffff 80%);
  background-image: linear-gradient(#eeeeee 20%, #ffffff 80%);
  box-shadow: 0 1px 0 #fff inset;
}
.chosen-container-active.chosen-with-drop .chosen-single div {
  border-left: none;
  background: transparent;
}
.chosen-container-active.chosen-with-drop .chosen-single div b {
  background-position: -18px 2px;
}
.chosen-container-active .chosen-choices {
  border: 1px solid #5897fb;
  box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
}
.chosen-container-active .chosen-choices li.search-field input[type="text"] {
  color: #222 !important;
}

/* @end */
/* @group Disabled Support */
.chosen-disabled {
  opacity: 0.5 !important;
  cursor: default;
}
.chosen-disabled .chosen-single {
  cursor: default;
}
.chosen-disabled .chosen-choices .search-choice .search-choice-close {
  cursor: default;
}

/* @end */
/* @group Right to Left */
.chosen-rtl {
  text-align: right;
}
.chosen-rtl .chosen-single {
  overflow: visible;
  padding: 0 8px 0 0;
}
.chosen-rtl .chosen-single span {
  margin-right: 0;
  margin-left: 26px;
  direction: rtl;
}
.chosen-rtl .chosen-single-with-deselect span {
  margin-left: 38px;
}
.chosen-rtl .chosen-single div {
  right: auto;
  left: 3px;
}
.chosen-rtl .chosen-single abbr {
  right: auto;
  left: 26px;
}
.chosen-rtl .chosen-choices li {
  float: right;
}
.chosen-rtl .chosen-choices li.search-field input[type="text"] {
  direction: rtl;
}
.chosen-rtl .chosen-choices li.search-choice {
  margin: 3px 5px 3px 0;
  padding: 3px 5px 3px 19px;
}
.chosen-rtl .chosen-choices li.search-choice .search-choice-close {
  right: auto;
  left: 4px;
}
.chosen-rtl.chosen-container-single-nosearch .chosen-search,
.chosen-rtl .chosen-drop {
  left: 9999px;
}
.chosen-rtl.chosen-container-single .chosen-results {
  margin: 0 0 4px 4px;
  padding: 0 4px 0 0;
}
.chosen-rtl .chosen-results li.group-option {
  padding-right: 15px;
  padding-left: 0;
}
.chosen-rtl.chosen-container-active.chosen-with-drop .chosen-single div {
  border-right: none;
}
.chosen-rtl .chosen-search input[type="text"] {
  padding: 4px 5px 4px 20px;
  background: white url('chosen-sprite.png') no-repeat -30px -20px;
  background: url('chosen-sprite.png') no-repeat -30px -20px;
  direction: rtl;
}
.chosen-rtl.chosen-container-single .chosen-single div b {
  background-position: 6px 2px;
}
.chosen-rtl.chosen-container-single.chosen-with-drop .chosen-single div b {
  background-position: -12px 2px;
}

/* @end */
/* @group Retina compatibility */
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-resolution: 144dpi) {
  .chosen-rtl .chosen-search input[type="text"],
  .chosen-container-single .chosen-single abbr,
  .chosen-container-single .chosen-single div b,
  .chosen-container-single .chosen-search input[type="text"],
  .chosen-container-multi .chosen-choices .search-choice .search-choice-close,
  .chosen-container .chosen-results-scroll-down span,
  .chosen-container .chosen-results-scroll-up span {
    background-image: url('chosen-sprite@2x.png') !important;
    background-size: 52px 37px !important;
    background-repeat: no-repeat !important;
  }
}
/* @end */
admin/assets/inc/chosen/chosen-min.css000064400000024751151213253540013752 0ustar00/* Chosen v1.2.0 | (c) 2011-2014 by Harvest | MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md */
.chosen-container{position:relative;display:inline-block;vertical-align:middle;font-size:13px;zoom:1;*display:inline;-webkit-user-select:none;-moz-user-select:none;user-select:none}.chosen-container *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.chosen-container .chosen-drop{position:absolute;top:100%;left:-9999px;z-index:1010;width:100%;border:1px solid #aaa;border-top:0;background:#fff;box-shadow:0 4px 5px rgba(0,0,0,.15)}.chosen-container.chosen-with-drop .chosen-drop{left:0}.chosen-container a{cursor:pointer}.chosen-container-single .chosen-single{position:relative;display:block;overflow:hidden;padding:0 0 0 8px;height:25px;border:1px solid #aaa;border-radius:5px;background-color:#fff;background:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#fff),color-stop(50%,#f6f6f6),color-stop(52%,#eee),color-stop(100%,#f4f4f4));background:-webkit-linear-gradient(top,#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background:-moz-linear-gradient(top,#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background:-o-linear-gradient(top,#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background:linear-gradient(top,#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background-clip:padding-box;box-shadow:0 0 3px #fff inset,0 1px 1px rgba(0,0,0,.1);color:#444;text-decoration:none;white-space:nowrap;line-height:24px}.chosen-container-single .chosen-default{color:#999}.chosen-container-single .chosen-single span{display:block;overflow:hidden;margin-right:26px;text-overflow:ellipsis;white-space:nowrap}.chosen-container-single .chosen-single-with-deselect span{margin-right:38px}.chosen-container-single .chosen-single abbr{position:absolute;top:6px;right:26px;display:block;width:12px;height:12px;background:url(chosen-sprite.png) -42px 1px no-repeat;font-size:1px}.chosen-container-single .chosen-single abbr:hover{background-position:-42px -10px}.chosen-container-single.chosen-disabled .chosen-single abbr:hover{background-position:-42px -10px}.chosen-container-single .chosen-single div{position:absolute;top:0;right:0;display:block;width:18px;height:100%}.chosen-container-single .chosen-single div b{display:block;width:100%;height:100%;background:url(chosen-sprite.png) no-repeat 0 2px}.chosen-container-single .chosen-search{position:relative;z-index:1010;margin:0;padding:3px 4px;white-space:nowrap}.chosen-container-single .chosen-search input[type=text]{margin:1px 0;padding:4px 20px 4px 5px;width:100%;height:auto;outline:0;border:1px solid #aaa;background:#fff url(chosen-sprite.png) no-repeat 100% -20px;background:url(chosen-sprite.png) no-repeat 100% -20px;font-size:1em;font-family:sans-serif;line-height:normal;border-radius:0}.chosen-container-single .chosen-drop{margin-top:-1px;border-radius:0 0 4px 4px;background-clip:padding-box}.chosen-container-single.chosen-container-single-nosearch .chosen-search{position:absolute;left:-9999px}.chosen-container .chosen-results{color:#444;position:relative;overflow-x:hidden;overflow-y:auto;margin:0 4px 4px 0;padding:0 0 0 4px;max-height:240px;-webkit-overflow-scrolling:touch}.chosen-container .chosen-results li{display:none;margin:0;padding:5px 6px;list-style:none;line-height:15px;word-wrap:break-word;-webkit-touch-callout:none}.chosen-container .chosen-results li.active-result{display:list-item;cursor:pointer}.chosen-container .chosen-results li.disabled-result{display:list-item;color:#ccc;cursor:default}.chosen-container .chosen-results li.highlighted{background-color:#3875d7;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#3875d7),color-stop(90%,#2a62bc));background-image:-webkit-linear-gradient(#3875d7 20%,#2a62bc 90%);background-image:-moz-linear-gradient(#3875d7 20%,#2a62bc 90%);background-image:-o-linear-gradient(#3875d7 20%,#2a62bc 90%);background-image:linear-gradient(#3875d7 20%,#2a62bc 90%);color:#fff}.chosen-container .chosen-results li.no-results{color:#777;display:list-item;background:#f4f4f4}.chosen-container .chosen-results li.group-result{display:list-item;font-weight:700;cursor:default}.chosen-container .chosen-results li.group-option{padding-left:15px}.chosen-container .chosen-results li em{font-style:normal;text-decoration:underline}.chosen-container-multi .chosen-choices{position:relative;overflow:hidden;margin:0;padding:0 5px;width:100%;height:auto!important;height:1%;border:1px solid #aaa;background-color:#fff;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(1%,#eee),color-stop(15%,#fff));background-image:-webkit-linear-gradient(#eee 1%,#fff 15%);background-image:-moz-linear-gradient(#eee 1%,#fff 15%);background-image:-o-linear-gradient(#eee 1%,#fff 15%);background-image:linear-gradient(#eee 1%,#fff 15%);cursor:text}.chosen-container-multi .chosen-choices li{float:left;list-style:none}.chosen-container-multi .chosen-choices li.search-field{margin:0;padding:0;white-space:nowrap}.chosen-container-multi .chosen-choices li.search-field input[type=text]{margin:1px 0;padding:0;height:25px;outline:0;border:0!important;background:transparent!important;box-shadow:none;color:#999;font-size:100%;font-family:sans-serif;line-height:normal;border-radius:0}.chosen-container-multi .chosen-choices li.search-choice{position:relative;margin:3px 5px 3px 0;padding:3px 20px 3px 5px;border:1px solid #aaa;max-width:100%;border-radius:3px;background-color:#eee;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#f4f4f4),color-stop(50%,#f0f0f0),color-stop(52%,#e8e8e8),color-stop(100%,#eee));background-image:-webkit-linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-moz-linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-o-linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-size:100% 19px;background-repeat:repeat-x;background-clip:padding-box;box-shadow:0 0 2px #fff inset,0 1px 0 rgba(0,0,0,.05);color:#333;line-height:13px;cursor:default}.chosen-container-multi .chosen-choices li.search-choice span{word-wrap:break-word}.chosen-container-multi .chosen-choices li.search-choice .search-choice-close{position:absolute;top:4px;right:3px;display:block;width:12px;height:12px;background:url(chosen-sprite.png) -42px 1px no-repeat;font-size:1px}.chosen-container-multi .chosen-choices li.search-choice .search-choice-close:hover{background-position:-42px -10px}.chosen-container-multi .chosen-choices li.search-choice-disabled{padding-right:5px;border:1px solid #ccc;background-color:#e4e4e4;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#f4f4f4),color-stop(50%,#f0f0f0),color-stop(52%,#e8e8e8),color-stop(100%,#eee));background-image:-webkit-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-moz-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-o-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);color:#666}.chosen-container-multi .chosen-choices li.search-choice-focus{background:#d4d4d4}.chosen-container-multi .chosen-choices li.search-choice-focus .search-choice-close{background-position:-42px -10px}.chosen-container-multi .chosen-results{margin:0;padding:0}.chosen-container-multi .chosen-drop .result-selected{display:list-item;color:#ccc;cursor:default}.chosen-container-active .chosen-single{border:1px solid #5897fb;box-shadow:0 0 5px rgba(0,0,0,.3)}.chosen-container-active.chosen-with-drop .chosen-single{border:1px solid #aaa;-moz-border-radius-bottomright:0;border-bottom-right-radius:0;-moz-border-radius-bottomleft:0;border-bottom-left-radius:0;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#eee),color-stop(80%,#fff));background-image:-webkit-linear-gradient(#eee 20%,#fff 80%);background-image:-moz-linear-gradient(#eee 20%,#fff 80%);background-image:-o-linear-gradient(#eee 20%,#fff 80%);background-image:linear-gradient(#eee 20%,#fff 80%);box-shadow:0 1px 0 #fff inset}.chosen-container-active.chosen-with-drop .chosen-single div{border-left:0;background:transparent}.chosen-container-active.chosen-with-drop .chosen-single div b{background-position:-18px 2px}.chosen-container-active .chosen-choices{border:1px solid #5897fb;box-shadow:0 0 5px rgba(0,0,0,.3)}.chosen-container-active .chosen-choices li.search-field input[type=text]{color:#222!important}.chosen-disabled{opacity:.5!important;cursor:default}.chosen-disabled .chosen-single{cursor:default}.chosen-disabled .chosen-choices .search-choice .search-choice-close{cursor:default}.chosen-rtl{text-align:right}.chosen-rtl .chosen-single{overflow:visible;padding:0 8px 0 0}.chosen-rtl .chosen-single span{margin-right:0;margin-left:26px;direction:rtl}.chosen-rtl .chosen-single-with-deselect span{margin-left:38px}.chosen-rtl .chosen-single div{right:auto;left:3px}.chosen-rtl .chosen-single abbr{right:auto;left:26px}.chosen-rtl .chosen-choices li{float:right}.chosen-rtl .chosen-choices li.search-field input[type=text]{direction:rtl}.chosen-rtl .chosen-choices li.search-choice{margin:3px 5px 3px 0;padding:3px 5px 3px 19px}.chosen-rtl .chosen-choices li.search-choice .search-choice-close{right:auto;left:4px}.chosen-rtl.chosen-container-single-nosearch .chosen-search,.chosen-rtl .chosen-drop{left:9999px}.chosen-rtl.chosen-container-single .chosen-results{margin:0 0 4px 4px;padding:0 4px 0 0}.chosen-rtl .chosen-results li.group-option{padding-right:15px;padding-left:0}.chosen-rtl.chosen-container-active.chosen-with-drop .chosen-single div{border-right:0}.chosen-rtl .chosen-search input[type=text]{padding:4px 5px 4px 20px;background:#fff url(chosen-sprite.png) no-repeat -30px -20px;background:url(chosen-sprite.png) no-repeat -30px -20px;direction:rtl}.chosen-rtl.chosen-container-single .chosen-single div b{background-position:6px 2px}.chosen-rtl.chosen-container-single.chosen-with-drop .chosen-single div b{background-position:-12px 2px}@media only screen and (-webkit-min-device-pixel-ratio:2),only screen and (min-resolution:144dpi){.chosen-rtl .chosen-search input[type=text],.chosen-container-single .chosen-single abbr,.chosen-container-single .chosen-single div b,.chosen-container-single .chosen-search input[type=text],.chosen-container-multi .chosen-choices .search-choice .search-choice-close,.chosen-container .chosen-results-scroll-down span,.chosen-container .chosen-results-scroll-up span{background-image:url(chosen-sprite@2x.png)!important;background-size:52px 37px!important;background-repeat:no-repeat!important}}admin/assets/inc/chosen/chosen-min.js000064400000065323151213253540013576 0ustar00/* Chosen v1.2.0 | (c) 2011-2014 by Harvest | MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md */
!function(){var a,AbstractChosen,Chosen,SelectParser,b,c={}.hasOwnProperty,d=function(a,b){function d(){this.constructor=a}for(var e in b)c.call(b,e)&&(a[e]=b[e]);return d.prototype=b.prototype,a.prototype=new d,a.__super__=b.prototype,a};SelectParser=function(){function SelectParser(){this.options_index=0,this.parsed=[]}return SelectParser.prototype.add_node=function(a){return"OPTGROUP"===a.nodeName.toUpperCase()?this.add_group(a):this.add_option(a)},SelectParser.prototype.add_group=function(a){var b,c,d,e,f,g;for(b=this.parsed.length,this.parsed.push({array_index:b,group:!0,label:this.escapeExpression(a.label),children:0,disabled:a.disabled}),f=a.childNodes,g=[],d=0,e=f.length;e>d;d++)c=f[d],g.push(this.add_option(c,b,a.disabled));return g},SelectParser.prototype.add_option=function(a,b,c){return"OPTION"===a.nodeName.toUpperCase()?(""!==a.text?(null!=b&&(this.parsed[b].children+=1),this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,value:a.value,text:a.text,html:a.innerHTML,selected:a.selected,disabled:c===!0?c:a.disabled,group_array_index:b,classes:a.className,style:a.style.cssText})):this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,empty:!0}),this.options_index+=1):void 0},SelectParser.prototype.escapeExpression=function(a){var b,c;return null==a||a===!1?"":/[\&\<\>\"\'\`]/.test(a)?(b={"<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","`":"&#x60;"},c=/&(?!\w+;)|[\<\>\"\'\`]/g,a.replace(c,function(a){return b[a]||"&amp;"})):a},SelectParser}(),SelectParser.select_to_array=function(a){var b,c,d,e,f;for(c=new SelectParser,f=a.childNodes,d=0,e=f.length;e>d;d++)b=f[d],c.add_node(b);return c.parsed},AbstractChosen=function(){function AbstractChosen(a,b){this.form_field=a,this.options=null!=b?b:{},AbstractChosen.browser_is_supported()&&(this.is_multiple=this.form_field.multiple,this.set_default_text(),this.set_default_values(),this.setup(),this.set_up_html(),this.register_observers())}return AbstractChosen.prototype.set_default_values=function(){var a=this;return this.click_test_action=function(b){return a.test_active_click(b)},this.activate_action=function(b){return a.activate_field(b)},this.active_field=!1,this.mouse_on_container=!1,this.results_showing=!1,this.result_highlighted=null,this.allow_single_deselect=null!=this.options.allow_single_deselect&&null!=this.form_field.options[0]&&""===this.form_field.options[0].text?this.options.allow_single_deselect:!1,this.disable_search_threshold=this.options.disable_search_threshold||0,this.disable_search=this.options.disable_search||!1,this.enable_split_word_search=null!=this.options.enable_split_word_search?this.options.enable_split_word_search:!0,this.group_search=null!=this.options.group_search?this.options.group_search:!0,this.search_contains=this.options.search_contains||!1,this.single_backstroke_delete=null!=this.options.single_backstroke_delete?this.options.single_backstroke_delete:!0,this.max_selected_options=this.options.max_selected_options||1/0,this.inherit_select_classes=this.options.inherit_select_classes||!1,this.display_selected_options=null!=this.options.display_selected_options?this.options.display_selected_options:!0,this.display_disabled_options=null!=this.options.display_disabled_options?this.options.display_disabled_options:!0},AbstractChosen.prototype.set_default_text=function(){return this.default_text=this.form_field.getAttribute("data-placeholder")?this.form_field.getAttribute("data-placeholder"):this.is_multiple?this.options.placeholder_text_multiple||this.options.placeholder_text||AbstractChosen.default_multiple_text:this.options.placeholder_text_single||this.options.placeholder_text||AbstractChosen.default_single_text,this.results_none_found=this.form_field.getAttribute("data-no_results_text")||this.options.no_results_text||AbstractChosen.default_no_result_text},AbstractChosen.prototype.mouse_enter=function(){return this.mouse_on_container=!0},AbstractChosen.prototype.mouse_leave=function(){return this.mouse_on_container=!1},AbstractChosen.prototype.input_focus=function(){var a=this;if(this.is_multiple){if(!this.active_field)return setTimeout(function(){return a.container_mousedown()},50)}else if(!this.active_field)return this.activate_field()},AbstractChosen.prototype.input_blur=function(){var a=this;return this.mouse_on_container?void 0:(this.active_field=!1,setTimeout(function(){return a.blur_test()},100))},AbstractChosen.prototype.results_option_build=function(a){var b,c,d,e,f;for(b="",f=this.results_data,d=0,e=f.length;e>d;d++)c=f[d],b+=c.group?this.result_add_group(c):this.result_add_option(c),(null!=a?a.first:void 0)&&(c.selected&&this.is_multiple?this.choice_build(c):c.selected&&!this.is_multiple&&this.single_set_selected_text(c.text));return b},AbstractChosen.prototype.result_add_option=function(a){var b,c;return a.search_match?this.include_option_in_results(a)?(b=[],a.disabled||a.selected&&this.is_multiple||b.push("active-result"),!a.disabled||a.selected&&this.is_multiple||b.push("disabled-result"),a.selected&&b.push("result-selected"),null!=a.group_array_index&&b.push("group-option"),""!==a.classes&&b.push(a.classes),c=document.createElement("li"),c.className=b.join(" "),c.style.cssText=a.style,c.setAttribute("data-option-array-index",a.array_index),c.innerHTML=a.search_text,this.outerHTML(c)):"":""},AbstractChosen.prototype.result_add_group=function(a){var b;return a.search_match||a.group_match?a.active_options>0?(b=document.createElement("li"),b.className="group-result",b.innerHTML=a.search_text,this.outerHTML(b)):"":""},AbstractChosen.prototype.results_update_field=function(){return this.set_default_text(),this.is_multiple||this.results_reset_cleanup(),this.result_clear_highlight(),this.results_build(),this.results_showing?this.winnow_results():void 0},AbstractChosen.prototype.reset_single_select_options=function(){var a,b,c,d,e;for(d=this.results_data,e=[],b=0,c=d.length;c>b;b++)a=d[b],a.selected?e.push(a.selected=!1):e.push(void 0);return e},AbstractChosen.prototype.results_toggle=function(){return this.results_showing?this.results_hide():this.results_show()},AbstractChosen.prototype.results_search=function(){return this.results_showing?this.winnow_results():this.results_show()},AbstractChosen.prototype.winnow_results=function(){var a,b,c,d,e,f,g,h,i,j,k,l;for(this.no_results_clear(),d=0,f=this.get_search_text(),a=f.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),i=new RegExp(a,"i"),c=this.get_search_regex(a),l=this.results_data,j=0,k=l.length;k>j;j++)b=l[j],b.search_match=!1,e=null,this.include_option_in_results(b)&&(b.group&&(b.group_match=!1,b.active_options=0),null!=b.group_array_index&&this.results_data[b.group_array_index]&&(e=this.results_data[b.group_array_index],0===e.active_options&&e.search_match&&(d+=1),e.active_options+=1),(!b.group||this.group_search)&&(b.search_text=b.group?b.label:b.text,b.search_match=this.search_string_match(b.search_text,c),b.search_match&&!b.group&&(d+=1),b.search_match?(f.length&&(g=b.search_text.search(i),h=b.search_text.substr(0,g+f.length)+"</em>"+b.search_text.substr(g+f.length),b.search_text=h.substr(0,g)+"<em>"+h.substr(g)),null!=e&&(e.group_match=!0)):null!=b.group_array_index&&this.results_data[b.group_array_index].search_match&&(b.search_match=!0)));return this.result_clear_highlight(),1>d&&f.length?(this.update_results_content(""),this.no_results(f)):(this.update_results_content(this.results_option_build()),this.winnow_results_set_highlight())},AbstractChosen.prototype.get_search_regex=function(a){var b;return b=this.search_contains?"":"^",new RegExp(b+a,"i")},AbstractChosen.prototype.search_string_match=function(a,b){var c,d,e,f;if(b.test(a))return!0;if(this.enable_split_word_search&&(a.indexOf(" ")>=0||0===a.indexOf("["))&&(d=a.replace(/\[|\]/g,"").split(" "),d.length))for(e=0,f=d.length;f>e;e++)if(c=d[e],b.test(c))return!0},AbstractChosen.prototype.choices_count=function(){var a,b,c,d;if(null!=this.selected_option_count)return this.selected_option_count;for(this.selected_option_count=0,d=this.form_field.options,b=0,c=d.length;c>b;b++)a=d[b],a.selected&&(this.selected_option_count+=1);return this.selected_option_count},AbstractChosen.prototype.choices_click=function(a){return a.preventDefault(),this.results_showing||this.is_disabled?void 0:this.results_show()},AbstractChosen.prototype.keyup_checker=function(a){var b,c;switch(b=null!=(c=a.which)?c:a.keyCode,this.search_field_scale(),b){case 8:if(this.is_multiple&&this.backstroke_length<1&&this.choices_count()>0)return this.keydown_backstroke();if(!this.pending_backstroke)return this.result_clear_highlight(),this.results_search();break;case 13:if(a.preventDefault(),this.results_showing)return this.result_select(a);break;case 27:return this.results_showing&&this.results_hide(),!0;case 9:case 38:case 40:case 16:case 91:case 17:break;default:return this.results_search()}},AbstractChosen.prototype.clipboard_event_checker=function(){var a=this;return setTimeout(function(){return a.results_search()},50)},AbstractChosen.prototype.container_width=function(){return null!=this.options.width?this.options.width:""+this.form_field.offsetWidth+"px"},AbstractChosen.prototype.include_option_in_results=function(a){return this.is_multiple&&!this.display_selected_options&&a.selected?!1:!this.display_disabled_options&&a.disabled?!1:a.empty?!1:!0},AbstractChosen.prototype.search_results_touchstart=function(a){return this.touch_started=!0,this.search_results_mouseover(a)},AbstractChosen.prototype.search_results_touchmove=function(a){return this.touch_started=!1,this.search_results_mouseout(a)},AbstractChosen.prototype.search_results_touchend=function(a){return this.touch_started?this.search_results_mouseup(a):void 0},AbstractChosen.prototype.outerHTML=function(a){var b;return a.outerHTML?a.outerHTML:(b=document.createElement("div"),b.appendChild(a),b.innerHTML)},AbstractChosen.browser_is_supported=function(){return"Microsoft Internet Explorer"===window.navigator.appName?document.documentMode>=8:/iP(od|hone)/i.test(window.navigator.userAgent)?!1:/Android/i.test(window.navigator.userAgent)&&/Mobile/i.test(window.navigator.userAgent)?!1:!0},AbstractChosen.default_multiple_text="Select Some Options",AbstractChosen.default_single_text="Select an Option",AbstractChosen.default_no_result_text="No results match",AbstractChosen}(),a=jQuery,a.fn.extend({chosen:function(b){return AbstractChosen.browser_is_supported()?this.each(function(){var c,d;c=a(this),d=c.data("chosen"),"destroy"===b&&d instanceof Chosen?d.destroy():d instanceof Chosen||c.data("chosen",new Chosen(this,b))}):this}}),Chosen=function(c){function Chosen(){return b=Chosen.__super__.constructor.apply(this,arguments)}return d(Chosen,c),Chosen.prototype.setup=function(){return this.form_field_jq=a(this.form_field),this.current_selectedIndex=this.form_field.selectedIndex,this.is_rtl=this.form_field_jq.hasClass("chosen-rtl")},Chosen.prototype.set_up_html=function(){var b,c;return b=["chosen-container"],b.push("chosen-container-"+(this.is_multiple?"multi":"single")),this.inherit_select_classes&&this.form_field.className&&b.push(this.form_field.className),this.is_rtl&&b.push("chosen-rtl"),c={"class":b.join(" "),style:"width: "+this.container_width()+";",title:this.form_field.title},this.form_field.id.length&&(c.id=this.form_field.id.replace(/[^\w]/g,"_")+"_chosen"),this.container=a("<div />",c),this.is_multiple?this.container.html('<ul class="chosen-choices"><li class="search-field"><input type="text" value="'+this.default_text+'" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chosen-drop"><ul class="chosen-results"></ul></div>'):this.container.html('<a class="chosen-single chosen-default" tabindex="-1"><span>'+this.default_text+'</span><div><b></b></div></a><div class="chosen-drop"><div class="chosen-search"><input type="text" autocomplete="off" /></div><ul class="chosen-results"></ul></div>'),this.form_field_jq.hide().after(this.container),this.dropdown=this.container.find("div.chosen-drop").first(),this.search_field=this.container.find("input").first(),this.search_results=this.container.find("ul.chosen-results").first(),this.search_field_scale(),this.search_no_results=this.container.find("li.no-results").first(),this.is_multiple?(this.search_choices=this.container.find("ul.chosen-choices").first(),this.search_container=this.container.find("li.search-field").first()):(this.search_container=this.container.find("div.chosen-search").first(),this.selected_item=this.container.find(".chosen-single").first()),this.results_build(),this.set_tab_index(),this.set_label_behavior(),this.form_field_jq.trigger("chosen:ready",{chosen:this})},Chosen.prototype.register_observers=function(){var a=this;return this.container.bind("touchstart.chosen",function(b){a.container_mousedown(b)}),this.container.bind("touchend.chosen",function(b){a.container_mouseup(b)}),this.container.bind("mousedown.chosen",function(b){a.container_mousedown(b)}),this.container.bind("mouseup.chosen",function(b){a.container_mouseup(b)}),this.container.bind("mouseenter.chosen",function(b){a.mouse_enter(b)}),this.container.bind("mouseleave.chosen",function(b){a.mouse_leave(b)}),this.search_results.bind("mouseup.chosen",function(b){a.search_results_mouseup(b)}),this.search_results.bind("mouseover.chosen",function(b){a.search_results_mouseover(b)}),this.search_results.bind("mouseout.chosen",function(b){a.search_results_mouseout(b)}),this.search_results.bind("mousewheel.chosen DOMMouseScroll.chosen",function(b){a.search_results_mousewheel(b)}),this.search_results.bind("touchstart.chosen",function(b){a.search_results_touchstart(b)}),this.search_results.bind("touchmove.chosen",function(b){a.search_results_touchmove(b)}),this.search_results.bind("touchend.chosen",function(b){a.search_results_touchend(b)}),this.form_field_jq.bind("chosen:updated.chosen",function(b){a.results_update_field(b)}),this.form_field_jq.bind("chosen:activate.chosen",function(b){a.activate_field(b)}),this.form_field_jq.bind("chosen:open.chosen",function(b){a.container_mousedown(b)}),this.form_field_jq.bind("chosen:close.chosen",function(b){a.input_blur(b)}),this.search_field.bind("blur.chosen",function(b){a.input_blur(b)}),this.search_field.bind("keyup.chosen",function(b){a.keyup_checker(b)}),this.search_field.bind("keydown.chosen",function(b){a.keydown_checker(b)}),this.search_field.bind("focus.chosen",function(b){a.input_focus(b)}),this.search_field.bind("cut.chosen",function(b){a.clipboard_event_checker(b)}),this.search_field.bind("paste.chosen",function(b){a.clipboard_event_checker(b)}),this.is_multiple?this.search_choices.bind("click.chosen",function(b){a.choices_click(b)}):this.container.bind("click.chosen",function(a){a.preventDefault()})},Chosen.prototype.destroy=function(){return a(this.container[0].ownerDocument).unbind("click.chosen",this.click_test_action),this.search_field[0].tabIndex&&(this.form_field_jq[0].tabIndex=this.search_field[0].tabIndex),this.container.remove(),this.form_field_jq.removeData("chosen"),this.form_field_jq.show()},Chosen.prototype.search_field_disabled=function(){return this.is_disabled=this.form_field_jq[0].disabled,this.is_disabled?(this.container.addClass("chosen-disabled"),this.search_field[0].disabled=!0,this.is_multiple||this.selected_item.unbind("focus.chosen",this.activate_action),this.close_field()):(this.container.removeClass("chosen-disabled"),this.search_field[0].disabled=!1,this.is_multiple?void 0:this.selected_item.bind("focus.chosen",this.activate_action))},Chosen.prototype.container_mousedown=function(b){return this.is_disabled||(b&&"mousedown"===b.type&&!this.results_showing&&b.preventDefault(),null!=b&&a(b.target).hasClass("search-choice-close"))?void 0:(this.active_field?this.is_multiple||!b||a(b.target)[0]!==this.selected_item[0]&&!a(b.target).parents("a.chosen-single").length||(b.preventDefault(),this.results_toggle()):(this.is_multiple&&this.search_field.val(""),a(this.container[0].ownerDocument).bind("click.chosen",this.click_test_action),this.results_show()),this.activate_field())},Chosen.prototype.container_mouseup=function(a){return"ABBR"!==a.target.nodeName||this.is_disabled?void 0:this.results_reset(a)},Chosen.prototype.search_results_mousewheel=function(a){var b;return a.originalEvent&&(b=a.originalEvent.deltaY||-a.originalEvent.wheelDelta||a.originalEvent.detail),null!=b?(a.preventDefault(),"DOMMouseScroll"===a.type&&(b=40*b),this.search_results.scrollTop(b+this.search_results.scrollTop())):void 0},Chosen.prototype.blur_test=function(){return!this.active_field&&this.container.hasClass("chosen-container-active")?this.close_field():void 0},Chosen.prototype.close_field=function(){return a(this.container[0].ownerDocument).unbind("click.chosen",this.click_test_action),this.active_field=!1,this.results_hide(),this.container.removeClass("chosen-container-active"),this.clear_backstroke(),this.show_search_field_default(),this.search_field_scale()},Chosen.prototype.activate_field=function(){return this.container.addClass("chosen-container-active"),this.active_field=!0,this.search_field.val(this.search_field.val()),this.search_field.focus()},Chosen.prototype.test_active_click=function(b){var c;return c=a(b.target).closest(".chosen-container"),c.length&&this.container[0]===c[0]?this.active_field=!0:this.close_field()},Chosen.prototype.results_build=function(){return this.parsing=!0,this.selected_option_count=null,this.results_data=SelectParser.select_to_array(this.form_field),this.is_multiple?this.search_choices.find("li.search-choice").remove():this.is_multiple||(this.single_set_selected_text(),this.disable_search||this.form_field.options.length<=this.disable_search_threshold?(this.search_field[0].readOnly=!0,this.container.addClass("chosen-container-single-nosearch")):(this.search_field[0].readOnly=!1,this.container.removeClass("chosen-container-single-nosearch"))),this.update_results_content(this.results_option_build({first:!0})),this.search_field_disabled(),this.show_search_field_default(),this.search_field_scale(),this.parsing=!1},Chosen.prototype.result_do_highlight=function(a){var b,c,d,e,f;if(a.length){if(this.result_clear_highlight(),this.result_highlight=a,this.result_highlight.addClass("highlighted"),d=parseInt(this.search_results.css("maxHeight"),10),f=this.search_results.scrollTop(),e=d+f,c=this.result_highlight.position().top+this.search_results.scrollTop(),b=c+this.result_highlight.outerHeight(),b>=e)return this.search_results.scrollTop(b-d>0?b-d:0);if(f>c)return this.search_results.scrollTop(c)}},Chosen.prototype.result_clear_highlight=function(){return this.result_highlight&&this.result_highlight.removeClass("highlighted"),this.result_highlight=null},Chosen.prototype.results_show=function(){return this.is_multiple&&this.max_selected_options<=this.choices_count()?(this.form_field_jq.trigger("chosen:maxselected",{chosen:this}),!1):(this.container.addClass("chosen-with-drop"),this.results_showing=!0,this.search_field.focus(),this.search_field.val(this.search_field.val()),this.winnow_results(),this.form_field_jq.trigger("chosen:showing_dropdown",{chosen:this}))},Chosen.prototype.update_results_content=function(a){return this.search_results.html(a)},Chosen.prototype.results_hide=function(){return this.results_showing&&(this.result_clear_highlight(),this.container.removeClass("chosen-with-drop"),this.form_field_jq.trigger("chosen:hiding_dropdown",{chosen:this})),this.results_showing=!1},Chosen.prototype.set_tab_index=function(){var a;return this.form_field.tabIndex?(a=this.form_field.tabIndex,this.form_field.tabIndex=-1,this.search_field[0].tabIndex=a):void 0},Chosen.prototype.set_label_behavior=function(){var b=this;return this.form_field_label=this.form_field_jq.parents("label"),!this.form_field_label.length&&this.form_field.id.length&&(this.form_field_label=a("label[for='"+this.form_field.id+"']")),this.form_field_label.length>0?this.form_field_label.bind("click.chosen",function(a){return b.is_multiple?b.container_mousedown(a):b.activate_field()}):void 0},Chosen.prototype.show_search_field_default=function(){return this.is_multiple&&this.choices_count()<1&&!this.active_field?(this.search_field.val(this.default_text),this.search_field.addClass("default")):(this.search_field.val(""),this.search_field.removeClass("default"))},Chosen.prototype.search_results_mouseup=function(b){var c;return c=a(b.target).hasClass("active-result")?a(b.target):a(b.target).parents(".active-result").first(),c.length?(this.result_highlight=c,this.result_select(b),this.search_field.focus()):void 0},Chosen.prototype.search_results_mouseover=function(b){var c;return c=a(b.target).hasClass("active-result")?a(b.target):a(b.target).parents(".active-result").first(),c?this.result_do_highlight(c):void 0},Chosen.prototype.search_results_mouseout=function(b){return a(b.target).hasClass("active-result")?this.result_clear_highlight():void 0},Chosen.prototype.choice_build=function(b){var c,d,e=this;return c=a("<li />",{"class":"search-choice"}).html("<span>"+b.html+"</span>"),b.disabled?c.addClass("search-choice-disabled"):(d=a("<a />",{"class":"search-choice-close","data-option-array-index":b.array_index}),d.bind("click.chosen",function(a){return e.choice_destroy_link_click(a)}),c.append(d)),this.search_container.before(c)},Chosen.prototype.choice_destroy_link_click=function(b){return b.preventDefault(),b.stopPropagation(),this.is_disabled?void 0:this.choice_destroy(a(b.target))},Chosen.prototype.choice_destroy=function(a){return this.result_deselect(a[0].getAttribute("data-option-array-index"))?(this.show_search_field_default(),this.is_multiple&&this.choices_count()>0&&this.search_field.val().length<1&&this.results_hide(),a.parents("li").first().remove(),this.search_field_scale()):void 0},Chosen.prototype.results_reset=function(){return this.reset_single_select_options(),this.form_field.options[0].selected=!0,this.single_set_selected_text(),this.show_search_field_default(),this.results_reset_cleanup(),this.form_field_jq.trigger("change"),this.active_field?this.results_hide():void 0},Chosen.prototype.results_reset_cleanup=function(){return this.current_selectedIndex=this.form_field.selectedIndex,this.selected_item.find("abbr").remove()},Chosen.prototype.result_select=function(a){var b,c;return this.result_highlight?(b=this.result_highlight,this.result_clear_highlight(),this.is_multiple&&this.max_selected_options<=this.choices_count()?(this.form_field_jq.trigger("chosen:maxselected",{chosen:this}),!1):(this.is_multiple?b.removeClass("active-result"):this.reset_single_select_options(),c=this.results_data[b[0].getAttribute("data-option-array-index")],c.selected=!0,this.form_field.options[c.options_index].selected=!0,this.selected_option_count=null,this.is_multiple?this.choice_build(c):this.single_set_selected_text(c.text),(a.metaKey||a.ctrlKey)&&this.is_multiple||this.results_hide(),this.search_field.val(""),(this.is_multiple||this.form_field.selectedIndex!==this.current_selectedIndex)&&this.form_field_jq.trigger("change",{selected:this.form_field.options[c.options_index].value}),this.current_selectedIndex=this.form_field.selectedIndex,this.search_field_scale())):void 0},Chosen.prototype.single_set_selected_text=function(a){return null==a&&(a=this.default_text),a===this.default_text?this.selected_item.addClass("chosen-default"):(this.single_deselect_control_build(),this.selected_item.removeClass("chosen-default")),this.selected_item.find("span").text(a)},Chosen.prototype.result_deselect=function(a){var b;return b=this.results_data[a],this.form_field.options[b.options_index].disabled?!1:(b.selected=!1,this.form_field.options[b.options_index].selected=!1,this.selected_option_count=null,this.result_clear_highlight(),this.results_showing&&this.winnow_results(),this.form_field_jq.trigger("change",{deselected:this.form_field.options[b.options_index].value}),this.search_field_scale(),!0)},Chosen.prototype.single_deselect_control_build=function(){return this.allow_single_deselect?(this.selected_item.find("abbr").length||this.selected_item.find("span").first().after('<abbr class="search-choice-close"></abbr>'),this.selected_item.addClass("chosen-single-with-deselect")):void 0},Chosen.prototype.get_search_text=function(){return this.search_field.val()===this.default_text?"":a("<div/>").text(a.trim(this.search_field.val())).html()},Chosen.prototype.winnow_results_set_highlight=function(){var a,b;return b=this.is_multiple?[]:this.search_results.find(".result-selected.active-result"),a=b.length?b.first():this.search_results.find(".active-result").first(),null!=a?this.result_do_highlight(a):void 0},Chosen.prototype.no_results=function(b){var c;return c=a('<li class="no-results">'+this.results_none_found+' "<span></span>"</li>'),c.find("span").first().html(b),this.search_results.append(c),this.form_field_jq.trigger("chosen:no_results",{chosen:this})},Chosen.prototype.no_results_clear=function(){return this.search_results.find(".no-results").remove()},Chosen.prototype.keydown_arrow=function(){var a;return this.results_showing&&this.result_highlight?(a=this.result_highlight.nextAll("li.active-result").first())?this.result_do_highlight(a):void 0:this.results_show()},Chosen.prototype.keyup_arrow=function(){var a;return this.results_showing||this.is_multiple?this.result_highlight?(a=this.result_highlight.prevAll("li.active-result"),a.length?this.result_do_highlight(a.first()):(this.choices_count()>0&&this.results_hide(),this.result_clear_highlight())):void 0:this.results_show()},Chosen.prototype.keydown_backstroke=function(){var a;return this.pending_backstroke?(this.choice_destroy(this.pending_backstroke.find("a").first()),this.clear_backstroke()):(a=this.search_container.siblings("li.search-choice").last(),a.length&&!a.hasClass("search-choice-disabled")?(this.pending_backstroke=a,this.single_backstroke_delete?this.keydown_backstroke():this.pending_backstroke.addClass("search-choice-focus")):void 0)},Chosen.prototype.clear_backstroke=function(){return this.pending_backstroke&&this.pending_backstroke.removeClass("search-choice-focus"),this.pending_backstroke=null},Chosen.prototype.keydown_checker=function(a){var b,c;switch(b=null!=(c=a.which)?c:a.keyCode,this.search_field_scale(),8!==b&&this.pending_backstroke&&this.clear_backstroke(),b){case 8:this.backstroke_length=this.search_field.val().length;break;case 9:this.results_showing&&!this.is_multiple&&this.result_select(a),this.mouse_on_container=!1;break;case 13:this.results_showing&&a.preventDefault();break;case 32:this.disable_search&&a.preventDefault();break;case 38:a.preventDefault(),this.keyup_arrow();break;case 40:a.preventDefault(),this.keydown_arrow()}},Chosen.prototype.search_field_scale=function(){var b,c,d,e,f,g,h,i,j;if(this.is_multiple){for(d=0,h=0,f="position:absolute; left: -1000px; top: -1000px; display:none;",g=["font-size","font-style","font-weight","font-family","line-height","text-transform","letter-spacing"],i=0,j=g.length;j>i;i++)e=g[i],f+=e+":"+this.search_field.css(e)+";";return b=a("<div />",{style:f}),b.text(this.search_field.val()),a("body").append(b),h=b.width()+25,b.remove(),c=this.container.outerWidth(),h>c-10&&(h=c-10),this.search_field.css({width:h+"px"})}},Chosen}(AbstractChosen)}.call(this);admin/class-daextlnl-admin.php000064400000102474151213253540012362 0ustar00<?php
/**
 * This class is used to work with the administrative side of WordPress.
 *
 * @package live-news-lite
 */

/**
 * This class should be used to work with the administrative side of WordPress.
 */
class Daextlnl_Admin {

	protected static $instance = null;
	private $shared            = null;

	private $screen_id_tickers       = null;
	private $screen_id_featured      = null;
	private $screen_id_sliding       = null;
	private $screen_id_export_to_pro = null;
	private $screen_id_help          = null;
	private $screen_id_pro_version   = null;
	private $screen_id_options       = null;

	private function __construct() {

		// assign an instance of the shared class.
		$this->shared = Daextlnl_Shared::get_instance();

		// Load admin stylesheets and JavaScript.
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_styles' ) );
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) );

		// Write in back-end head.
		add_action( 'admin_head', array( $this, 'wr_admin_head' ) );

		// Add the admin menu.
		add_action( 'admin_menu', array( $this, 'me_add_admin_menu' ) );

		// Load the options API registrations and callbacks.
		add_action( 'admin_init', array( $this, 'op_register_options' ) );

		// this hook is triggered during the creation of a new blog.
		add_action( 'wpmu_new_blog', array( $this, 'new_blog_create_options_and_tables' ), 10, 6 );

		// this hook is triggered during the deletion of a blog.
		add_action( 'delete_blog', array( $this, 'delete_blog_delete_options_and_tables' ), 10, 1 );

		// Export XML controller.
		add_action( 'init', array( $this, 'export_xml_controller' ) );

		// Change the WordPress footer text on all the plugin menus.
		add_filter( 'admin_footer_text', array( $this, 'change_footer_text' ) );
	}

	/**
	 * Return an instance of this class.
	 */
	public static function get_instance() {

		if ( null == self::$instance ) {
			self::$instance = new self();
		}

		return self::$instance;
	}

	/**
	 * Write in the admin head.
	 */
	public function wr_admin_head() {

		echo '<script type="text/javascript">';
		echo 'var daextlnl_ajax_url = "' . admin_url( 'admin-ajax.php' ) . '";';
		echo 'var daextlnl_nonce = "' . wp_create_nonce( 'live-news' ) . '";';
		echo 'var daextlnl_admin_url ="' . get_admin_url() . '";';
		echo '</script>';
	}

	public function enqueue_admin_styles() {

		$screen = get_current_screen();

		// menu tickers.
		if ( $screen->id == $this->screen_id_tickers ) {
			wp_enqueue_style( 'wp-color-picker' );
			wp_enqueue_style( $this->shared->get( 'slug' ) . '-menu-sliding', $this->shared->get( 'url' ) . 'admin/assets/css/menu-tickers.css', array(), $this->shared->get( 'ver' ) );
			wp_enqueue_style( $this->shared->get( 'slug' ) . '-framework-menu', $this->shared->get( 'url' ) . 'admin/assets/css/framework/menu.css', array(), $this->shared->get( 'ver' ) );
			wp_enqueue_style( $this->shared->get( 'slug' ) . '-jquery-ui-tooltip', $this->shared->get( 'url' ) . 'admin/assets/css/jquery-ui-tooltip.css', array(), $this->shared->get( 'ver' ) );
			wp_enqueue_style( $this->shared->get( 'slug' ) . '-chosen', $this->shared->get( 'url' ) . 'admin/assets/inc/chosen/chosen-min.css', array(), $this->shared->get( 'ver' ) );
			wp_enqueue_style( $this->shared->get( 'slug' ) . '-chosen-custom', $this->shared->get( 'url' ) . 'admin/assets/css/chosen-custom.css', array(), $this->shared->get( 'ver' ) );
		}

		// menu featured.
		if ( $screen->id == $this->screen_id_featured ) {
			wp_enqueue_style( $this->shared->get( 'slug' ) . '-menu-featured', $this->shared->get( 'url' ) . 'admin/assets/css/menu-featured.css', array(), $this->shared->get( 'ver' ) );
			wp_enqueue_style( $this->shared->get( 'slug' ) . '-framework-menu', $this->shared->get( 'url' ) . 'admin/assets/css/framework/menu.css', array(), $this->shared->get( 'ver' ) );
			wp_enqueue_style( $this->shared->get( 'slug' ) . '-jquery-ui-tooltip', $this->shared->get( 'url' ) . 'admin/assets/css/jquery-ui-tooltip.css', array(), $this->shared->get( 'ver' ) );
			wp_enqueue_style( $this->shared->get( 'slug' ) . '-chosen', $this->shared->get( 'url' ) . 'admin/assets/inc/chosen/chosen-min.css', array(), $this->shared->get( 'ver' ) );
			wp_enqueue_style( $this->shared->get( 'slug' ) . '-chosen-custom', $this->shared->get( 'url' ) . 'admin/assets/css/chosen-custom.css', array(), $this->shared->get( 'ver' ) );
		}

		// menu sliding.
		if ( $screen->id == $this->screen_id_sliding ) {
			wp_enqueue_style( 'wp-color-picker' );
			wp_enqueue_style( $this->shared->get( 'slug' ) . '-menu-sliding', $this->shared->get( 'url' ) . 'admin/assets/css/menu-sliding.css', array(), $this->shared->get( 'ver' ) );
			wp_enqueue_style( $this->shared->get( 'slug' ) . '-framework-menu', $this->shared->get( 'url' ) . 'admin/assets/css/framework/menu.css', array(), $this->shared->get( 'ver' ) );
			wp_enqueue_style( $this->shared->get( 'slug' ) . '-jquery-ui-tooltip', $this->shared->get( 'url' ) . 'admin/assets/css/jquery-ui-tooltip.css', array(), $this->shared->get( 'ver' ) );
			wp_enqueue_style( $this->shared->get( 'slug' ) . '-chosen', $this->shared->get( 'url' ) . 'admin/assets/inc/chosen/chosen-min.css', array(), $this->shared->get( 'ver' ) );
			wp_enqueue_style( $this->shared->get( 'slug' ) . '-chosen-custom', $this->shared->get( 'url' ) . 'admin/assets/css/chosen-custom.css', array(), $this->shared->get( 'ver' ) );
		}

		// menu help.
		if ( $screen->id == $this->screen_id_help ) {
			wp_enqueue_style(
				$this->shared->get( 'slug' ) . '-menu-help',
				$this->shared->get( 'url' ) . 'admin/assets/css/menu-help.css',
				array(),
				$this->shared->get( 'ver' )
			);
		}

		// menu pro version
		if ( $screen->id == $this->screen_id_pro_version ) {
			wp_enqueue_style(
				$this->shared->get( 'slug' ) . '-menu-pro-version',
				$this->shared->get( 'url' ) . 'admin/assets/css/menu-pro-version.css',
				array(),
				$this->shared->get( 'ver' )
			);
		}

		// menu options.
		if ( $screen->id == $this->screen_id_options ) {
			wp_enqueue_style( $this->shared->get( 'slug' ) . '-framework-options', $this->shared->get( 'url' ) . 'admin/assets/css/framework/options.css', array(), $this->shared->get( 'ver' ) );
			wp_enqueue_style( $this->shared->get( 'slug' ) . '-jquery-ui-tooltip', $this->shared->get( 'url' ) . 'admin/assets/css/jquery-ui-tooltip.css', array(), $this->shared->get( 'ver' ) );
			wp_enqueue_style( $this->shared->get( 'slug' ) . '-chosen', $this->shared->get( 'url' ) . 'admin/assets/inc/chosen/chosen-min.css', array(), $this->shared->get( 'ver' ) );
			wp_enqueue_style( $this->shared->get( 'slug' ) . '-chosen-custom', $this->shared->get( 'url' ) . 'admin/assets/css/chosen-custom.css', array(), $this->shared->get( 'ver' ) );
		}
	}

	/**
	 * Enqueue admin-specific javascript.
	 */
	public function enqueue_admin_scripts() {

		$screen = get_current_screen();

		// menu tickers.
		if ( $screen->id == $this->screen_id_tickers ) {
			wp_enqueue_script( 'jquery-ui-tooltip' );
			wp_enqueue_script( $this->shared->get( 'slug' ) . '-menu-tickers', $this->shared->get( 'url' ) . 'admin/assets/js/menu-tickers.js', 'jquery', $this->shared->get( 'ver' ) );
			wp_enqueue_script( $this->shared->get( 'slug' ) . '-jquery-ui-tooltip-init', $this->shared->get( 'url' ) . 'admin/assets/js/jquery-ui-tooltip-init.js', 'jquery', $this->shared->get( 'ver' ) );
			wp_enqueue_script( $this->shared->get( 'slug' ) . '-wp-color-picker-init', $this->shared->get( 'url' ) . 'admin/assets/js/wp-color-picker-init.js', array( 'wp-color-picker' ), false, true );
			wp_enqueue_script( $this->shared->get( 'slug' ) . '-chosen', $this->shared->get( 'url' ) . 'admin/assets/inc/chosen/chosen-min.js', 'jquery', $this->shared->get( 'ver' ) );
			wp_enqueue_script( $this->shared->get( 'slug' ) . '-jquery-ui-chosen-init-tickers', $this->shared->get( 'url' ) . 'admin/assets/js/chosen-init-tickers.js', 'jquery', $this->shared->get( 'ver' ) );
			wp_enqueue_media();
			wp_enqueue_script( $this->shared->get( 'slug' ) . '-media-uploader', $this->shared->get( 'url' ) . 'admin/assets/js/media-uploader.js', 'jquery', $this->shared->get( 'ver' ) );
		}

		// menu featured.
		if ( $screen->id == $this->screen_id_featured ) {
			wp_enqueue_script( 'jquery-ui-tooltip' );
			wp_enqueue_script( $this->shared->get( 'slug' ) . '-jquery-ui-tooltip-init', $this->shared->get( 'url' ) . 'admin/assets/js/jquery-ui-tooltip-init.js', 'jquery', $this->shared->get( 'ver' ) );
			wp_enqueue_script( $this->shared->get( 'slug' ) . '-chosen', $this->shared->get( 'url' ) . 'admin/assets/inc/chosen/chosen-min.js', 'jquery', $this->shared->get( 'ver' ) );
			wp_enqueue_script( $this->shared->get( 'slug' ) . '-jquery-ui-chosen-init-featured', $this->shared->get( 'url' ) . 'admin/assets/js/chosen-init-featured.js', 'jquery', $this->shared->get( 'ver' ) );
			wp_enqueue_script( $this->shared->get( 'slug' ) . '-menu-featured', $this->shared->get( 'url' ) . 'admin/assets/js/menu-featured.js', 'jquery', $this->shared->get( 'ver' ) );
		}

		// menu sliding.
		if ( $screen->id == $this->screen_id_sliding ) {
			wp_enqueue_script( 'jquery-ui-tooltip' );
			wp_enqueue_script( $this->shared->get( 'slug' ) . '-jquery-ui-tooltip-init', $this->shared->get( 'url' ) . 'admin/assets/js/jquery-ui-tooltip-init.js', 'jquery', $this->shared->get( 'ver' ) );
			wp_enqueue_script( $this->shared->get( 'slug' ) . '-chosen', $this->shared->get( 'url' ) . 'admin/assets/inc/chosen/chosen-min.js', 'jquery', $this->shared->get( 'ver' ) );
			wp_enqueue_script( $this->shared->get( 'slug' ) . '-jquery-ui-chosen-init-sliding', $this->shared->get( 'url' ) . 'admin/assets/js/chosen-init-sliding.js', 'jquery', $this->shared->get( 'ver' ) );
			wp_enqueue_script( $this->shared->get( 'slug' ) . '-wp-color-picker-init', $this->shared->get( 'url' ) . 'admin/assets/js/wp-color-picker-init.js', array( 'wp-color-picker' ), false, true );
			wp_enqueue_script( $this->shared->get( 'slug' ) . '-menu-sliding', $this->shared->get( 'url' ) . 'admin/assets/js/menu-sliding.js', 'jquery', $this->shared->get( 'ver' ) );
			wp_enqueue_media();
			wp_enqueue_script( $this->shared->get( 'slug' ) . '-media-uploader', $this->shared->get( 'url' ) . 'admin/assets/js/media-uploader.js', 'jquery', $this->shared->get( 'ver' ) );
		}

		// menu options.
		if ( $screen->id == $this->screen_id_options ) {
			wp_enqueue_script( 'jquery-ui-tooltip' );
			wp_enqueue_script( $this->shared->get( 'slug' ) . '-jquery-ui-tooltip-init', $this->shared->get( 'url' ) . 'admin/assets/js/jquery-ui-tooltip-init.js', 'jquery', $this->shared->get( 'ver' ) );
			wp_enqueue_script( $this->shared->get( 'slug' ) . '-chosen', $this->shared->get( 'url' ) . 'admin/assets/inc/chosen/chosen-min.js', 'jquery', $this->shared->get( 'ver' ) );
			wp_enqueue_script( $this->shared->get( 'slug' ) . '-chosen-init-options', $this->shared->get( 'url' ) . 'admin/assets/js/chosen-init-options.js', 'jquery', $this->shared->get( 'ver' ) );
		}
	}

	/**
	 * plugin activation.
	 */
	static public function ac_activate( $networkwide ) {

		/**
		 * Create options and tables for all the sites in the network.
		 */
		if ( function_exists( 'is_multisite' ) and is_multisite() ) {

			/**
			 * If this is a "Network Activation" create the options and tables
			 * for each blog.
			 */
			if ( $networkwide ) {

				// get the current blog id.
				global $wpdb;
				$current_blog = $wpdb->blogid;

				// create an array with all the blog ids.
				$blogids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );

				// iterate through all the blogs.
				foreach ( $blogids as $blog_id ) {

					// switch to the iterated blog.
					switch_to_blog( $blog_id );

					// create options and tables for the iterated blog.
					self::ac_initialize_options();
					self::ac_create_database_tables();

				}

				// switch to the current blog.
				switch_to_blog( $current_blog );

			} else {

				/**
				 * if this is not a "Network Activation" create options and
				 * tables only for the current blog
				 */
				self::ac_initialize_options();
				self::ac_create_database_tables();

			}
		} else {

			/**
			 * If this is not a multisite installation create options and
			 * tables only for the current blog.
			 */
			self::ac_initialize_options();
			self::ac_create_database_tables();

		}
	}

	/**
	 * Create the options and tables for the newly created blog.
	 *
	 * @param $blog_id
	 * @param $user_id
	 * @param $domain
	 * @param $path
	 * @param $site_id
	 * @param $meta
	 *
	 * @return void
	 */
	public function new_blog_create_options_and_tables( $blog_id, $user_id, $domain, $path, $site_id, $meta ) {

		global $wpdb;

		/**
		 * If the plugin is "Network Active" create the options and tables for
		 * this new blog.
		 */
		if ( is_plugin_active_for_network( 'uberchart/init.php' ) ) {

			// get the id of the current blog.
			$current_blog = $wpdb->blogid;

			// switch to the blog that is being activated.
			switch_to_blog( $blog_id );

			// create options and database tables for the new blog.
			$this->ac_initialize_options();
			$this->ac_create_database_tables();

			// switch to the current blog.
			switch_to_blog( $current_blog );

		}
	}

	/**
	 * Delete options and tables for the deleted blog.
	 *
	 * @param $blog_id
	 *
	 * @return void
	 */
	public function delete_blog_delete_options_and_tables( $blog_id ) {

		global $wpdb;

		// get the id of the current blog.
		$current_blog = $wpdb->blogid;

		// switch to the blog that is being activated.
		switch_to_blog( $blog_id );

		// create options and database tables for the new blog.
		$this->un_delete_options();
		$this->un_delete_database_tables();

		// switch to the current blog.
		switch_to_blog( $current_blog );
	}

	/**
	 * Initialize plugin options.
	 */
	static private function ac_initialize_options() {

		// assign an instance of Daextlnl_Shared.
		$shared = Daextlnl_Shared::get_instance();

		// database version -----------------------------------------------------.
		add_option( $shared->get( 'slug' ) . '_database_version', '0' );

		// general --------------------------------------------------------------.
		add_option( $shared->get( 'slug' ) . '_detect_url_mode', 'wp_request' );
		add_option( $shared->get( 'slug' ) . '_tickers_menu_capability', 'manage_options' );
		add_option( $shared->get( 'slug' ) . '_featured_menu_capability', 'manage_options' );
		add_option( $shared->get( 'slug' ) . '_sliding_menu_capability', 'manage_options' );
	}

	/**
	 * Create the plugin database tables.
	 */
	static private function ac_create_database_tables() {

		global $wpdb;

		// Get the database character collate that will be appended at the end of each query.
		$charset_collate = $wpdb->get_charset_collate();

		// Check database version and create the database.
		if ( intval( get_option( 'daextlnl_database_version' ), 10 ) < 1 ) {

			require_once ABSPATH . 'wp-admin/includes/upgrade.php';

			// Create *prefix*_daextlnl_tickers.
			global $wpdb;
			$table_name = $wpdb->prefix . 'daextlnl_tickers';
			$sql        = "CREATE TABLE $table_name (
                  `name` varchar(100) NOT NULL DEFAULT '',
                  `id` bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
                  `target` int(11) NOT NULL DEFAULT '1',
                  `url` TEXT NOT NULL DEFAULT '',
                  `open_links_new_tab` tinyint(1) DEFAULT '0',
                  `clock_offset` int(11) NOT NULL DEFAULT '0',
                  `clock_format` varchar(40) NOT NULL DEFAULT 'HH:mm',
                  `clock_source` int(11) NOT NULL DEFAULT '2',
                  `clock_autoupdate` tinyint(1) DEFAULT '1',
                  `clock_autoupdate_time` int(11) NOT NULL DEFAULT '10',
                  `number_of_sliding_news` int(11) NOT NULL DEFAULT '10',
                  `featured_title_maximum_length` int(11) NOT NULL DEFAULT '255',
                  `featured_excerpt_maximum_length` int(11) NOT NULL DEFAULT '255',
                  `sliding_news_maximum_length` int(11) NOT NULL DEFAULT '255',
                  `open_news_as_default` tinyint(1) DEFAULT '1',
                  `hide_featured_news` int(11) NOT NULL DEFAULT '1',
                  `hide_clock` tinyint(1) DEFAULT '0',
                  `enable_rtl_layout` tinyint(1) DEFAULT '0',
                  `cached_cycles` int(11) NOT NULL DEFAULT '0',
                  `featured_news_background_color` varchar(7) DEFAULT NULL,
                  `sliding_news_background_color` varchar(7) DEFAULT NULL,
                  `sliding_news_background_color_opacity` float DEFAULT NULL,
                  `font_family` varchar(255) DEFAULT NULL,
                  `google_font` varchar(255) DEFAULT NULL,
                  `featured_title_font_size` int(11) NOT NULL DEFAULT '38',
                  `featured_excerpt_font_size` int(11) NOT NULL DEFAULT '28',
                  `sliding_news_font_size` int(11) NOT NULL DEFAULT '28',
                  `clock_font_size` int(11) NOT NULL DEFAULT '28',
                  `enable_with_mobile_devices` tinyint(1) DEFAULT '0',
                  `open_button_image` varchar(2083) NOT NULL DEFAULT '',
                  `close_button_image` varchar(2083) NOT NULL DEFAULT '',
                  `clock_background_image` varchar(2083) NOT NULL DEFAULT '',
                  `featured_news_title_color` varchar(7) DEFAULT NULL,
                  `featured_news_title_color_hover` varchar(7) DEFAULT NULL,
                  `featured_news_excerpt_color` varchar(7) DEFAULT NULL,
                  `sliding_news_color` varchar(7) DEFAULT NULL,
                  `sliding_news_color_hover` varchar(7) DEFAULT NULL,
                  `clock_text_color` varchar(7) DEFAULT NULL,
                  `featured_news_background_color_opacity` float DEFAULT NULL,
                  `enable_ticker` tinyint(1) DEFAULT '1',
                  `enable_links` tinyint(1) DEFAULT '1',
                  `transient_expiration` int(11) NOT NULL DEFAULT '0',
                  `sliding_news_margin` int(11) NOT NULL DEFAULT '84',
                  `sliding_news_padding` int(11) NOT NULL DEFAULT '28',
                  `url_mode` tinyint(1) DEFAULT '0'
            ) $charset_collate";

			dbDelta( $sql );

			// Create *prefix*_daextlnl_featured_news.
			global $wpdb;
			$table_name = $wpdb->prefix . 'daextlnl_featured_news';
			$sql        = "CREATE TABLE $table_name (
                  `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
                  `news_title` varchar(1000) NOT NULL DEFAULT '',
                  `news_excerpt` varchar(1000) NOT NULL DEFAULT '',
                  `url` varchar(2083) NOT NULL DEFAULT '',
                  `ticker_id` bigint(20) NOT NULL
            ) $charset_collate";

			dbDelta( $sql );

			// create *prefix*_daextlnl_sliding_news.
			global $wpdb;
			$table_name = $wpdb->prefix . 'daextlnl_sliding_news';
			$sql        = "CREATE TABLE $table_name (
                  `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
                  `news_title` varchar(1000) NOT NULL DEFAULT '',
                  `url` varchar(2083) NOT NULL DEFAULT '',
                  `ticker_id` bigint(20) NOT NULL,
                  `text_color` varchar(7) DEFAULT NULL,
                  `text_color_hover` varchar(7) DEFAULT NULL,
                  `background_color` varchar(7) DEFAULT NULL,
                  `background_color_opacity` float DEFAULT NULL,
                  `image_before` varchar(2083) NOT NULL DEFAULT '',
                  `image_after` varchar(2083) NOT NULL DEFAULT ''
            ) $charset_collate";

			dbDelta( $sql );

			// Update database version.
			update_option( 'daextlnl_database_version', '1' );

		}
	}

	/**
	 * Plugin delete.
	 */
	public static function un_delete() {

		/**
		 * Delete options and tables for all the sites in the network.
		 */
		if ( function_exists( 'is_multisite' ) and is_multisite() ) {

			// get the current blog id.
			global $wpdb;
			$current_blog = $wpdb->blogid;

			// create an array with all the blog ids.
			$blogids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );

			// iterate through all the blogs.
			foreach ( $blogids as $blog_id ) {

				// switch to the iterated blog.
				switch_to_blog( $blog_id );

				// create options and tables for the iterated blog.
				self::un_delete_options();
				self::un_delete_database_tables();

			}

			// switch to the current blog.
			switch_to_blog( $current_blog );

		} else {

			/**
			 * If this is not a multisite installation delete options and
			 * tables only for the current blog.
			 */
			self::un_delete_options();
			self::un_delete_database_tables();

		}
	}

	/**
	 * Delete plugin options.
	 */
	public static function un_delete_options() {

		// assign an instance of Daextlnl_Shared.
		$shared = Daextlnl_Shared::get_instance();

		// database version -----------------------------------------------------.
		delete_option( $shared->get( 'slug' ) . '_database_version' );

		// general --------------------------------------------------------------.
		delete_option( $shared->get( 'slug' ) . '_detect_url_mode' );
		delete_option( $shared->get( 'slug' ) . '_tickers_menu_capability' );
		delete_option( $shared->get( 'slug' ) . '_featured_menu_capability' );
		delete_option( $shared->get( 'slug' ) . '_sliding_menu_capability' );
	}

	/**
	 * Delete plugin database tables.
	 */
	public static function un_delete_database_tables() {

		// assign an instance of Daextlnl_Shared.
		$shared = Daextlnl_Shared::get_instance();

		global $wpdb;

		// delete transients associated with the table prefix '_tickers'.
		$table_name = $wpdb->prefix . $shared->get( 'slug' ) . '_tickers';
		$results    = $wpdb->get_results( "SELECT id FROM $table_name", ARRAY_A );
		foreach ( $results as $result ) {
			delete_transient( 'daextlnl_ticker_' . $result['id'] );
		}

		// delete table prefix + '_tickers'.
		$table_name = $wpdb->prefix . $shared->get( 'slug' ) . '_tickers';
		$sql        = "DROP TABLE $table_name";
		$wpdb->query( $sql );

		// delete table prefix + '_featured_news'.
		$table_name = $wpdb->prefix . $shared->get( 'slug' ) . '_featured_news';
		$sql        = "DROP TABLE $table_name";
		$wpdb->query( $sql );

		// delete table prefix + '_sliding_news'.
		$table_name = $wpdb->prefix . $shared->get( 'slug' ) . '_sliding_news';
		$sql        = "DROP TABLE $table_name";
		$wpdb->query( $sql );
	}

	/**
	 * Register the admin menu.
	 */
	public function me_add_admin_menu() {

		add_menu_page(
			esc_html__( 'LN', $this->shared->get( 'text_domain' ) ),
			esc_html__( 'Live News', $this->shared->get( 'text_domain' ) ),
			get_option( $this->shared->get( 'slug' ) . '_tickers_menu_capability' ),
			$this->shared->get( 'slug' ) . '-tickers',
			array( $this, 'me_display_menu_tickers' ),
			'dashicons-admin-site'
		);

		$this->screen_id_tickers = add_submenu_page(
			$this->shared->get( 'slug' ) . '-tickers',
			esc_html__( 'News Tickers', $this->shared->get( 'text_domain' ) ),
			esc_html__( 'News Tickers', $this->shared->get( 'text_domain' ) ),
			get_option( $this->shared->get( 'slug' ) . '_tickers_menu_capability' ),
			$this->shared->get( 'slug' ) . '-tickers',
			array( $this, 'me_display_menu_tickers' )
		);

		$this->screen_id_featured = add_submenu_page(
			$this->shared->get( 'slug' ) . '-tickers',
			esc_html__( 'Featured News', $this->shared->get( 'text_domain' ) ),
			esc_html__( 'Featured News', $this->shared->get( 'text_domain' ) ),
			get_option( $this->shared->get( 'slug' ) . '_featured_menu_capability' ),
			$this->shared->get( 'slug' ) . '-featured',
			array( $this, 'me_display_menu_featured' )
		);

		$this->screen_id_sliding = add_submenu_page(
			$this->shared->get( 'slug' ) . '-tickers',
			esc_html__( 'Sliding News', $this->shared->get( 'text_domain' ) ),
			esc_html__( 'Sliding News', $this->shared->get( 'text_domain' ) ),
			get_option( $this->shared->get( 'slug' ) . '_sliding_menu_capability' ),
			$this->shared->get( 'slug' ) . '-sliding',
			array( $this, 'me_display_menu_sliding' )
		);

		$this->screen_id_export_to_pro = add_submenu_page(
			$this->shared->get( 'slug' ) . '-tickers',
			esc_html__( 'Export to Pro', $this->shared->get( 'text_domain' ) ),
			esc_html__( 'Export to Pro', $this->shared->get( 'text_domain' ) ),
			'manage_options',
			$this->shared->get( 'slug' ) . '-export-to-pro',
			array( $this, 'me_display_menu_export_to_pro' )
		);

		$this->screen_id_help = add_submenu_page(
			$this->shared->get( 'slug' ) . '-tickers',
			esc_html__( 'Help', $this->shared->get( 'text_domain' ) ),
			esc_html__( 'Help', $this->shared->get( 'text_domain' ) ),
			'manage_options',
			$this->shared->get( 'slug' ) . '-help',
			array( $this, 'me_display_menu_help' )
		);

		$this->screen_id_pro_version = add_submenu_page(
			$this->shared->get( 'slug' ) . '-tickers',
			esc_html__( 'Pro Version', $this->shared->get( 'text_domain' ) ),
			esc_html__( 'Pro Version', $this->shared->get( 'text_domain' ) ),
			'manage_options',
			$this->shared->get( 'slug' ) . '-pro-version',
			array( $this, 'me_display_menu_pro_version' )
		);

		$this->screen_id_options = add_submenu_page(
			$this->shared->get( 'slug' ) . '-tickers',
			esc_html__( 'Options', $this->shared->get( 'text_domain' ) ),
			esc_html__( 'Options', $this->shared->get( 'text_domain' ) ),
			'manage_options',
			$this->shared->get( 'slug' ) . '-options',
			array( $this, 'me_display_menu_options' )
		);
	}

	/**
	 * Includes the tickers view.
	 */
	public function me_display_menu_tickers() {
		include_once 'view/tickers.php';
	}

	/**
	 * Includes the featured view.
	 */
	public function me_display_menu_featured() {
		include_once 'view/featured.php';
	}

	/**
	 * Includes the sliding view.
	 */
	public function me_display_menu_sliding() {
		include_once 'view/sliding.php';
	}

	/**
	 * Includes the export to pro view.
	 */
	public function me_display_menu_export_to_pro() {
		include_once 'view/export_to_pro.php';
	}

	/**
	 * Includes the help view.
	 */
	public function me_display_menu_help() {
		include_once 'view/help.php';
	}

	/**
	 * Includes the pro version view.
	 */
	public function me_display_menu_pro_version() {
		include_once 'view/pro_version.php';
	}

	/**
	 * Includes the options view.
	 */
	public function me_display_menu_options() {
		include_once 'view/options.php';
	}

	/**
	 * Register options.
	 */
	public function op_register_options() {

		// section general ----------------------------------------------------------.
		add_settings_section(
			'daextlnl_general_settings_section',
			null,
			null,
			'daextlnl_general_options'
		);

		add_settings_field(
			'detect_url_mode',
			esc_html__( 'Detect URL Mode', $this->shared->get( 'text_domain' ) ),
			array( $this, 'detect_url_mode_callback' ),
			'daextlnl_general_options',
			'daextlnl_general_settings_section'
		);

		register_setting(
			'daextlnl_general_options',
			'daextlnl_detect_url_mode',
			array( $this, 'detect_url_mode_validation' )
		);

		add_settings_field(
			'tickers_menu_capability',
			esc_html__( 'Tickers Menu Capability', $this->shared->get( 'text_domain' ) ),
			array( $this, 'tickers_menu_capability_callback' ),
			'daextlnl_general_options',
			'daextlnl_general_settings_section'
		);

		register_setting(
			'daextlnl_general_options',
			'daextlnl_tickers_menu_capability',
			array( $this, 'tickers_menu_capability_validation' )
		);

		add_settings_field(
			'featured_menu_capability',
			esc_html__( 'Featured News Menu Capability', $this->shared->get( 'text_domain' ) ),
			array( $this, 'featured_menu_capability_callback' ),
			'daextlnl_general_options',
			'daextlnl_general_settings_section'
		);

		register_setting(
			'daextlnl_general_options',
			'daextlnl_featured_menu_capability',
			array( $this, 'featured_menu_capability_validation' )
		);

		add_settings_field(
			'sliding_menu_capability',
			esc_html__( 'Sliding News Menu Capability', $this->shared->get( 'text_domain' ) ),
			array( $this, 'sliding_menu_capability_callback' ),
			'daextlnl_general_options',
			'daextlnl_general_settings_section'
		);

		register_setting(
			'daextlnl_general_options',
			'daextlnl_sliding_menu_capability',
			array( $this, 'sliding_menu_capability_validation' )
		);
	}


	public function detect_url_mode_callback( $args ) {

		$html  = '<select id="daextlnl-detect-url-mode" name="daextlnl_detect_url_mode" class="daext-display-none">';
		$html .= '<option ' . selected( get_option( 'daextlnl_detect_url_mode' ), 'server_variable', false ) . ' value="server_variable">' . esc_attr__( 'Server Variable', $this->shared->get( 'text_domain' ) ) . '</option>';
		$html .= '<option ' . selected( get_option( 'daextlnl_detect_url_mode' ), 'wp_request', false ) . ' value="wp_request">' . esc_attr__( 'WP Request', $this->shared->get( 'text_domain' ) ) . '</option>';
		$html .= '</select>';
		$html .= '<div class="help-icon" title="' . esc_attr__( 'Select the method used to detect the URL of the page.', $this->shared->get( 'text_domain' ) ) . '"></div>';

		echo $html;
	}

	public function detect_url_mode_validation( $input ) {

		if ( $input === 'server_variable' or $input === 'wp_request' ) {
			$output = $input;
		} else {
			$output = 'server_variable';
		}

		return $output;
	}

	public function tickers_menu_capability_callback( $args ) {

		$html  = '<input autocomplete="off" type="text" id="daextlnl-tickers-menu-capability" name="daextlnl_tickers_menu_capability" class="regular-text" value="' . esc_attr( get_option( 'daextlnl_tickers_menu_capability' ) ) . '" />';
		$html .= '<div class="help-icon" title="' . esc_attr__( 'The capability required to get access on the "News Tickers" menu.', $this->shared->get( 'text_domain' ) ) . '"></div>';

		echo $html;
	}

	public function tickers_menu_capability_validation( $input ) {

		return sanitize_key( $input );
	}

	public function featured_menu_capability_callback( $args ) {

		$html  = '<input autocomplete="off" type="text" id="daextlnl-featured-menu-capability" name="daextlnl_featured_menu_capability" class="regular-text" value="' . esc_attr( get_option( 'daextlnl_featured_menu_capability' ) ) . '" />';
		$html .= '<div class="help-icon" title="' . esc_attr__( 'The capability required to get access on the "Featured News" menu.', $this->shared->get( 'text_domain' ) ) . '"></div>';

		echo $html;
	}

	public function featured_menu_capability_validation( $input ) {

		return sanitize_key( $input );
	}

	public function sliding_menu_capability_callback( $args ) {

		$html  = '<input autocomplete="off" type="text" id="daextlnl-sliding-menu-capability" name="daextlnl_sliding_menu_capability" class="regular-text" value="' . esc_attr( get_option( 'daextlnl_sliding_menu_capability' ) ) . '" />';
		$html .= '<div class="help-icon" title="' . esc_attr__( 'The capability required to get access on the "Sliding News" menu.', $this->shared->get( 'text_domain' ) ) . '"></div>';

		echo $html;
	}

	public function sliding_menu_capability_validation( $input ) {

		return sanitize_key( $input );
	}

	/**
	 * Echo all the dismissible notices based on the values of the $notices array.
	 *
	 * @param $notices
	 */
	public function dismissible_notice( $notices ) {

		foreach ( $notices as $key => $notice ) {
			echo '<div class="' . esc_attr( $notice['class'] ) . ' settings-error notice is-dismissible below-h2"><p>' . esc_html( $notice['message'] ) . '</p></div>';
		}
	}

	/*
	 * The click on the "Export" button available in the "Export to Pro" menu is intercepted and the method that
	 * generates the downloadable XML file is called.
	 */
	public function export_xml_controller() {

		/*
		 * Intercept requests that come from the "Export" button of the "Export" menu and generate the downloadable XML
		 * file.
		 */
		if ( isset( $_POST['daextlnl_export'] ) ) {

			// verify capability
			if ( ! current_user_can( 'manage_options' ) ) {
				wp_die( esc_html__( 'You do not have sufficient permissions to access this page.' ) );
			}

			// generate the header of the XML file
			header( 'Content-Encoding: UTF-8' );
			header( 'Content-type: text/xml; charset=UTF-8' );
			header( 'Content-Disposition: attachment; filename=live-news-' . time() . '.xml' );
			header( 'Pragma: no-cache' );
			header( 'Expires: 0' );

			// generate initial part of the XML file
			$out  = '<?xml version="1.0" encoding="UTF-8" ?>';
			$out .= '<root>';

			// Generate the XML of the various db tables
			$out .= $this->shared->convert_db_table_to_xml( 'tickers', 'id' );
			$out .= $this->shared->convert_db_table_to_xml( 'featured_news', 'id' );
			$out .= $this->shared->convert_db_table_to_xml( 'sliding_news', 'id' );

			// generate the final part of the XML file
			$out .= '</root>';

			echo $out;
			die();

		}
	}


	/**
	 * Change the WordPress footer text on all the plugin menus.
	 */
	public function change_footer_text() {

		$screen = get_current_screen();

		if ( $screen->id == $this->screen_id_tickers or
			$screen->id == $this->screen_id_featured or
			$screen->id == $this->screen_id_sliding or
			$screen->id == $this->screen_id_export_to_pro or
			$screen->id == $this->screen_id_help or
			$screen->id == $this->screen_id_pro_version or
			$screen->id == $this->screen_id_options ) {

			echo '<a target="_blank" href="http://wordpress.org/support/plugin/live-news-lite#postform">' . esc_attr__(
				'Contact Support',
				$this->shared->get( 'text_domain' )
			) . '</a> | ' .
				'<a target="_blank" href="https://translate.wordpress.org/projects/wp-plugins/live-news-lite/">' . esc_attr__(
					'Translate',
					$this->shared->get( 'text_domain' )
				) . '</a> | ' .
				str_replace(
					array( '[stars]', '[wp.org]' ),
					array(
						'<a target="_blank" href="https://wordpress.org/support/plugin/live-news-lite/reviews/?filter=5">&#9733;&#9733;&#9733;&#9733;&#9733;</a>',
						'<a target="_blank" href="http://wordpress.org/plugins/live-news-lite/" >wordpress.org</a>',
					),
					__( 'Add your [stars] on [wp.org] to spread the love.', $this->shared->get( 'text_domain' ) )
				);

		}
	}
}
public/class-daextlnl-public.php000064400000031772151213253540012740 0ustar00<?php
/**
 * The public-facing functionality of the plugin.
 *
 * @package live-news-lite
 */

/*
 * This class should be used to work with the public side of WordPress.
 */
class Daextlnl_Public {

	// general class properties.
	protected static $instance = null;
	private $shared            = null;
	private $apply_ticker      = true;

	/**
	 * create an instance of this class
	 */
	public static function get_instance() {

		if ( null == self::$instance ) {
			self::$instance = new self();
		}

		return self::$instance;
	}

	/**
	 * Constructor.
	 */
	private function __construct() {

		// assign an instance of the shared class.
		$this->shared = Daextlnl_Shared::get_instance();

		// Write in the front-end head.
		add_action( 'wp_head', array( $this, 'generate_ticker' ) );

		// Load public css and js.
		add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_styles' ) );
		add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
	}

	/**
	 * Enqueue styles.
	 *
	 * @return void
	 */
	public function enqueue_styles() {
		wp_enqueue_style( $this->shared->get( 'slug' ) . '-general', $this->shared->get( 'url' ) . 'public/assets/css/general.css', array(), $this->shared->get( 'ver' ) );
	}

	/**
	 * Enqueue scripts.
	 *
	 * @return void
	 */
	public function enqueue_scripts() {

		wp_enqueue_script( $this->shared->get( 'slug' ) . '-momentjs', $this->shared->get( 'url' ) . 'public/assets/js/inc/momentjs/moment.js', array( 'jquery' ), $this->shared->get( 'ver' ), true );
		wp_enqueue_script( $this->shared->get( 'slug' ) . '-mobile-detect-js', $this->shared->get( 'url' ) . 'public/assets/js/inc/mobile-detect-js/mobile-detect.min.js', array( 'jquery' ), $this->shared->get( 'ver' ), true );
		wp_enqueue_script( $this->shared->get( 'slug' ) . '-general', $this->shared->get( 'url' ) . 'public/assets/js/general.js', array( 'jquery', $this->shared->get( 'slug' ) . '-momentjs', $this->shared->get( 'slug' ) . '-mobile-detect-js' ), $this->shared->get( 'ver' ), true );
	}

	/**
	 * This method generates in the <head> section of the page:
	 *
	 * - The window.DAEXTLNL_DATA JavaScript object used by general.js to generate the news ticker
	 * - The CSS of the ticker
	 */
	function generate_ticker() {

		$current_url = $this->shared->get_current_url();
		$ticker_obj  = $this->shared->get_ticker_with_target_url( $current_url );

		/*
		 * If there isn't a ticker associated with this url use the ticker associated with the website if exists.
		 */
		if ( $ticker_obj === false ) {

			global $wpdb;
			$table_name = $wpdb->prefix . $this->shared->get( 'slug' ) . '_tickers';
			$safe_sql   = $wpdb->prepare( "SELECT * FROM $table_name WHERE target = %d", 1 );
			$ticker_obj = $wpdb->get_row( $safe_sql );

			// if there is no ticker set the class property $apply_ticker to true and return.
			if ( $ticker_obj === null ) {
				$this->apply_ticker = false;
			}
		}

		/**
		 * Do not display the ticker if the "Enable Ticker" flag is set to no.
		 */
		if ( $ticker_obj === null or intval( $ticker_obj->enable_ticker, 10 ) == 0 ) {
			$this->apply_ticker = false;
		}

		if ( $this->apply_ticker ) {

			$data = array();

			/**
			 * Flag used to verify if the ticker should be appended by javascript (in general.js) before the ending
			 * body tag.
			 */
			$data['apply_ticker'] = 'true';

			// nonce used for the ajax requests.
			$data['nonce'] = "'" . esc_js( wp_create_nonce( 'live-news' ) ) . "'";

			// set the ajax url variable in javascript.
			$data['ajax_url'] = "'" . esc_js( admin_url( 'admin-ajax.php' ) ) . "'";

			// set the target attribute of the links.
			if ( intval( $ticker_obj->open_links_new_tab, 10 ) == 1 ) {
				$data['target_attribute'] = "'_blank'";
			} else {
				$data['target_attribute'] = "'_self'";
			}

			// set the number of cached cycles.
			$data['rtl_layout'] = intval( $ticker_obj->enable_rtl_layout, 10 );

			// set the "Enable with Mobile Devices" option value.
			if ( intval( $ticker_obj->enable_with_mobile_devices, 10 ) === 1 ) {
				$data['enable_with_mobile_devices'] = 'true';
			} else {
				$data['enable_with_mobile_devices'] = 'false';
			}

			// set the "Hide Featured News" option value.
			$data['hide_featured_news'] = intval( $ticker_obj->hide_featured_news, 10 );

			// set the ticker_id.
			$data['ticker_id'] = intval( $ticker_obj->id, 10 );

			// enable_links.
			if ( intval( $ticker_obj->enable_links, 10 ) === 1 ) {
				$data['enable_links'] = 'true';
			} else {
				$data['enable_links'] = 'false';
			}

			// clock offset.
			$data['clock_offset'] = intval( $ticker_obj->clock_offset, 10 );

			// clock format.
			$data['clock_format'] = "'" . esc_js( stripslashes( $ticker_obj->clock_format ) ) . "'";

			// clock source.
			$data['clock_source'] = intval( $ticker_obj->clock_source, 10 );

			// clock autoupdate.
			$data['clock_autoupdate'] = intval( $ticker_obj->clock_autoupdate, 10 );

			// clock autoupdate time.
			$data['clock_autoupdate_time'] = intval( $ticker_obj->clock_autoupdate_time, 10 );

			// cached cycles.
			$data['cached_cycles'] = intval( $ticker_obj->cached_cycles, 10 );

			/*
			 * If the transient exists generate the daextlnl_ticker_transient JavaScript variable. Which is a string
			 * that includes the ticker XML.
			 */
			$ticker_transient = get_transient( 'daextlnl_ticker_' . $ticker_obj->id );
			if ( $ticker_transient !== false ) {

				/**
				 * Save the XML string in a JavaScript variable.
				 *
				 * Note that json_encode() is only used to avoid errors and escape the JavaScript variable, not
				 * to perform a conversion to json. The resulting daextlnl_ticker_transient JavaScript variable is
				 * an XML string. (that will be converted to an actual XML Document by jQuery.parseXML() in
				 * general.js)
				 */
				$data['ticker_transient'] = json_encode( $ticker_transient );

			} else {

				$data['ticker_transient'] = 'null';

			}

			// Generate the JavaScript object that includes the data.
			echo '<script>';
			echo 'window.DAEXTLNL_DATA = {';
			echo 'apply_ticker:' . $data['apply_ticker'] . ',';
			echo 'nonce:' . $data['nonce'] . ',';
			echo 'ajax_url:' . $data['ajax_url'] . ',';
			echo 'target_attribute:' . $data['target_attribute'] . ',';
			echo 'rtl_layout:' . $data['rtl_layout'] . ',';
			echo 'enable_with_mobile_devices:' . $data['enable_with_mobile_devices'] . ',';
			echo 'hide_featured_news:' . $data['hide_featured_news'] . ',';
			echo 'ticker_id:' . $data['ticker_id'] . ',';
			echo 'enable_links:' . $data['enable_links'] . ',';
			echo 'clock_offset:' . $data['clock_offset'] . ',';
			echo 'clock_format:' . $data['clock_format'] . ',';
			echo 'clock_source:' . $data['clock_source'] . ',';
			echo 'clock_autoupdate:' . $data['clock_autoupdate'] . ',';
			echo 'clock_autoupdate_time:' . $data['clock_autoupdate_time'] . ',';
			echo 'cached_cycles:' . $data['cached_cycles'] . ',';
			echo 'ticker_transient:' . $data['ticker_transient'] . ',';
			echo '};';
			echo '</script>';

			// Generate custom CSS based on the plugin options.
			echo '<style type="text/css">';

				/**
				* If in "Hide the featured news" is selected "No" or if is selected "Only with Mobile Devices" and
				* the current device is not a mobile device use the "live_news_status" cookie to determine the
				* status of the news ticker (open or closed).
				*/
				$live_news_status = isset( $_COOKIE['live_news_status'] ) ? sanitize_key( $_COOKIE['live_news_status'] ) : null;
			if ( $live_news_status !== null ) {

				// If the live_news_status cookie exists set the news ticker status based on this cookie
				if ( $live_news_status === 'open' ) {
					$current_status = 'open';
				} else {
					$current_status = 'closed';
				}
			} else {

				/**
				 * If the "live_news_status" cookie doesn't exist set the gallery status based on the
				 * "Open news as default" option.
				 */
				if ( intval( $ticker_obj->open_news_as_default, 10 ) == 1 ) {
					$current_status = 'open';
				} else {
					$current_status = 'closed';
				}
			}

				/**
				 * Use the status to set the proper CSS.
				 */
			if ( $current_status == 'open' ) {

				echo '#daextlnl-container{ display: block; }';
				echo '#daextlnl-open{ display: none; }';

			} else {

				echo '#daextlnl-container{ display: none; }';
				echo '#daextlnl-open{ display: block; }';

			}

				// set the font family based on the plugin option.
				echo '#daextlnl-featured-title, #daextlnl-featured-title a,#daextlnl-featured-excerpt, #daextlnl-featured-excerpt a, #daextlnl-clock, #daextlnl-close, .daextlnl-slider-single-news, .daextlnl-slider-single-news a{ font-family: ' . htmlentities( stripslashes( $ticker_obj->font_family ), ENT_COMPAT ) . ' !important; }';

				// set the sliding news background color.
				$color_a = $this->shared->rgb_hex_to_dec( str_replace( '#', '', $ticker_obj->featured_news_background_color ) );
				echo '#daextlnl-featured-container{ background: ' . 'rgba(' . $color_a['r'] . ',' . $color_a['g'] . ',' . $color_a['b'] . ', ' . floatval( $ticker_obj->featured_news_background_color_opacity ) . ')' . '; }';

				// set the sliding news background color.
				$color_a = $this->shared->rgb_hex_to_dec( str_replace( '#', '', $ticker_obj->sliding_news_background_color ) );
				echo '#daextlnl-slider{ background: ' . 'rgba(' . $color_a['r'] . ',' . $color_a['g'] . ',' . $color_a['b'] . ', ' . floatval( $ticker_obj->sliding_news_background_color_opacity ) . ')' . '; }';

				// set the font size of the textual elements.
				echo '#daextlnl-featured-title{ font-size: ' . intval( $ticker_obj->featured_title_font_size, 10 ) . 'px; }';
				echo '#daextlnl-featured-excerpt{ font-size: ' . intval( $ticker_obj->featured_excerpt_font_size, 10 ) . 'px; }';
				echo '#daextlnl-slider-floating-content .daextlnl-slider-single-news{ font-size: ' . intval( $ticker_obj->sliding_news_font_size, 10 ) . 'px; }';
				echo '#daextlnl-clock{ font-size: ' . intval( $ticker_obj->clock_font_size, 10 ) . 'px; }';

				// hide the clock if this options is set in the plugin option
			if ( $ticker_obj->hide_clock === '1' ) {
				echo '#daextlnl-clock{ display: none; }';
			}

				// set news css for the rtl layout
			if ( intval( $ticker_obj->enable_rtl_layout, 10 ) == 1 ) {
				echo '#daextlnl-featured-title-container, #daextlnl-featured-title, #daextlnl-featured-title a{ text-align: right !important; direction: rtl !important; unicode-bidi: embed !important; }';
				echo '#daextlnl-featured-excerpt-container, #daextlnl-featured-excerpt a{ text-align: right !important; direction: rtl !important; unicode-bidi: embed !important; }';
				echo '#daextlnl-slider, #daextlnl-slider-floating-content, .daextlnl-slider-single-news{ text-align: right !important; direction: rtl !important; unicode-bidi: embed !important; }';
			}

				// set the open button image url.
				echo "#daextlnl-open{background: url( '" . esc_attr( stripslashes( $ticker_obj->open_button_image ) ) . "');}";

				// set the close button image url.
				echo "#daextlnl-close{background: url( '" . esc_attr( stripslashes( $ticker_obj->close_button_image ) ) . "');}";

				// set the clock background image url.
				echo "#daextlnl-clock{background: url( '" . esc_attr( stripslashes( $ticker_obj->clock_background_image ) ) . "');}";

				// set the featured news title color.
				echo '#daextlnl-featured-title a{color: ' . esc_attr( stripslashes( $ticker_obj->featured_news_title_color ) ) . ';}';

				// set the featured news title color hover.
				echo '#daextlnl-featured-title a:hover{color: ' . esc_attr( stripslashes( $ticker_obj->featured_news_title_color_hover ) ) . ';}';

				// set the featured news excerpt color.
				echo '#daextlnl-featured-excerpt{color: ' . esc_attr( stripslashes( $ticker_obj->featured_news_excerpt_color ) ) . ';}';

				// set the sliding news color.
				echo '.daextlnl-slider-single-news, .daextlnl-slider-single-news a{color: ' . esc_attr( stripslashes( $ticker_obj->sliding_news_color ) ) . ';}';

				// set the sliding news color hover.
				echo '.daextlnl-slider-single-news a:hover{color: ' . esc_attr( stripslashes( $ticker_obj->sliding_news_color_hover ) ) . ';}';

				// set the clock text color.
				echo '#daextlnl-clock{color: ' . esc_attr( stripslashes( $ticker_obj->clock_text_color ) ) . ';}';

				// set the sliding news margin.
				echo '#daextlnl-slider-floating-content .daextlnl-slider-single-news{margin-right: ' . intval( $ticker_obj->sliding_news_margin, 10 ) . 'px !important; }';

				// set the sliding news padding.
				echo '#daextlnl-slider-floating-content .daextlnl-slider-single-news{padding: 0 ' . intval( $ticker_obj->sliding_news_padding, 10 ) . 'px !important; }';
				echo '#daextlnl-container .daextlnl-image-before{margin: 0 ' . intval( $ticker_obj->sliding_news_padding, 10 ) . 'px 0 0 !important; }';
				echo '#daextlnl-container .daextlnl-image-after{margin: 0 0 0 ' . intval( $ticker_obj->sliding_news_padding, 10 ) . 'px !important; }';

			echo '</style>';

			// embed google fonts if selected.
			if ( mb_strlen( trim( $ticker_obj->google_font ) ) > 0 ) {
				echo '<link rel="preconnect" href="https://fonts.gstatic.com">';
				echo '<link href="' . esc_url( stripslashes( $ticker_obj->google_font ) ) . '" rel="stylesheet">';
			}
		}
	}
}
public/assets/js/general.js000064400000037615151213253540011730 0ustar00jQuery(document).ready(function($) {

	'use strict';

	let daextlnl_archived_ticker_data_xml = '';
	let daextlnl_ticker_cycles = 0;
	let mobile_detect = new MobileDetect(window.navigator.userAgent);
	let mobile_device = mobile_detect.mobile();

	/*
	 * Append the ticker in the DOM if the window.DAEXTLNL_DATA.apply_ticker flag is defined
	 */
	if ( typeof window.DAEXTLNL_DATA != 'undefined' && window.DAEXTLNL_DATA.apply_ticker ){

		//Do not create the news ticker if the "Enable with Mobile Devices" option is set to "No"
		if(window.DAEXTLNL_DATA.enable_with_mobile_devices === false && mobile_device !== null){
			return;
		}

		/*
    * If in "Hide the featured news" is selected "Yes" or if is selected "Only with Mobile Devices" and
    * the current device is a mobile device hide the featured news area and remove the button used to open
    * and close the featured news area.
    */
		if ( window.DAEXTLNL_DATA.hide_featured_news === 2 || ( window.DAEXTLNL_DATA.hide_featured_news == 3 && mobile_device !== null ) ){

			$("<style>")
			.prop("type", "text/css")
			.html("#daextlnl-container{ min-height: 40px; }#daextlnl-featured-container{ display: none; }")
			.appendTo("head");

		}

		//append the ticker before the ending body tag
		daextlnl_append_html();

		//refresh the news only if the news ticker is in "open" status
		if (( $("#daextlnl-container").css("display") == "block") ){

			//refresh the news
			daextlnl_refresh_news();

		}

		/*
		 * If the clock is based on the user time and the clock_autoupdate option enabled set the interval used to
		 * update the clock
		 */
		if(window.DAEXTLNL_DATA.clock_source == 2 && window.DAEXTLNL_DATA.clock_autoupdate == 1) {
			window.setInterval(daextlnl_set_clock_based_on_user_time, (window.DAEXTLNL_DATA.clock_autoupdate_time * 1000) );
		}

	}

	/*
	 * This function is used to refresh all the data displayed in the ticker and to animate the sliding news from the
	 * initial to the final destination. It's called in the following situations:
	 *
	 * - When the document is ready
	 * - When a cycle of sliding news has finished its animation
	 * - When the news ticker is opened with the open button
	 */
	function daextlnl_refresh_news(){

		'use strict';

		if(typeof window.DAEXTLNL_DATA.ticker_transient != 'undefined' && window.DAEXTLNL_DATA.ticker_transient !== null){

			//Convert the XML string to a JavaScript XML Document
      daextlnl_archived_ticker_data_xml = $.parseXML(window.DAEXTLNL_DATA.ticker_transient);

			//Set the transient to null so it won't be used multiple times
			window.DAEXTLNL_DATA.ticker_transient = null;

		}

		if( $.isXMLDoc( daextlnl_archived_ticker_data_xml) === false || daextlnl_ticker_cycles >= window.DAEXTLNL_DATA.cached_cycles ){

			//retrieve the news with ajax and refresh the news ---------------------------------------------------------

			daextlnl_ticker_cycles = 0;

			//set ajax in synchronous mode
			jQuery.ajaxSetup({async:false});

			//prepare input for the ajax request
			let data = {
				"action": "get_ticker_data",
				"security": window.DAEXTLNL_DATA.nonce,
				"ticker_id": window.DAEXTLNL_DATA.ticker_id
			};

			//ajax
			$.post(window.DAEXTLNL_DATA.ajax_url, data, function(ticker_data_xml) {

				'use strict';

				daextlnl_archived_ticker_data_xml = ticker_data_xml;

				daextlnl_update_the_clock(ticker_data_xml);

				daextlnl_refresh_featured_news(ticker_data_xml);

				daextlnl_refresh_sliding_news(ticker_data_xml);

				daextlnl_slide_the_news();

			});

			//set ajax in asynchronous mode
			jQuery.ajaxSetup({async:true});

		}else{

			//use the current ticker xml data to refresh the news ------------------------------------------------------

			daextlnl_ticker_cycles++;

			daextlnl_update_the_clock(daextlnl_archived_ticker_data_xml);

			daextlnl_refresh_featured_news(daextlnl_archived_ticker_data_xml);

			daextlnl_refresh_sliding_news(daextlnl_archived_ticker_data_xml);

			daextlnl_slide_the_news();

		}

	}

	/*
	 * Update the clock
	 */
	function daextlnl_update_the_clock(ticker_data_xml){

		'use strict';

		if(window.DAEXTLNL_DATA.clock_source == 2){

			//update the clock based on the user time ------------------------------------------------------------------
			daextlnl_set_clock_based_on_user_time();

		}else{

			//update the clock based on the server time ----------------------------------------------------------------
			let currentTime = $(ticker_data_xml).find('time').text();

      let timestamp = moment.unix(currentTime).utc();
			$("#daextlnl-clock").text(timestamp.format(window.DAEXTLNL_DATA.clock_format));

		}

	}

	/*
	 * Remove the featured news title and excerpt from the DOM and uses the ticker data in XML format data to append the
	 * news featured news title and excerpt
	 */
	function daextlnl_refresh_featured_news(ticker_data_xml){

		'use strict';

		//parse the xml string
		$(ticker_data_xml).find("featurednews news").each(function(){

			'use strict';

			let news_title = $(this).find("newstitle").text();
			let news_excerpt = $(this).find("newsexcerpt").text();
			let url = $(this).find("url").text();

			//Delete the featured title
			$('#daextlnl-featured-title').html("");

			//Delete the featured excerpt
			$('#daextlnl-featured-excerpt').html("");

			if( url.length > 0 && window.DAEXTLNL_DATA.enable_links ){

				//Append the new featured title
				$('#daextlnl-featured-title').html( '<a target="' + window.DAEXTLNL_DATA.target_attribute + '" href="' + url + '">' + daextlnl_htmlEscape( news_title ) + '</a>' );

				//Append the new featured excerpt
				$('#daextlnl-featured-excerpt').html( daextlnl_htmlEscape( news_excerpt ) );

			}else{

				//Append the new featured title
				$('#daextlnl-featured-title').html(  daextlnl_htmlEscape( news_title )  );

				//Append the new featured excerpt
				$('#daextlnl-featured-excerpt').html( daextlnl_htmlEscape( news_excerpt ) );

			}

		});

	}

	/*
	 * Deletes all the sliding news from the DOM and uses the ticker data in XML format to append the news sliding news
	 */
	function daextlnl_refresh_sliding_news(ticker_data_xml){

		'use strict';

		//Delete the previous sliding news
		$('#daextlnl-slider-floating-content').empty();

		//parse the xml string
		$(ticker_data_xml).find("slidingnews news").each(function(){

			let news_title = $(this).find("newstitle").text();
			let url = $(this).find("url").text();
			let text_color = $(this).find("text_color").text();
			let text_color_hover = $(this).find("text_color_hover").text();
			let background_color = $(this).find("background_color").text();
			let background_color_opacity = $(this).find("background_color_opacity").text();
			let image_before = $(this).find("image_before").text();
			let image_after = $(this).find("image_after").text();
			let style_text_color = null;
			let style_background_color = null;
			let image_before_html = null;
			let image_after_html = null;

			//generate the style for the text color
			if( text_color.trim().length > 0 ){
				style_text_color = 'style="color: ' + text_color + ';"';
			}else{
				style_text_color = '';
			}

			//generate the style for the background color
			if( background_color.trim().length > 0 ) {
				let color_a = rgb_hex_to_dec(background_color);
				style_background_color = 'style="background: rgba(' + color_a['r'] + ',' + color_a['g'] + ',' + color_a['b'] + ',' + parseFloat(background_color_opacity) + ');"';
			}else{
				style_background_color = '';
			}

			//generate the image_before html
			if(image_before.trim().length > 0){
				image_before_html = '<img class="daextlnl-image-before" src="' + image_before + '">';
			}else{
				image_before_html = '';
			}

			//generate the image_after html
			if(image_after.trim().length > 0){
				image_after_html = '<img class="daextlnl-image-after" src="' + image_after + '">';
			}else{
				image_after_html = '';
			}

			//check if is set the RTL layout option
			if( window.DAEXTLNL_DATA.rtl_layout == 0 ){

				//LTR layout -----------------------------------------------------------------------
				if( url.length > 0 && window.DAEXTLNL_DATA.enable_links ){
					$('#daextlnl-slider-floating-content').append( '<div ' + style_background_color + ' class="daextlnl-slider-single-news">' + image_before_html + '<a data-text-color="' + text_color + '" onmouseout=\'jQuery(this).css("color", jQuery(this).attr("data-text-color"))\' onmouseover=\'jQuery(this).css("color", "' + text_color_hover + '" )\' ' + style_text_color + ' target="' + window.DAEXTLNL_DATA.target_attribute + '" href="' + url + '">' + daextlnl_htmlEscape( news_title ) + '</a>' + image_after_html + '</div>' );
				}else{
					$('#daextlnl-slider-floating-content').append( '<div ' + style_background_color + ' class="daextlnl-slider-single-news">' + image_before_html + '<span ' + style_text_color + ' >' + daextlnl_htmlEscape( news_title ) + '</span>' + image_after_html + '</div>' );
				}

			}else{

				//RTL layout -----------------------------------------------------------------------
				if( url.length > 0 && window.DAEXTLNL_DATA.enable_links ){
					$('#daextlnl-slider-floating-content').prepend( '<div ' + style_background_color + ' class="daextlnl-slider-single-news">' + image_before_html + '<a  data-text-color="' + text_color + '" onmouseout=\'jQuery(this).css("color", jQuery(this).attr("data-text-color"))\' onmouseover=\'jQuery(this).css("color", "' + text_color_hover + '" )\' ' + style_text_color + ' target="' + window.DAEXTLNL_DATA.target_attribute + '" href="' + url + '">' + daextlnl_htmlEscape( news_title ) + '</a>' + image_after_html + '</div>' );
				}else{
					$('#daextlnl-slider-floating-content').prepend( '<div ' + style_background_color + ' class="daextlnl-slider-single-news">' + image_before_html + '<span ' + style_text_color + ' >' + daextlnl_htmlEscape( news_title ) + '</span>' + image_after_html + '</div>' );
				}

			}
		});

	}

	/*
	 * Slides the news with jQuery animate from the initial to the final position. When the animation is complete calls
	 * daextlnl_refresh_news() which restarts the process from the start.
	 */
	function daextlnl_slide_the_news(){

		'use strict';

		let outside_left = null;

		//if the news slider is already animated then return
		if( ( $('#daextlnl-slider-floating-content:animated').length ) == 1 ){ return; };

		//get browser with
		let window_width = $(window).width();

		//floating news width
		let floating_news_width =parseInt( $( "#daextlnl-slider-floating-content" ).css("width"), 10 );

		//check if is set the RTL layout option
		if( window.DAEXTLNL_DATA.rtl_layout == 0 ){

			//LTR layout -----------------------------------------------------------------------

			//position outside the screen to the left
			outside_left = floating_news_width + window_width;

			//set floating content left position outside the screen
			$( "#daextlnl-slider-floating-content" ).css("left", window_width );

			//start floating the news
			$( "#daextlnl-slider-floating-content" ).animate({
				left: "-=" + outside_left,
				easing: "linear"
			}, ( outside_left * 10 ), "linear", function() {

				//animation complete
				daextlnl_refresh_news();

			});

		}else{

			//RTL layout -----------------------------------------------------------------------

			//position outside the screen to the left
			outside_left = floating_news_width + window_width;

			//set floating content left position outside the screen
			$( "#daextlnl-slider-floating-content" ).css("left", - floating_news_width );

			//start floating the news
			$( "#daextlnl-slider-floating-content" ).animate({
				left: "+=" + outside_left,
				easing: "linear"
			}, ( outside_left * 10 ), "linear", function() {

				//animation complete
				daextlnl_refresh_news();

			});

		}

	}

	/*
	 * On the click event of the "#daextlnl-close" element closes the news ticker and sends an ajax request used to save the
	 * "closed" status in the "live_news_status" cookie
	 */
	$(document.body).on('click', '#daextlnl-close' , function(){

		'use strict';

		//Stop the animation
		$("#daextlnl-slider-floating-content").stop();

		//Delete the previous sliding news
		$('#daextlnl-slider-floating-content').empty();

		//Hide the news container
		$("#daextlnl-container").hide();

		//Show the open button
		$("#daextlnl-open").show();

        //prepare input for the ajax request
        let data = {
            "action": "set_status_cookie",
            "security": window.DAEXTLNL_DATA.nonce,
            "status": "closed"
        };

        //ajax
        $.post(window.DAEXTLNL_DATA.ajax_url, data, function(ajax_response) {

			if( ajax_response == "success" ){
				//nothing
			}

        });

		//set the status hidden field to closed
		$("#daextlnl-status").attr("value","closed");

	});

	/*
	 * On the click event of the "#daextlnl-open" element opens the news ticker and sends an ajax request used to save the
	 * "open" status in the "live_news_status" cookie
	 */
	$(document.body).on('click', '#daextlnl-open' , function(){

		'use strict';

		//Show the news container
		$("#daextlnl-container").show();

		//Show the open button
		$("#daextlnl-open").hide();

		daextlnl_refresh_news();

        //prepare input for the ajax request
        let data = {
            "action": "set_status_cookie",
            "security": window.DAEXTLNL_DATA.nonce,
            "status": "open"
        };

        //ajax
        $.post(window.DAEXTLNL_DATA.ajax_url, data, function(ajax_response) {

			if( ajax_response == "success" ){
				//nothing
			}

        });

		//set the status hidden field to open
		$("#daextlnl-status").attr("value","open");

	});

	/*
	 * Converts certain characters to their HTML entities
	 */
	function daextlnl_htmlEscape(str) {

		'use strict';

	    return String(str)
			.replace(/&/g, '&amp;')
			.replace(/"/g, '&quot;')
			.replace(/'/g, '&#39;')
			.replace(/</g, '&lt;')
			.replace(/>/g, '&gt;');

	}

	/*
	 * Appends the ticker HTML just before the ending body element
	 */
	function daextlnl_append_html(){

		'use strict';

		let html_output = '<div id="daextlnl-container">' +

			'<!-- featured news -->' +
			'<div id="daextlnl-featured-container">' +
				'<div id="daextlnl-featured-title-container">' +
					'<div id="daextlnl-featured-title"></div>' +
				'</div>' +
				'<div id="daextlnl-featured-excerpt-container">' +
					'<div id="daextlnl-featured-excerpt"></div>' +
				'</div>' +
			'</div>' +

			'<!-- slider -->' +
			'<div id="daextlnl-slider">' +
				'<!-- floating content -->' +
				'<div id="daextlnl-slider-floating-content"></div>' +
			'</div>' +

			'<!-- clock -->' +
			'<div id="daextlnl-clock"></div>' +

			'<!-- close button -->' +
			'<div id="daextlnl-close"></div>' +

		'</div>' +

		'<!-- open button -->' +
		'<div id="daextlnl-open"></div>';

		$('body').append(html_output);

	}

	/*
	 * Uses a "Date" object to retrieve the user time and adds the clock offset of this news ticker
	 */
	function daextlnl_set_clock_based_on_user_time(){

		'use strict';

		//Get the current unix timestamp and add the offset
		let timestamp = moment().unix() + window.DAEXTLNL_DATA.clock_offset;

		//Convert the unix timestamp to the provided format
		let time = moment.unix(timestamp).format(window.DAEXTLNL_DATA.clock_format);

		//Update the DOM
    $("#daextlnl-clock").text(time);

	}

	/*
	 * Given an hexadecimal rgb color an array with the 3 components converted in decimal is returned
	 *
	 * @param string The hexadecimal rgb color
	 * @return array An array with the 3 component of the color converted in decimal
	 */
	function rgb_hex_to_dec(hex){

		'use strict';
		let r = null;
		let g = null;
		let b = null;
		let color_a = new Array();

		//remove the # character
		hex = hex.replace('#', '');

		//find the component of the color
		if ( hex.length == 3 ) {
			r = parseInt(hex.substring(0, 1), 16);
			g = parseInt(hex.substring(1, 2), 16);
			b = parseInt(hex.substring(2, 3), 16);
		} else {
			r = parseInt(hex.substring(0, 2), 16);
			g = parseInt(hex.substring(2, 4), 16);
			b = parseInt(hex.substring(4, 6), 16);
		}

		//generate the array with the component of the color

		color_a['r'] = r;
		color_a['g'] = g;
		color_a['b'] = b;

		return color_a;

	}

});public/assets/js/inc/mobile-detect-js/mobile-detect.js000064400000211030151213253540016711 0ustar00// THIS FILE IS GENERATED - DO NOT EDIT!
/*!mobile-detect v1.4.5 2021-03-13*/
/*global module:false, define:false*/
/*jshint latedef:false*/
/*!@license Copyright 2013, Heinrich Goebl, License: MIT, see https://github.com/hgoebl/mobile-detect.js*/
(function (define, undefined) {
define(function () {
    'use strict';

    var impl = {};

    impl.mobileDetectRules = {
    "phones": {
        "iPhone": "\\biPhone\\b|\\biPod\\b",
        "BlackBerry": "BlackBerry|\\bBB10\\b|rim[0-9]+|\\b(BBA100|BBB100|BBD100|BBE100|BBF100|STH100)\\b-[0-9]+",
        "Pixel": "; \\bPixel\\b",
        "HTC": "HTC|HTC.*(Sensation|Evo|Vision|Explorer|6800|8100|8900|A7272|S510e|C110e|Legend|Desire|T8282)|APX515CKT|Qtek9090|APA9292KT|HD_mini|Sensation.*Z710e|PG86100|Z715e|Desire.*(A8181|HD)|ADR6200|ADR6400L|ADR6425|001HT|Inspire 4G|Android.*\\bEVO\\b|T-Mobile G1|Z520m|Android [0-9.]+; Pixel",
        "Nexus": "Nexus One|Nexus S|Galaxy.*Nexus|Android.*Nexus.*Mobile|Nexus 4|Nexus 5|Nexus 5X|Nexus 6",
        "Dell": "Dell[;]? (Streak|Aero|Venue|Venue Pro|Flash|Smoke|Mini 3iX)|XCD28|XCD35|\\b001DL\\b|\\b101DL\\b|\\bGS01\\b",
        "Motorola": "Motorola|DROIDX|DROID BIONIC|\\bDroid\\b.*Build|Android.*Xoom|HRI39|MOT-|A1260|A1680|A555|A853|A855|A953|A955|A956|Motorola.*ELECTRIFY|Motorola.*i1|i867|i940|MB200|MB300|MB501|MB502|MB508|MB511|MB520|MB525|MB526|MB611|MB612|MB632|MB810|MB855|MB860|MB861|MB865|MB870|ME501|ME502|ME511|ME525|ME600|ME632|ME722|ME811|ME860|ME863|ME865|MT620|MT710|MT716|MT720|MT810|MT870|MT917|Motorola.*TITANIUM|WX435|WX445|XT300|XT301|XT311|XT316|XT317|XT319|XT320|XT390|XT502|XT530|XT531|XT532|XT535|XT603|XT610|XT611|XT615|XT681|XT701|XT702|XT711|XT720|XT800|XT806|XT860|XT862|XT875|XT882|XT883|XT894|XT901|XT907|XT909|XT910|XT912|XT928|XT926|XT915|XT919|XT925|XT1021|\\bMoto E\\b|XT1068|XT1092|XT1052",
        "Samsung": "\\bSamsung\\b|SM-G950F|SM-G955F|SM-G9250|GT-19300|SGH-I337|BGT-S5230|GT-B2100|GT-B2700|GT-B2710|GT-B3210|GT-B3310|GT-B3410|GT-B3730|GT-B3740|GT-B5510|GT-B5512|GT-B5722|GT-B6520|GT-B7300|GT-B7320|GT-B7330|GT-B7350|GT-B7510|GT-B7722|GT-B7800|GT-C3010|GT-C3011|GT-C3060|GT-C3200|GT-C3212|GT-C3212I|GT-C3262|GT-C3222|GT-C3300|GT-C3300K|GT-C3303|GT-C3303K|GT-C3310|GT-C3322|GT-C3330|GT-C3350|GT-C3500|GT-C3510|GT-C3530|GT-C3630|GT-C3780|GT-C5010|GT-C5212|GT-C6620|GT-C6625|GT-C6712|GT-E1050|GT-E1070|GT-E1075|GT-E1080|GT-E1081|GT-E1085|GT-E1087|GT-E1100|GT-E1107|GT-E1110|GT-E1120|GT-E1125|GT-E1130|GT-E1160|GT-E1170|GT-E1175|GT-E1180|GT-E1182|GT-E1200|GT-E1210|GT-E1225|GT-E1230|GT-E1390|GT-E2100|GT-E2120|GT-E2121|GT-E2152|GT-E2220|GT-E2222|GT-E2230|GT-E2232|GT-E2250|GT-E2370|GT-E2550|GT-E2652|GT-E3210|GT-E3213|GT-I5500|GT-I5503|GT-I5700|GT-I5800|GT-I5801|GT-I6410|GT-I6420|GT-I7110|GT-I7410|GT-I7500|GT-I8000|GT-I8150|GT-I8160|GT-I8190|GT-I8320|GT-I8330|GT-I8350|GT-I8530|GT-I8700|GT-I8703|GT-I8910|GT-I9000|GT-I9001|GT-I9003|GT-I9010|GT-I9020|GT-I9023|GT-I9070|GT-I9082|GT-I9100|GT-I9103|GT-I9220|GT-I9250|GT-I9300|GT-I9305|GT-I9500|GT-I9505|GT-M3510|GT-M5650|GT-M7500|GT-M7600|GT-M7603|GT-M8800|GT-M8910|GT-N7000|GT-S3110|GT-S3310|GT-S3350|GT-S3353|GT-S3370|GT-S3650|GT-S3653|GT-S3770|GT-S3850|GT-S5210|GT-S5220|GT-S5229|GT-S5230|GT-S5233|GT-S5250|GT-S5253|GT-S5260|GT-S5263|GT-S5270|GT-S5300|GT-S5330|GT-S5350|GT-S5360|GT-S5363|GT-S5369|GT-S5380|GT-S5380D|GT-S5560|GT-S5570|GT-S5600|GT-S5603|GT-S5610|GT-S5620|GT-S5660|GT-S5670|GT-S5690|GT-S5750|GT-S5780|GT-S5830|GT-S5839|GT-S6102|GT-S6500|GT-S7070|GT-S7200|GT-S7220|GT-S7230|GT-S7233|GT-S7250|GT-S7500|GT-S7530|GT-S7550|GT-S7562|GT-S7710|GT-S8000|GT-S8003|GT-S8500|GT-S8530|GT-S8600|SCH-A310|SCH-A530|SCH-A570|SCH-A610|SCH-A630|SCH-A650|SCH-A790|SCH-A795|SCH-A850|SCH-A870|SCH-A890|SCH-A930|SCH-A950|SCH-A970|SCH-A990|SCH-I100|SCH-I110|SCH-I400|SCH-I405|SCH-I500|SCH-I510|SCH-I515|SCH-I600|SCH-I730|SCH-I760|SCH-I770|SCH-I830|SCH-I910|SCH-I920|SCH-I959|SCH-LC11|SCH-N150|SCH-N300|SCH-R100|SCH-R300|SCH-R351|SCH-R400|SCH-R410|SCH-T300|SCH-U310|SCH-U320|SCH-U350|SCH-U360|SCH-U365|SCH-U370|SCH-U380|SCH-U410|SCH-U430|SCH-U450|SCH-U460|SCH-U470|SCH-U490|SCH-U540|SCH-U550|SCH-U620|SCH-U640|SCH-U650|SCH-U660|SCH-U700|SCH-U740|SCH-U750|SCH-U810|SCH-U820|SCH-U900|SCH-U940|SCH-U960|SCS-26UC|SGH-A107|SGH-A117|SGH-A127|SGH-A137|SGH-A157|SGH-A167|SGH-A177|SGH-A187|SGH-A197|SGH-A227|SGH-A237|SGH-A257|SGH-A437|SGH-A517|SGH-A597|SGH-A637|SGH-A657|SGH-A667|SGH-A687|SGH-A697|SGH-A707|SGH-A717|SGH-A727|SGH-A737|SGH-A747|SGH-A767|SGH-A777|SGH-A797|SGH-A817|SGH-A827|SGH-A837|SGH-A847|SGH-A867|SGH-A877|SGH-A887|SGH-A897|SGH-A927|SGH-B100|SGH-B130|SGH-B200|SGH-B220|SGH-C100|SGH-C110|SGH-C120|SGH-C130|SGH-C140|SGH-C160|SGH-C170|SGH-C180|SGH-C200|SGH-C207|SGH-C210|SGH-C225|SGH-C230|SGH-C417|SGH-C450|SGH-D307|SGH-D347|SGH-D357|SGH-D407|SGH-D415|SGH-D780|SGH-D807|SGH-D980|SGH-E105|SGH-E200|SGH-E315|SGH-E316|SGH-E317|SGH-E335|SGH-E590|SGH-E635|SGH-E715|SGH-E890|SGH-F300|SGH-F480|SGH-I200|SGH-I300|SGH-I320|SGH-I550|SGH-I577|SGH-I600|SGH-I607|SGH-I617|SGH-I627|SGH-I637|SGH-I677|SGH-I700|SGH-I717|SGH-I727|SGH-i747M|SGH-I777|SGH-I780|SGH-I827|SGH-I847|SGH-I857|SGH-I896|SGH-I897|SGH-I900|SGH-I907|SGH-I917|SGH-I927|SGH-I937|SGH-I997|SGH-J150|SGH-J200|SGH-L170|SGH-L700|SGH-M110|SGH-M150|SGH-M200|SGH-N105|SGH-N500|SGH-N600|SGH-N620|SGH-N625|SGH-N700|SGH-N710|SGH-P107|SGH-P207|SGH-P300|SGH-P310|SGH-P520|SGH-P735|SGH-P777|SGH-Q105|SGH-R210|SGH-R220|SGH-R225|SGH-S105|SGH-S307|SGH-T109|SGH-T119|SGH-T139|SGH-T209|SGH-T219|SGH-T229|SGH-T239|SGH-T249|SGH-T259|SGH-T309|SGH-T319|SGH-T329|SGH-T339|SGH-T349|SGH-T359|SGH-T369|SGH-T379|SGH-T409|SGH-T429|SGH-T439|SGH-T459|SGH-T469|SGH-T479|SGH-T499|SGH-T509|SGH-T519|SGH-T539|SGH-T559|SGH-T589|SGH-T609|SGH-T619|SGH-T629|SGH-T639|SGH-T659|SGH-T669|SGH-T679|SGH-T709|SGH-T719|SGH-T729|SGH-T739|SGH-T746|SGH-T749|SGH-T759|SGH-T769|SGH-T809|SGH-T819|SGH-T839|SGH-T919|SGH-T929|SGH-T939|SGH-T959|SGH-T989|SGH-U100|SGH-U200|SGH-U800|SGH-V205|SGH-V206|SGH-X100|SGH-X105|SGH-X120|SGH-X140|SGH-X426|SGH-X427|SGH-X475|SGH-X495|SGH-X497|SGH-X507|SGH-X600|SGH-X610|SGH-X620|SGH-X630|SGH-X700|SGH-X820|SGH-X890|SGH-Z130|SGH-Z150|SGH-Z170|SGH-ZX10|SGH-ZX20|SHW-M110|SPH-A120|SPH-A400|SPH-A420|SPH-A460|SPH-A500|SPH-A560|SPH-A600|SPH-A620|SPH-A660|SPH-A700|SPH-A740|SPH-A760|SPH-A790|SPH-A800|SPH-A820|SPH-A840|SPH-A880|SPH-A900|SPH-A940|SPH-A960|SPH-D600|SPH-D700|SPH-D710|SPH-D720|SPH-I300|SPH-I325|SPH-I330|SPH-I350|SPH-I500|SPH-I600|SPH-I700|SPH-L700|SPH-M100|SPH-M220|SPH-M240|SPH-M300|SPH-M305|SPH-M320|SPH-M330|SPH-M350|SPH-M360|SPH-M370|SPH-M380|SPH-M510|SPH-M540|SPH-M550|SPH-M560|SPH-M570|SPH-M580|SPH-M610|SPH-M620|SPH-M630|SPH-M800|SPH-M810|SPH-M850|SPH-M900|SPH-M910|SPH-M920|SPH-M930|SPH-N100|SPH-N200|SPH-N240|SPH-N300|SPH-N400|SPH-Z400|SWC-E100|SCH-i909|GT-N7100|GT-N7105|SCH-I535|SM-N900A|SGH-I317|SGH-T999L|GT-S5360B|GT-I8262|GT-S6802|GT-S6312|GT-S6310|GT-S5312|GT-S5310|GT-I9105|GT-I8510|GT-S6790N|SM-G7105|SM-N9005|GT-S5301|GT-I9295|GT-I9195|SM-C101|GT-S7392|GT-S7560|GT-B7610|GT-I5510|GT-S7582|GT-S7530E|GT-I8750|SM-G9006V|SM-G9008V|SM-G9009D|SM-G900A|SM-G900D|SM-G900F|SM-G900H|SM-G900I|SM-G900J|SM-G900K|SM-G900L|SM-G900M|SM-G900P|SM-G900R4|SM-G900S|SM-G900T|SM-G900V|SM-G900W8|SHV-E160K|SCH-P709|SCH-P729|SM-T2558|GT-I9205|SM-G9350|SM-J120F|SM-G920F|SM-G920V|SM-G930F|SM-N910C|SM-A310F|GT-I9190|SM-J500FN|SM-G903F|SM-J330F|SM-G610F|SM-G981B|SM-G892A|SM-A530F",
        "LG": "\\bLG\\b;|LG[- ]?(C800|C900|E400|E610|E900|E-900|F160|F180K|F180L|F180S|730|855|L160|LS740|LS840|LS970|LU6200|MS690|MS695|MS770|MS840|MS870|MS910|P500|P700|P705|VM696|AS680|AS695|AX840|C729|E970|GS505|272|C395|E739BK|E960|L55C|L75C|LS696|LS860|P769BK|P350|P500|P509|P870|UN272|US730|VS840|VS950|LN272|LN510|LS670|LS855|LW690|MN270|MN510|P509|P769|P930|UN200|UN270|UN510|UN610|US670|US740|US760|UX265|UX840|VN271|VN530|VS660|VS700|VS740|VS750|VS910|VS920|VS930|VX9200|VX11000|AX840A|LW770|P506|P925|P999|E612|D955|D802|MS323|M257)|LM-G710",
        "Sony": "SonyST|SonyLT|SonyEricsson|SonyEricssonLT15iv|LT18i|E10i|LT28h|LT26w|SonyEricssonMT27i|C5303|C6902|C6903|C6906|C6943|D2533|SOV34|601SO|F8332",
        "Asus": "Asus.*Galaxy|PadFone.*Mobile",
        "Xiaomi": "^(?!.*\\bx11\\b).*xiaomi.*$|POCOPHONE F1|MI 8|Redmi Note 9S|Redmi Note 5A Prime|N2G47H|M2001J2G|M2001J2I|M1805E10A|M2004J11G|M1902F1G|M2002J9G|M2004J19G|M2003J6A1G",
        "NokiaLumia": "Lumia [0-9]{3,4}",
        "Micromax": "Micromax.*\\b(A210|A92|A88|A72|A111|A110Q|A115|A116|A110|A90S|A26|A51|A35|A54|A25|A27|A89|A68|A65|A57|A90)\\b",
        "Palm": "PalmSource|Palm",
        "Vertu": "Vertu|Vertu.*Ltd|Vertu.*Ascent|Vertu.*Ayxta|Vertu.*Constellation(F|Quest)?|Vertu.*Monika|Vertu.*Signature",
        "Pantech": "PANTECH|IM-A850S|IM-A840S|IM-A830L|IM-A830K|IM-A830S|IM-A820L|IM-A810K|IM-A810S|IM-A800S|IM-T100K|IM-A725L|IM-A780L|IM-A775C|IM-A770K|IM-A760S|IM-A750K|IM-A740S|IM-A730S|IM-A720L|IM-A710K|IM-A690L|IM-A690S|IM-A650S|IM-A630K|IM-A600S|VEGA PTL21|PT003|P8010|ADR910L|P6030|P6020|P9070|P4100|P9060|P5000|CDM8992|TXT8045|ADR8995|IS11PT|P2030|P6010|P8000|PT002|IS06|CDM8999|P9050|PT001|TXT8040|P2020|P9020|P2000|P7040|P7000|C790",
        "Fly": "IQ230|IQ444|IQ450|IQ440|IQ442|IQ441|IQ245|IQ256|IQ236|IQ255|IQ235|IQ245|IQ275|IQ240|IQ285|IQ280|IQ270|IQ260|IQ250",
        "Wiko": "KITE 4G|HIGHWAY|GETAWAY|STAIRWAY|DARKSIDE|DARKFULL|DARKNIGHT|DARKMOON|SLIDE|WAX 4G|RAINBOW|BLOOM|SUNSET|GOA(?!nna)|LENNY|BARRY|IGGY|OZZY|CINK FIVE|CINK PEAX|CINK PEAX 2|CINK SLIM|CINK SLIM 2|CINK +|CINK KING|CINK PEAX|CINK SLIM|SUBLIM",
        "iMobile": "i-mobile (IQ|i-STYLE|idea|ZAA|Hitz)",
        "SimValley": "\\b(SP-80|XT-930|SX-340|XT-930|SX-310|SP-360|SP60|SPT-800|SP-120|SPT-800|SP-140|SPX-5|SPX-8|SP-100|SPX-8|SPX-12)\\b",
        "Wolfgang": "AT-B24D|AT-AS50HD|AT-AS40W|AT-AS55HD|AT-AS45q2|AT-B26D|AT-AS50Q",
        "Alcatel": "Alcatel",
        "Nintendo": "Nintendo (3DS|Switch)",
        "Amoi": "Amoi",
        "INQ": "INQ",
        "OnePlus": "ONEPLUS",
        "GenericPhone": "Tapatalk|PDA;|SAGEM|\\bmmp\\b|pocket|\\bpsp\\b|symbian|Smartphone|smartfon|treo|up.browser|up.link|vodafone|\\bwap\\b|nokia|Series40|Series60|S60|SonyEricsson|N900|MAUI.*WAP.*Browser"
    },
    "tablets": {
        "iPad": "iPad|iPad.*Mobile",
        "NexusTablet": "Android.*Nexus[\\s]+(7|9|10)",
        "GoogleTablet": "Android.*Pixel C",
        "SamsungTablet": "SAMSUNG.*Tablet|Galaxy.*Tab|SC-01C|GT-P1000|GT-P1003|GT-P1010|GT-P3105|GT-P6210|GT-P6800|GT-P6810|GT-P7100|GT-P7300|GT-P7310|GT-P7500|GT-P7510|SCH-I800|SCH-I815|SCH-I905|SGH-I957|SGH-I987|SGH-T849|SGH-T859|SGH-T869|SPH-P100|GT-P3100|GT-P3108|GT-P3110|GT-P5100|GT-P5110|GT-P6200|GT-P7320|GT-P7511|GT-N8000|GT-P8510|SGH-I497|SPH-P500|SGH-T779|SCH-I705|SCH-I915|GT-N8013|GT-P3113|GT-P5113|GT-P8110|GT-N8010|GT-N8005|GT-N8020|GT-P1013|GT-P6201|GT-P7501|GT-N5100|GT-N5105|GT-N5110|SHV-E140K|SHV-E140L|SHV-E140S|SHV-E150S|SHV-E230K|SHV-E230L|SHV-E230S|SHW-M180K|SHW-M180L|SHW-M180S|SHW-M180W|SHW-M300W|SHW-M305W|SHW-M380K|SHW-M380S|SHW-M380W|SHW-M430W|SHW-M480K|SHW-M480S|SHW-M480W|SHW-M485W|SHW-M486W|SHW-M500W|GT-I9228|SCH-P739|SCH-I925|GT-I9200|GT-P5200|GT-P5210|GT-P5210X|SM-T311|SM-T310|SM-T310X|SM-T210|SM-T210R|SM-T211|SM-P600|SM-P601|SM-P605|SM-P900|SM-P901|SM-T217|SM-T217A|SM-T217S|SM-P6000|SM-T3100|SGH-I467|XE500|SM-T110|GT-P5220|GT-I9200X|GT-N5110X|GT-N5120|SM-P905|SM-T111|SM-T2105|SM-T315|SM-T320|SM-T320X|SM-T321|SM-T520|SM-T525|SM-T530NU|SM-T230NU|SM-T330NU|SM-T900|XE500T1C|SM-P605V|SM-P905V|SM-T337V|SM-T537V|SM-T707V|SM-T807V|SM-P600X|SM-P900X|SM-T210X|SM-T230|SM-T230X|SM-T325|GT-P7503|SM-T531|SM-T330|SM-T530|SM-T705|SM-T705C|SM-T535|SM-T331|SM-T800|SM-T700|SM-T537|SM-T807|SM-P907A|SM-T337A|SM-T537A|SM-T707A|SM-T807A|SM-T237|SM-T807P|SM-P607T|SM-T217T|SM-T337T|SM-T807T|SM-T116NQ|SM-T116BU|SM-P550|SM-T350|SM-T550|SM-T9000|SM-P9000|SM-T705Y|SM-T805|GT-P3113|SM-T710|SM-T810|SM-T815|SM-T360|SM-T533|SM-T113|SM-T335|SM-T715|SM-T560|SM-T670|SM-T677|SM-T377|SM-T567|SM-T357T|SM-T555|SM-T561|SM-T713|SM-T719|SM-T813|SM-T819|SM-T580|SM-T355Y?|SM-T280|SM-T817A|SM-T820|SM-W700|SM-P580|SM-T587|SM-P350|SM-P555M|SM-P355M|SM-T113NU|SM-T815Y|SM-T585|SM-T285|SM-T825|SM-W708|SM-T835|SM-T830|SM-T837V|SM-T720|SM-T510|SM-T387V|SM-P610|SM-T290|SM-T515|SM-T590|SM-T595|SM-T725|SM-T817P|SM-P585N0|SM-T395|SM-T295|SM-T865|SM-P610N|SM-P615|SM-T970|SM-T380|SM-T5950|SM-T905|SM-T231|SM-T500|SM-T860",
        "Kindle": "Kindle|Silk.*Accelerated|Android.*\\b(KFOT|KFTT|KFJWI|KFJWA|KFOTE|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|WFJWAE|KFSAWA|KFSAWI|KFASWI|KFARWI|KFFOWI|KFGIWI|KFMEWI)\\b|Android.*Silk\/[0-9.]+ like Chrome\/[0-9.]+ (?!Mobile)",
        "SurfaceTablet": "Windows NT [0-9.]+; ARM;.*(Tablet|ARMBJS)",
        "HPTablet": "HP Slate (7|8|10)|HP ElitePad 900|hp-tablet|EliteBook.*Touch|HP 8|Slate 21|HP SlateBook 10",
        "AsusTablet": "^.*PadFone((?!Mobile).)*$|Transformer|TF101|TF101G|TF300T|TF300TG|TF300TL|TF700T|TF700KL|TF701T|TF810C|ME171|ME301T|ME302C|ME371MG|ME370T|ME372MG|ME172V|ME173X|ME400C|Slider SL101|\\bK00F\\b|\\bK00C\\b|\\bK00E\\b|\\bK00L\\b|TX201LA|ME176C|ME102A|\\bM80TA\\b|ME372CL|ME560CG|ME372CG|ME302KL| K010 | K011 | K017 | K01E |ME572C|ME103K|ME170C|ME171C|\\bME70C\\b|ME581C|ME581CL|ME8510C|ME181C|P01Y|PO1MA|P01Z|\\bP027\\b|\\bP024\\b|\\bP00C\\b",
        "BlackBerryTablet": "PlayBook|RIM Tablet",
        "HTCtablet": "HTC_Flyer_P512|HTC Flyer|HTC Jetstream|HTC-P715a|HTC EVO View 4G|PG41200|PG09410",
        "MotorolaTablet": "xoom|sholest|MZ615|MZ605|MZ505|MZ601|MZ602|MZ603|MZ604|MZ606|MZ607|MZ608|MZ609|MZ615|MZ616|MZ617",
        "NookTablet": "Android.*Nook|NookColor|nook browser|BNRV200|BNRV200A|BNTV250|BNTV250A|BNTV400|BNTV600|LogicPD Zoom2",
        "AcerTablet": "Android.*; \\b(A100|A101|A110|A200|A210|A211|A500|A501|A510|A511|A700|A701|W500|W500P|W501|W501P|W510|W511|W700|G100|G100W|B1-A71|B1-710|B1-711|A1-810|A1-811|A1-830)\\b|W3-810|\\bA3-A10\\b|\\bA3-A11\\b|\\bA3-A20\\b|\\bA3-A30|A3-A40",
        "ToshibaTablet": "Android.*(AT100|AT105|AT200|AT205|AT270|AT275|AT300|AT305|AT1S5|AT500|AT570|AT700|AT830)|TOSHIBA.*FOLIO",
        "LGTablet": "\\bL-06C|LG-V909|LG-V900|LG-V700|LG-V510|LG-V500|LG-V410|LG-V400|LG-VK810\\b",
        "FujitsuTablet": "Android.*\\b(F-01D|F-02F|F-05E|F-10D|M532|Q572)\\b",
        "PrestigioTablet": "PMP3170B|PMP3270B|PMP3470B|PMP7170B|PMP3370B|PMP3570C|PMP5870C|PMP3670B|PMP5570C|PMP5770D|PMP3970B|PMP3870C|PMP5580C|PMP5880D|PMP5780D|PMP5588C|PMP7280C|PMP7280C3G|PMP7280|PMP7880D|PMP5597D|PMP5597|PMP7100D|PER3464|PER3274|PER3574|PER3884|PER5274|PER5474|PMP5097CPRO|PMP5097|PMP7380D|PMP5297C|PMP5297C_QUAD|PMP812E|PMP812E3G|PMP812F|PMP810E|PMP880TD|PMT3017|PMT3037|PMT3047|PMT3057|PMT7008|PMT5887|PMT5001|PMT5002",
        "LenovoTablet": "Lenovo TAB|Idea(Tab|Pad)( A1|A10| K1|)|ThinkPad([ ]+)?Tablet|YT3-850M|YT3-X90L|YT3-X90F|YT3-X90X|Lenovo.*(S2109|S2110|S5000|S6000|K3011|A3000|A3500|A1000|A2107|A2109|A1107|A5500|A7600|B6000|B8000|B8080)(-|)(FL|F|HV|H|)|TB-X103F|TB-X304X|TB-X304F|TB-X304L|TB-X505F|TB-X505L|TB-X505X|TB-X605F|TB-X605L|TB-8703F|TB-8703X|TB-8703N|TB-8704N|TB-8704F|TB-8704X|TB-8704V|TB-7304F|TB-7304I|TB-7304X|Tab2A7-10F|Tab2A7-20F|TB2-X30L|YT3-X50L|YT3-X50F|YT3-X50M|YT-X705F|YT-X703F|YT-X703L|YT-X705L|YT-X705X|TB2-X30F|TB2-X30L|TB2-X30M|A2107A-F|A2107A-H|TB3-730F|TB3-730M|TB3-730X|TB-7504F|TB-7504X|TB-X704F|TB-X104F|TB3-X70F|TB-X705F|TB-8504F|TB3-X70L|TB3-710F|TB-X704L",
        "DellTablet": "Venue 11|Venue 8|Venue 7|Dell Streak 10|Dell Streak 7",
        "YarvikTablet": "Android.*\\b(TAB210|TAB211|TAB224|TAB250|TAB260|TAB264|TAB310|TAB360|TAB364|TAB410|TAB411|TAB420|TAB424|TAB450|TAB460|TAB461|TAB464|TAB465|TAB467|TAB468|TAB07-100|TAB07-101|TAB07-150|TAB07-151|TAB07-152|TAB07-200|TAB07-201-3G|TAB07-210|TAB07-211|TAB07-212|TAB07-214|TAB07-220|TAB07-400|TAB07-485|TAB08-150|TAB08-200|TAB08-201-3G|TAB08-201-30|TAB09-100|TAB09-211|TAB09-410|TAB10-150|TAB10-201|TAB10-211|TAB10-400|TAB10-410|TAB13-201|TAB274EUK|TAB275EUK|TAB374EUK|TAB462EUK|TAB474EUK|TAB9-200)\\b",
        "MedionTablet": "Android.*\\bOYO\\b|LIFE.*(P9212|P9514|P9516|S9512)|LIFETAB",
        "ArnovaTablet": "97G4|AN10G2|AN7bG3|AN7fG3|AN8G3|AN8cG3|AN7G3|AN9G3|AN7dG3|AN7dG3ST|AN7dG3ChildPad|AN10bG3|AN10bG3DT|AN9G2",
        "IntensoTablet": "INM8002KP|INM1010FP|INM805ND|Intenso Tab|TAB1004",
        "IRUTablet": "M702pro",
        "MegafonTablet": "MegaFon V9|\\bZTE V9\\b|Android.*\\bMT7A\\b",
        "EbodaTablet": "E-Boda (Supreme|Impresspeed|Izzycomm|Essential)",
        "AllViewTablet": "Allview.*(Viva|Alldro|City|Speed|All TV|Frenzy|Quasar|Shine|TX1|AX1|AX2)",
        "ArchosTablet": "\\b(101G9|80G9|A101IT)\\b|Qilive 97R|Archos5|\\bARCHOS (70|79|80|90|97|101|FAMILYPAD|)(b|c|)(G10| Cobalt| TITANIUM(HD|)| Xenon| Neon|XSK| 2| XS 2| PLATINUM| CARBON|GAMEPAD)\\b",
        "AinolTablet": "NOVO7|NOVO8|NOVO10|Novo7Aurora|Novo7Basic|NOVO7PALADIN|novo9-Spark",
        "NokiaLumiaTablet": "Lumia 2520",
        "SonyTablet": "Sony.*Tablet|Xperia Tablet|Sony Tablet S|SO-03E|SGPT12|SGPT13|SGPT114|SGPT121|SGPT122|SGPT123|SGPT111|SGPT112|SGPT113|SGPT131|SGPT132|SGPT133|SGPT211|SGPT212|SGPT213|SGP311|SGP312|SGP321|EBRD1101|EBRD1102|EBRD1201|SGP351|SGP341|SGP511|SGP512|SGP521|SGP541|SGP551|SGP621|SGP641|SGP612|SOT31|SGP771|SGP611|SGP612|SGP712",
        "PhilipsTablet": "\\b(PI2010|PI3000|PI3100|PI3105|PI3110|PI3205|PI3210|PI3900|PI4010|PI7000|PI7100)\\b",
        "CubeTablet": "Android.*(K8GT|U9GT|U10GT|U16GT|U17GT|U18GT|U19GT|U20GT|U23GT|U30GT)|CUBE U8GT",
        "CobyTablet": "MID1042|MID1045|MID1125|MID1126|MID7012|MID7014|MID7015|MID7034|MID7035|MID7036|MID7042|MID7048|MID7127|MID8042|MID8048|MID8127|MID9042|MID9740|MID9742|MID7022|MID7010",
        "MIDTablet": "M9701|M9000|M9100|M806|M1052|M806|T703|MID701|MID713|MID710|MID727|MID760|MID830|MID728|MID933|MID125|MID810|MID732|MID120|MID930|MID800|MID731|MID900|MID100|MID820|MID735|MID980|MID130|MID833|MID737|MID960|MID135|MID860|MID736|MID140|MID930|MID835|MID733|MID4X10",
        "MSITablet": "MSI \\b(Primo 73K|Primo 73L|Primo 81L|Primo 77|Primo 93|Primo 75|Primo 76|Primo 73|Primo 81|Primo 91|Primo 90|Enjoy 71|Enjoy 7|Enjoy 10)\\b",
        "SMiTTablet": "Android.*(\\bMID\\b|MID-560|MTV-T1200|MTV-PND531|MTV-P1101|MTV-PND530)",
        "RockChipTablet": "Android.*(RK2818|RK2808A|RK2918|RK3066)|RK2738|RK2808A",
        "FlyTablet": "IQ310|Fly Vision",
        "bqTablet": "Android.*(bq)?.*\\b(Elcano|Curie|Edison|Maxwell|Kepler|Pascal|Tesla|Hypatia|Platon|Newton|Livingstone|Cervantes|Avant|Aquaris ([E|M]10|M8))\\b|Maxwell.*Lite|Maxwell.*Plus",
        "HuaweiTablet": "MediaPad|MediaPad 7 Youth|IDEOS S7|S7-201c|S7-202u|S7-101|S7-103|S7-104|S7-105|S7-106|S7-201|S7-Slim|M2-A01L|BAH-L09|BAH-W09|AGS-L09|CMR-AL19",
        "NecTablet": "\\bN-06D|\\bN-08D",
        "PantechTablet": "Pantech.*P4100",
        "BronchoTablet": "Broncho.*(N701|N708|N802|a710)",
        "VersusTablet": "TOUCHPAD.*[78910]|\\bTOUCHTAB\\b",
        "ZyncTablet": "z1000|Z99 2G|z930|z990|z909|Z919|z900",
        "PositivoTablet": "TB07STA|TB10STA|TB07FTA|TB10FTA",
        "NabiTablet": "Android.*\\bNabi",
        "KoboTablet": "Kobo Touch|\\bK080\\b|\\bVox\\b Build|\\bArc\\b Build",
        "DanewTablet": "DSlide.*\\b(700|701R|702|703R|704|802|970|971|972|973|974|1010|1012)\\b",
        "TexetTablet": "NaviPad|TB-772A|TM-7045|TM-7055|TM-9750|TM-7016|TM-7024|TM-7026|TM-7041|TM-7043|TM-7047|TM-8041|TM-9741|TM-9747|TM-9748|TM-9751|TM-7022|TM-7021|TM-7020|TM-7011|TM-7010|TM-7023|TM-7025|TM-7037W|TM-7038W|TM-7027W|TM-9720|TM-9725|TM-9737W|TM-1020|TM-9738W|TM-9740|TM-9743W|TB-807A|TB-771A|TB-727A|TB-725A|TB-719A|TB-823A|TB-805A|TB-723A|TB-715A|TB-707A|TB-705A|TB-709A|TB-711A|TB-890HD|TB-880HD|TB-790HD|TB-780HD|TB-770HD|TB-721HD|TB-710HD|TB-434HD|TB-860HD|TB-840HD|TB-760HD|TB-750HD|TB-740HD|TB-730HD|TB-722HD|TB-720HD|TB-700HD|TB-500HD|TB-470HD|TB-431HD|TB-430HD|TB-506|TB-504|TB-446|TB-436|TB-416|TB-146SE|TB-126SE",
        "PlaystationTablet": "Playstation.*(Portable|Vita)",
        "TrekstorTablet": "ST10416-1|VT10416-1|ST70408-1|ST702xx-1|ST702xx-2|ST80208|ST97216|ST70104-2|VT10416-2|ST10216-2A|SurfTab",
        "PyleAudioTablet": "\\b(PTBL10CEU|PTBL10C|PTBL72BC|PTBL72BCEU|PTBL7CEU|PTBL7C|PTBL92BC|PTBL92BCEU|PTBL9CEU|PTBL9CUK|PTBL9C)\\b",
        "AdvanTablet": "Android.* \\b(E3A|T3X|T5C|T5B|T3E|T3C|T3B|T1J|T1F|T2A|T1H|T1i|E1C|T1-E|T5-A|T4|E1-B|T2Ci|T1-B|T1-D|O1-A|E1-A|T1-A|T3A|T4i)\\b ",
        "DanyTechTablet": "Genius Tab G3|Genius Tab S2|Genius Tab Q3|Genius Tab G4|Genius Tab Q4|Genius Tab G-II|Genius TAB GII|Genius TAB GIII|Genius Tab S1",
        "GalapadTablet": "Android [0-9.]+; [a-z-]+; \\bG1\\b",
        "MicromaxTablet": "Funbook|Micromax.*\\b(P250|P560|P360|P362|P600|P300|P350|P500|P275)\\b",
        "KarbonnTablet": "Android.*\\b(A39|A37|A34|ST8|ST10|ST7|Smart Tab3|Smart Tab2)\\b",
        "AllFineTablet": "Fine7 Genius|Fine7 Shine|Fine7 Air|Fine8 Style|Fine9 More|Fine10 Joy|Fine11 Wide",
        "PROSCANTablet": "\\b(PEM63|PLT1023G|PLT1041|PLT1044|PLT1044G|PLT1091|PLT4311|PLT4311PL|PLT4315|PLT7030|PLT7033|PLT7033D|PLT7035|PLT7035D|PLT7044K|PLT7045K|PLT7045KB|PLT7071KG|PLT7072|PLT7223G|PLT7225G|PLT7777G|PLT7810K|PLT7849G|PLT7851G|PLT7852G|PLT8015|PLT8031|PLT8034|PLT8036|PLT8080K|PLT8082|PLT8088|PLT8223G|PLT8234G|PLT8235G|PLT8816K|PLT9011|PLT9045K|PLT9233G|PLT9735|PLT9760G|PLT9770G)\\b",
        "YONESTablet": "BQ1078|BC1003|BC1077|RK9702|BC9730|BC9001|IT9001|BC7008|BC7010|BC708|BC728|BC7012|BC7030|BC7027|BC7026",
        "ChangJiaTablet": "TPC7102|TPC7103|TPC7105|TPC7106|TPC7107|TPC7201|TPC7203|TPC7205|TPC7210|TPC7708|TPC7709|TPC7712|TPC7110|TPC8101|TPC8103|TPC8105|TPC8106|TPC8203|TPC8205|TPC8503|TPC9106|TPC9701|TPC97101|TPC97103|TPC97105|TPC97106|TPC97111|TPC97113|TPC97203|TPC97603|TPC97809|TPC97205|TPC10101|TPC10103|TPC10106|TPC10111|TPC10203|TPC10205|TPC10503",
        "GUTablet": "TX-A1301|TX-M9002|Q702|kf026",
        "PointOfViewTablet": "TAB-P506|TAB-navi-7-3G-M|TAB-P517|TAB-P-527|TAB-P701|TAB-P703|TAB-P721|TAB-P731N|TAB-P741|TAB-P825|TAB-P905|TAB-P925|TAB-PR945|TAB-PL1015|TAB-P1025|TAB-PI1045|TAB-P1325|TAB-PROTAB[0-9]+|TAB-PROTAB25|TAB-PROTAB26|TAB-PROTAB27|TAB-PROTAB26XL|TAB-PROTAB2-IPS9|TAB-PROTAB30-IPS9|TAB-PROTAB25XXL|TAB-PROTAB26-IPS10|TAB-PROTAB30-IPS10",
        "OvermaxTablet": "OV-(SteelCore|NewBase|Basecore|Baseone|Exellen|Quattor|EduTab|Solution|ACTION|BasicTab|TeddyTab|MagicTab|Stream|TB-08|TB-09)|Qualcore 1027",
        "HCLTablet": "HCL.*Tablet|Connect-3G-2.0|Connect-2G-2.0|ME Tablet U1|ME Tablet U2|ME Tablet G1|ME Tablet X1|ME Tablet Y2|ME Tablet Sync",
        "DPSTablet": "DPS Dream 9|DPS Dual 7",
        "VistureTablet": "V97 HD|i75 3G|Visture V4( HD)?|Visture V5( HD)?|Visture V10",
        "CrestaTablet": "CTP(-)?810|CTP(-)?818|CTP(-)?828|CTP(-)?838|CTP(-)?888|CTP(-)?978|CTP(-)?980|CTP(-)?987|CTP(-)?988|CTP(-)?989",
        "MediatekTablet": "\\bMT8125|MT8389|MT8135|MT8377\\b",
        "ConcordeTablet": "Concorde([ ]+)?Tab|ConCorde ReadMan",
        "GoCleverTablet": "GOCLEVER TAB|A7GOCLEVER|M1042|M7841|M742|R1042BK|R1041|TAB A975|TAB A7842|TAB A741|TAB A741L|TAB M723G|TAB M721|TAB A1021|TAB I921|TAB R721|TAB I720|TAB T76|TAB R70|TAB R76.2|TAB R106|TAB R83.2|TAB M813G|TAB I721|GCTA722|TAB I70|TAB I71|TAB S73|TAB R73|TAB R74|TAB R93|TAB R75|TAB R76.1|TAB A73|TAB A93|TAB A93.2|TAB T72|TAB R83|TAB R974|TAB R973|TAB A101|TAB A103|TAB A104|TAB A104.2|R105BK|M713G|A972BK|TAB A971|TAB R974.2|TAB R104|TAB R83.3|TAB A1042",
        "ModecomTablet": "FreeTAB 9000|FreeTAB 7.4|FreeTAB 7004|FreeTAB 7800|FreeTAB 2096|FreeTAB 7.5|FreeTAB 1014|FreeTAB 1001 |FreeTAB 8001|FreeTAB 9706|FreeTAB 9702|FreeTAB 7003|FreeTAB 7002|FreeTAB 1002|FreeTAB 7801|FreeTAB 1331|FreeTAB 1004|FreeTAB 8002|FreeTAB 8014|FreeTAB 9704|FreeTAB 1003",
        "VoninoTablet": "\\b(Argus[ _]?S|Diamond[ _]?79HD|Emerald[ _]?78E|Luna[ _]?70C|Onyx[ _]?S|Onyx[ _]?Z|Orin[ _]?HD|Orin[ _]?S|Otis[ _]?S|SpeedStar[ _]?S|Magnet[ _]?M9|Primus[ _]?94[ _]?3G|Primus[ _]?94HD|Primus[ _]?QS|Android.*\\bQ8\\b|Sirius[ _]?EVO[ _]?QS|Sirius[ _]?QS|Spirit[ _]?S)\\b",
        "ECSTablet": "V07OT2|TM105A|S10OT1|TR10CS1",
        "StorexTablet": "eZee[_']?(Tab|Go)[0-9]+|TabLC7|Looney Tunes Tab",
        "VodafoneTablet": "SmartTab([ ]+)?[0-9]+|SmartTabII10|SmartTabII7|VF-1497|VFD 1400",
        "EssentielBTablet": "Smart[ ']?TAB[ ]+?[0-9]+|Family[ ']?TAB2",
        "RossMoorTablet": "RM-790|RM-997|RMD-878G|RMD-974R|RMT-705A|RMT-701|RME-601|RMT-501|RMT-711",
        "iMobileTablet": "i-mobile i-note",
        "TolinoTablet": "tolino tab [0-9.]+|tolino shine",
        "AudioSonicTablet": "\\bC-22Q|T7-QC|T-17B|T-17P\\b",
        "AMPETablet": "Android.* A78 ",
        "SkkTablet": "Android.* (SKYPAD|PHOENIX|CYCLOPS)",
        "TecnoTablet": "TECNO P9|TECNO DP8D",
        "JXDTablet": "Android.* \\b(F3000|A3300|JXD5000|JXD3000|JXD2000|JXD300B|JXD300|S5800|S7800|S602b|S5110b|S7300|S5300|S602|S603|S5100|S5110|S601|S7100a|P3000F|P3000s|P101|P200s|P1000m|P200m|P9100|P1000s|S6600b|S908|P1000|P300|S18|S6600|S9100)\\b",
        "iJoyTablet": "Tablet (Spirit 7|Essentia|Galatea|Fusion|Onix 7|Landa|Titan|Scooby|Deox|Stella|Themis|Argon|Unique 7|Sygnus|Hexen|Finity 7|Cream|Cream X2|Jade|Neon 7|Neron 7|Kandy|Scape|Saphyr 7|Rebel|Biox|Rebel|Rebel 8GB|Myst|Draco 7|Myst|Tab7-004|Myst|Tadeo Jones|Tablet Boing|Arrow|Draco Dual Cam|Aurix|Mint|Amity|Revolution|Finity 9|Neon 9|T9w|Amity 4GB Dual Cam|Stone 4GB|Stone 8GB|Andromeda|Silken|X2|Andromeda II|Halley|Flame|Saphyr 9,7|Touch 8|Planet|Triton|Unique 10|Hexen 10|Memphis 4GB|Memphis 8GB|Onix 10)",
        "FX2Tablet": "FX2 PAD7|FX2 PAD10",
        "XoroTablet": "KidsPAD 701|PAD[ ]?712|PAD[ ]?714|PAD[ ]?716|PAD[ ]?717|PAD[ ]?718|PAD[ ]?720|PAD[ ]?721|PAD[ ]?722|PAD[ ]?790|PAD[ ]?792|PAD[ ]?900|PAD[ ]?9715D|PAD[ ]?9716DR|PAD[ ]?9718DR|PAD[ ]?9719QR|PAD[ ]?9720QR|TelePAD1030|Telepad1032|TelePAD730|TelePAD731|TelePAD732|TelePAD735Q|TelePAD830|TelePAD9730|TelePAD795|MegaPAD 1331|MegaPAD 1851|MegaPAD 2151",
        "ViewsonicTablet": "ViewPad 10pi|ViewPad 10e|ViewPad 10s|ViewPad E72|ViewPad7|ViewPad E100|ViewPad 7e|ViewSonic VB733|VB100a",
        "VerizonTablet": "QTAQZ3|QTAIR7|QTAQTZ3|QTASUN1|QTASUN2|QTAXIA1",
        "OdysTablet": "LOOX|XENO10|ODYS[ -](Space|EVO|Xpress|NOON)|\\bXELIO\\b|Xelio10Pro|XELIO7PHONETAB|XELIO10EXTREME|XELIOPT2|NEO_QUAD10",
        "CaptivaTablet": "CAPTIVA PAD",
        "IconbitTablet": "NetTAB|NT-3702|NT-3702S|NT-3702S|NT-3603P|NT-3603P|NT-0704S|NT-0704S|NT-3805C|NT-3805C|NT-0806C|NT-0806C|NT-0909T|NT-0909T|NT-0907S|NT-0907S|NT-0902S|NT-0902S",
        "TeclastTablet": "T98 4G|\\bP80\\b|\\bX90HD\\b|X98 Air|X98 Air 3G|\\bX89\\b|P80 3G|\\bX80h\\b|P98 Air|\\bX89HD\\b|P98 3G|\\bP90HD\\b|P89 3G|X98 3G|\\bP70h\\b|P79HD 3G|G18d 3G|\\bP79HD\\b|\\bP89s\\b|\\bA88\\b|\\bP10HD\\b|\\bP19HD\\b|G18 3G|\\bP78HD\\b|\\bA78\\b|\\bP75\\b|G17s 3G|G17h 3G|\\bP85t\\b|\\bP90\\b|\\bP11\\b|\\bP98t\\b|\\bP98HD\\b|\\bG18d\\b|\\bP85s\\b|\\bP11HD\\b|\\bP88s\\b|\\bA80HD\\b|\\bA80se\\b|\\bA10h\\b|\\bP89\\b|\\bP78s\\b|\\bG18\\b|\\bP85\\b|\\bA70h\\b|\\bA70\\b|\\bG17\\b|\\bP18\\b|\\bA80s\\b|\\bA11s\\b|\\bP88HD\\b|\\bA80h\\b|\\bP76s\\b|\\bP76h\\b|\\bP98\\b|\\bA10HD\\b|\\bP78\\b|\\bP88\\b|\\bA11\\b|\\bA10t\\b|\\bP76a\\b|\\bP76t\\b|\\bP76e\\b|\\bP85HD\\b|\\bP85a\\b|\\bP86\\b|\\bP75HD\\b|\\bP76v\\b|\\bA12\\b|\\bP75a\\b|\\bA15\\b|\\bP76Ti\\b|\\bP81HD\\b|\\bA10\\b|\\bT760VE\\b|\\bT720HD\\b|\\bP76\\b|\\bP73\\b|\\bP71\\b|\\bP72\\b|\\bT720SE\\b|\\bC520Ti\\b|\\bT760\\b|\\bT720VE\\b|T720-3GE|T720-WiFi",
        "OndaTablet": "\\b(V975i|Vi30|VX530|V701|Vi60|V701s|Vi50|V801s|V719|Vx610w|VX610W|V819i|Vi10|VX580W|Vi10|V711s|V813|V811|V820w|V820|Vi20|V711|VI30W|V712|V891w|V972|V819w|V820w|Vi60|V820w|V711|V813s|V801|V819|V975s|V801|V819|V819|V818|V811|V712|V975m|V101w|V961w|V812|V818|V971|V971s|V919|V989|V116w|V102w|V973|Vi40)\\b[\\s]+|V10 \\b4G\\b",
        "JaytechTablet": "TPC-PA762",
        "BlaupunktTablet": "Endeavour 800NG|Endeavour 1010",
        "DigmaTablet": "\\b(iDx10|iDx9|iDx8|iDx7|iDxD7|iDxD8|iDsQ8|iDsQ7|iDsQ8|iDsD10|iDnD7|3TS804H|iDsQ11|iDj7|iDs10)\\b",
        "EvolioTablet": "ARIA_Mini_wifi|Aria[ _]Mini|Evolio X10|Evolio X7|Evolio X8|\\bEvotab\\b|\\bNeura\\b",
        "LavaTablet": "QPAD E704|\\bIvoryS\\b|E-TAB IVORY|\\bE-TAB\\b",
        "AocTablet": "MW0811|MW0812|MW0922|MTK8382|MW1031|MW0831|MW0821|MW0931|MW0712",
        "MpmanTablet": "MP11 OCTA|MP10 OCTA|MPQC1114|MPQC1004|MPQC994|MPQC974|MPQC973|MPQC804|MPQC784|MPQC780|\\bMPG7\\b|MPDCG75|MPDCG71|MPDC1006|MP101DC|MPDC9000|MPDC905|MPDC706HD|MPDC706|MPDC705|MPDC110|MPDC100|MPDC99|MPDC97|MPDC88|MPDC8|MPDC77|MP709|MID701|MID711|MID170|MPDC703|MPQC1010",
        "CelkonTablet": "CT695|CT888|CT[\\s]?910|CT7 Tab|CT9 Tab|CT3 Tab|CT2 Tab|CT1 Tab|C820|C720|\\bCT-1\\b",
        "WolderTablet": "miTab \\b(DIAMOND|SPACE|BROOKLYN|NEO|FLY|MANHATTAN|FUNK|EVOLUTION|SKY|GOCAR|IRON|GENIUS|POP|MINT|EPSILON|BROADWAY|JUMP|HOP|LEGEND|NEW AGE|LINE|ADVANCE|FEEL|FOLLOW|LIKE|LINK|LIVE|THINK|FREEDOM|CHICAGO|CLEVELAND|BALTIMORE-GH|IOWA|BOSTON|SEATTLE|PHOENIX|DALLAS|IN 101|MasterChef)\\b",
        "MediacomTablet": "M-MPI10C3G|M-SP10EG|M-SP10EGP|M-SP10HXAH|M-SP7HXAH|M-SP10HXBH|M-SP8HXAH|M-SP8MXA",
        "MiTablet": "\\bMI PAD\\b|\\bHM NOTE 1W\\b",
        "NibiruTablet": "Nibiru M1|Nibiru Jupiter One",
        "NexoTablet": "NEXO NOVA|NEXO 10|NEXO AVIO|NEXO FREE|NEXO GO|NEXO EVO|NEXO 3G|NEXO SMART|NEXO KIDDO|NEXO MOBI",
        "LeaderTablet": "TBLT10Q|TBLT10I|TBL-10WDKB|TBL-10WDKBO2013|TBL-W230V2|TBL-W450|TBL-W500|SV572|TBLT7I|TBA-AC7-8G|TBLT79|TBL-8W16|TBL-10W32|TBL-10WKB|TBL-W100",
        "UbislateTablet": "UbiSlate[\\s]?7C",
        "PocketBookTablet": "Pocketbook",
        "KocasoTablet": "\\b(TB-1207)\\b",
        "HisenseTablet": "\\b(F5281|E2371)\\b",
        "Hudl": "Hudl HT7S3|Hudl 2",
        "TelstraTablet": "T-Hub2",
        "GenericTablet": "Android.*\\b97D\\b|Tablet(?!.*PC)|BNTV250A|MID-WCDMA|LogicPD Zoom2|\\bA7EB\\b|CatNova8|A1_07|CT704|CT1002|\\bM721\\b|rk30sdk|\\bEVOTAB\\b|M758A|ET904|ALUMIUM10|Smartfren Tab|Endeavour 1010|Tablet-PC-4|Tagi Tab|\\bM6pro\\b|CT1020W|arc 10HD|\\bTP750\\b|\\bQTAQZ3\\b|WVT101|TM1088|KT107"
    },
    "oss": {
        "AndroidOS": "Android",
        "BlackBerryOS": "blackberry|\\bBB10\\b|rim tablet os",
        "PalmOS": "PalmOS|avantgo|blazer|elaine|hiptop|palm|plucker|xiino",
        "SymbianOS": "Symbian|SymbOS|Series60|Series40|SYB-[0-9]+|\\bS60\\b",
        "WindowsMobileOS": "Windows CE.*(PPC|Smartphone|Mobile|[0-9]{3}x[0-9]{3})|Windows Mobile|Windows Phone [0-9.]+|WCE;",
        "WindowsPhoneOS": "Windows Phone 10.0|Windows Phone 8.1|Windows Phone 8.0|Windows Phone OS|XBLWP7|ZuneWP7|Windows NT 6.[23]; ARM;",
        "iOS": "\\biPhone.*Mobile|\\biPod|\\biPad|AppleCoreMedia",
        "iPadOS": "CPU OS 13",
        "SailfishOS": "Sailfish",
        "MeeGoOS": "MeeGo",
        "MaemoOS": "Maemo",
        "JavaOS": "J2ME\/|\\bMIDP\\b|\\bCLDC\\b",
        "webOS": "webOS|hpwOS",
        "badaOS": "\\bBada\\b",
        "BREWOS": "BREW"
    },
    "uas": {
        "Chrome": "\\bCrMo\\b|CriOS|Android.*Chrome\/[.0-9]* (Mobile)?",
        "Dolfin": "\\bDolfin\\b",
        "Opera": "Opera.*Mini|Opera.*Mobi|Android.*Opera|Mobile.*OPR\/[0-9.]+$|Coast\/[0-9.]+",
        "Skyfire": "Skyfire",
        "Edge": "\\bEdgiOS\\b|Mobile Safari\/[.0-9]* Edge",
        "IE": "IEMobile|MSIEMobile",
        "Firefox": "fennec|firefox.*maemo|(Mobile|Tablet).*Firefox|Firefox.*Mobile|FxiOS",
        "Bolt": "bolt",
        "TeaShark": "teashark",
        "Blazer": "Blazer",
        "Safari": "Version((?!\\bEdgiOS\\b).)*Mobile.*Safari|Safari.*Mobile|MobileSafari",
        "WeChat": "\\bMicroMessenger\\b",
        "UCBrowser": "UC.*Browser|UCWEB",
        "baiduboxapp": "baiduboxapp",
        "baidubrowser": "baidubrowser",
        "DiigoBrowser": "DiigoBrowser",
        "Mercury": "\\bMercury\\b",
        "ObigoBrowser": "Obigo",
        "NetFront": "NF-Browser",
        "GenericBrowser": "NokiaBrowser|OviBrowser|OneBrowser|TwonkyBeamBrowser|SEMC.*Browser|FlyFlow|Minimo|NetFront|Novarra-Vision|MQQBrowser|MicroMessenger",
        "PaleMoon": "Android.*PaleMoon|Mobile.*PaleMoon"
    },
    "props": {
        "Mobile": "Mobile\/[VER]",
        "Build": "Build\/[VER]",
        "Version": "Version\/[VER]",
        "VendorID": "VendorID\/[VER]",
        "iPad": "iPad.*CPU[a-z ]+[VER]",
        "iPhone": "iPhone.*CPU[a-z ]+[VER]",
        "iPod": "iPod.*CPU[a-z ]+[VER]",
        "Kindle": "Kindle\/[VER]",
        "Chrome": [
            "Chrome\/[VER]",
            "CriOS\/[VER]",
            "CrMo\/[VER]"
        ],
        "Coast": [
            "Coast\/[VER]"
        ],
        "Dolfin": "Dolfin\/[VER]",
        "Firefox": [
            "Firefox\/[VER]",
            "FxiOS\/[VER]"
        ],
        "Fennec": "Fennec\/[VER]",
        "Edge": "Edge\/[VER]",
        "IE": [
            "IEMobile\/[VER];",
            "IEMobile [VER]",
            "MSIE [VER];",
            "Trident\/[0-9.]+;.*rv:[VER]"
        ],
        "NetFront": "NetFront\/[VER]",
        "NokiaBrowser": "NokiaBrowser\/[VER]",
        "Opera": [
            " OPR\/[VER]",
            "Opera Mini\/[VER]",
            "Version\/[VER]"
        ],
        "Opera Mini": "Opera Mini\/[VER]",
        "Opera Mobi": "Version\/[VER]",
        "UCBrowser": [
            "UCWEB[VER]",
            "UC.*Browser\/[VER]"
        ],
        "MQQBrowser": "MQQBrowser\/[VER]",
        "MicroMessenger": "MicroMessenger\/[VER]",
        "baiduboxapp": "baiduboxapp\/[VER]",
        "baidubrowser": "baidubrowser\/[VER]",
        "SamsungBrowser": "SamsungBrowser\/[VER]",
        "Iron": "Iron\/[VER]",
        "Safari": [
            "Version\/[VER]",
            "Safari\/[VER]"
        ],
        "Skyfire": "Skyfire\/[VER]",
        "Tizen": "Tizen\/[VER]",
        "Webkit": "webkit[ \/][VER]",
        "PaleMoon": "PaleMoon\/[VER]",
        "SailfishBrowser": "SailfishBrowser\/[VER]",
        "Gecko": "Gecko\/[VER]",
        "Trident": "Trident\/[VER]",
        "Presto": "Presto\/[VER]",
        "Goanna": "Goanna\/[VER]",
        "iOS": " \\bi?OS\\b [VER][ ;]{1}",
        "Android": "Android [VER]",
        "Sailfish": "Sailfish [VER]",
        "BlackBerry": [
            "BlackBerry[\\w]+\/[VER]",
            "BlackBerry.*Version\/[VER]",
            "Version\/[VER]"
        ],
        "BREW": "BREW [VER]",
        "Java": "Java\/[VER]",
        "Windows Phone OS": [
            "Windows Phone OS [VER]",
            "Windows Phone [VER]"
        ],
        "Windows Phone": "Windows Phone [VER]",
        "Windows CE": "Windows CE\/[VER]",
        "Windows NT": "Windows NT [VER]",
        "Symbian": [
            "SymbianOS\/[VER]",
            "Symbian\/[VER]"
        ],
        "webOS": [
            "webOS\/[VER]",
            "hpwOS\/[VER];"
        ]
    },
    "utils": {
        "Bot": "Googlebot|facebookexternalhit|Google-AMPHTML|s~amp-validator|AdsBot-Google|Google Keyword Suggestion|Facebot|YandexBot|YandexMobileBot|bingbot|ia_archiver|AhrefsBot|Ezooms|GSLFbot|WBSearchBot|Twitterbot|TweetmemeBot|Twikle|PaperLiBot|Wotbox|UnwindFetchor|Exabot|MJ12bot|YandexImages|TurnitinBot|Pingdom|contentkingapp|AspiegelBot",
        "MobileBot": "Googlebot-Mobile|AdsBot-Google-Mobile|YahooSeeker\/M1A1-R2D2",
        "DesktopMode": "WPDesktop",
        "TV": "SonyDTV|HbbTV",
        "WebKit": "(webkit)[ \/]([\\w.]+)",
        "Console": "\\b(Nintendo|Nintendo WiiU|Nintendo 3DS|Nintendo Switch|PLAYSTATION|Xbox)\\b",
        "Watch": "SM-V700"
    }
};

    // following patterns come from http://detectmobilebrowsers.com/
    impl.detectMobileBrowsers = {
        fullPattern: /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i,
        shortPattern: /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i,
        tabletPattern: /android|ipad|playbook|silk/i
    };

    var hasOwnProp = Object.prototype.hasOwnProperty,
        isArray;

    impl.FALLBACK_PHONE = 'UnknownPhone';
    impl.FALLBACK_TABLET = 'UnknownTablet';
    impl.FALLBACK_MOBILE = 'UnknownMobile';

    isArray = ('isArray' in Array) ?
        Array.isArray : function (value) { return Object.prototype.toString.call(value) === '[object Array]'; };

    function equalIC(a, b) {
        return a != null && b != null && a.toLowerCase() === b.toLowerCase();
    }

    function containsIC(array, value) {
        var valueLC, i, len = array.length;
        if (!len || !value) {
            return false;
        }
        valueLC = value.toLowerCase();
        for (i = 0; i < len; ++i) {
            if (valueLC === array[i].toLowerCase()) {
                return true;
            }
        }
        return false;
    }

    function convertPropsToRegExp(object) {
        for (var key in object) {
            if (hasOwnProp.call(object, key)) {
                object[key] = new RegExp(object[key], 'i');
            }
        }
    }

    function prepareUserAgent(userAgent) {
        return (userAgent || '').substr(0, 500); // mitigate vulnerable to ReDoS
    }

    (function init() {
        var key, values, value, i, len, verPos, mobileDetectRules = impl.mobileDetectRules;
        for (key in mobileDetectRules.props) {
            if (hasOwnProp.call(mobileDetectRules.props, key)) {
                values = mobileDetectRules.props[key];
                if (!isArray(values)) {
                    values = [values];
                }
                len = values.length;
                for (i = 0; i < len; ++i) {
                    value = values[i];
                    verPos = value.indexOf('[VER]');
                    if (verPos >= 0) {
                        value = value.substring(0, verPos) + '([\\w._\\+]+)' + value.substring(verPos + 5);
                    }
                    values[i] = new RegExp(value, 'i');
                }
                mobileDetectRules.props[key] = values;
            }
        }
        convertPropsToRegExp(mobileDetectRules.oss);
        convertPropsToRegExp(mobileDetectRules.phones);
        convertPropsToRegExp(mobileDetectRules.tablets);
        convertPropsToRegExp(mobileDetectRules.uas);
        convertPropsToRegExp(mobileDetectRules.utils);

        // copy some patterns to oss0 which are tested first (see issue#15)
        mobileDetectRules.oss0 = {
            WindowsPhoneOS: mobileDetectRules.oss.WindowsPhoneOS,
            WindowsMobileOS: mobileDetectRules.oss.WindowsMobileOS
        };
    }());

    /**
     * Test userAgent string against a set of rules and find the first matched key.
     * @param {Object} rules (key is String, value is RegExp)
     * @param {String} userAgent the navigator.userAgent (or HTTP-Header 'User-Agent').
     * @returns {String|null} the matched key if found, otherwise <tt>null</tt>
     * @private
     */
    impl.findMatch = function(rules, userAgent) {
        for (var key in rules) {
            if (hasOwnProp.call(rules, key)) {
                if (rules[key].test(userAgent)) {
                    return key;
                }
            }
        }
        return null;
    };

    /**
     * Test userAgent string against a set of rules and return an array of matched keys.
     * @param {Object} rules (key is String, value is RegExp)
     * @param {String} userAgent the navigator.userAgent (or HTTP-Header 'User-Agent').
     * @returns {Array} an array of matched keys, may be empty when there is no match, but not <tt>null</tt>
     * @private
     */
    impl.findMatches = function(rules, userAgent) {
        var result = [];
        for (var key in rules) {
            if (hasOwnProp.call(rules, key)) {
                if (rules[key].test(userAgent)) {
                    result.push(key);
                }
            }
        }
        return result;
    };

    /**
     * Check the version of the given property in the User-Agent.
     *
     * @param {String} propertyName
     * @param {String} userAgent
     * @return {String} version or <tt>null</tt> if version not found
     * @private
     */
    impl.getVersionStr = function (propertyName, userAgent) {
        var props = impl.mobileDetectRules.props, patterns, i, len, match;
        if (hasOwnProp.call(props, propertyName)) {
            patterns = props[propertyName];
            len = patterns.length;
            for (i = 0; i < len; ++i) {
                match = patterns[i].exec(userAgent);
                if (match !== null) {
                    return match[1];
                }
            }
        }
        return null;
    };

    /**
     * Check the version of the given property in the User-Agent.
     * Will return a float number. (eg. 2_0 will return 2.0, 4.3.1 will return 4.31)
     *
     * @param {String} propertyName
     * @param {String} userAgent
     * @return {Number} version or <tt>NaN</tt> if version not found
     * @private
     */
    impl.getVersion = function (propertyName, userAgent) {
        var version = impl.getVersionStr(propertyName, userAgent);
        return version ? impl.prepareVersionNo(version) : NaN;
    };

    /**
     * Prepare the version number.
     *
     * @param {String} version
     * @return {Number} the version number as a floating number
     * @private
     */
    impl.prepareVersionNo = function (version) {
        var numbers;

        numbers = version.split(/[a-z._ \/\-]/i);
        if (numbers.length === 1) {
            version = numbers[0];
        }
        if (numbers.length > 1) {
            version = numbers[0] + '.';
            numbers.shift();
            version += numbers.join('');
        }
        return Number(version);
    };

    impl.isMobileFallback = function (userAgent) {
        return impl.detectMobileBrowsers.fullPattern.test(userAgent) ||
            impl.detectMobileBrowsers.shortPattern.test(userAgent.substr(0,4));
    };

    impl.isTabletFallback = function (userAgent) {
        return impl.detectMobileBrowsers.tabletPattern.test(userAgent);
    };

    impl.prepareDetectionCache = function (cache, userAgent, maxPhoneWidth) {
        if (cache.mobile !== undefined) {
            return;
        }
        var phone, tablet, phoneSized;

        // first check for stronger tablet rules, then phone (see issue#5)
        tablet = impl.findMatch(impl.mobileDetectRules.tablets, userAgent);
        if (tablet) {
            cache.mobile = cache.tablet = tablet;
            cache.phone = null;
            return; // unambiguously identified as tablet
        }

        phone = impl.findMatch(impl.mobileDetectRules.phones, userAgent);
        if (phone) {
            cache.mobile = cache.phone = phone;
            cache.tablet = null;
            return; // unambiguously identified as phone
        }

        // our rules haven't found a match -> try more general fallback rules
        if (impl.isMobileFallback(userAgent)) {
            phoneSized = MobileDetect.isPhoneSized(maxPhoneWidth);
            if (phoneSized === undefined) {
                cache.mobile = impl.FALLBACK_MOBILE;
                cache.tablet = cache.phone = null;
            } else if (phoneSized) {
                cache.mobile = cache.phone = impl.FALLBACK_PHONE;
                cache.tablet = null;
            } else {
                cache.mobile = cache.tablet = impl.FALLBACK_TABLET;
                cache.phone = null;
            }
        } else if (impl.isTabletFallback(userAgent)) {
            cache.mobile = cache.tablet = impl.FALLBACK_TABLET;
            cache.phone = null;
        } else {
            // not mobile at all!
            cache.mobile = cache.tablet = cache.phone = null;
        }
    };

    // t is a reference to a MobileDetect instance
    impl.mobileGrade = function (t) {
        // impl note:
        // To keep in sync w/ Mobile_Detect.php easily, the following code is tightly aligned to the PHP version.
        // When changes are made in Mobile_Detect.php, copy this method and replace:
        //     $this-> / t.
        //     self::MOBILE_GRADE_(.) / '$1'
        //     , self::VERSION_TYPE_FLOAT / (nothing)
        //     isIOS() / os('iOS')
        //     [reg] / (nothing)   <-- jsdelivr complaining about unescaped unicode character U+00AE
        var $isMobile = t.mobile() !== null;

        if (
            // Apple iOS 3.2-5.1 - Tested on the original iPad (4.3 / 5.0), iPad 2 (4.3), iPad 3 (5.1), original iPhone (3.1), iPhone 3 (3.2), 3GS (4.3), 4 (4.3 / 5.0), and 4S (5.1)
            t.os('iOS') && t.version('iPad')>=4.3 ||
            t.os('iOS') && t.version('iPhone')>=3.1 ||
            t.os('iOS') && t.version('iPod')>=3.1 ||

            // Android 2.1-2.3 - Tested on the HTC Incredible (2.2), original Droid (2.2), HTC Aria (2.1), Google Nexus S (2.3). Functional on 1.5 & 1.6 but performance may be sluggish, tested on Google G1 (1.5)
            // Android 3.1 (Honeycomb)  - Tested on the Samsung Galaxy Tab 10.1 and Motorola XOOM
            // Android 4.0 (ICS)  - Tested on a Galaxy Nexus. Note: transition performance can be poor on upgraded devices
            // Android 4.1 (Jelly Bean)  - Tested on a Galaxy Nexus and Galaxy 7
            ( t.version('Android')>2.1 && t.is('Webkit') ) ||

            // Windows Phone 7-7.5 - Tested on the HTC Surround (7.0) HTC Trophy (7.5), LG-E900 (7.5), Nokia Lumia 800
            t.version('Windows Phone OS')>=7.0 ||

            // Blackberry 7 - Tested on BlackBerry Torch 9810
            // Blackberry 6.0 - Tested on the Torch 9800 and Style 9670
            t.is('BlackBerry') && t.version('BlackBerry')>=6.0 ||
            // Blackberry Playbook (1.0-2.0) - Tested on PlayBook
            t.match('Playbook.*Tablet') ||

            // Palm WebOS (1.4-2.0) - Tested on the Palm Pixi (1.4), Pre (1.4), Pre 2 (2.0)
            ( t.version('webOS')>=1.4 && t.match('Palm|Pre|Pixi') ) ||
            // Palm WebOS 3.0  - Tested on HP TouchPad
            t.match('hp.*TouchPad') ||

            // Firefox Mobile (12 Beta) - Tested on Android 2.3 device
            ( t.is('Firefox') && t.version('Firefox')>=12 ) ||

            // Chrome for Android - Tested on Android 4.0, 4.1 device
            ( t.is('Chrome') && t.is('AndroidOS') && t.version('Android')>=4.0 ) ||

            // Skyfire 4.1 - Tested on Android 2.3 device
            ( t.is('Skyfire') && t.version('Skyfire')>=4.1 && t.is('AndroidOS') && t.version('Android')>=2.3 ) ||

            // Opera Mobile 11.5-12: Tested on Android 2.3
            ( t.is('Opera') && t.version('Opera Mobi')>11 && t.is('AndroidOS') ) ||

            // Meego 1.2 - Tested on Nokia 950 and N9
            t.is('MeeGoOS') ||

            // Tizen (pre-release) - Tested on early hardware
            t.is('Tizen') ||

            // Samsung Bada 2.0 - Tested on a Samsung Wave 3, Dolphin browser
            // @todo: more tests here!
            t.is('Dolfin') && t.version('Bada')>=2.0 ||

            // UC Browser - Tested on Android 2.3 device
            ( (t.is('UC Browser') || t.is('Dolfin')) && t.version('Android')>=2.3 ) ||

            // Kindle 3 and Fire  - Tested on the built-in WebKit browser for each
            ( t.match('Kindle Fire') ||
                t.is('Kindle') && t.version('Kindle')>=3.0 ) ||

            // Nook Color 1.4.1 - Tested on original Nook Color, not Nook Tablet
            t.is('AndroidOS') && t.is('NookTablet') ||

            // Chrome Desktop 11-21 - Tested on OS X 10.7 and Windows 7
            t.version('Chrome')>=11 && !$isMobile ||

            // Safari Desktop 4-5 - Tested on OS X 10.7 and Windows 7
            t.version('Safari')>=5.0 && !$isMobile ||

            // Firefox Desktop 4-13 - Tested on OS X 10.7 and Windows 7
            t.version('Firefox')>=4.0 && !$isMobile ||

            // Internet Explorer 7-9 - Tested on Windows XP, Vista and 7
            t.version('MSIE')>=7.0 && !$isMobile ||

            // Opera Desktop 10-12 - Tested on OS X 10.7 and Windows 7
            // @reference: http://my.opera.com/community/openweb/idopera/
            t.version('Opera')>=10 && !$isMobile

            ){
            return 'A';
        }

        if (
            t.os('iOS') && t.version('iPad')<4.3 ||
            t.os('iOS') && t.version('iPhone')<3.1 ||
            t.os('iOS') && t.version('iPod')<3.1 ||

            // Blackberry 5.0: Tested on the Storm 2 9550, Bold 9770
            t.is('Blackberry') && t.version('BlackBerry')>=5 && t.version('BlackBerry')<6 ||

            //Opera Mini (5.0-6.5) - Tested on iOS 3.2/4.3 and Android 2.3
            ( t.version('Opera Mini')>=5.0 && t.version('Opera Mini')<=6.5 &&
                (t.version('Android')>=2.3 || t.is('iOS')) ) ||

            // Nokia Symbian^3 - Tested on Nokia N8 (Symbian^3), C7 (Symbian^3), also works on N97 (Symbian^1)
            t.match('NokiaN8|NokiaC7|N97.*Series60|Symbian/3') ||

            // @todo: report this (tested on Nokia N71)
            t.version('Opera Mobi')>=11 && t.is('SymbianOS')
            ){
            return 'B';
        }

        if (
        // Blackberry 4.x - Tested on the Curve 8330
            t.version('BlackBerry')<5.0 ||
            // Windows Mobile - Tested on the HTC Leo (WinMo 5.2)
            t.match('MSIEMobile|Windows CE.*Mobile') || t.version('Windows Mobile')<=5.2

            ){
            return 'C';
        }

        //All older smartphone platforms and featurephones - Any device that doesn't support media queries
        //will receive the basic, C grade experience.
        return 'C';
    };

    impl.detectOS = function (ua) {
        return impl.findMatch(impl.mobileDetectRules.oss0, ua) ||
            impl.findMatch(impl.mobileDetectRules.oss, ua);
    };

    impl.getDeviceSmallerSide = function () {
        return window.screen.width < window.screen.height ?
            window.screen.width :
            window.screen.height;
    };

    /**
     * Constructor for MobileDetect object.
     * <br>
     * Such an object will keep a reference to the given user-agent string and cache most of the detect queries.<br>
     * <div style="background-color: #d9edf7; border: 1px solid #bce8f1; color: #3a87ad; padding: 14px; border-radius: 2px; margin-top: 20px">
     *     <strong>Find information how to download and install:</strong>
     *     <a href="https://github.com/hgoebl/mobile-detect.js/">github.com/hgoebl/mobile-detect.js/</a>
     * </div>
     *
     * @example <pre>
     *     var md = new MobileDetect(window.navigator.userAgent);
     *     if (md.mobile()) {
     *         location.href = (md.mobileGrade() === 'A') ? '/mobile/' : '/lynx/';
     *     }
     * </pre>
     *
     * @param {string} userAgent typically taken from window.navigator.userAgent or http_header['User-Agent']
     * @param {number} [maxPhoneWidth=600] <strong>only for browsers</strong> specify a value for the maximum
     *        width of smallest device side (in logical "CSS" pixels) until a device detected as mobile will be handled
     *        as phone.
     *        This is only used in cases where the device cannot be classified as phone or tablet.<br>
     *        See <a href="http://developer.android.com/guide/practices/screens_support.html">Declaring Tablet Layouts
     *        for Android</a>.<br>
     *        If you provide a value < 0, then this "fuzzy" check is disabled.
     * @constructor
     * @global
     */
    function MobileDetect(userAgent, maxPhoneWidth) {
        this.ua = prepareUserAgent(userAgent);
        this._cache = {};
        //600dp is typical 7" tablet minimum width
        this.maxPhoneWidth = maxPhoneWidth || 600;
    }

    MobileDetect.prototype = {
        constructor: MobileDetect,

        /**
         * Returns the detected phone or tablet type or <tt>null</tt> if it is not a mobile device.
         * <br>
         * For a list of possible return values see {@link MobileDetect#phone} and {@link MobileDetect#tablet}.<br>
         * <br>
         * If the device is not detected by the regular expressions from Mobile-Detect, a test is made against
         * the patterns of <a href="http://detectmobilebrowsers.com/">detectmobilebrowsers.com</a>. If this test
         * is positive, a value of <code>UnknownPhone</code>, <code>UnknownTablet</code> or
         * <code>UnknownMobile</code> is returned.<br>
         * When used in browser, the decision whether phone or tablet is made based on <code>screen.width/height</code>.<br>
         * <br>
         * When used server-side (node.js), there is no way to tell the difference between <code>UnknownTablet</code>
         * and <code>UnknownMobile</code>, so you will get <code>UnknownMobile</code> here.<br>
         * Be aware that since v1.0.0 in this special case you will get <code>UnknownMobile</code> only for:
         * {@link MobileDetect#mobile}, not for {@link MobileDetect#phone} and {@link MobileDetect#tablet}.
         * In versions before v1.0.0 all 3 methods returned <code>UnknownMobile</code> which was tedious to use.
         * <br>
         * In most cases you will use the return value just as a boolean.
         *
         * @returns {String} the key for the phone family or tablet family, e.g. "Nexus".
         * @function MobileDetect#mobile
         */
        mobile: function () {
            impl.prepareDetectionCache(this._cache, this.ua, this.maxPhoneWidth);
            return this._cache.mobile;
        },

        /**
         * Returns the detected phone type/family string or <tt>null</tt>.
         * <br>
         * The returned tablet (family or producer) is one of following keys:<br>
         * <br><tt>iPhone, BlackBerry, Pixel, HTC, Nexus, Dell, Motorola, Samsung, LG, Sony, Asus,
         * Xiaomi, NokiaLumia, Micromax, Palm, Vertu, Pantech, Fly, Wiko, iMobile,
         * SimValley, Wolfgang, Alcatel, Nintendo, Amoi, INQ, OnePlus, GenericPhone</tt><br>
         * <br>
         * If the device is not detected by the regular expressions from Mobile-Detect, a test is made against
         * the patterns of <a href="http://detectmobilebrowsers.com/">detectmobilebrowsers.com</a>. If this test
         * is positive, a value of <code>UnknownPhone</code> or <code>UnknownMobile</code> is returned.<br>
         * When used in browser, the decision whether phone or tablet is made based on <code>screen.width/height</code>.<br>
         * <br>
         * When used server-side (node.js), there is no way to tell the difference between <code>UnknownTablet</code>
         * and <code>UnknownMobile</code>, so you will get <code>null</code> here, while {@link MobileDetect#mobile}
         * will return <code>UnknownMobile</code>.<br>
         * Be aware that since v1.0.0 in this special case you will get <code>UnknownMobile</code> only for:
         * {@link MobileDetect#mobile}, not for {@link MobileDetect#phone} and {@link MobileDetect#tablet}.
         * In versions before v1.0.0 all 3 methods returned <code>UnknownMobile</code> which was tedious to use.
         * <br>
         * In most cases you will use the return value just as a boolean.
         *
         * @returns {String} the key of the phone family or producer, e.g. "iPhone"
         * @function MobileDetect#phone
         */
        phone: function () {
            impl.prepareDetectionCache(this._cache, this.ua, this.maxPhoneWidth);
            return this._cache.phone;
        },

        /**
         * Returns the detected tablet type/family string or <tt>null</tt>.
         * <br>
         * The returned tablet (family or producer) is one of following keys:<br>
         * <br><tt>iPad, NexusTablet, GoogleTablet, SamsungTablet, Kindle, SurfaceTablet,
         * HPTablet, AsusTablet, BlackBerryTablet, HTCtablet, MotorolaTablet, NookTablet,
         * AcerTablet, ToshibaTablet, LGTablet, FujitsuTablet, PrestigioTablet,
         * LenovoTablet, DellTablet, YarvikTablet, MedionTablet, ArnovaTablet,
         * IntensoTablet, IRUTablet, MegafonTablet, EbodaTablet, AllViewTablet,
         * ArchosTablet, AinolTablet, NokiaLumiaTablet, SonyTablet, PhilipsTablet,
         * CubeTablet, CobyTablet, MIDTablet, MSITablet, SMiTTablet, RockChipTablet,
         * FlyTablet, bqTablet, HuaweiTablet, NecTablet, PantechTablet, BronchoTablet,
         * VersusTablet, ZyncTablet, PositivoTablet, NabiTablet, KoboTablet, DanewTablet,
         * TexetTablet, PlaystationTablet, TrekstorTablet, PyleAudioTablet, AdvanTablet,
         * DanyTechTablet, GalapadTablet, MicromaxTablet, KarbonnTablet, AllFineTablet,
         * PROSCANTablet, YONESTablet, ChangJiaTablet, GUTablet, PointOfViewTablet,
         * OvermaxTablet, HCLTablet, DPSTablet, VistureTablet, CrestaTablet,
         * MediatekTablet, ConcordeTablet, GoCleverTablet, ModecomTablet, VoninoTablet,
         * ECSTablet, StorexTablet, VodafoneTablet, EssentielBTablet, RossMoorTablet,
         * iMobileTablet, TolinoTablet, AudioSonicTablet, AMPETablet, SkkTablet,
         * TecnoTablet, JXDTablet, iJoyTablet, FX2Tablet, XoroTablet, ViewsonicTablet,
         * VerizonTablet, OdysTablet, CaptivaTablet, IconbitTablet, TeclastTablet,
         * OndaTablet, JaytechTablet, BlaupunktTablet, DigmaTablet, EvolioTablet,
         * LavaTablet, AocTablet, MpmanTablet, CelkonTablet, WolderTablet, MediacomTablet,
         * MiTablet, NibiruTablet, NexoTablet, LeaderTablet, UbislateTablet,
         * PocketBookTablet, KocasoTablet, HisenseTablet, Hudl, TelstraTablet,
         * GenericTablet</tt><br>
         * <br>
         * If the device is not detected by the regular expressions from Mobile-Detect, a test is made against
         * the patterns of <a href="http://detectmobilebrowsers.com/">detectmobilebrowsers.com</a>. If this test
         * is positive, a value of <code>UnknownTablet</code> or <code>UnknownMobile</code> is returned.<br>
         * When used in browser, the decision whether phone or tablet is made based on <code>screen.width/height</code>.<br>
         * <br>
         * When used server-side (node.js), there is no way to tell the difference between <code>UnknownTablet</code>
         * and <code>UnknownMobile</code>, so you will get <code>null</code> here, while {@link MobileDetect#mobile}
         * will return <code>UnknownMobile</code>.<br>
         * Be aware that since v1.0.0 in this special case you will get <code>UnknownMobile</code> only for:
         * {@link MobileDetect#mobile}, not for {@link MobileDetect#phone} and {@link MobileDetect#tablet}.
         * In versions before v1.0.0 all 3 methods returned <code>UnknownMobile</code> which was tedious to use.
         * <br>
         * In most cases you will use the return value just as a boolean.
         *
         * @returns {String} the key of the tablet family or producer, e.g. "SamsungTablet"
         * @function MobileDetect#tablet
         */
        tablet: function () {
            impl.prepareDetectionCache(this._cache, this.ua, this.maxPhoneWidth);
            return this._cache.tablet;
        },

        /**
         * Returns the (first) detected user-agent string or <tt>null</tt>.
         * <br>
         * The returned user-agent is one of following keys:<br>
         * <br><tt>Chrome, Dolfin, Opera, Skyfire, Edge, IE, Firefox, Bolt, TeaShark, Blazer,
         * Safari, WeChat, UCBrowser, baiduboxapp, baidubrowser, DiigoBrowser, Mercury,
         * ObigoBrowser, NetFront, GenericBrowser, PaleMoon</tt><br>
         * <br>
         * In most cases calling {@link MobileDetect#userAgent} will be sufficient. But there are rare
         * cases where a mobile device pretends to be more than one particular browser. You can get the
         * list of all matches with {@link MobileDetect#userAgents} or check for a particular value by
         * providing one of the defined keys as first argument to {@link MobileDetect#is}.
         *
         * @returns {String} the key for the detected user-agent or <tt>null</tt>
         * @function MobileDetect#userAgent
         */
        userAgent: function () {
            if (this._cache.userAgent === undefined) {
                this._cache.userAgent = impl.findMatch(impl.mobileDetectRules.uas, this.ua);
            }
            return this._cache.userAgent;
        },

        /**
         * Returns all detected user-agent strings.
         * <br>
         * The array is empty or contains one or more of following keys:<br>
         * <br><tt>Chrome, Dolfin, Opera, Skyfire, Edge, IE, Firefox, Bolt, TeaShark, Blazer,
         * Safari, WeChat, UCBrowser, baiduboxapp, baidubrowser, DiigoBrowser, Mercury,
         * ObigoBrowser, NetFront, GenericBrowser, PaleMoon</tt><br>
         * <br>
         * In most cases calling {@link MobileDetect#userAgent} will be sufficient. But there are rare
         * cases where a mobile device pretends to be more than one particular browser. You can get the
         * list of all matches with {@link MobileDetect#userAgents} or check for a particular value by
         * providing one of the defined keys as first argument to {@link MobileDetect#is}.
         *
         * @returns {Array} the array of detected user-agent keys or <tt>[]</tt>
         * @function MobileDetect#userAgents
         */
        userAgents: function () {
            if (this._cache.userAgents === undefined) {
                this._cache.userAgents = impl.findMatches(impl.mobileDetectRules.uas, this.ua);
            }
            return this._cache.userAgents;
        },

        /**
         * Returns the detected operating system string or <tt>null</tt>.
         * <br>
         * The operating system is one of following keys:<br>
         * <br><tt>AndroidOS, BlackBerryOS, PalmOS, SymbianOS, WindowsMobileOS, WindowsPhoneOS,
         * iOS, iPadOS, SailfishOS, MeeGoOS, MaemoOS, JavaOS, webOS, badaOS, BREWOS</tt><br>
         *
         * @returns {String} the key for the detected operating system.
         * @function MobileDetect#os
         */
        os: function () {
            if (this._cache.os === undefined) {
                this._cache.os = impl.detectOS(this.ua);
            }
            return this._cache.os;
        },

        /**
         * Get the version (as Number) of the given property in the User-Agent.
         * <br>
         * Will return a float number. (eg. 2_0 will return 2.0, 4.3.1 will return 4.31)
         *
         * @param {String} key a key defining a thing which has a version.<br>
         *        You can use one of following keys:<br>
         * <br><tt>Mobile, Build, Version, VendorID, iPad, iPhone, iPod, Kindle, Chrome, Coast,
         * Dolfin, Firefox, Fennec, Edge, IE, NetFront, NokiaBrowser, Opera, Opera Mini,
         * Opera Mobi, UCBrowser, MQQBrowser, MicroMessenger, baiduboxapp, baidubrowser,
         * SamsungBrowser, Iron, Safari, Skyfire, Tizen, Webkit, PaleMoon,
         * SailfishBrowser, Gecko, Trident, Presto, Goanna, iOS, Android, Sailfish,
         * BlackBerry, BREW, Java, Windows Phone OS, Windows Phone, Windows CE, Windows
         * NT, Symbian, webOS</tt><br>
         *
         * @returns {Number} the version as float or <tt>NaN</tt> if User-Agent doesn't contain this version.
         *          Be careful when comparing this value with '==' operator!
         * @function MobileDetect#version
         */
        version: function (key) {
            return impl.getVersion(key, this.ua);
        },

        /**
         * Get the version (as String) of the given property in the User-Agent.
         * <br>
         *
         * @param {String} key a key defining a thing which has a version.<br>
         *        You can use one of following keys:<br>
         * <br><tt>Mobile, Build, Version, VendorID, iPad, iPhone, iPod, Kindle, Chrome, Coast,
         * Dolfin, Firefox, Fennec, Edge, IE, NetFront, NokiaBrowser, Opera, Opera Mini,
         * Opera Mobi, UCBrowser, MQQBrowser, MicroMessenger, baiduboxapp, baidubrowser,
         * SamsungBrowser, Iron, Safari, Skyfire, Tizen, Webkit, PaleMoon,
         * SailfishBrowser, Gecko, Trident, Presto, Goanna, iOS, Android, Sailfish,
         * BlackBerry, BREW, Java, Windows Phone OS, Windows Phone, Windows CE, Windows
         * NT, Symbian, webOS</tt><br>
         *
         * @returns {String} the "raw" version as String or <tt>null</tt> if User-Agent doesn't contain this version.
         *
         * @function MobileDetect#versionStr
         */
        versionStr: function (key) {
            return impl.getVersionStr(key, this.ua);
        },

        /**
         * Global test key against userAgent, os, phone, tablet and some other properties of userAgent string.
         *
         * @param {String} key the key (case-insensitive) of a userAgent, an operating system, phone or
         *        tablet family.<br>
         *        For a complete list of possible values, see {@link MobileDetect#userAgent},
         *        {@link MobileDetect#os}, {@link MobileDetect#phone}, {@link MobileDetect#tablet}.<br>
         *        Additionally you have following keys:<br>
         * <br><tt>Bot, MobileBot, DesktopMode, TV, WebKit, Console, Watch</tt><br>
         *
         * @returns {boolean} <tt>true</tt> when the given key is one of the defined keys of userAgent, os, phone,
         *                    tablet or one of the listed additional keys, otherwise <tt>false</tt>
         * @function MobileDetect#is
         */
        is: function (key) {
            return containsIC(this.userAgents(), key) ||
                   equalIC(key, this.os()) ||
                   equalIC(key, this.phone()) ||
                   equalIC(key, this.tablet()) ||
                   containsIC(impl.findMatches(impl.mobileDetectRules.utils, this.ua), key);
        },

        /**
         * Do a quick test against navigator::userAgent.
         *
         * @param {String|RegExp} pattern the pattern, either as String or RegExp
         *                        (a string will be converted to a case-insensitive RegExp).
         * @returns {boolean} <tt>true</tt> when the pattern matches, otherwise <tt>false</tt>
         * @function MobileDetect#match
         */
        match: function (pattern) {
            if (!(pattern instanceof RegExp)) {
                pattern = new RegExp(pattern, 'i');
            }
            return pattern.test(this.ua);
        },

        /**
         * Checks whether the mobile device can be considered as phone regarding <code>screen.width</code>.
         * <br>
         * Obviously this method makes sense in browser environments only (not for Node.js)!
         * @param {number} [maxPhoneWidth] the maximum logical pixels (aka. CSS-pixels) to be considered as phone.<br>
         *        The argument is optional and if not present or falsy, the value of the constructor is taken.
         * @returns {boolean|undefined} <code>undefined</code> if screen size wasn't detectable, else <code>true</code>
         *          when screen.width is less or equal to maxPhoneWidth, otherwise <code>false</code>.<br>
         *          Will always return <code>undefined</code> server-side.
         */
        isPhoneSized: function (maxPhoneWidth) {
            return MobileDetect.isPhoneSized(maxPhoneWidth || this.maxPhoneWidth);
        },

        /**
         * Returns the mobile grade ('A', 'B', 'C').
         *
         * @returns {String} one of the mobile grades ('A', 'B', 'C').
         * @function MobileDetect#mobileGrade
         */
        mobileGrade: function () {
            if (this._cache.grade === undefined) {
                this._cache.grade = impl.mobileGrade(this);
            }
            return this._cache.grade;
        }
    };

    // environment-dependent
    if (typeof window !== 'undefined' && window.screen) {
        MobileDetect.isPhoneSized = function (maxPhoneWidth) {
            return maxPhoneWidth < 0 ? undefined : impl.getDeviceSmallerSide() <= maxPhoneWidth;
        };
    } else {
        MobileDetect.isPhoneSized = function () {};
    }

    // should not be replaced by a completely new object - just overwrite existing methods
    MobileDetect._impl = impl;
    
    MobileDetect.version = '1.4.5 2021-03-13';

    return MobileDetect;
}); // end of call of define()
})((function (undefined) {
    if (typeof module !== 'undefined' && module.exports) {
        return function (factory) { module.exports = factory(); };
    } else if (typeof define === 'function' && define.amd) {
        return define;
    } else if (typeof window !== 'undefined') {
        return function (factory) { window.MobileDetect = factory(); };
    } else {
        // please file a bug if you get this error!
        throw new Error('unknown environment');
    }
})());public/assets/js/inc/mobile-detect-js/mobile-detect.min.js000064400000115241151213253550017503 0ustar00/*!@license Copyright 2013, Heinrich Goebl, License: MIT, see https://github.com/hgoebl/mobile-detect.js*/
!function(a,b){a(function(){"use strict";function a(a,b){return null!=a&&null!=b&&a.toLowerCase()===b.toLowerCase()}function c(a,b){var c,d,e=a.length;if(!e||!b)return!1;for(c=b.toLowerCase(),d=0;d<e;++d)if(c===a[d].toLowerCase())return!0;return!1}function d(a){for(var b in a)i.call(a,b)&&(a[b]=new RegExp(a[b],"i"))}function e(a){return(a||"").substr(0,500)}function f(a,b){this.ua=e(a),this._cache={},this.maxPhoneWidth=b||600}var g={};g.mobileDetectRules={phones:{iPhone:"\\biPhone\\b|\\biPod\\b",BlackBerry:"BlackBerry|\\bBB10\\b|rim[0-9]+|\\b(BBA100|BBB100|BBD100|BBE100|BBF100|STH100)\\b-[0-9]+",Pixel:"; \\bPixel\\b",HTC:"HTC|HTC.*(Sensation|Evo|Vision|Explorer|6800|8100|8900|A7272|S510e|C110e|Legend|Desire|T8282)|APX515CKT|Qtek9090|APA9292KT|HD_mini|Sensation.*Z710e|PG86100|Z715e|Desire.*(A8181|HD)|ADR6200|ADR6400L|ADR6425|001HT|Inspire 4G|Android.*\\bEVO\\b|T-Mobile G1|Z520m|Android [0-9.]+; Pixel",Nexus:"Nexus One|Nexus S|Galaxy.*Nexus|Android.*Nexus.*Mobile|Nexus 4|Nexus 5|Nexus 5X|Nexus 6",Dell:"Dell[;]? (Streak|Aero|Venue|Venue Pro|Flash|Smoke|Mini 3iX)|XCD28|XCD35|\\b001DL\\b|\\b101DL\\b|\\bGS01\\b",Motorola:"Motorola|DROIDX|DROID BIONIC|\\bDroid\\b.*Build|Android.*Xoom|HRI39|MOT-|A1260|A1680|A555|A853|A855|A953|A955|A956|Motorola.*ELECTRIFY|Motorola.*i1|i867|i940|MB200|MB300|MB501|MB502|MB508|MB511|MB520|MB525|MB526|MB611|MB612|MB632|MB810|MB855|MB860|MB861|MB865|MB870|ME501|ME502|ME511|ME525|ME600|ME632|ME722|ME811|ME860|ME863|ME865|MT620|MT710|MT716|MT720|MT810|MT870|MT917|Motorola.*TITANIUM|WX435|WX445|XT300|XT301|XT311|XT316|XT317|XT319|XT320|XT390|XT502|XT530|XT531|XT532|XT535|XT603|XT610|XT611|XT615|XT681|XT701|XT702|XT711|XT720|XT800|XT806|XT860|XT862|XT875|XT882|XT883|XT894|XT901|XT907|XT909|XT910|XT912|XT928|XT926|XT915|XT919|XT925|XT1021|\\bMoto E\\b|XT1068|XT1092|XT1052",Samsung:"\\bSamsung\\b|SM-G950F|SM-G955F|SM-G9250|GT-19300|SGH-I337|BGT-S5230|GT-B2100|GT-B2700|GT-B2710|GT-B3210|GT-B3310|GT-B3410|GT-B3730|GT-B3740|GT-B5510|GT-B5512|GT-B5722|GT-B6520|GT-B7300|GT-B7320|GT-B7330|GT-B7350|GT-B7510|GT-B7722|GT-B7800|GT-C3010|GT-C3011|GT-C3060|GT-C3200|GT-C3212|GT-C3212I|GT-C3262|GT-C3222|GT-C3300|GT-C3300K|GT-C3303|GT-C3303K|GT-C3310|GT-C3322|GT-C3330|GT-C3350|GT-C3500|GT-C3510|GT-C3530|GT-C3630|GT-C3780|GT-C5010|GT-C5212|GT-C6620|GT-C6625|GT-C6712|GT-E1050|GT-E1070|GT-E1075|GT-E1080|GT-E1081|GT-E1085|GT-E1087|GT-E1100|GT-E1107|GT-E1110|GT-E1120|GT-E1125|GT-E1130|GT-E1160|GT-E1170|GT-E1175|GT-E1180|GT-E1182|GT-E1200|GT-E1210|GT-E1225|GT-E1230|GT-E1390|GT-E2100|GT-E2120|GT-E2121|GT-E2152|GT-E2220|GT-E2222|GT-E2230|GT-E2232|GT-E2250|GT-E2370|GT-E2550|GT-E2652|GT-E3210|GT-E3213|GT-I5500|GT-I5503|GT-I5700|GT-I5800|GT-I5801|GT-I6410|GT-I6420|GT-I7110|GT-I7410|GT-I7500|GT-I8000|GT-I8150|GT-I8160|GT-I8190|GT-I8320|GT-I8330|GT-I8350|GT-I8530|GT-I8700|GT-I8703|GT-I8910|GT-I9000|GT-I9001|GT-I9003|GT-I9010|GT-I9020|GT-I9023|GT-I9070|GT-I9082|GT-I9100|GT-I9103|GT-I9220|GT-I9250|GT-I9300|GT-I9305|GT-I9500|GT-I9505|GT-M3510|GT-M5650|GT-M7500|GT-M7600|GT-M7603|GT-M8800|GT-M8910|GT-N7000|GT-S3110|GT-S3310|GT-S3350|GT-S3353|GT-S3370|GT-S3650|GT-S3653|GT-S3770|GT-S3850|GT-S5210|GT-S5220|GT-S5229|GT-S5230|GT-S5233|GT-S5250|GT-S5253|GT-S5260|GT-S5263|GT-S5270|GT-S5300|GT-S5330|GT-S5350|GT-S5360|GT-S5363|GT-S5369|GT-S5380|GT-S5380D|GT-S5560|GT-S5570|GT-S5600|GT-S5603|GT-S5610|GT-S5620|GT-S5660|GT-S5670|GT-S5690|GT-S5750|GT-S5780|GT-S5830|GT-S5839|GT-S6102|GT-S6500|GT-S7070|GT-S7200|GT-S7220|GT-S7230|GT-S7233|GT-S7250|GT-S7500|GT-S7530|GT-S7550|GT-S7562|GT-S7710|GT-S8000|GT-S8003|GT-S8500|GT-S8530|GT-S8600|SCH-A310|SCH-A530|SCH-A570|SCH-A610|SCH-A630|SCH-A650|SCH-A790|SCH-A795|SCH-A850|SCH-A870|SCH-A890|SCH-A930|SCH-A950|SCH-A970|SCH-A990|SCH-I100|SCH-I110|SCH-I400|SCH-I405|SCH-I500|SCH-I510|SCH-I515|SCH-I600|SCH-I730|SCH-I760|SCH-I770|SCH-I830|SCH-I910|SCH-I920|SCH-I959|SCH-LC11|SCH-N150|SCH-N300|SCH-R100|SCH-R300|SCH-R351|SCH-R400|SCH-R410|SCH-T300|SCH-U310|SCH-U320|SCH-U350|SCH-U360|SCH-U365|SCH-U370|SCH-U380|SCH-U410|SCH-U430|SCH-U450|SCH-U460|SCH-U470|SCH-U490|SCH-U540|SCH-U550|SCH-U620|SCH-U640|SCH-U650|SCH-U660|SCH-U700|SCH-U740|SCH-U750|SCH-U810|SCH-U820|SCH-U900|SCH-U940|SCH-U960|SCS-26UC|SGH-A107|SGH-A117|SGH-A127|SGH-A137|SGH-A157|SGH-A167|SGH-A177|SGH-A187|SGH-A197|SGH-A227|SGH-A237|SGH-A257|SGH-A437|SGH-A517|SGH-A597|SGH-A637|SGH-A657|SGH-A667|SGH-A687|SGH-A697|SGH-A707|SGH-A717|SGH-A727|SGH-A737|SGH-A747|SGH-A767|SGH-A777|SGH-A797|SGH-A817|SGH-A827|SGH-A837|SGH-A847|SGH-A867|SGH-A877|SGH-A887|SGH-A897|SGH-A927|SGH-B100|SGH-B130|SGH-B200|SGH-B220|SGH-C100|SGH-C110|SGH-C120|SGH-C130|SGH-C140|SGH-C160|SGH-C170|SGH-C180|SGH-C200|SGH-C207|SGH-C210|SGH-C225|SGH-C230|SGH-C417|SGH-C450|SGH-D307|SGH-D347|SGH-D357|SGH-D407|SGH-D415|SGH-D780|SGH-D807|SGH-D980|SGH-E105|SGH-E200|SGH-E315|SGH-E316|SGH-E317|SGH-E335|SGH-E590|SGH-E635|SGH-E715|SGH-E890|SGH-F300|SGH-F480|SGH-I200|SGH-I300|SGH-I320|SGH-I550|SGH-I577|SGH-I600|SGH-I607|SGH-I617|SGH-I627|SGH-I637|SGH-I677|SGH-I700|SGH-I717|SGH-I727|SGH-i747M|SGH-I777|SGH-I780|SGH-I827|SGH-I847|SGH-I857|SGH-I896|SGH-I897|SGH-I900|SGH-I907|SGH-I917|SGH-I927|SGH-I937|SGH-I997|SGH-J150|SGH-J200|SGH-L170|SGH-L700|SGH-M110|SGH-M150|SGH-M200|SGH-N105|SGH-N500|SGH-N600|SGH-N620|SGH-N625|SGH-N700|SGH-N710|SGH-P107|SGH-P207|SGH-P300|SGH-P310|SGH-P520|SGH-P735|SGH-P777|SGH-Q105|SGH-R210|SGH-R220|SGH-R225|SGH-S105|SGH-S307|SGH-T109|SGH-T119|SGH-T139|SGH-T209|SGH-T219|SGH-T229|SGH-T239|SGH-T249|SGH-T259|SGH-T309|SGH-T319|SGH-T329|SGH-T339|SGH-T349|SGH-T359|SGH-T369|SGH-T379|SGH-T409|SGH-T429|SGH-T439|SGH-T459|SGH-T469|SGH-T479|SGH-T499|SGH-T509|SGH-T519|SGH-T539|SGH-T559|SGH-T589|SGH-T609|SGH-T619|SGH-T629|SGH-T639|SGH-T659|SGH-T669|SGH-T679|SGH-T709|SGH-T719|SGH-T729|SGH-T739|SGH-T746|SGH-T749|SGH-T759|SGH-T769|SGH-T809|SGH-T819|SGH-T839|SGH-T919|SGH-T929|SGH-T939|SGH-T959|SGH-T989|SGH-U100|SGH-U200|SGH-U800|SGH-V205|SGH-V206|SGH-X100|SGH-X105|SGH-X120|SGH-X140|SGH-X426|SGH-X427|SGH-X475|SGH-X495|SGH-X497|SGH-X507|SGH-X600|SGH-X610|SGH-X620|SGH-X630|SGH-X700|SGH-X820|SGH-X890|SGH-Z130|SGH-Z150|SGH-Z170|SGH-ZX10|SGH-ZX20|SHW-M110|SPH-A120|SPH-A400|SPH-A420|SPH-A460|SPH-A500|SPH-A560|SPH-A600|SPH-A620|SPH-A660|SPH-A700|SPH-A740|SPH-A760|SPH-A790|SPH-A800|SPH-A820|SPH-A840|SPH-A880|SPH-A900|SPH-A940|SPH-A960|SPH-D600|SPH-D700|SPH-D710|SPH-D720|SPH-I300|SPH-I325|SPH-I330|SPH-I350|SPH-I500|SPH-I600|SPH-I700|SPH-L700|SPH-M100|SPH-M220|SPH-M240|SPH-M300|SPH-M305|SPH-M320|SPH-M330|SPH-M350|SPH-M360|SPH-M370|SPH-M380|SPH-M510|SPH-M540|SPH-M550|SPH-M560|SPH-M570|SPH-M580|SPH-M610|SPH-M620|SPH-M630|SPH-M800|SPH-M810|SPH-M850|SPH-M900|SPH-M910|SPH-M920|SPH-M930|SPH-N100|SPH-N200|SPH-N240|SPH-N300|SPH-N400|SPH-Z400|SWC-E100|SCH-i909|GT-N7100|GT-N7105|SCH-I535|SM-N900A|SGH-I317|SGH-T999L|GT-S5360B|GT-I8262|GT-S6802|GT-S6312|GT-S6310|GT-S5312|GT-S5310|GT-I9105|GT-I8510|GT-S6790N|SM-G7105|SM-N9005|GT-S5301|GT-I9295|GT-I9195|SM-C101|GT-S7392|GT-S7560|GT-B7610|GT-I5510|GT-S7582|GT-S7530E|GT-I8750|SM-G9006V|SM-G9008V|SM-G9009D|SM-G900A|SM-G900D|SM-G900F|SM-G900H|SM-G900I|SM-G900J|SM-G900K|SM-G900L|SM-G900M|SM-G900P|SM-G900R4|SM-G900S|SM-G900T|SM-G900V|SM-G900W8|SHV-E160K|SCH-P709|SCH-P729|SM-T2558|GT-I9205|SM-G9350|SM-J120F|SM-G920F|SM-G920V|SM-G930F|SM-N910C|SM-A310F|GT-I9190|SM-J500FN|SM-G903F|SM-J330F|SM-G610F|SM-G981B|SM-G892A|SM-A530F",LG:"\\bLG\\b;|LG[- ]?(C800|C900|E400|E610|E900|E-900|F160|F180K|F180L|F180S|730|855|L160|LS740|LS840|LS970|LU6200|MS690|MS695|MS770|MS840|MS870|MS910|P500|P700|P705|VM696|AS680|AS695|AX840|C729|E970|GS505|272|C395|E739BK|E960|L55C|L75C|LS696|LS860|P769BK|P350|P500|P509|P870|UN272|US730|VS840|VS950|LN272|LN510|LS670|LS855|LW690|MN270|MN510|P509|P769|P930|UN200|UN270|UN510|UN610|US670|US740|US760|UX265|UX840|VN271|VN530|VS660|VS700|VS740|VS750|VS910|VS920|VS930|VX9200|VX11000|AX840A|LW770|P506|P925|P999|E612|D955|D802|MS323|M257)|LM-G710",Sony:"SonyST|SonyLT|SonyEricsson|SonyEricssonLT15iv|LT18i|E10i|LT28h|LT26w|SonyEricssonMT27i|C5303|C6902|C6903|C6906|C6943|D2533|SOV34|601SO|F8332",Asus:"Asus.*Galaxy|PadFone.*Mobile",Xiaomi:"^(?!.*\\bx11\\b).*xiaomi.*$|POCOPHONE F1|MI 8|Redmi Note 9S|Redmi Note 5A Prime|N2G47H|M2001J2G|M2001J2I|M1805E10A|M2004J11G|M1902F1G|M2002J9G|M2004J19G|M2003J6A1G",NokiaLumia:"Lumia [0-9]{3,4}",Micromax:"Micromax.*\\b(A210|A92|A88|A72|A111|A110Q|A115|A116|A110|A90S|A26|A51|A35|A54|A25|A27|A89|A68|A65|A57|A90)\\b",Palm:"PalmSource|Palm",Vertu:"Vertu|Vertu.*Ltd|Vertu.*Ascent|Vertu.*Ayxta|Vertu.*Constellation(F|Quest)?|Vertu.*Monika|Vertu.*Signature",Pantech:"PANTECH|IM-A850S|IM-A840S|IM-A830L|IM-A830K|IM-A830S|IM-A820L|IM-A810K|IM-A810S|IM-A800S|IM-T100K|IM-A725L|IM-A780L|IM-A775C|IM-A770K|IM-A760S|IM-A750K|IM-A740S|IM-A730S|IM-A720L|IM-A710K|IM-A690L|IM-A690S|IM-A650S|IM-A630K|IM-A600S|VEGA PTL21|PT003|P8010|ADR910L|P6030|P6020|P9070|P4100|P9060|P5000|CDM8992|TXT8045|ADR8995|IS11PT|P2030|P6010|P8000|PT002|IS06|CDM8999|P9050|PT001|TXT8040|P2020|P9020|P2000|P7040|P7000|C790",Fly:"IQ230|IQ444|IQ450|IQ440|IQ442|IQ441|IQ245|IQ256|IQ236|IQ255|IQ235|IQ245|IQ275|IQ240|IQ285|IQ280|IQ270|IQ260|IQ250",Wiko:"KITE 4G|HIGHWAY|GETAWAY|STAIRWAY|DARKSIDE|DARKFULL|DARKNIGHT|DARKMOON|SLIDE|WAX 4G|RAINBOW|BLOOM|SUNSET|GOA(?!nna)|LENNY|BARRY|IGGY|OZZY|CINK FIVE|CINK PEAX|CINK PEAX 2|CINK SLIM|CINK SLIM 2|CINK +|CINK KING|CINK PEAX|CINK SLIM|SUBLIM",iMobile:"i-mobile (IQ|i-STYLE|idea|ZAA|Hitz)",SimValley:"\\b(SP-80|XT-930|SX-340|XT-930|SX-310|SP-360|SP60|SPT-800|SP-120|SPT-800|SP-140|SPX-5|SPX-8|SP-100|SPX-8|SPX-12)\\b",Wolfgang:"AT-B24D|AT-AS50HD|AT-AS40W|AT-AS55HD|AT-AS45q2|AT-B26D|AT-AS50Q",Alcatel:"Alcatel",Nintendo:"Nintendo (3DS|Switch)",Amoi:"Amoi",INQ:"INQ",OnePlus:"ONEPLUS",GenericPhone:"Tapatalk|PDA;|SAGEM|\\bmmp\\b|pocket|\\bpsp\\b|symbian|Smartphone|smartfon|treo|up.browser|up.link|vodafone|\\bwap\\b|nokia|Series40|Series60|S60|SonyEricsson|N900|MAUI.*WAP.*Browser"},tablets:{iPad:"iPad|iPad.*Mobile",NexusTablet:"Android.*Nexus[\\s]+(7|9|10)",GoogleTablet:"Android.*Pixel C",SamsungTablet:"SAMSUNG.*Tablet|Galaxy.*Tab|SC-01C|GT-P1000|GT-P1003|GT-P1010|GT-P3105|GT-P6210|GT-P6800|GT-P6810|GT-P7100|GT-P7300|GT-P7310|GT-P7500|GT-P7510|SCH-I800|SCH-I815|SCH-I905|SGH-I957|SGH-I987|SGH-T849|SGH-T859|SGH-T869|SPH-P100|GT-P3100|GT-P3108|GT-P3110|GT-P5100|GT-P5110|GT-P6200|GT-P7320|GT-P7511|GT-N8000|GT-P8510|SGH-I497|SPH-P500|SGH-T779|SCH-I705|SCH-I915|GT-N8013|GT-P3113|GT-P5113|GT-P8110|GT-N8010|GT-N8005|GT-N8020|GT-P1013|GT-P6201|GT-P7501|GT-N5100|GT-N5105|GT-N5110|SHV-E140K|SHV-E140L|SHV-E140S|SHV-E150S|SHV-E230K|SHV-E230L|SHV-E230S|SHW-M180K|SHW-M180L|SHW-M180S|SHW-M180W|SHW-M300W|SHW-M305W|SHW-M380K|SHW-M380S|SHW-M380W|SHW-M430W|SHW-M480K|SHW-M480S|SHW-M480W|SHW-M485W|SHW-M486W|SHW-M500W|GT-I9228|SCH-P739|SCH-I925|GT-I9200|GT-P5200|GT-P5210|GT-P5210X|SM-T311|SM-T310|SM-T310X|SM-T210|SM-T210R|SM-T211|SM-P600|SM-P601|SM-P605|SM-P900|SM-P901|SM-T217|SM-T217A|SM-T217S|SM-P6000|SM-T3100|SGH-I467|XE500|SM-T110|GT-P5220|GT-I9200X|GT-N5110X|GT-N5120|SM-P905|SM-T111|SM-T2105|SM-T315|SM-T320|SM-T320X|SM-T321|SM-T520|SM-T525|SM-T530NU|SM-T230NU|SM-T330NU|SM-T900|XE500T1C|SM-P605V|SM-P905V|SM-T337V|SM-T537V|SM-T707V|SM-T807V|SM-P600X|SM-P900X|SM-T210X|SM-T230|SM-T230X|SM-T325|GT-P7503|SM-T531|SM-T330|SM-T530|SM-T705|SM-T705C|SM-T535|SM-T331|SM-T800|SM-T700|SM-T537|SM-T807|SM-P907A|SM-T337A|SM-T537A|SM-T707A|SM-T807A|SM-T237|SM-T807P|SM-P607T|SM-T217T|SM-T337T|SM-T807T|SM-T116NQ|SM-T116BU|SM-P550|SM-T350|SM-T550|SM-T9000|SM-P9000|SM-T705Y|SM-T805|GT-P3113|SM-T710|SM-T810|SM-T815|SM-T360|SM-T533|SM-T113|SM-T335|SM-T715|SM-T560|SM-T670|SM-T677|SM-T377|SM-T567|SM-T357T|SM-T555|SM-T561|SM-T713|SM-T719|SM-T813|SM-T819|SM-T580|SM-T355Y?|SM-T280|SM-T817A|SM-T820|SM-W700|SM-P580|SM-T587|SM-P350|SM-P555M|SM-P355M|SM-T113NU|SM-T815Y|SM-T585|SM-T285|SM-T825|SM-W708|SM-T835|SM-T830|SM-T837V|SM-T720|SM-T510|SM-T387V|SM-P610|SM-T290|SM-T515|SM-T590|SM-T595|SM-T725|SM-T817P|SM-P585N0|SM-T395|SM-T295|SM-T865|SM-P610N|SM-P615|SM-T970|SM-T380|SM-T5950|SM-T905|SM-T231|SM-T500|SM-T860",Kindle:"Kindle|Silk.*Accelerated|Android.*\\b(KFOT|KFTT|KFJWI|KFJWA|KFOTE|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|WFJWAE|KFSAWA|KFSAWI|KFASWI|KFARWI|KFFOWI|KFGIWI|KFMEWI)\\b|Android.*Silk/[0-9.]+ like Chrome/[0-9.]+ (?!Mobile)",SurfaceTablet:"Windows NT [0-9.]+; ARM;.*(Tablet|ARMBJS)",HPTablet:"HP Slate (7|8|10)|HP ElitePad 900|hp-tablet|EliteBook.*Touch|HP 8|Slate 21|HP SlateBook 10",AsusTablet:"^.*PadFone((?!Mobile).)*$|Transformer|TF101|TF101G|TF300T|TF300TG|TF300TL|TF700T|TF700KL|TF701T|TF810C|ME171|ME301T|ME302C|ME371MG|ME370T|ME372MG|ME172V|ME173X|ME400C|Slider SL101|\\bK00F\\b|\\bK00C\\b|\\bK00E\\b|\\bK00L\\b|TX201LA|ME176C|ME102A|\\bM80TA\\b|ME372CL|ME560CG|ME372CG|ME302KL| K010 | K011 | K017 | K01E |ME572C|ME103K|ME170C|ME171C|\\bME70C\\b|ME581C|ME581CL|ME8510C|ME181C|P01Y|PO1MA|P01Z|\\bP027\\b|\\bP024\\b|\\bP00C\\b",BlackBerryTablet:"PlayBook|RIM Tablet",HTCtablet:"HTC_Flyer_P512|HTC Flyer|HTC Jetstream|HTC-P715a|HTC EVO View 4G|PG41200|PG09410",MotorolaTablet:"xoom|sholest|MZ615|MZ605|MZ505|MZ601|MZ602|MZ603|MZ604|MZ606|MZ607|MZ608|MZ609|MZ615|MZ616|MZ617",NookTablet:"Android.*Nook|NookColor|nook browser|BNRV200|BNRV200A|BNTV250|BNTV250A|BNTV400|BNTV600|LogicPD Zoom2",AcerTablet:"Android.*; \\b(A100|A101|A110|A200|A210|A211|A500|A501|A510|A511|A700|A701|W500|W500P|W501|W501P|W510|W511|W700|G100|G100W|B1-A71|B1-710|B1-711|A1-810|A1-811|A1-830)\\b|W3-810|\\bA3-A10\\b|\\bA3-A11\\b|\\bA3-A20\\b|\\bA3-A30|A3-A40",ToshibaTablet:"Android.*(AT100|AT105|AT200|AT205|AT270|AT275|AT300|AT305|AT1S5|AT500|AT570|AT700|AT830)|TOSHIBA.*FOLIO",LGTablet:"\\bL-06C|LG-V909|LG-V900|LG-V700|LG-V510|LG-V500|LG-V410|LG-V400|LG-VK810\\b",FujitsuTablet:"Android.*\\b(F-01D|F-02F|F-05E|F-10D|M532|Q572)\\b",PrestigioTablet:"PMP3170B|PMP3270B|PMP3470B|PMP7170B|PMP3370B|PMP3570C|PMP5870C|PMP3670B|PMP5570C|PMP5770D|PMP3970B|PMP3870C|PMP5580C|PMP5880D|PMP5780D|PMP5588C|PMP7280C|PMP7280C3G|PMP7280|PMP7880D|PMP5597D|PMP5597|PMP7100D|PER3464|PER3274|PER3574|PER3884|PER5274|PER5474|PMP5097CPRO|PMP5097|PMP7380D|PMP5297C|PMP5297C_QUAD|PMP812E|PMP812E3G|PMP812F|PMP810E|PMP880TD|PMT3017|PMT3037|PMT3047|PMT3057|PMT7008|PMT5887|PMT5001|PMT5002",LenovoTablet:"Lenovo TAB|Idea(Tab|Pad)( A1|A10| K1|)|ThinkPad([ ]+)?Tablet|YT3-850M|YT3-X90L|YT3-X90F|YT3-X90X|Lenovo.*(S2109|S2110|S5000|S6000|K3011|A3000|A3500|A1000|A2107|A2109|A1107|A5500|A7600|B6000|B8000|B8080)(-|)(FL|F|HV|H|)|TB-X103F|TB-X304X|TB-X304F|TB-X304L|TB-X505F|TB-X505L|TB-X505X|TB-X605F|TB-X605L|TB-8703F|TB-8703X|TB-8703N|TB-8704N|TB-8704F|TB-8704X|TB-8704V|TB-7304F|TB-7304I|TB-7304X|Tab2A7-10F|Tab2A7-20F|TB2-X30L|YT3-X50L|YT3-X50F|YT3-X50M|YT-X705F|YT-X703F|YT-X703L|YT-X705L|YT-X705X|TB2-X30F|TB2-X30L|TB2-X30M|A2107A-F|A2107A-H|TB3-730F|TB3-730M|TB3-730X|TB-7504F|TB-7504X|TB-X704F|TB-X104F|TB3-X70F|TB-X705F|TB-8504F|TB3-X70L|TB3-710F|TB-X704L",DellTablet:"Venue 11|Venue 8|Venue 7|Dell Streak 10|Dell Streak 7",YarvikTablet:"Android.*\\b(TAB210|TAB211|TAB224|TAB250|TAB260|TAB264|TAB310|TAB360|TAB364|TAB410|TAB411|TAB420|TAB424|TAB450|TAB460|TAB461|TAB464|TAB465|TAB467|TAB468|TAB07-100|TAB07-101|TAB07-150|TAB07-151|TAB07-152|TAB07-200|TAB07-201-3G|TAB07-210|TAB07-211|TAB07-212|TAB07-214|TAB07-220|TAB07-400|TAB07-485|TAB08-150|TAB08-200|TAB08-201-3G|TAB08-201-30|TAB09-100|TAB09-211|TAB09-410|TAB10-150|TAB10-201|TAB10-211|TAB10-400|TAB10-410|TAB13-201|TAB274EUK|TAB275EUK|TAB374EUK|TAB462EUK|TAB474EUK|TAB9-200)\\b",MedionTablet:"Android.*\\bOYO\\b|LIFE.*(P9212|P9514|P9516|S9512)|LIFETAB",ArnovaTablet:"97G4|AN10G2|AN7bG3|AN7fG3|AN8G3|AN8cG3|AN7G3|AN9G3|AN7dG3|AN7dG3ST|AN7dG3ChildPad|AN10bG3|AN10bG3DT|AN9G2",IntensoTablet:"INM8002KP|INM1010FP|INM805ND|Intenso Tab|TAB1004",IRUTablet:"M702pro",MegafonTablet:"MegaFon V9|\\bZTE V9\\b|Android.*\\bMT7A\\b",EbodaTablet:"E-Boda (Supreme|Impresspeed|Izzycomm|Essential)",AllViewTablet:"Allview.*(Viva|Alldro|City|Speed|All TV|Frenzy|Quasar|Shine|TX1|AX1|AX2)",ArchosTablet:"\\b(101G9|80G9|A101IT)\\b|Qilive 97R|Archos5|\\bARCHOS (70|79|80|90|97|101|FAMILYPAD|)(b|c|)(G10| Cobalt| TITANIUM(HD|)| Xenon| Neon|XSK| 2| XS 2| PLATINUM| CARBON|GAMEPAD)\\b",AinolTablet:"NOVO7|NOVO8|NOVO10|Novo7Aurora|Novo7Basic|NOVO7PALADIN|novo9-Spark",NokiaLumiaTablet:"Lumia 2520",SonyTablet:"Sony.*Tablet|Xperia Tablet|Sony Tablet S|SO-03E|SGPT12|SGPT13|SGPT114|SGPT121|SGPT122|SGPT123|SGPT111|SGPT112|SGPT113|SGPT131|SGPT132|SGPT133|SGPT211|SGPT212|SGPT213|SGP311|SGP312|SGP321|EBRD1101|EBRD1102|EBRD1201|SGP351|SGP341|SGP511|SGP512|SGP521|SGP541|SGP551|SGP621|SGP641|SGP612|SOT31|SGP771|SGP611|SGP612|SGP712",PhilipsTablet:"\\b(PI2010|PI3000|PI3100|PI3105|PI3110|PI3205|PI3210|PI3900|PI4010|PI7000|PI7100)\\b",CubeTablet:"Android.*(K8GT|U9GT|U10GT|U16GT|U17GT|U18GT|U19GT|U20GT|U23GT|U30GT)|CUBE U8GT",CobyTablet:"MID1042|MID1045|MID1125|MID1126|MID7012|MID7014|MID7015|MID7034|MID7035|MID7036|MID7042|MID7048|MID7127|MID8042|MID8048|MID8127|MID9042|MID9740|MID9742|MID7022|MID7010",MIDTablet:"M9701|M9000|M9100|M806|M1052|M806|T703|MID701|MID713|MID710|MID727|MID760|MID830|MID728|MID933|MID125|MID810|MID732|MID120|MID930|MID800|MID731|MID900|MID100|MID820|MID735|MID980|MID130|MID833|MID737|MID960|MID135|MID860|MID736|MID140|MID930|MID835|MID733|MID4X10",MSITablet:"MSI \\b(Primo 73K|Primo 73L|Primo 81L|Primo 77|Primo 93|Primo 75|Primo 76|Primo 73|Primo 81|Primo 91|Primo 90|Enjoy 71|Enjoy 7|Enjoy 10)\\b",SMiTTablet:"Android.*(\\bMID\\b|MID-560|MTV-T1200|MTV-PND531|MTV-P1101|MTV-PND530)",RockChipTablet:"Android.*(RK2818|RK2808A|RK2918|RK3066)|RK2738|RK2808A",FlyTablet:"IQ310|Fly Vision",bqTablet:"Android.*(bq)?.*\\b(Elcano|Curie|Edison|Maxwell|Kepler|Pascal|Tesla|Hypatia|Platon|Newton|Livingstone|Cervantes|Avant|Aquaris ([E|M]10|M8))\\b|Maxwell.*Lite|Maxwell.*Plus",HuaweiTablet:"MediaPad|MediaPad 7 Youth|IDEOS S7|S7-201c|S7-202u|S7-101|S7-103|S7-104|S7-105|S7-106|S7-201|S7-Slim|M2-A01L|BAH-L09|BAH-W09|AGS-L09|CMR-AL19",NecTablet:"\\bN-06D|\\bN-08D",PantechTablet:"Pantech.*P4100",BronchoTablet:"Broncho.*(N701|N708|N802|a710)",VersusTablet:"TOUCHPAD.*[78910]|\\bTOUCHTAB\\b",ZyncTablet:"z1000|Z99 2G|z930|z990|z909|Z919|z900",PositivoTablet:"TB07STA|TB10STA|TB07FTA|TB10FTA",NabiTablet:"Android.*\\bNabi",KoboTablet:"Kobo Touch|\\bK080\\b|\\bVox\\b Build|\\bArc\\b Build",DanewTablet:"DSlide.*\\b(700|701R|702|703R|704|802|970|971|972|973|974|1010|1012)\\b",TexetTablet:"NaviPad|TB-772A|TM-7045|TM-7055|TM-9750|TM-7016|TM-7024|TM-7026|TM-7041|TM-7043|TM-7047|TM-8041|TM-9741|TM-9747|TM-9748|TM-9751|TM-7022|TM-7021|TM-7020|TM-7011|TM-7010|TM-7023|TM-7025|TM-7037W|TM-7038W|TM-7027W|TM-9720|TM-9725|TM-9737W|TM-1020|TM-9738W|TM-9740|TM-9743W|TB-807A|TB-771A|TB-727A|TB-725A|TB-719A|TB-823A|TB-805A|TB-723A|TB-715A|TB-707A|TB-705A|TB-709A|TB-711A|TB-890HD|TB-880HD|TB-790HD|TB-780HD|TB-770HD|TB-721HD|TB-710HD|TB-434HD|TB-860HD|TB-840HD|TB-760HD|TB-750HD|TB-740HD|TB-730HD|TB-722HD|TB-720HD|TB-700HD|TB-500HD|TB-470HD|TB-431HD|TB-430HD|TB-506|TB-504|TB-446|TB-436|TB-416|TB-146SE|TB-126SE",PlaystationTablet:"Playstation.*(Portable|Vita)",TrekstorTablet:"ST10416-1|VT10416-1|ST70408-1|ST702xx-1|ST702xx-2|ST80208|ST97216|ST70104-2|VT10416-2|ST10216-2A|SurfTab",PyleAudioTablet:"\\b(PTBL10CEU|PTBL10C|PTBL72BC|PTBL72BCEU|PTBL7CEU|PTBL7C|PTBL92BC|PTBL92BCEU|PTBL9CEU|PTBL9CUK|PTBL9C)\\b",AdvanTablet:"Android.* \\b(E3A|T3X|T5C|T5B|T3E|T3C|T3B|T1J|T1F|T2A|T1H|T1i|E1C|T1-E|T5-A|T4|E1-B|T2Ci|T1-B|T1-D|O1-A|E1-A|T1-A|T3A|T4i)\\b ",DanyTechTablet:"Genius Tab G3|Genius Tab S2|Genius Tab Q3|Genius Tab G4|Genius Tab Q4|Genius Tab G-II|Genius TAB GII|Genius TAB GIII|Genius Tab S1",GalapadTablet:"Android [0-9.]+; [a-z-]+; \\bG1\\b",MicromaxTablet:"Funbook|Micromax.*\\b(P250|P560|P360|P362|P600|P300|P350|P500|P275)\\b",KarbonnTablet:"Android.*\\b(A39|A37|A34|ST8|ST10|ST7|Smart Tab3|Smart Tab2)\\b",AllFineTablet:"Fine7 Genius|Fine7 Shine|Fine7 Air|Fine8 Style|Fine9 More|Fine10 Joy|Fine11 Wide",PROSCANTablet:"\\b(PEM63|PLT1023G|PLT1041|PLT1044|PLT1044G|PLT1091|PLT4311|PLT4311PL|PLT4315|PLT7030|PLT7033|PLT7033D|PLT7035|PLT7035D|PLT7044K|PLT7045K|PLT7045KB|PLT7071KG|PLT7072|PLT7223G|PLT7225G|PLT7777G|PLT7810K|PLT7849G|PLT7851G|PLT7852G|PLT8015|PLT8031|PLT8034|PLT8036|PLT8080K|PLT8082|PLT8088|PLT8223G|PLT8234G|PLT8235G|PLT8816K|PLT9011|PLT9045K|PLT9233G|PLT9735|PLT9760G|PLT9770G)\\b",YONESTablet:"BQ1078|BC1003|BC1077|RK9702|BC9730|BC9001|IT9001|BC7008|BC7010|BC708|BC728|BC7012|BC7030|BC7027|BC7026",ChangJiaTablet:"TPC7102|TPC7103|TPC7105|TPC7106|TPC7107|TPC7201|TPC7203|TPC7205|TPC7210|TPC7708|TPC7709|TPC7712|TPC7110|TPC8101|TPC8103|TPC8105|TPC8106|TPC8203|TPC8205|TPC8503|TPC9106|TPC9701|TPC97101|TPC97103|TPC97105|TPC97106|TPC97111|TPC97113|TPC97203|TPC97603|TPC97809|TPC97205|TPC10101|TPC10103|TPC10106|TPC10111|TPC10203|TPC10205|TPC10503",GUTablet:"TX-A1301|TX-M9002|Q702|kf026",PointOfViewTablet:"TAB-P506|TAB-navi-7-3G-M|TAB-P517|TAB-P-527|TAB-P701|TAB-P703|TAB-P721|TAB-P731N|TAB-P741|TAB-P825|TAB-P905|TAB-P925|TAB-PR945|TAB-PL1015|TAB-P1025|TAB-PI1045|TAB-P1325|TAB-PROTAB[0-9]+|TAB-PROTAB25|TAB-PROTAB26|TAB-PROTAB27|TAB-PROTAB26XL|TAB-PROTAB2-IPS9|TAB-PROTAB30-IPS9|TAB-PROTAB25XXL|TAB-PROTAB26-IPS10|TAB-PROTAB30-IPS10",OvermaxTablet:"OV-(SteelCore|NewBase|Basecore|Baseone|Exellen|Quattor|EduTab|Solution|ACTION|BasicTab|TeddyTab|MagicTab|Stream|TB-08|TB-09)|Qualcore 1027",HCLTablet:"HCL.*Tablet|Connect-3G-2.0|Connect-2G-2.0|ME Tablet U1|ME Tablet U2|ME Tablet G1|ME Tablet X1|ME Tablet Y2|ME Tablet Sync",DPSTablet:"DPS Dream 9|DPS Dual 7",VistureTablet:"V97 HD|i75 3G|Visture V4( HD)?|Visture V5( HD)?|Visture V10",CrestaTablet:"CTP(-)?810|CTP(-)?818|CTP(-)?828|CTP(-)?838|CTP(-)?888|CTP(-)?978|CTP(-)?980|CTP(-)?987|CTP(-)?988|CTP(-)?989",MediatekTablet:"\\bMT8125|MT8389|MT8135|MT8377\\b",ConcordeTablet:"Concorde([ ]+)?Tab|ConCorde ReadMan",GoCleverTablet:"GOCLEVER TAB|A7GOCLEVER|M1042|M7841|M742|R1042BK|R1041|TAB A975|TAB A7842|TAB A741|TAB A741L|TAB M723G|TAB M721|TAB A1021|TAB I921|TAB R721|TAB I720|TAB T76|TAB R70|TAB R76.2|TAB R106|TAB R83.2|TAB M813G|TAB I721|GCTA722|TAB I70|TAB I71|TAB S73|TAB R73|TAB R74|TAB R93|TAB R75|TAB R76.1|TAB A73|TAB A93|TAB A93.2|TAB T72|TAB R83|TAB R974|TAB R973|TAB A101|TAB A103|TAB A104|TAB A104.2|R105BK|M713G|A972BK|TAB A971|TAB R974.2|TAB R104|TAB R83.3|TAB A1042",ModecomTablet:"FreeTAB 9000|FreeTAB 7.4|FreeTAB 7004|FreeTAB 7800|FreeTAB 2096|FreeTAB 7.5|FreeTAB 1014|FreeTAB 1001 |FreeTAB 8001|FreeTAB 9706|FreeTAB 9702|FreeTAB 7003|FreeTAB 7002|FreeTAB 1002|FreeTAB 7801|FreeTAB 1331|FreeTAB 1004|FreeTAB 8002|FreeTAB 8014|FreeTAB 9704|FreeTAB 1003",VoninoTablet:"\\b(Argus[ _]?S|Diamond[ _]?79HD|Emerald[ _]?78E|Luna[ _]?70C|Onyx[ _]?S|Onyx[ _]?Z|Orin[ _]?HD|Orin[ _]?S|Otis[ _]?S|SpeedStar[ _]?S|Magnet[ _]?M9|Primus[ _]?94[ _]?3G|Primus[ _]?94HD|Primus[ _]?QS|Android.*\\bQ8\\b|Sirius[ _]?EVO[ _]?QS|Sirius[ _]?QS|Spirit[ _]?S)\\b",ECSTablet:"V07OT2|TM105A|S10OT1|TR10CS1",StorexTablet:"eZee[_']?(Tab|Go)[0-9]+|TabLC7|Looney Tunes Tab",VodafoneTablet:"SmartTab([ ]+)?[0-9]+|SmartTabII10|SmartTabII7|VF-1497|VFD 1400",EssentielBTablet:"Smart[ ']?TAB[ ]+?[0-9]+|Family[ ']?TAB2",RossMoorTablet:"RM-790|RM-997|RMD-878G|RMD-974R|RMT-705A|RMT-701|RME-601|RMT-501|RMT-711",iMobileTablet:"i-mobile i-note",TolinoTablet:"tolino tab [0-9.]+|tolino shine",AudioSonicTablet:"\\bC-22Q|T7-QC|T-17B|T-17P\\b",AMPETablet:"Android.* A78 ",SkkTablet:"Android.* (SKYPAD|PHOENIX|CYCLOPS)",TecnoTablet:"TECNO P9|TECNO DP8D",JXDTablet:"Android.* \\b(F3000|A3300|JXD5000|JXD3000|JXD2000|JXD300B|JXD300|S5800|S7800|S602b|S5110b|S7300|S5300|S602|S603|S5100|S5110|S601|S7100a|P3000F|P3000s|P101|P200s|P1000m|P200m|P9100|P1000s|S6600b|S908|P1000|P300|S18|S6600|S9100)\\b",iJoyTablet:"Tablet (Spirit 7|Essentia|Galatea|Fusion|Onix 7|Landa|Titan|Scooby|Deox|Stella|Themis|Argon|Unique 7|Sygnus|Hexen|Finity 7|Cream|Cream X2|Jade|Neon 7|Neron 7|Kandy|Scape|Saphyr 7|Rebel|Biox|Rebel|Rebel 8GB|Myst|Draco 7|Myst|Tab7-004|Myst|Tadeo Jones|Tablet Boing|Arrow|Draco Dual Cam|Aurix|Mint|Amity|Revolution|Finity 9|Neon 9|T9w|Amity 4GB Dual Cam|Stone 4GB|Stone 8GB|Andromeda|Silken|X2|Andromeda II|Halley|Flame|Saphyr 9,7|Touch 8|Planet|Triton|Unique 10|Hexen 10|Memphis 4GB|Memphis 8GB|Onix 10)",FX2Tablet:"FX2 PAD7|FX2 PAD10",XoroTablet:"KidsPAD 701|PAD[ ]?712|PAD[ ]?714|PAD[ ]?716|PAD[ ]?717|PAD[ ]?718|PAD[ ]?720|PAD[ ]?721|PAD[ ]?722|PAD[ ]?790|PAD[ ]?792|PAD[ ]?900|PAD[ ]?9715D|PAD[ ]?9716DR|PAD[ ]?9718DR|PAD[ ]?9719QR|PAD[ ]?9720QR|TelePAD1030|Telepad1032|TelePAD730|TelePAD731|TelePAD732|TelePAD735Q|TelePAD830|TelePAD9730|TelePAD795|MegaPAD 1331|MegaPAD 1851|MegaPAD 2151",ViewsonicTablet:"ViewPad 10pi|ViewPad 10e|ViewPad 10s|ViewPad E72|ViewPad7|ViewPad E100|ViewPad 7e|ViewSonic VB733|VB100a",VerizonTablet:"QTAQZ3|QTAIR7|QTAQTZ3|QTASUN1|QTASUN2|QTAXIA1",OdysTablet:"LOOX|XENO10|ODYS[ -](Space|EVO|Xpress|NOON)|\\bXELIO\\b|Xelio10Pro|XELIO7PHONETAB|XELIO10EXTREME|XELIOPT2|NEO_QUAD10",CaptivaTablet:"CAPTIVA PAD",IconbitTablet:"NetTAB|NT-3702|NT-3702S|NT-3702S|NT-3603P|NT-3603P|NT-0704S|NT-0704S|NT-3805C|NT-3805C|NT-0806C|NT-0806C|NT-0909T|NT-0909T|NT-0907S|NT-0907S|NT-0902S|NT-0902S",TeclastTablet:"T98 4G|\\bP80\\b|\\bX90HD\\b|X98 Air|X98 Air 3G|\\bX89\\b|P80 3G|\\bX80h\\b|P98 Air|\\bX89HD\\b|P98 3G|\\bP90HD\\b|P89 3G|X98 3G|\\bP70h\\b|P79HD 3G|G18d 3G|\\bP79HD\\b|\\bP89s\\b|\\bA88\\b|\\bP10HD\\b|\\bP19HD\\b|G18 3G|\\bP78HD\\b|\\bA78\\b|\\bP75\\b|G17s 3G|G17h 3G|\\bP85t\\b|\\bP90\\b|\\bP11\\b|\\bP98t\\b|\\bP98HD\\b|\\bG18d\\b|\\bP85s\\b|\\bP11HD\\b|\\bP88s\\b|\\bA80HD\\b|\\bA80se\\b|\\bA10h\\b|\\bP89\\b|\\bP78s\\b|\\bG18\\b|\\bP85\\b|\\bA70h\\b|\\bA70\\b|\\bG17\\b|\\bP18\\b|\\bA80s\\b|\\bA11s\\b|\\bP88HD\\b|\\bA80h\\b|\\bP76s\\b|\\bP76h\\b|\\bP98\\b|\\bA10HD\\b|\\bP78\\b|\\bP88\\b|\\bA11\\b|\\bA10t\\b|\\bP76a\\b|\\bP76t\\b|\\bP76e\\b|\\bP85HD\\b|\\bP85a\\b|\\bP86\\b|\\bP75HD\\b|\\bP76v\\b|\\bA12\\b|\\bP75a\\b|\\bA15\\b|\\bP76Ti\\b|\\bP81HD\\b|\\bA10\\b|\\bT760VE\\b|\\bT720HD\\b|\\bP76\\b|\\bP73\\b|\\bP71\\b|\\bP72\\b|\\bT720SE\\b|\\bC520Ti\\b|\\bT760\\b|\\bT720VE\\b|T720-3GE|T720-WiFi",OndaTablet:"\\b(V975i|Vi30|VX530|V701|Vi60|V701s|Vi50|V801s|V719|Vx610w|VX610W|V819i|Vi10|VX580W|Vi10|V711s|V813|V811|V820w|V820|Vi20|V711|VI30W|V712|V891w|V972|V819w|V820w|Vi60|V820w|V711|V813s|V801|V819|V975s|V801|V819|V819|V818|V811|V712|V975m|V101w|V961w|V812|V818|V971|V971s|V919|V989|V116w|V102w|V973|Vi40)\\b[\\s]+|V10 \\b4G\\b",JaytechTablet:"TPC-PA762",BlaupunktTablet:"Endeavour 800NG|Endeavour 1010",DigmaTablet:"\\b(iDx10|iDx9|iDx8|iDx7|iDxD7|iDxD8|iDsQ8|iDsQ7|iDsQ8|iDsD10|iDnD7|3TS804H|iDsQ11|iDj7|iDs10)\\b",EvolioTablet:"ARIA_Mini_wifi|Aria[ _]Mini|Evolio X10|Evolio X7|Evolio X8|\\bEvotab\\b|\\bNeura\\b",LavaTablet:"QPAD E704|\\bIvoryS\\b|E-TAB IVORY|\\bE-TAB\\b",AocTablet:"MW0811|MW0812|MW0922|MTK8382|MW1031|MW0831|MW0821|MW0931|MW0712",MpmanTablet:"MP11 OCTA|MP10 OCTA|MPQC1114|MPQC1004|MPQC994|MPQC974|MPQC973|MPQC804|MPQC784|MPQC780|\\bMPG7\\b|MPDCG75|MPDCG71|MPDC1006|MP101DC|MPDC9000|MPDC905|MPDC706HD|MPDC706|MPDC705|MPDC110|MPDC100|MPDC99|MPDC97|MPDC88|MPDC8|MPDC77|MP709|MID701|MID711|MID170|MPDC703|MPQC1010",CelkonTablet:"CT695|CT888|CT[\\s]?910|CT7 Tab|CT9 Tab|CT3 Tab|CT2 Tab|CT1 Tab|C820|C720|\\bCT-1\\b",WolderTablet:"miTab \\b(DIAMOND|SPACE|BROOKLYN|NEO|FLY|MANHATTAN|FUNK|EVOLUTION|SKY|GOCAR|IRON|GENIUS|POP|MINT|EPSILON|BROADWAY|JUMP|HOP|LEGEND|NEW AGE|LINE|ADVANCE|FEEL|FOLLOW|LIKE|LINK|LIVE|THINK|FREEDOM|CHICAGO|CLEVELAND|BALTIMORE-GH|IOWA|BOSTON|SEATTLE|PHOENIX|DALLAS|IN 101|MasterChef)\\b",MediacomTablet:"M-MPI10C3G|M-SP10EG|M-SP10EGP|M-SP10HXAH|M-SP7HXAH|M-SP10HXBH|M-SP8HXAH|M-SP8MXA",MiTablet:"\\bMI PAD\\b|\\bHM NOTE 1W\\b",NibiruTablet:"Nibiru M1|Nibiru Jupiter One",NexoTablet:"NEXO NOVA|NEXO 10|NEXO AVIO|NEXO FREE|NEXO GO|NEXO EVO|NEXO 3G|NEXO SMART|NEXO KIDDO|NEXO MOBI",LeaderTablet:"TBLT10Q|TBLT10I|TBL-10WDKB|TBL-10WDKBO2013|TBL-W230V2|TBL-W450|TBL-W500|SV572|TBLT7I|TBA-AC7-8G|TBLT79|TBL-8W16|TBL-10W32|TBL-10WKB|TBL-W100",UbislateTablet:"UbiSlate[\\s]?7C",PocketBookTablet:"Pocketbook",KocasoTablet:"\\b(TB-1207)\\b",HisenseTablet:"\\b(F5281|E2371)\\b",Hudl:"Hudl HT7S3|Hudl 2",TelstraTablet:"T-Hub2",GenericTablet:"Android.*\\b97D\\b|Tablet(?!.*PC)|BNTV250A|MID-WCDMA|LogicPD Zoom2|\\bA7EB\\b|CatNova8|A1_07|CT704|CT1002|\\bM721\\b|rk30sdk|\\bEVOTAB\\b|M758A|ET904|ALUMIUM10|Smartfren Tab|Endeavour 1010|Tablet-PC-4|Tagi Tab|\\bM6pro\\b|CT1020W|arc 10HD|\\bTP750\\b|\\bQTAQZ3\\b|WVT101|TM1088|KT107"},oss:{AndroidOS:"Android",BlackBerryOS:"blackberry|\\bBB10\\b|rim tablet os",PalmOS:"PalmOS|avantgo|blazer|elaine|hiptop|palm|plucker|xiino",SymbianOS:"Symbian|SymbOS|Series60|Series40|SYB-[0-9]+|\\bS60\\b",WindowsMobileOS:"Windows CE.*(PPC|Smartphone|Mobile|[0-9]{3}x[0-9]{3})|Windows Mobile|Windows Phone [0-9.]+|WCE;",WindowsPhoneOS:"Windows Phone 10.0|Windows Phone 8.1|Windows Phone 8.0|Windows Phone OS|XBLWP7|ZuneWP7|Windows NT 6.[23]; ARM;",iOS:"\\biPhone.*Mobile|\\biPod|\\biPad|AppleCoreMedia",iPadOS:"CPU OS 13",SailfishOS:"Sailfish",MeeGoOS:"MeeGo",MaemoOS:"Maemo",JavaOS:"J2ME/|\\bMIDP\\b|\\bCLDC\\b",webOS:"webOS|hpwOS",badaOS:"\\bBada\\b",BREWOS:"BREW"},uas:{Chrome:"\\bCrMo\\b|CriOS|Android.*Chrome/[.0-9]* (Mobile)?",Dolfin:"\\bDolfin\\b",Opera:"Opera.*Mini|Opera.*Mobi|Android.*Opera|Mobile.*OPR/[0-9.]+$|Coast/[0-9.]+",Skyfire:"Skyfire",Edge:"\\bEdgiOS\\b|Mobile Safari/[.0-9]* Edge",IE:"IEMobile|MSIEMobile",Firefox:"fennec|firefox.*maemo|(Mobile|Tablet).*Firefox|Firefox.*Mobile|FxiOS",Bolt:"bolt",TeaShark:"teashark",Blazer:"Blazer",Safari:"Version((?!\\bEdgiOS\\b).)*Mobile.*Safari|Safari.*Mobile|MobileSafari",WeChat:"\\bMicroMessenger\\b",UCBrowser:"UC.*Browser|UCWEB",baiduboxapp:"baiduboxapp",baidubrowser:"baidubrowser",DiigoBrowser:"DiigoBrowser",Mercury:"\\bMercury\\b",ObigoBrowser:"Obigo",NetFront:"NF-Browser",GenericBrowser:"NokiaBrowser|OviBrowser|OneBrowser|TwonkyBeamBrowser|SEMC.*Browser|FlyFlow|Minimo|NetFront|Novarra-Vision|MQQBrowser|MicroMessenger",PaleMoon:"Android.*PaleMoon|Mobile.*PaleMoon"},props:{Mobile:"Mobile/[VER]",Build:"Build/[VER]",Version:"Version/[VER]",VendorID:"VendorID/[VER]",iPad:"iPad.*CPU[a-z ]+[VER]",iPhone:"iPhone.*CPU[a-z ]+[VER]",iPod:"iPod.*CPU[a-z ]+[VER]",Kindle:"Kindle/[VER]",Chrome:["Chrome/[VER]","CriOS/[VER]","CrMo/[VER]"],Coast:["Coast/[VER]"],Dolfin:"Dolfin/[VER]",Firefox:["Firefox/[VER]","FxiOS/[VER]"],Fennec:"Fennec/[VER]",Edge:"Edge/[VER]",IE:["IEMobile/[VER];","IEMobile [VER]","MSIE [VER];","Trident/[0-9.]+;.*rv:[VER]"],NetFront:"NetFront/[VER]",NokiaBrowser:"NokiaBrowser/[VER]",Opera:[" OPR/[VER]","Opera Mini/[VER]","Version/[VER]"],"Opera Mini":"Opera Mini/[VER]","Opera Mobi":"Version/[VER]",UCBrowser:["UCWEB[VER]","UC.*Browser/[VER]"],MQQBrowser:"MQQBrowser/[VER]",MicroMessenger:"MicroMessenger/[VER]",baiduboxapp:"baiduboxapp/[VER]",baidubrowser:"baidubrowser/[VER]",SamsungBrowser:"SamsungBrowser/[VER]",Iron:"Iron/[VER]",Safari:["Version/[VER]","Safari/[VER]"],Skyfire:"Skyfire/[VER]",Tizen:"Tizen/[VER]",Webkit:"webkit[ /][VER]",PaleMoon:"PaleMoon/[VER]",SailfishBrowser:"SailfishBrowser/[VER]",Gecko:"Gecko/[VER]",Trident:"Trident/[VER]",Presto:"Presto/[VER]",Goanna:"Goanna/[VER]",iOS:" \\bi?OS\\b [VER][ ;]{1}",Android:"Android [VER]",Sailfish:"Sailfish [VER]",BlackBerry:["BlackBerry[\\w]+/[VER]","BlackBerry.*Version/[VER]","Version/[VER]"],BREW:"BREW [VER]",Java:"Java/[VER]","Windows Phone OS":["Windows Phone OS [VER]","Windows Phone [VER]"],"Windows Phone":"Windows Phone [VER]","Windows CE":"Windows CE/[VER]","Windows NT":"Windows NT [VER]",Symbian:["SymbianOS/[VER]","Symbian/[VER]"],webOS:["webOS/[VER]","hpwOS/[VER];"]},utils:{Bot:"Googlebot|facebookexternalhit|Google-AMPHTML|s~amp-validator|AdsBot-Google|Google Keyword Suggestion|Facebot|YandexBot|YandexMobileBot|bingbot|ia_archiver|AhrefsBot|Ezooms|GSLFbot|WBSearchBot|Twitterbot|TweetmemeBot|Twikle|PaperLiBot|Wotbox|UnwindFetchor|Exabot|MJ12bot|YandexImages|TurnitinBot|Pingdom|contentkingapp|AspiegelBot",MobileBot:"Googlebot-Mobile|AdsBot-Google-Mobile|YahooSeeker/M1A1-R2D2",DesktopMode:"WPDesktop",TV:"SonyDTV|HbbTV",WebKit:"(webkit)[ /]([\\w.]+)",Console:"\\b(Nintendo|Nintendo WiiU|Nintendo 3DS|Nintendo Switch|PLAYSTATION|Xbox)\\b",Watch:"SM-V700"}},g.detectMobileBrowsers={fullPattern:/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i,
shortPattern:/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i,tabletPattern:/android|ipad|playbook|silk/i};var h,i=Object.prototype.hasOwnProperty;return g.FALLBACK_PHONE="UnknownPhone",g.FALLBACK_TABLET="UnknownTablet",g.FALLBACK_MOBILE="UnknownMobile",h="isArray"in Array?Array.isArray:function(a){return"[object Array]"===Object.prototype.toString.call(a)},function(){var a,b,c,e,f,j,k=g.mobileDetectRules;for(a in k.props)if(i.call(k.props,a)){for(b=k.props[a],h(b)||(b=[b]),f=b.length,e=0;e<f;++e)c=b[e],j=c.indexOf("[VER]"),j>=0&&(c=c.substring(0,j)+"([\\w._\\+]+)"+c.substring(j+5)),b[e]=new RegExp(c,"i");k.props[a]=b}d(k.oss),d(k.phones),d(k.tablets),d(k.uas),d(k.utils),k.oss0={WindowsPhoneOS:k.oss.WindowsPhoneOS,WindowsMobileOS:k.oss.WindowsMobileOS}}(),g.findMatch=function(a,b){for(var c in a)if(i.call(a,c)&&a[c].test(b))return c;return null},g.findMatches=function(a,b){var c=[];for(var d in a)i.call(a,d)&&a[d].test(b)&&c.push(d);return c},g.getVersionStr=function(a,b){var c,d,e,f,h=g.mobileDetectRules.props;if(i.call(h,a))for(c=h[a],e=c.length,d=0;d<e;++d)if(f=c[d].exec(b),null!==f)return f[1];return null},g.getVersion=function(a,b){var c=g.getVersionStr(a,b);return c?g.prepareVersionNo(c):NaN},g.prepareVersionNo=function(a){var b;return b=a.split(/[a-z._ \/\-]/i),1===b.length&&(a=b[0]),b.length>1&&(a=b[0]+".",b.shift(),a+=b.join("")),Number(a)},g.isMobileFallback=function(a){return g.detectMobileBrowsers.fullPattern.test(a)||g.detectMobileBrowsers.shortPattern.test(a.substr(0,4))},g.isTabletFallback=function(a){return g.detectMobileBrowsers.tabletPattern.test(a)},g.prepareDetectionCache=function(a,c,d){if(a.mobile===b){var e,h,i;return(h=g.findMatch(g.mobileDetectRules.tablets,c))?(a.mobile=a.tablet=h,void(a.phone=null)):(e=g.findMatch(g.mobileDetectRules.phones,c))?(a.mobile=a.phone=e,void(a.tablet=null)):void(g.isMobileFallback(c)?(i=f.isPhoneSized(d),i===b?(a.mobile=g.FALLBACK_MOBILE,a.tablet=a.phone=null):i?(a.mobile=a.phone=g.FALLBACK_PHONE,a.tablet=null):(a.mobile=a.tablet=g.FALLBACK_TABLET,a.phone=null)):g.isTabletFallback(c)?(a.mobile=a.tablet=g.FALLBACK_TABLET,a.phone=null):a.mobile=a.tablet=a.phone=null)}},g.mobileGrade=function(a){var b=null!==a.mobile();return a.os("iOS")&&a.version("iPad")>=4.3||a.os("iOS")&&a.version("iPhone")>=3.1||a.os("iOS")&&a.version("iPod")>=3.1||a.version("Android")>2.1&&a.is("Webkit")||a.version("Windows Phone OS")>=7||a.is("BlackBerry")&&a.version("BlackBerry")>=6||a.match("Playbook.*Tablet")||a.version("webOS")>=1.4&&a.match("Palm|Pre|Pixi")||a.match("hp.*TouchPad")||a.is("Firefox")&&a.version("Firefox")>=12||a.is("Chrome")&&a.is("AndroidOS")&&a.version("Android")>=4||a.is("Skyfire")&&a.version("Skyfire")>=4.1&&a.is("AndroidOS")&&a.version("Android")>=2.3||a.is("Opera")&&a.version("Opera Mobi")>11&&a.is("AndroidOS")||a.is("MeeGoOS")||a.is("Tizen")||a.is("Dolfin")&&a.version("Bada")>=2||(a.is("UC Browser")||a.is("Dolfin"))&&a.version("Android")>=2.3||a.match("Kindle Fire")||a.is("Kindle")&&a.version("Kindle")>=3||a.is("AndroidOS")&&a.is("NookTablet")||a.version("Chrome")>=11&&!b||a.version("Safari")>=5&&!b||a.version("Firefox")>=4&&!b||a.version("MSIE")>=7&&!b||a.version("Opera")>=10&&!b?"A":a.os("iOS")&&a.version("iPad")<4.3||a.os("iOS")&&a.version("iPhone")<3.1||a.os("iOS")&&a.version("iPod")<3.1||a.is("Blackberry")&&a.version("BlackBerry")>=5&&a.version("BlackBerry")<6||a.version("Opera Mini")>=5&&a.version("Opera Mini")<=6.5&&(a.version("Android")>=2.3||a.is("iOS"))||a.match("NokiaN8|NokiaC7|N97.*Series60|Symbian/3")||a.version("Opera Mobi")>=11&&a.is("SymbianOS")?"B":(a.version("BlackBerry")<5||a.match("MSIEMobile|Windows CE.*Mobile")||a.version("Windows Mobile")<=5.2,"C")},g.detectOS=function(a){return g.findMatch(g.mobileDetectRules.oss0,a)||g.findMatch(g.mobileDetectRules.oss,a)},g.getDeviceSmallerSide=function(){return window.screen.width<window.screen.height?window.screen.width:window.screen.height},f.prototype={constructor:f,mobile:function(){return g.prepareDetectionCache(this._cache,this.ua,this.maxPhoneWidth),this._cache.mobile},phone:function(){return g.prepareDetectionCache(this._cache,this.ua,this.maxPhoneWidth),this._cache.phone},tablet:function(){return g.prepareDetectionCache(this._cache,this.ua,this.maxPhoneWidth),this._cache.tablet},userAgent:function(){return this._cache.userAgent===b&&(this._cache.userAgent=g.findMatch(g.mobileDetectRules.uas,this.ua)),this._cache.userAgent},userAgents:function(){return this._cache.userAgents===b&&(this._cache.userAgents=g.findMatches(g.mobileDetectRules.uas,this.ua)),this._cache.userAgents},os:function(){return this._cache.os===b&&(this._cache.os=g.detectOS(this.ua)),this._cache.os},version:function(a){return g.getVersion(a,this.ua)},versionStr:function(a){return g.getVersionStr(a,this.ua)},is:function(b){return c(this.userAgents(),b)||a(b,this.os())||a(b,this.phone())||a(b,this.tablet())||c(g.findMatches(g.mobileDetectRules.utils,this.ua),b)},match:function(a){return a instanceof RegExp||(a=new RegExp(a,"i")),a.test(this.ua)},isPhoneSized:function(a){return f.isPhoneSized(a||this.maxPhoneWidth)},mobileGrade:function(){return this._cache.grade===b&&(this._cache.grade=g.mobileGrade(this)),this._cache.grade}},"undefined"!=typeof window&&window.screen?f.isPhoneSized=function(a){return a<0?b:g.getDeviceSmallerSide()<=a}:f.isPhoneSized=function(){},f._impl=g,f.version="1.4.5 2021-03-13",f})}(function(a){if("undefined"!=typeof module&&module.exports)return function(a){module.exports=a()};if("function"==typeof define&&define.amd)return define;if("undefined"!=typeof window)return function(a){window.MobileDetect=a()};throw new Error("unknown environment")}());public/assets/js/inc/mobile-detect-js/LICENSE000064400000002070151213253550014646 0ustar00The MIT License (MIT)

Copyright (c) 2013 Heinrich Goebl

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.public/assets/js/inc/momentjs/moment.js000064400000523516151213253550014220 0ustar00//! moment.js
//! version : 2.29.1
//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
//! license : MIT
//! momentjs.com

;(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
    typeof define === 'function' && define.amd ? define(factory) :
    global.moment = factory()
}(this, (function () { 'use strict';

    var hookCallback;

    function hooks() {
        return hookCallback.apply(null, arguments);
    }

    // This is done to register the method called with moment()
    // without creating circular dependencies.
    function setHookCallback(callback) {
        hookCallback = callback;
    }

    function isArray(input) {
        return (
            input instanceof Array ||
            Object.prototype.toString.call(input) === '[object Array]'
        );
    }

    function isObject(input) {
        // IE8 will treat undefined and null as object if it wasn't for
        // input != null
        return (
            input != null &&
            Object.prototype.toString.call(input) === '[object Object]'
        );
    }

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function isObjectEmpty(obj) {
        if (Object.getOwnPropertyNames) {
            return Object.getOwnPropertyNames(obj).length === 0;
        } else {
            var k;
            for (k in obj) {
                if (hasOwnProp(obj, k)) {
                    return false;
                }
            }
            return true;
        }
    }

    function isUndefined(input) {
        return input === void 0;
    }

    function isNumber(input) {
        return (
            typeof input === 'number' ||
            Object.prototype.toString.call(input) === '[object Number]'
        );
    }

    function isDate(input) {
        return (
            input instanceof Date ||
            Object.prototype.toString.call(input) === '[object Date]'
        );
    }

    function map(arr, fn) {
        var res = [],
            i;
        for (i = 0; i < arr.length; ++i) {
            res.push(fn(arr[i], i));
        }
        return res;
    }

    function extend(a, b) {
        for (var i in b) {
            if (hasOwnProp(b, i)) {
                a[i] = b[i];
            }
        }

        if (hasOwnProp(b, 'toString')) {
            a.toString = b.toString;
        }

        if (hasOwnProp(b, 'valueOf')) {
            a.valueOf = b.valueOf;
        }

        return a;
    }

    function createUTC(input, format, locale, strict) {
        return createLocalOrUTC(input, format, locale, strict, true).utc();
    }

    function defaultParsingFlags() {
        // We need to deep clone this object.
        return {
            empty: false,
            unusedTokens: [],
            unusedInput: [],
            overflow: -2,
            charsLeftOver: 0,
            nullInput: false,
            invalidEra: null,
            invalidMonth: null,
            invalidFormat: false,
            userInvalidated: false,
            iso: false,
            parsedDateParts: [],
            era: null,
            meridiem: null,
            rfc2822: false,
            weekdayMismatch: false,
        };
    }

    function getParsingFlags(m) {
        if (m._pf == null) {
            m._pf = defaultParsingFlags();
        }
        return m._pf;
    }

    var some;
    if (Array.prototype.some) {
        some = Array.prototype.some;
    } else {
        some = function (fun) {
            var t = Object(this),
                len = t.length >>> 0,
                i;

            for (i = 0; i < len; i++) {
                if (i in t && fun.call(this, t[i], i, t)) {
                    return true;
                }
            }

            return false;
        };
    }

    function isValid(m) {
        if (m._isValid == null) {
            var flags = getParsingFlags(m),
                parsedParts = some.call(flags.parsedDateParts, function (i) {
                    return i != null;
                }),
                isNowValid =
                    !isNaN(m._d.getTime()) &&
                    flags.overflow < 0 &&
                    !flags.empty &&
                    !flags.invalidEra &&
                    !flags.invalidMonth &&
                    !flags.invalidWeekday &&
                    !flags.weekdayMismatch &&
                    !flags.nullInput &&
                    !flags.invalidFormat &&
                    !flags.userInvalidated &&
                    (!flags.meridiem || (flags.meridiem && parsedParts));

            if (m._strict) {
                isNowValid =
                    isNowValid &&
                    flags.charsLeftOver === 0 &&
                    flags.unusedTokens.length === 0 &&
                    flags.bigHour === undefined;
            }

            if (Object.isFrozen == null || !Object.isFrozen(m)) {
                m._isValid = isNowValid;
            } else {
                return isNowValid;
            }
        }
        return m._isValid;
    }

    function createInvalid(flags) {
        var m = createUTC(NaN);
        if (flags != null) {
            extend(getParsingFlags(m), flags);
        } else {
            getParsingFlags(m).userInvalidated = true;
        }

        return m;
    }

    // Plugins that add properties should also add the key here (null value),
    // so we can properly clone ourselves.
    var momentProperties = (hooks.momentProperties = []),
        updateInProgress = false;

    function copyConfig(to, from) {
        var i, prop, val;

        if (!isUndefined(from._isAMomentObject)) {
            to._isAMomentObject = from._isAMomentObject;
        }
        if (!isUndefined(from._i)) {
            to._i = from._i;
        }
        if (!isUndefined(from._f)) {
            to._f = from._f;
        }
        if (!isUndefined(from._l)) {
            to._l = from._l;
        }
        if (!isUndefined(from._strict)) {
            to._strict = from._strict;
        }
        if (!isUndefined(from._tzm)) {
            to._tzm = from._tzm;
        }
        if (!isUndefined(from._isUTC)) {
            to._isUTC = from._isUTC;
        }
        if (!isUndefined(from._offset)) {
            to._offset = from._offset;
        }
        if (!isUndefined(from._pf)) {
            to._pf = getParsingFlags(from);
        }
        if (!isUndefined(from._locale)) {
            to._locale = from._locale;
        }

        if (momentProperties.length > 0) {
            for (i = 0; i < momentProperties.length; i++) {
                prop = momentProperties[i];
                val = from[prop];
                if (!isUndefined(val)) {
                    to[prop] = val;
                }
            }
        }

        return to;
    }

    // Moment prototype object
    function Moment(config) {
        copyConfig(this, config);
        this._d = new Date(config._d != null ? config._d.getTime() : NaN);
        if (!this.isValid()) {
            this._d = new Date(NaN);
        }
        // Prevent infinite loop in case updateOffset creates new moment
        // objects.
        if (updateInProgress === false) {
            updateInProgress = true;
            hooks.updateOffset(this);
            updateInProgress = false;
        }
    }

    function isMoment(obj) {
        return (
            obj instanceof Moment || (obj != null && obj._isAMomentObject != null)
        );
    }

    function warn(msg) {
        if (
            hooks.suppressDeprecationWarnings === false &&
            typeof console !== 'undefined' &&
            console.warn
        ) {
            console.warn('Deprecation warning: ' + msg);
        }
    }

    function deprecate(msg, fn) {
        var firstTime = true;

        return extend(function () {
            if (hooks.deprecationHandler != null) {
                hooks.deprecationHandler(null, msg);
            }
            if (firstTime) {
                var args = [],
                    arg,
                    i,
                    key;
                for (i = 0; i < arguments.length; i++) {
                    arg = '';
                    if (typeof arguments[i] === 'object') {
                        arg += '\n[' + i + '] ';
                        for (key in arguments[0]) {
                            if (hasOwnProp(arguments[0], key)) {
                                arg += key + ': ' + arguments[0][key] + ', ';
                            }
                        }
                        arg = arg.slice(0, -2); // Remove trailing comma and space
                    } else {
                        arg = arguments[i];
                    }
                    args.push(arg);
                }
                warn(
                    msg +
                        '\nArguments: ' +
                        Array.prototype.slice.call(args).join('') +
                        '\n' +
                        new Error().stack
                );
                firstTime = false;
            }
            return fn.apply(this, arguments);
        }, fn);
    }

    var deprecations = {};

    function deprecateSimple(name, msg) {
        if (hooks.deprecationHandler != null) {
            hooks.deprecationHandler(name, msg);
        }
        if (!deprecations[name]) {
            warn(msg);
            deprecations[name] = true;
        }
    }

    hooks.suppressDeprecationWarnings = false;
    hooks.deprecationHandler = null;

    function isFunction(input) {
        return (
            (typeof Function !== 'undefined' && input instanceof Function) ||
            Object.prototype.toString.call(input) === '[object Function]'
        );
    }

    function set(config) {
        var prop, i;
        for (i in config) {
            if (hasOwnProp(config, i)) {
                prop = config[i];
                if (isFunction(prop)) {
                    this[i] = prop;
                } else {
                    this['_' + i] = prop;
                }
            }
        }
        this._config = config;
        // Lenient ordinal parsing accepts just a number in addition to
        // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.
        // TODO: Remove "ordinalParse" fallback in next major release.
        this._dayOfMonthOrdinalParseLenient = new RegExp(
            (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +
                '|' +
                /\d{1,2}/.source
        );
    }

    function mergeConfigs(parentConfig, childConfig) {
        var res = extend({}, parentConfig),
            prop;
        for (prop in childConfig) {
            if (hasOwnProp(childConfig, prop)) {
                if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
                    res[prop] = {};
                    extend(res[prop], parentConfig[prop]);
                    extend(res[prop], childConfig[prop]);
                } else if (childConfig[prop] != null) {
                    res[prop] = childConfig[prop];
                } else {
                    delete res[prop];
                }
            }
        }
        for (prop in parentConfig) {
            if (
                hasOwnProp(parentConfig, prop) &&
                !hasOwnProp(childConfig, prop) &&
                isObject(parentConfig[prop])
            ) {
                // make sure changes to properties don't modify parent config
                res[prop] = extend({}, res[prop]);
            }
        }
        return res;
    }

    function Locale(config) {
        if (config != null) {
            this.set(config);
        }
    }

    var keys;

    if (Object.keys) {
        keys = Object.keys;
    } else {
        keys = function (obj) {
            var i,
                res = [];
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        };
    }

    var defaultCalendar = {
        sameDay: '[Today at] LT',
        nextDay: '[Tomorrow at] LT',
        nextWeek: 'dddd [at] LT',
        lastDay: '[Yesterday at] LT',
        lastWeek: '[Last] dddd [at] LT',
        sameElse: 'L',
    };

    function calendar(key, mom, now) {
        var output = this._calendar[key] || this._calendar['sameElse'];
        return isFunction(output) ? output.call(mom, now) : output;
    }

    function zeroFill(number, targetLength, forceSign) {
        var absNumber = '' + Math.abs(number),
            zerosToFill = targetLength - absNumber.length,
            sign = number >= 0;
        return (
            (sign ? (forceSign ? '+' : '') : '-') +
            Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) +
            absNumber
        );
    }

    var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|N{1,5}|YYYYYY|YYYYY|YYYY|YY|y{2,4}|yo?|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,
        localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,
        formatFunctions = {},
        formatTokenFunctions = {};

    // token:    'M'
    // padded:   ['MM', 2]
    // ordinal:  'Mo'
    // callback: function () { this.month() + 1 }
    function addFormatToken(token, padded, ordinal, callback) {
        var func = callback;
        if (typeof callback === 'string') {
            func = function () {
                return this[callback]();
            };
        }
        if (token) {
            formatTokenFunctions[token] = func;
        }
        if (padded) {
            formatTokenFunctions[padded[0]] = function () {
                return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
            };
        }
        if (ordinal) {
            formatTokenFunctions[ordinal] = function () {
                return this.localeData().ordinal(
                    func.apply(this, arguments),
                    token
                );
            };
        }
    }

    function removeFormattingTokens(input) {
        if (input.match(/\[[\s\S]/)) {
            return input.replace(/^\[|\]$/g, '');
        }
        return input.replace(/\\/g, '');
    }

    function makeFormatFunction(format) {
        var array = format.match(formattingTokens),
            i,
            length;

        for (i = 0, length = array.length; i < length; i++) {
            if (formatTokenFunctions[array[i]]) {
                array[i] = formatTokenFunctions[array[i]];
            } else {
                array[i] = removeFormattingTokens(array[i]);
            }
        }

        return function (mom) {
            var output = '',
                i;
            for (i = 0; i < length; i++) {
                output += isFunction(array[i])
                    ? array[i].call(mom, format)
                    : array[i];
            }
            return output;
        };
    }

    // format date using native date object
    function formatMoment(m, format) {
        if (!m.isValid()) {
            return m.localeData().invalidDate();
        }

        format = expandFormat(format, m.localeData());
        formatFunctions[format] =
            formatFunctions[format] || makeFormatFunction(format);

        return formatFunctions[format](m);
    }

    function expandFormat(format, locale) {
        var i = 5;

        function replaceLongDateFormatTokens(input) {
            return locale.longDateFormat(input) || input;
        }

        localFormattingTokens.lastIndex = 0;
        while (i >= 0 && localFormattingTokens.test(format)) {
            format = format.replace(
                localFormattingTokens,
                replaceLongDateFormatTokens
            );
            localFormattingTokens.lastIndex = 0;
            i -= 1;
        }

        return format;
    }

    var defaultLongDateFormat = {
        LTS: 'h:mm:ss A',
        LT: 'h:mm A',
        L: 'MM/DD/YYYY',
        LL: 'MMMM D, YYYY',
        LLL: 'MMMM D, YYYY h:mm A',
        LLLL: 'dddd, MMMM D, YYYY h:mm A',
    };

    function longDateFormat(key) {
        var format = this._longDateFormat[key],
            formatUpper = this._longDateFormat[key.toUpperCase()];

        if (format || !formatUpper) {
            return format;
        }

        this._longDateFormat[key] = formatUpper
            .match(formattingTokens)
            .map(function (tok) {
                if (
                    tok === 'MMMM' ||
                    tok === 'MM' ||
                    tok === 'DD' ||
                    tok === 'dddd'
                ) {
                    return tok.slice(1);
                }
                return tok;
            })
            .join('');

        return this._longDateFormat[key];
    }

    var defaultInvalidDate = 'Invalid date';

    function invalidDate() {
        return this._invalidDate;
    }

    var defaultOrdinal = '%d',
        defaultDayOfMonthOrdinalParse = /\d{1,2}/;

    function ordinal(number) {
        return this._ordinal.replace('%d', number);
    }

    var defaultRelativeTime = {
        future: 'in %s',
        past: '%s ago',
        s: 'a few seconds',
        ss: '%d seconds',
        m: 'a minute',
        mm: '%d minutes',
        h: 'an hour',
        hh: '%d hours',
        d: 'a day',
        dd: '%d days',
        w: 'a week',
        ww: '%d weeks',
        M: 'a month',
        MM: '%d months',
        y: 'a year',
        yy: '%d years',
    };

    function relativeTime(number, withoutSuffix, string, isFuture) {
        var output = this._relativeTime[string];
        return isFunction(output)
            ? output(number, withoutSuffix, string, isFuture)
            : output.replace(/%d/i, number);
    }

    function pastFuture(diff, output) {
        var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
        return isFunction(format) ? format(output) : format.replace(/%s/i, output);
    }

    var aliases = {};

    function addUnitAlias(unit, shorthand) {
        var lowerCase = unit.toLowerCase();
        aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
    }

    function normalizeUnits(units) {
        return typeof units === 'string'
            ? aliases[units] || aliases[units.toLowerCase()]
            : undefined;
    }

    function normalizeObjectUnits(inputObject) {
        var normalizedInput = {},
            normalizedProp,
            prop;

        for (prop in inputObject) {
            if (hasOwnProp(inputObject, prop)) {
                normalizedProp = normalizeUnits(prop);
                if (normalizedProp) {
                    normalizedInput[normalizedProp] = inputObject[prop];
                }
            }
        }

        return normalizedInput;
    }

    var priorities = {};

    function addUnitPriority(unit, priority) {
        priorities[unit] = priority;
    }

    function getPrioritizedUnits(unitsObj) {
        var units = [],
            u;
        for (u in unitsObj) {
            if (hasOwnProp(unitsObj, u)) {
                units.push({ unit: u, priority: priorities[u] });
            }
        }
        units.sort(function (a, b) {
            return a.priority - b.priority;
        });
        return units;
    }

    function isLeapYear(year) {
        return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
    }

    function absFloor(number) {
        if (number < 0) {
            // -0 -> 0
            return Math.ceil(number) || 0;
        } else {
            return Math.floor(number);
        }
    }

    function toInt(argumentForCoercion) {
        var coercedNumber = +argumentForCoercion,
            value = 0;

        if (coercedNumber !== 0 && isFinite(coercedNumber)) {
            value = absFloor(coercedNumber);
        }

        return value;
    }

    function makeGetSet(unit, keepTime) {
        return function (value) {
            if (value != null) {
                set$1(this, unit, value);
                hooks.updateOffset(this, keepTime);
                return this;
            } else {
                return get(this, unit);
            }
        };
    }

    function get(mom, unit) {
        return mom.isValid()
            ? mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]()
            : NaN;
    }

    function set$1(mom, unit, value) {
        if (mom.isValid() && !isNaN(value)) {
            if (
                unit === 'FullYear' &&
                isLeapYear(mom.year()) &&
                mom.month() === 1 &&
                mom.date() === 29
            ) {
                value = toInt(value);
                mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](
                    value,
                    mom.month(),
                    daysInMonth(value, mom.month())
                );
            } else {
                mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
            }
        }
    }

    // MOMENTS

    function stringGet(units) {
        units = normalizeUnits(units);
        if (isFunction(this[units])) {
            return this[units]();
        }
        return this;
    }

    function stringSet(units, value) {
        if (typeof units === 'object') {
            units = normalizeObjectUnits(units);
            var prioritized = getPrioritizedUnits(units),
                i;
            for (i = 0; i < prioritized.length; i++) {
                this[prioritized[i].unit](units[prioritized[i].unit]);
            }
        } else {
            units = normalizeUnits(units);
            if (isFunction(this[units])) {
                return this[units](value);
            }
        }
        return this;
    }

    var match1 = /\d/, //       0 - 9
        match2 = /\d\d/, //      00 - 99
        match3 = /\d{3}/, //     000 - 999
        match4 = /\d{4}/, //    0000 - 9999
        match6 = /[+-]?\d{6}/, // -999999 - 999999
        match1to2 = /\d\d?/, //       0 - 99
        match3to4 = /\d\d\d\d?/, //     999 - 9999
        match5to6 = /\d\d\d\d\d\d?/, //   99999 - 999999
        match1to3 = /\d{1,3}/, //       0 - 999
        match1to4 = /\d{1,4}/, //       0 - 9999
        match1to6 = /[+-]?\d{1,6}/, // -999999 - 999999
        matchUnsigned = /\d+/, //       0 - inf
        matchSigned = /[+-]?\d+/, //    -inf - inf
        matchOffset = /Z|[+-]\d\d:?\d\d/gi, // +00:00 -00:00 +0000 -0000 or Z
        matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi, // +00 -00 +00:00 -00:00 +0000 -0000 or Z
        matchTimestamp = /[+-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123
        // any word (or two) characters or numbers including two/three word month in arabic.
        // includes scottish gaelic two word and hyphenated months
        matchWord = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i,
        regexes;

    regexes = {};

    function addRegexToken(token, regex, strictRegex) {
        regexes[token] = isFunction(regex)
            ? regex
            : function (isStrict, localeData) {
                  return isStrict && strictRegex ? strictRegex : regex;
              };
    }

    function getParseRegexForToken(token, config) {
        if (!hasOwnProp(regexes, token)) {
            return new RegExp(unescapeFormat(token));
        }

        return regexes[token](config._strict, config._locale);
    }

    // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
    function unescapeFormat(s) {
        return regexEscape(
            s
                .replace('\\', '')
                .replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (
                    matched,
                    p1,
                    p2,
                    p3,
                    p4
                ) {
                    return p1 || p2 || p3 || p4;
                })
        );
    }

    function regexEscape(s) {
        return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
    }

    var tokens = {};

    function addParseToken(token, callback) {
        var i,
            func = callback;
        if (typeof token === 'string') {
            token = [token];
        }
        if (isNumber(callback)) {
            func = function (input, array) {
                array[callback] = toInt(input);
            };
        }
        for (i = 0; i < token.length; i++) {
            tokens[token[i]] = func;
        }
    }

    function addWeekParseToken(token, callback) {
        addParseToken(token, function (input, array, config, token) {
            config._w = config._w || {};
            callback(input, config._w, config, token);
        });
    }

    function addTimeToArrayFromToken(token, input, config) {
        if (input != null && hasOwnProp(tokens, token)) {
            tokens[token](input, config._a, config, token);
        }
    }

    var YEAR = 0,
        MONTH = 1,
        DATE = 2,
        HOUR = 3,
        MINUTE = 4,
        SECOND = 5,
        MILLISECOND = 6,
        WEEK = 7,
        WEEKDAY = 8;

    function mod(n, x) {
        return ((n % x) + x) % x;
    }

    var indexOf;

    if (Array.prototype.indexOf) {
        indexOf = Array.prototype.indexOf;
    } else {
        indexOf = function (o) {
            // I know
            var i;
            for (i = 0; i < this.length; ++i) {
                if (this[i] === o) {
                    return i;
                }
            }
            return -1;
        };
    }

    function daysInMonth(year, month) {
        if (isNaN(year) || isNaN(month)) {
            return NaN;
        }
        var modMonth = mod(month, 12);
        year += (month - modMonth) / 12;
        return modMonth === 1
            ? isLeapYear(year)
                ? 29
                : 28
            : 31 - ((modMonth % 7) % 2);
    }

    // FORMATTING

    addFormatToken('M', ['MM', 2], 'Mo', function () {
        return this.month() + 1;
    });

    addFormatToken('MMM', 0, 0, function (format) {
        return this.localeData().monthsShort(this, format);
    });

    addFormatToken('MMMM', 0, 0, function (format) {
        return this.localeData().months(this, format);
    });

    // ALIASES

    addUnitAlias('month', 'M');

    // PRIORITY

    addUnitPriority('month', 8);

    // PARSING

    addRegexToken('M', match1to2);
    addRegexToken('MM', match1to2, match2);
    addRegexToken('MMM', function (isStrict, locale) {
        return locale.monthsShortRegex(isStrict);
    });
    addRegexToken('MMMM', function (isStrict, locale) {
        return locale.monthsRegex(isStrict);
    });

    addParseToken(['M', 'MM'], function (input, array) {
        array[MONTH] = toInt(input) - 1;
    });

    addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
        var month = config._locale.monthsParse(input, token, config._strict);
        // if we didn't find a month name, mark the date as invalid.
        if (month != null) {
            array[MONTH] = month;
        } else {
            getParsingFlags(config).invalidMonth = input;
        }
    });

    // LOCALES

    var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split(
            '_'
        ),
        defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split(
            '_'
        ),
        MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/,
        defaultMonthsShortRegex = matchWord,
        defaultMonthsRegex = matchWord;

    function localeMonths(m, format) {
        if (!m) {
            return isArray(this._months)
                ? this._months
                : this._months['standalone'];
        }
        return isArray(this._months)
            ? this._months[m.month()]
            : this._months[
                  (this._months.isFormat || MONTHS_IN_FORMAT).test(format)
                      ? 'format'
                      : 'standalone'
              ][m.month()];
    }

    function localeMonthsShort(m, format) {
        if (!m) {
            return isArray(this._monthsShort)
                ? this._monthsShort
                : this._monthsShort['standalone'];
        }
        return isArray(this._monthsShort)
            ? this._monthsShort[m.month()]
            : this._monthsShort[
                  MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'
              ][m.month()];
    }

    function handleStrictParse(monthName, format, strict) {
        var i,
            ii,
            mom,
            llc = monthName.toLocaleLowerCase();
        if (!this._monthsParse) {
            // this is not used
            this._monthsParse = [];
            this._longMonthsParse = [];
            this._shortMonthsParse = [];
            for (i = 0; i < 12; ++i) {
                mom = createUTC([2000, i]);
                this._shortMonthsParse[i] = this.monthsShort(
                    mom,
                    ''
                ).toLocaleLowerCase();
                this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
            }
        }

        if (strict) {
            if (format === 'MMM') {
                ii = indexOf.call(this._shortMonthsParse, llc);
                return ii !== -1 ? ii : null;
            } else {
                ii = indexOf.call(this._longMonthsParse, llc);
                return ii !== -1 ? ii : null;
            }
        } else {
            if (format === 'MMM') {
                ii = indexOf.call(this._shortMonthsParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._longMonthsParse, llc);
                return ii !== -1 ? ii : null;
            } else {
                ii = indexOf.call(this._longMonthsParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._shortMonthsParse, llc);
                return ii !== -1 ? ii : null;
            }
        }
    }

    function localeMonthsParse(monthName, format, strict) {
        var i, mom, regex;

        if (this._monthsParseExact) {
            return handleStrictParse.call(this, monthName, format, strict);
        }

        if (!this._monthsParse) {
            this._monthsParse = [];
            this._longMonthsParse = [];
            this._shortMonthsParse = [];
        }

        // TODO: add sorting
        // Sorting makes sure if one month (or abbr) is a prefix of another
        // see sorting in computeMonthsParse
        for (i = 0; i < 12; i++) {
            // make the regex if we don't have it already
            mom = createUTC([2000, i]);
            if (strict && !this._longMonthsParse[i]) {
                this._longMonthsParse[i] = new RegExp(
                    '^' + this.months(mom, '').replace('.', '') + '$',
                    'i'
                );
                this._shortMonthsParse[i] = new RegExp(
                    '^' + this.monthsShort(mom, '').replace('.', '') + '$',
                    'i'
                );
            }
            if (!strict && !this._monthsParse[i]) {
                regex =
                    '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
                this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
            }
            // test the regex
            if (
                strict &&
                format === 'MMMM' &&
                this._longMonthsParse[i].test(monthName)
            ) {
                return i;
            } else if (
                strict &&
                format === 'MMM' &&
                this._shortMonthsParse[i].test(monthName)
            ) {
                return i;
            } else if (!strict && this._monthsParse[i].test(monthName)) {
                return i;
            }
        }
    }

    // MOMENTS

    function setMonth(mom, value) {
        var dayOfMonth;

        if (!mom.isValid()) {
            // No op
            return mom;
        }

        if (typeof value === 'string') {
            if (/^\d+$/.test(value)) {
                value = toInt(value);
            } else {
                value = mom.localeData().monthsParse(value);
                // TODO: Another silent failure?
                if (!isNumber(value)) {
                    return mom;
                }
            }
        }

        dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
        mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
        return mom;
    }

    function getSetMonth(value) {
        if (value != null) {
            setMonth(this, value);
            hooks.updateOffset(this, true);
            return this;
        } else {
            return get(this, 'Month');
        }
    }

    function getDaysInMonth() {
        return daysInMonth(this.year(), this.month());
    }

    function monthsShortRegex(isStrict) {
        if (this._monthsParseExact) {
            if (!hasOwnProp(this, '_monthsRegex')) {
                computeMonthsParse.call(this);
            }
            if (isStrict) {
                return this._monthsShortStrictRegex;
            } else {
                return this._monthsShortRegex;
            }
        } else {
            if (!hasOwnProp(this, '_monthsShortRegex')) {
                this._monthsShortRegex = defaultMonthsShortRegex;
            }
            return this._monthsShortStrictRegex && isStrict
                ? this._monthsShortStrictRegex
                : this._monthsShortRegex;
        }
    }

    function monthsRegex(isStrict) {
        if (this._monthsParseExact) {
            if (!hasOwnProp(this, '_monthsRegex')) {
                computeMonthsParse.call(this);
            }
            if (isStrict) {
                return this._monthsStrictRegex;
            } else {
                return this._monthsRegex;
            }
        } else {
            if (!hasOwnProp(this, '_monthsRegex')) {
                this._monthsRegex = defaultMonthsRegex;
            }
            return this._monthsStrictRegex && isStrict
                ? this._monthsStrictRegex
                : this._monthsRegex;
        }
    }

    function computeMonthsParse() {
        function cmpLenRev(a, b) {
            return b.length - a.length;
        }

        var shortPieces = [],
            longPieces = [],
            mixedPieces = [],
            i,
            mom;
        for (i = 0; i < 12; i++) {
            // make the regex if we don't have it already
            mom = createUTC([2000, i]);
            shortPieces.push(this.monthsShort(mom, ''));
            longPieces.push(this.months(mom, ''));
            mixedPieces.push(this.months(mom, ''));
            mixedPieces.push(this.monthsShort(mom, ''));
        }
        // Sorting makes sure if one month (or abbr) is a prefix of another it
        // will match the longer piece.
        shortPieces.sort(cmpLenRev);
        longPieces.sort(cmpLenRev);
        mixedPieces.sort(cmpLenRev);
        for (i = 0; i < 12; i++) {
            shortPieces[i] = regexEscape(shortPieces[i]);
            longPieces[i] = regexEscape(longPieces[i]);
        }
        for (i = 0; i < 24; i++) {
            mixedPieces[i] = regexEscape(mixedPieces[i]);
        }

        this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
        this._monthsShortRegex = this._monthsRegex;
        this._monthsStrictRegex = new RegExp(
            '^(' + longPieces.join('|') + ')',
            'i'
        );
        this._monthsShortStrictRegex = new RegExp(
            '^(' + shortPieces.join('|') + ')',
            'i'
        );
    }

    // FORMATTING

    addFormatToken('Y', 0, 0, function () {
        var y = this.year();
        return y <= 9999 ? zeroFill(y, 4) : '+' + y;
    });

    addFormatToken(0, ['YY', 2], 0, function () {
        return this.year() % 100;
    });

    addFormatToken(0, ['YYYY', 4], 0, 'year');
    addFormatToken(0, ['YYYYY', 5], 0, 'year');
    addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');

    // ALIASES

    addUnitAlias('year', 'y');

    // PRIORITIES

    addUnitPriority('year', 1);

    // PARSING

    addRegexToken('Y', matchSigned);
    addRegexToken('YY', match1to2, match2);
    addRegexToken('YYYY', match1to4, match4);
    addRegexToken('YYYYY', match1to6, match6);
    addRegexToken('YYYYYY', match1to6, match6);

    addParseToken(['YYYYY', 'YYYYYY'], YEAR);
    addParseToken('YYYY', function (input, array) {
        array[YEAR] =
            input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);
    });
    addParseToken('YY', function (input, array) {
        array[YEAR] = hooks.parseTwoDigitYear(input);
    });
    addParseToken('Y', function (input, array) {
        array[YEAR] = parseInt(input, 10);
    });

    // HELPERS

    function daysInYear(year) {
        return isLeapYear(year) ? 366 : 365;
    }

    // HOOKS

    hooks.parseTwoDigitYear = function (input) {
        return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
    };

    // MOMENTS

    var getSetYear = makeGetSet('FullYear', true);

    function getIsLeapYear() {
        return isLeapYear(this.year());
    }

    function createDate(y, m, d, h, M, s, ms) {
        // can't just apply() to create a date:
        // https://stackoverflow.com/q/181348
        var date;
        // the date constructor remaps years 0-99 to 1900-1999
        if (y < 100 && y >= 0) {
            // preserve leap years using a full 400 year cycle, then reset
            date = new Date(y + 400, m, d, h, M, s, ms);
            if (isFinite(date.getFullYear())) {
                date.setFullYear(y);
            }
        } else {
            date = new Date(y, m, d, h, M, s, ms);
        }

        return date;
    }

    function createUTCDate(y) {
        var date, args;
        // the Date.UTC function remaps years 0-99 to 1900-1999
        if (y < 100 && y >= 0) {
            args = Array.prototype.slice.call(arguments);
            // preserve leap years using a full 400 year cycle, then reset
            args[0] = y + 400;
            date = new Date(Date.UTC.apply(null, args));
            if (isFinite(date.getUTCFullYear())) {
                date.setUTCFullYear(y);
            }
        } else {
            date = new Date(Date.UTC.apply(null, arguments));
        }

        return date;
    }

    // start-of-first-week - start-of-year
    function firstWeekOffset(year, dow, doy) {
        var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
            fwd = 7 + dow - doy,
            // first-week day local weekday -- which local weekday is fwd
            fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;

        return -fwdlw + fwd - 1;
    }

    // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
    function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
        var localWeekday = (7 + weekday - dow) % 7,
            weekOffset = firstWeekOffset(year, dow, doy),
            dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
            resYear,
            resDayOfYear;

        if (dayOfYear <= 0) {
            resYear = year - 1;
            resDayOfYear = daysInYear(resYear) + dayOfYear;
        } else if (dayOfYear > daysInYear(year)) {
            resYear = year + 1;
            resDayOfYear = dayOfYear - daysInYear(year);
        } else {
            resYear = year;
            resDayOfYear = dayOfYear;
        }

        return {
            year: resYear,
            dayOfYear: resDayOfYear,
        };
    }

    function weekOfYear(mom, dow, doy) {
        var weekOffset = firstWeekOffset(mom.year(), dow, doy),
            week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
            resWeek,
            resYear;

        if (week < 1) {
            resYear = mom.year() - 1;
            resWeek = week + weeksInYear(resYear, dow, doy);
        } else if (week > weeksInYear(mom.year(), dow, doy)) {
            resWeek = week - weeksInYear(mom.year(), dow, doy);
            resYear = mom.year() + 1;
        } else {
            resYear = mom.year();
            resWeek = week;
        }

        return {
            week: resWeek,
            year: resYear,
        };
    }

    function weeksInYear(year, dow, doy) {
        var weekOffset = firstWeekOffset(year, dow, doy),
            weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
        return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
    }

    // FORMATTING

    addFormatToken('w', ['ww', 2], 'wo', 'week');
    addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');

    // ALIASES

    addUnitAlias('week', 'w');
    addUnitAlias('isoWeek', 'W');

    // PRIORITIES

    addUnitPriority('week', 5);
    addUnitPriority('isoWeek', 5);

    // PARSING

    addRegexToken('w', match1to2);
    addRegexToken('ww', match1to2, match2);
    addRegexToken('W', match1to2);
    addRegexToken('WW', match1to2, match2);

    addWeekParseToken(['w', 'ww', 'W', 'WW'], function (
        input,
        week,
        config,
        token
    ) {
        week[token.substr(0, 1)] = toInt(input);
    });

    // HELPERS

    // LOCALES

    function localeWeek(mom) {
        return weekOfYear(mom, this._week.dow, this._week.doy).week;
    }

    var defaultLocaleWeek = {
        dow: 0, // Sunday is the first day of the week.
        doy: 6, // The week that contains Jan 6th is the first week of the year.
    };

    function localeFirstDayOfWeek() {
        return this._week.dow;
    }

    function localeFirstDayOfYear() {
        return this._week.doy;
    }

    // MOMENTS

    function getSetWeek(input) {
        var week = this.localeData().week(this);
        return input == null ? week : this.add((input - week) * 7, 'd');
    }

    function getSetISOWeek(input) {
        var week = weekOfYear(this, 1, 4).week;
        return input == null ? week : this.add((input - week) * 7, 'd');
    }

    // FORMATTING

    addFormatToken('d', 0, 'do', 'day');

    addFormatToken('dd', 0, 0, function (format) {
        return this.localeData().weekdaysMin(this, format);
    });

    addFormatToken('ddd', 0, 0, function (format) {
        return this.localeData().weekdaysShort(this, format);
    });

    addFormatToken('dddd', 0, 0, function (format) {
        return this.localeData().weekdays(this, format);
    });

    addFormatToken('e', 0, 0, 'weekday');
    addFormatToken('E', 0, 0, 'isoWeekday');

    // ALIASES

    addUnitAlias('day', 'd');
    addUnitAlias('weekday', 'e');
    addUnitAlias('isoWeekday', 'E');

    // PRIORITY
    addUnitPriority('day', 11);
    addUnitPriority('weekday', 11);
    addUnitPriority('isoWeekday', 11);

    // PARSING

    addRegexToken('d', match1to2);
    addRegexToken('e', match1to2);
    addRegexToken('E', match1to2);
    addRegexToken('dd', function (isStrict, locale) {
        return locale.weekdaysMinRegex(isStrict);
    });
    addRegexToken('ddd', function (isStrict, locale) {
        return locale.weekdaysShortRegex(isStrict);
    });
    addRegexToken('dddd', function (isStrict, locale) {
        return locale.weekdaysRegex(isStrict);
    });

    addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
        var weekday = config._locale.weekdaysParse(input, token, config._strict);
        // if we didn't get a weekday name, mark the date as invalid
        if (weekday != null) {
            week.d = weekday;
        } else {
            getParsingFlags(config).invalidWeekday = input;
        }
    });

    addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
        week[token] = toInt(input);
    });

    // HELPERS

    function parseWeekday(input, locale) {
        if (typeof input !== 'string') {
            return input;
        }

        if (!isNaN(input)) {
            return parseInt(input, 10);
        }

        input = locale.weekdaysParse(input);
        if (typeof input === 'number') {
            return input;
        }

        return null;
    }

    function parseIsoWeekday(input, locale) {
        if (typeof input === 'string') {
            return locale.weekdaysParse(input) % 7 || 7;
        }
        return isNaN(input) ? null : input;
    }

    // LOCALES
    function shiftWeekdays(ws, n) {
        return ws.slice(n, 7).concat(ws.slice(0, n));
    }

    var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split(
            '_'
        ),
        defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
        defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
        defaultWeekdaysRegex = matchWord,
        defaultWeekdaysShortRegex = matchWord,
        defaultWeekdaysMinRegex = matchWord;

    function localeWeekdays(m, format) {
        var weekdays = isArray(this._weekdays)
            ? this._weekdays
            : this._weekdays[
                  m && m !== true && this._weekdays.isFormat.test(format)
                      ? 'format'
                      : 'standalone'
              ];
        return m === true
            ? shiftWeekdays(weekdays, this._week.dow)
            : m
            ? weekdays[m.day()]
            : weekdays;
    }

    function localeWeekdaysShort(m) {
        return m === true
            ? shiftWeekdays(this._weekdaysShort, this._week.dow)
            : m
            ? this._weekdaysShort[m.day()]
            : this._weekdaysShort;
    }

    function localeWeekdaysMin(m) {
        return m === true
            ? shiftWeekdays(this._weekdaysMin, this._week.dow)
            : m
            ? this._weekdaysMin[m.day()]
            : this._weekdaysMin;
    }

    function handleStrictParse$1(weekdayName, format, strict) {
        var i,
            ii,
            mom,
            llc = weekdayName.toLocaleLowerCase();
        if (!this._weekdaysParse) {
            this._weekdaysParse = [];
            this._shortWeekdaysParse = [];
            this._minWeekdaysParse = [];

            for (i = 0; i < 7; ++i) {
                mom = createUTC([2000, 1]).day(i);
                this._minWeekdaysParse[i] = this.weekdaysMin(
                    mom,
                    ''
                ).toLocaleLowerCase();
                this._shortWeekdaysParse[i] = this.weekdaysShort(
                    mom,
                    ''
                ).toLocaleLowerCase();
                this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
            }
        }

        if (strict) {
            if (format === 'dddd') {
                ii = indexOf.call(this._weekdaysParse, llc);
                return ii !== -1 ? ii : null;
            } else if (format === 'ddd') {
                ii = indexOf.call(this._shortWeekdaysParse, llc);
                return ii !== -1 ? ii : null;
            } else {
                ii = indexOf.call(this._minWeekdaysParse, llc);
                return ii !== -1 ? ii : null;
            }
        } else {
            if (format === 'dddd') {
                ii = indexOf.call(this._weekdaysParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._shortWeekdaysParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._minWeekdaysParse, llc);
                return ii !== -1 ? ii : null;
            } else if (format === 'ddd') {
                ii = indexOf.call(this._shortWeekdaysParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._weekdaysParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._minWeekdaysParse, llc);
                return ii !== -1 ? ii : null;
            } else {
                ii = indexOf.call(this._minWeekdaysParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._weekdaysParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._shortWeekdaysParse, llc);
                return ii !== -1 ? ii : null;
            }
        }
    }

    function localeWeekdaysParse(weekdayName, format, strict) {
        var i, mom, regex;

        if (this._weekdaysParseExact) {
            return handleStrictParse$1.call(this, weekdayName, format, strict);
        }

        if (!this._weekdaysParse) {
            this._weekdaysParse = [];
            this._minWeekdaysParse = [];
            this._shortWeekdaysParse = [];
            this._fullWeekdaysParse = [];
        }

        for (i = 0; i < 7; i++) {
            // make the regex if we don't have it already

            mom = createUTC([2000, 1]).day(i);
            if (strict && !this._fullWeekdaysParse[i]) {
                this._fullWeekdaysParse[i] = new RegExp(
                    '^' + this.weekdays(mom, '').replace('.', '\\.?') + '$',
                    'i'
                );
                this._shortWeekdaysParse[i] = new RegExp(
                    '^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$',
                    'i'
                );
                this._minWeekdaysParse[i] = new RegExp(
                    '^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$',
                    'i'
                );
            }
            if (!this._weekdaysParse[i]) {
                regex =
                    '^' +
                    this.weekdays(mom, '') +
                    '|^' +
                    this.weekdaysShort(mom, '') +
                    '|^' +
                    this.weekdaysMin(mom, '');
                this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
            }
            // test the regex
            if (
                strict &&
                format === 'dddd' &&
                this._fullWeekdaysParse[i].test(weekdayName)
            ) {
                return i;
            } else if (
                strict &&
                format === 'ddd' &&
                this._shortWeekdaysParse[i].test(weekdayName)
            ) {
                return i;
            } else if (
                strict &&
                format === 'dd' &&
                this._minWeekdaysParse[i].test(weekdayName)
            ) {
                return i;
            } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
                return i;
            }
        }
    }

    // MOMENTS

    function getSetDayOfWeek(input) {
        if (!this.isValid()) {
            return input != null ? this : NaN;
        }
        var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
        if (input != null) {
            input = parseWeekday(input, this.localeData());
            return this.add(input - day, 'd');
        } else {
            return day;
        }
    }

    function getSetLocaleDayOfWeek(input) {
        if (!this.isValid()) {
            return input != null ? this : NaN;
        }
        var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
        return input == null ? weekday : this.add(input - weekday, 'd');
    }

    function getSetISODayOfWeek(input) {
        if (!this.isValid()) {
            return input != null ? this : NaN;
        }

        // behaves the same as moment#day except
        // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
        // as a setter, sunday should belong to the previous week.

        if (input != null) {
            var weekday = parseIsoWeekday(input, this.localeData());
            return this.day(this.day() % 7 ? weekday : weekday - 7);
        } else {
            return this.day() || 7;
        }
    }

    function weekdaysRegex(isStrict) {
        if (this._weekdaysParseExact) {
            if (!hasOwnProp(this, '_weekdaysRegex')) {
                computeWeekdaysParse.call(this);
            }
            if (isStrict) {
                return this._weekdaysStrictRegex;
            } else {
                return this._weekdaysRegex;
            }
        } else {
            if (!hasOwnProp(this, '_weekdaysRegex')) {
                this._weekdaysRegex = defaultWeekdaysRegex;
            }
            return this._weekdaysStrictRegex && isStrict
                ? this._weekdaysStrictRegex
                : this._weekdaysRegex;
        }
    }

    function weekdaysShortRegex(isStrict) {
        if (this._weekdaysParseExact) {
            if (!hasOwnProp(this, '_weekdaysRegex')) {
                computeWeekdaysParse.call(this);
            }
            if (isStrict) {
                return this._weekdaysShortStrictRegex;
            } else {
                return this._weekdaysShortRegex;
            }
        } else {
            if (!hasOwnProp(this, '_weekdaysShortRegex')) {
                this._weekdaysShortRegex = defaultWeekdaysShortRegex;
            }
            return this._weekdaysShortStrictRegex && isStrict
                ? this._weekdaysShortStrictRegex
                : this._weekdaysShortRegex;
        }
    }

    function weekdaysMinRegex(isStrict) {
        if (this._weekdaysParseExact) {
            if (!hasOwnProp(this, '_weekdaysRegex')) {
                computeWeekdaysParse.call(this);
            }
            if (isStrict) {
                return this._weekdaysMinStrictRegex;
            } else {
                return this._weekdaysMinRegex;
            }
        } else {
            if (!hasOwnProp(this, '_weekdaysMinRegex')) {
                this._weekdaysMinRegex = defaultWeekdaysMinRegex;
            }
            return this._weekdaysMinStrictRegex && isStrict
                ? this._weekdaysMinStrictRegex
                : this._weekdaysMinRegex;
        }
    }

    function computeWeekdaysParse() {
        function cmpLenRev(a, b) {
            return b.length - a.length;
        }

        var minPieces = [],
            shortPieces = [],
            longPieces = [],
            mixedPieces = [],
            i,
            mom,
            minp,
            shortp,
            longp;
        for (i = 0; i < 7; i++) {
            // make the regex if we don't have it already
            mom = createUTC([2000, 1]).day(i);
            minp = regexEscape(this.weekdaysMin(mom, ''));
            shortp = regexEscape(this.weekdaysShort(mom, ''));
            longp = regexEscape(this.weekdays(mom, ''));
            minPieces.push(minp);
            shortPieces.push(shortp);
            longPieces.push(longp);
            mixedPieces.push(minp);
            mixedPieces.push(shortp);
            mixedPieces.push(longp);
        }
        // Sorting makes sure if one weekday (or abbr) is a prefix of another it
        // will match the longer piece.
        minPieces.sort(cmpLenRev);
        shortPieces.sort(cmpLenRev);
        longPieces.sort(cmpLenRev);
        mixedPieces.sort(cmpLenRev);

        this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
        this._weekdaysShortRegex = this._weekdaysRegex;
        this._weekdaysMinRegex = this._weekdaysRegex;

        this._weekdaysStrictRegex = new RegExp(
            '^(' + longPieces.join('|') + ')',
            'i'
        );
        this._weekdaysShortStrictRegex = new RegExp(
            '^(' + shortPieces.join('|') + ')',
            'i'
        );
        this._weekdaysMinStrictRegex = new RegExp(
            '^(' + minPieces.join('|') + ')',
            'i'
        );
    }

    // FORMATTING

    function hFormat() {
        return this.hours() % 12 || 12;
    }

    function kFormat() {
        return this.hours() || 24;
    }

    addFormatToken('H', ['HH', 2], 0, 'hour');
    addFormatToken('h', ['hh', 2], 0, hFormat);
    addFormatToken('k', ['kk', 2], 0, kFormat);

    addFormatToken('hmm', 0, 0, function () {
        return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
    });

    addFormatToken('hmmss', 0, 0, function () {
        return (
            '' +
            hFormat.apply(this) +
            zeroFill(this.minutes(), 2) +
            zeroFill(this.seconds(), 2)
        );
    });

    addFormatToken('Hmm', 0, 0, function () {
        return '' + this.hours() + zeroFill(this.minutes(), 2);
    });

    addFormatToken('Hmmss', 0, 0, function () {
        return (
            '' +
            this.hours() +
            zeroFill(this.minutes(), 2) +
            zeroFill(this.seconds(), 2)
        );
    });

    function meridiem(token, lowercase) {
        addFormatToken(token, 0, 0, function () {
            return this.localeData().meridiem(
                this.hours(),
                this.minutes(),
                lowercase
            );
        });
    }

    meridiem('a', true);
    meridiem('A', false);

    // ALIASES

    addUnitAlias('hour', 'h');

    // PRIORITY
    addUnitPriority('hour', 13);

    // PARSING

    function matchMeridiem(isStrict, locale) {
        return locale._meridiemParse;
    }

    addRegexToken('a', matchMeridiem);
    addRegexToken('A', matchMeridiem);
    addRegexToken('H', match1to2);
    addRegexToken('h', match1to2);
    addRegexToken('k', match1to2);
    addRegexToken('HH', match1to2, match2);
    addRegexToken('hh', match1to2, match2);
    addRegexToken('kk', match1to2, match2);

    addRegexToken('hmm', match3to4);
    addRegexToken('hmmss', match5to6);
    addRegexToken('Hmm', match3to4);
    addRegexToken('Hmmss', match5to6);

    addParseToken(['H', 'HH'], HOUR);
    addParseToken(['k', 'kk'], function (input, array, config) {
        var kInput = toInt(input);
        array[HOUR] = kInput === 24 ? 0 : kInput;
    });
    addParseToken(['a', 'A'], function (input, array, config) {
        config._isPm = config._locale.isPM(input);
        config._meridiem = input;
    });
    addParseToken(['h', 'hh'], function (input, array, config) {
        array[HOUR] = toInt(input);
        getParsingFlags(config).bigHour = true;
    });
    addParseToken('hmm', function (input, array, config) {
        var pos = input.length - 2;
        array[HOUR] = toInt(input.substr(0, pos));
        array[MINUTE] = toInt(input.substr(pos));
        getParsingFlags(config).bigHour = true;
    });
    addParseToken('hmmss', function (input, array, config) {
        var pos1 = input.length - 4,
            pos2 = input.length - 2;
        array[HOUR] = toInt(input.substr(0, pos1));
        array[MINUTE] = toInt(input.substr(pos1, 2));
        array[SECOND] = toInt(input.substr(pos2));
        getParsingFlags(config).bigHour = true;
    });
    addParseToken('Hmm', function (input, array, config) {
        var pos = input.length - 2;
        array[HOUR] = toInt(input.substr(0, pos));
        array[MINUTE] = toInt(input.substr(pos));
    });
    addParseToken('Hmmss', function (input, array, config) {
        var pos1 = input.length - 4,
            pos2 = input.length - 2;
        array[HOUR] = toInt(input.substr(0, pos1));
        array[MINUTE] = toInt(input.substr(pos1, 2));
        array[SECOND] = toInt(input.substr(pos2));
    });

    // LOCALES

    function localeIsPM(input) {
        // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
        // Using charAt should be more compatible.
        return (input + '').toLowerCase().charAt(0) === 'p';
    }

    var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i,
        // Setting the hour should keep the time, because the user explicitly
        // specified which hour they want. So trying to maintain the same hour (in
        // a new timezone) makes sense. Adding/subtracting hours does not follow
        // this rule.
        getSetHour = makeGetSet('Hours', true);

    function localeMeridiem(hours, minutes, isLower) {
        if (hours > 11) {
            return isLower ? 'pm' : 'PM';
        } else {
            return isLower ? 'am' : 'AM';
        }
    }

    var baseConfig = {
        calendar: defaultCalendar,
        longDateFormat: defaultLongDateFormat,
        invalidDate: defaultInvalidDate,
        ordinal: defaultOrdinal,
        dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,
        relativeTime: defaultRelativeTime,

        months: defaultLocaleMonths,
        monthsShort: defaultLocaleMonthsShort,

        week: defaultLocaleWeek,

        weekdays: defaultLocaleWeekdays,
        weekdaysMin: defaultLocaleWeekdaysMin,
        weekdaysShort: defaultLocaleWeekdaysShort,

        meridiemParse: defaultLocaleMeridiemParse,
    };

    // internal storage for locale config files
    var locales = {},
        localeFamilies = {},
        globalLocale;

    function commonPrefix(arr1, arr2) {
        var i,
            minl = Math.min(arr1.length, arr2.length);
        for (i = 0; i < minl; i += 1) {
            if (arr1[i] !== arr2[i]) {
                return i;
            }
        }
        return minl;
    }

    function normalizeLocale(key) {
        return key ? key.toLowerCase().replace('_', '-') : key;
    }

    // pick the locale from the array
    // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
    // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
    function chooseLocale(names) {
        var i = 0,
            j,
            next,
            locale,
            split;

        while (i < names.length) {
            split = normalizeLocale(names[i]).split('-');
            j = split.length;
            next = normalizeLocale(names[i + 1]);
            next = next ? next.split('-') : null;
            while (j > 0) {
                locale = loadLocale(split.slice(0, j).join('-'));
                if (locale) {
                    return locale;
                }
                if (
                    next &&
                    next.length >= j &&
                    commonPrefix(split, next) >= j - 1
                ) {
                    //the next array item is better than a shallower substring of this one
                    break;
                }
                j--;
            }
            i++;
        }
        return globalLocale;
    }

    function loadLocale(name) {
        var oldLocale = null,
            aliasedRequire;
        // TODO: Find a better way to register and load all the locales in Node
        if (
            locales[name] === undefined &&
            typeof module !== 'undefined' &&
            module &&
            module.exports
        ) {
            try {
                oldLocale = globalLocale._abbr;
                aliasedRequire = require;
                aliasedRequire('./locale/' + name);
                getSetGlobalLocale(oldLocale);
            } catch (e) {
                // mark as not found to avoid repeating expensive file require call causing high CPU
                // when trying to find en-US, en_US, en-us for every format call
                locales[name] = null; // null means not found
            }
        }
        return locales[name];
    }

    // This function will load locale and then set the global locale.  If
    // no arguments are passed in, it will simply return the current global
    // locale key.
    function getSetGlobalLocale(key, values) {
        var data;
        if (key) {
            if (isUndefined(values)) {
                data = getLocale(key);
            } else {
                data = defineLocale(key, values);
            }

            if (data) {
                // moment.duration._locale = moment._locale = data;
                globalLocale = data;
            } else {
                if (typeof console !== 'undefined' && console.warn) {
                    //warn user if arguments are passed but the locale could not be set
                    console.warn(
                        'Locale ' + key + ' not found. Did you forget to load it?'
                    );
                }
            }
        }

        return globalLocale._abbr;
    }

    function defineLocale(name, config) {
        if (config !== null) {
            var locale,
                parentConfig = baseConfig;
            config.abbr = name;
            if (locales[name] != null) {
                deprecateSimple(
                    'defineLocaleOverride',
                    'use moment.updateLocale(localeName, config) to change ' +
                        'an existing locale. moment.defineLocale(localeName, ' +
                        'config) should only be used for creating a new locale ' +
                        'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.'
                );
                parentConfig = locales[name]._config;
            } else if (config.parentLocale != null) {
                if (locales[config.parentLocale] != null) {
                    parentConfig = locales[config.parentLocale]._config;
                } else {
                    locale = loadLocale(config.parentLocale);
                    if (locale != null) {
                        parentConfig = locale._config;
                    } else {
                        if (!localeFamilies[config.parentLocale]) {
                            localeFamilies[config.parentLocale] = [];
                        }
                        localeFamilies[config.parentLocale].push({
                            name: name,
                            config: config,
                        });
                        return null;
                    }
                }
            }
            locales[name] = new Locale(mergeConfigs(parentConfig, config));

            if (localeFamilies[name]) {
                localeFamilies[name].forEach(function (x) {
                    defineLocale(x.name, x.config);
                });
            }

            // backwards compat for now: also set the locale
            // make sure we set the locale AFTER all child locales have been
            // created, so we won't end up with the child locale set.
            getSetGlobalLocale(name);

            return locales[name];
        } else {
            // useful for testing
            delete locales[name];
            return null;
        }
    }

    function updateLocale(name, config) {
        if (config != null) {
            var locale,
                tmpLocale,
                parentConfig = baseConfig;

            if (locales[name] != null && locales[name].parentLocale != null) {
                // Update existing child locale in-place to avoid memory-leaks
                locales[name].set(mergeConfigs(locales[name]._config, config));
            } else {
                // MERGE
                tmpLocale = loadLocale(name);
                if (tmpLocale != null) {
                    parentConfig = tmpLocale._config;
                }
                config = mergeConfigs(parentConfig, config);
                if (tmpLocale == null) {
                    // updateLocale is called for creating a new locale
                    // Set abbr so it will have a name (getters return
                    // undefined otherwise).
                    config.abbr = name;
                }
                locale = new Locale(config);
                locale.parentLocale = locales[name];
                locales[name] = locale;
            }

            // backwards compat for now: also set the locale
            getSetGlobalLocale(name);
        } else {
            // pass null for config to unupdate, useful for tests
            if (locales[name] != null) {
                if (locales[name].parentLocale != null) {
                    locales[name] = locales[name].parentLocale;
                    if (name === getSetGlobalLocale()) {
                        getSetGlobalLocale(name);
                    }
                } else if (locales[name] != null) {
                    delete locales[name];
                }
            }
        }
        return locales[name];
    }

    // returns locale data
    function getLocale(key) {
        var locale;

        if (key && key._locale && key._locale._abbr) {
            key = key._locale._abbr;
        }

        if (!key) {
            return globalLocale;
        }

        if (!isArray(key)) {
            //short-circuit everything else
            locale = loadLocale(key);
            if (locale) {
                return locale;
            }
            key = [key];
        }

        return chooseLocale(key);
    }

    function listLocales() {
        return keys(locales);
    }

    function checkOverflow(m) {
        var overflow,
            a = m._a;

        if (a && getParsingFlags(m).overflow === -2) {
            overflow =
                a[MONTH] < 0 || a[MONTH] > 11
                    ? MONTH
                    : a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH])
                    ? DATE
                    : a[HOUR] < 0 ||
                      a[HOUR] > 24 ||
                      (a[HOUR] === 24 &&
                          (a[MINUTE] !== 0 ||
                              a[SECOND] !== 0 ||
                              a[MILLISECOND] !== 0))
                    ? HOUR
                    : a[MINUTE] < 0 || a[MINUTE] > 59
                    ? MINUTE
                    : a[SECOND] < 0 || a[SECOND] > 59
                    ? SECOND
                    : a[MILLISECOND] < 0 || a[MILLISECOND] > 999
                    ? MILLISECOND
                    : -1;

            if (
                getParsingFlags(m)._overflowDayOfYear &&
                (overflow < YEAR || overflow > DATE)
            ) {
                overflow = DATE;
            }
            if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
                overflow = WEEK;
            }
            if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
                overflow = WEEKDAY;
            }

            getParsingFlags(m).overflow = overflow;
        }

        return m;
    }

    // iso 8601 regex
    // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)
    var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/,
        basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d|))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/,
        tzRegex = /Z|[+-]\d\d(?::?\d\d)?/,
        isoDates = [
            ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/],
            ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/],
            ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/],
            ['GGGG-[W]WW', /\d{4}-W\d\d/, false],
            ['YYYY-DDD', /\d{4}-\d{3}/],
            ['YYYY-MM', /\d{4}-\d\d/, false],
            ['YYYYYYMMDD', /[+-]\d{10}/],
            ['YYYYMMDD', /\d{8}/],
            ['GGGG[W]WWE', /\d{4}W\d{3}/],
            ['GGGG[W]WW', /\d{4}W\d{2}/, false],
            ['YYYYDDD', /\d{7}/],
            ['YYYYMM', /\d{6}/, false],
            ['YYYY', /\d{4}/, false],
        ],
        // iso time formats and regexes
        isoTimes = [
            ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/],
            ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/],
            ['HH:mm:ss', /\d\d:\d\d:\d\d/],
            ['HH:mm', /\d\d:\d\d/],
            ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/],
            ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/],
            ['HHmmss', /\d\d\d\d\d\d/],
            ['HHmm', /\d\d\d\d/],
            ['HH', /\d\d/],
        ],
        aspNetJsonRegex = /^\/?Date\((-?\d+)/i,
        // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3
        rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/,
        obsOffsets = {
            UT: 0,
            GMT: 0,
            EDT: -4 * 60,
            EST: -5 * 60,
            CDT: -5 * 60,
            CST: -6 * 60,
            MDT: -6 * 60,
            MST: -7 * 60,
            PDT: -7 * 60,
            PST: -8 * 60,
        };

    // date from iso format
    function configFromISO(config) {
        var i,
            l,
            string = config._i,
            match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
            allowTime,
            dateFormat,
            timeFormat,
            tzFormat;

        if (match) {
            getParsingFlags(config).iso = true;

            for (i = 0, l = isoDates.length; i < l; i++) {
                if (isoDates[i][1].exec(match[1])) {
                    dateFormat = isoDates[i][0];
                    allowTime = isoDates[i][2] !== false;
                    break;
                }
            }
            if (dateFormat == null) {
                config._isValid = false;
                return;
            }
            if (match[3]) {
                for (i = 0, l = isoTimes.length; i < l; i++) {
                    if (isoTimes[i][1].exec(match[3])) {
                        // match[2] should be 'T' or space
                        timeFormat = (match[2] || ' ') + isoTimes[i][0];
                        break;
                    }
                }
                if (timeFormat == null) {
                    config._isValid = false;
                    return;
                }
            }
            if (!allowTime && timeFormat != null) {
                config._isValid = false;
                return;
            }
            if (match[4]) {
                if (tzRegex.exec(match[4])) {
                    tzFormat = 'Z';
                } else {
                    config._isValid = false;
                    return;
                }
            }
            config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
            configFromStringAndFormat(config);
        } else {
            config._isValid = false;
        }
    }

    function extractFromRFC2822Strings(
        yearStr,
        monthStr,
        dayStr,
        hourStr,
        minuteStr,
        secondStr
    ) {
        var result = [
            untruncateYear(yearStr),
            defaultLocaleMonthsShort.indexOf(monthStr),
            parseInt(dayStr, 10),
            parseInt(hourStr, 10),
            parseInt(minuteStr, 10),
        ];

        if (secondStr) {
            result.push(parseInt(secondStr, 10));
        }

        return result;
    }

    function untruncateYear(yearStr) {
        var year = parseInt(yearStr, 10);
        if (year <= 49) {
            return 2000 + year;
        } else if (year <= 999) {
            return 1900 + year;
        }
        return year;
    }

    function preprocessRFC2822(s) {
        // Remove comments and folding whitespace and replace multiple-spaces with a single space
        return s
            .replace(/\([^)]*\)|[\n\t]/g, ' ')
            .replace(/(\s\s+)/g, ' ')
            .replace(/^\s\s*/, '')
            .replace(/\s\s*$/, '');
    }

    function checkWeekday(weekdayStr, parsedInput, config) {
        if (weekdayStr) {
            // TODO: Replace the vanilla JS Date object with an independent day-of-week check.
            var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr),
                weekdayActual = new Date(
                    parsedInput[0],
                    parsedInput[1],
                    parsedInput[2]
                ).getDay();
            if (weekdayProvided !== weekdayActual) {
                getParsingFlags(config).weekdayMismatch = true;
                config._isValid = false;
                return false;
            }
        }
        return true;
    }

    function calculateOffset(obsOffset, militaryOffset, numOffset) {
        if (obsOffset) {
            return obsOffsets[obsOffset];
        } else if (militaryOffset) {
            // the only allowed military tz is Z
            return 0;
        } else {
            var hm = parseInt(numOffset, 10),
                m = hm % 100,
                h = (hm - m) / 100;
            return h * 60 + m;
        }
    }

    // date and time from ref 2822 format
    function configFromRFC2822(config) {
        var match = rfc2822.exec(preprocessRFC2822(config._i)),
            parsedArray;
        if (match) {
            parsedArray = extractFromRFC2822Strings(
                match[4],
                match[3],
                match[2],
                match[5],
                match[6],
                match[7]
            );
            if (!checkWeekday(match[1], parsedArray, config)) {
                return;
            }

            config._a = parsedArray;
            config._tzm = calculateOffset(match[8], match[9], match[10]);

            config._d = createUTCDate.apply(null, config._a);
            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);

            getParsingFlags(config).rfc2822 = true;
        } else {
            config._isValid = false;
        }
    }

    // date from 1) ASP.NET, 2) ISO, 3) RFC 2822 formats, or 4) optional fallback if parsing isn't strict
    function configFromString(config) {
        var matched = aspNetJsonRegex.exec(config._i);
        if (matched !== null) {
            config._d = new Date(+matched[1]);
            return;
        }

        configFromISO(config);
        if (config._isValid === false) {
            delete config._isValid;
        } else {
            return;
        }

        configFromRFC2822(config);
        if (config._isValid === false) {
            delete config._isValid;
        } else {
            return;
        }

        if (config._strict) {
            config._isValid = false;
        } else {
            // Final attempt, use Input Fallback
            hooks.createFromInputFallback(config);
        }
    }

    hooks.createFromInputFallback = deprecate(
        'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +
            'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +
            'discouraged. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.',
        function (config) {
            config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
        }
    );

    // Pick the first defined of two or three arguments.
    function defaults(a, b, c) {
        if (a != null) {
            return a;
        }
        if (b != null) {
            return b;
        }
        return c;
    }

    function currentDateArray(config) {
        // hooks is actually the exported moment object
        var nowValue = new Date(hooks.now());
        if (config._useUTC) {
            return [
                nowValue.getUTCFullYear(),
                nowValue.getUTCMonth(),
                nowValue.getUTCDate(),
            ];
        }
        return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
    }

    // convert an array to a date.
    // the array should mirror the parameters below
    // note: all values past the year are optional and will default to the lowest possible value.
    // [year, month, day , hour, minute, second, millisecond]
    function configFromArray(config) {
        var i,
            date,
            input = [],
            currentDate,
            expectedWeekday,
            yearToUse;

        if (config._d) {
            return;
        }

        currentDate = currentDateArray(config);

        //compute day of the year from weeks and weekdays
        if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
            dayOfYearFromWeekInfo(config);
        }

        //if the day of the year is set, figure out what it is
        if (config._dayOfYear != null) {
            yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);

            if (
                config._dayOfYear > daysInYear(yearToUse) ||
                config._dayOfYear === 0
            ) {
                getParsingFlags(config)._overflowDayOfYear = true;
            }

            date = createUTCDate(yearToUse, 0, config._dayOfYear);
            config._a[MONTH] = date.getUTCMonth();
            config._a[DATE] = date.getUTCDate();
        }

        // Default to current date.
        // * if no year, month, day of month are given, default to today
        // * if day of month is given, default month and year
        // * if month is given, default only year
        // * if year is given, don't default anything
        for (i = 0; i < 3 && config._a[i] == null; ++i) {
            config._a[i] = input[i] = currentDate[i];
        }

        // Zero out whatever was not defaulted, including time
        for (; i < 7; i++) {
            config._a[i] = input[i] =
                config._a[i] == null ? (i === 2 ? 1 : 0) : config._a[i];
        }

        // Check for 24:00:00.000
        if (
            config._a[HOUR] === 24 &&
            config._a[MINUTE] === 0 &&
            config._a[SECOND] === 0 &&
            config._a[MILLISECOND] === 0
        ) {
            config._nextDay = true;
            config._a[HOUR] = 0;
        }

        config._d = (config._useUTC ? createUTCDate : createDate).apply(
            null,
            input
        );
        expectedWeekday = config._useUTC
            ? config._d.getUTCDay()
            : config._d.getDay();

        // Apply timezone offset from input. The actual utcOffset can be changed
        // with parseZone.
        if (config._tzm != null) {
            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
        }

        if (config._nextDay) {
            config._a[HOUR] = 24;
        }

        // check for mismatching day of week
        if (
            config._w &&
            typeof config._w.d !== 'undefined' &&
            config._w.d !== expectedWeekday
        ) {
            getParsingFlags(config).weekdayMismatch = true;
        }
    }

    function dayOfYearFromWeekInfo(config) {
        var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow, curWeek;

        w = config._w;
        if (w.GG != null || w.W != null || w.E != null) {
            dow = 1;
            doy = 4;

            // TODO: We need to take the current isoWeekYear, but that depends on
            // how we interpret now (local, utc, fixed offset). So create
            // a now version of current config (take local/utc/offset flags, and
            // create now).
            weekYear = defaults(
                w.GG,
                config._a[YEAR],
                weekOfYear(createLocal(), 1, 4).year
            );
            week = defaults(w.W, 1);
            weekday = defaults(w.E, 1);
            if (weekday < 1 || weekday > 7) {
                weekdayOverflow = true;
            }
        } else {
            dow = config._locale._week.dow;
            doy = config._locale._week.doy;

            curWeek = weekOfYear(createLocal(), dow, doy);

            weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);

            // Default to current week.
            week = defaults(w.w, curWeek.week);

            if (w.d != null) {
                // weekday -- low day numbers are considered next week
                weekday = w.d;
                if (weekday < 0 || weekday > 6) {
                    weekdayOverflow = true;
                }
            } else if (w.e != null) {
                // local weekday -- counting starts from beginning of week
                weekday = w.e + dow;
                if (w.e < 0 || w.e > 6) {
                    weekdayOverflow = true;
                }
            } else {
                // default to beginning of week
                weekday = dow;
            }
        }
        if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
            getParsingFlags(config)._overflowWeeks = true;
        } else if (weekdayOverflow != null) {
            getParsingFlags(config)._overflowWeekday = true;
        } else {
            temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
            config._a[YEAR] = temp.year;
            config._dayOfYear = temp.dayOfYear;
        }
    }

    // constant that refers to the ISO standard
    hooks.ISO_8601 = function () {};

    // constant that refers to the RFC 2822 form
    hooks.RFC_2822 = function () {};

    // date from string and format string
    function configFromStringAndFormat(config) {
        // TODO: Move this to another part of the creation flow to prevent circular deps
        if (config._f === hooks.ISO_8601) {
            configFromISO(config);
            return;
        }
        if (config._f === hooks.RFC_2822) {
            configFromRFC2822(config);
            return;
        }
        config._a = [];
        getParsingFlags(config).empty = true;

        // This array is used to make a Date, either with `new Date` or `Date.UTC`
        var string = '' + config._i,
            i,
            parsedInput,
            tokens,
            token,
            skipped,
            stringLength = string.length,
            totalParsedInputLength = 0,
            era;

        tokens =
            expandFormat(config._f, config._locale).match(formattingTokens) || [];

        for (i = 0; i < tokens.length; i++) {
            token = tokens[i];
            parsedInput = (string.match(getParseRegexForToken(token, config)) ||
                [])[0];
            if (parsedInput) {
                skipped = string.substr(0, string.indexOf(parsedInput));
                if (skipped.length > 0) {
                    getParsingFlags(config).unusedInput.push(skipped);
                }
                string = string.slice(
                    string.indexOf(parsedInput) + parsedInput.length
                );
                totalParsedInputLength += parsedInput.length;
            }
            // don't parse if it's not a known token
            if (formatTokenFunctions[token]) {
                if (parsedInput) {
                    getParsingFlags(config).empty = false;
                } else {
                    getParsingFlags(config).unusedTokens.push(token);
                }
                addTimeToArrayFromToken(token, parsedInput, config);
            } else if (config._strict && !parsedInput) {
                getParsingFlags(config).unusedTokens.push(token);
            }
        }

        // add remaining unparsed input length to the string
        getParsingFlags(config).charsLeftOver =
            stringLength - totalParsedInputLength;
        if (string.length > 0) {
            getParsingFlags(config).unusedInput.push(string);
        }

        // clear _12h flag if hour is <= 12
        if (
            config._a[HOUR] <= 12 &&
            getParsingFlags(config).bigHour === true &&
            config._a[HOUR] > 0
        ) {
            getParsingFlags(config).bigHour = undefined;
        }

        getParsingFlags(config).parsedDateParts = config._a.slice(0);
        getParsingFlags(config).meridiem = config._meridiem;
        // handle meridiem
        config._a[HOUR] = meridiemFixWrap(
            config._locale,
            config._a[HOUR],
            config._meridiem
        );

        // handle era
        era = getParsingFlags(config).era;
        if (era !== null) {
            config._a[YEAR] = config._locale.erasConvertYear(era, config._a[YEAR]);
        }

        configFromArray(config);
        checkOverflow(config);
    }

    function meridiemFixWrap(locale, hour, meridiem) {
        var isPm;

        if (meridiem == null) {
            // nothing to do
            return hour;
        }
        if (locale.meridiemHour != null) {
            return locale.meridiemHour(hour, meridiem);
        } else if (locale.isPM != null) {
            // Fallback
            isPm = locale.isPM(meridiem);
            if (isPm && hour < 12) {
                hour += 12;
            }
            if (!isPm && hour === 12) {
                hour = 0;
            }
            return hour;
        } else {
            // this is not supposed to happen
            return hour;
        }
    }

    // date from string and array of format strings
    function configFromStringAndArray(config) {
        var tempConfig,
            bestMoment,
            scoreToBeat,
            i,
            currentScore,
            validFormatFound,
            bestFormatIsValid = false;

        if (config._f.length === 0) {
            getParsingFlags(config).invalidFormat = true;
            config._d = new Date(NaN);
            return;
        }

        for (i = 0; i < config._f.length; i++) {
            currentScore = 0;
            validFormatFound = false;
            tempConfig = copyConfig({}, config);
            if (config._useUTC != null) {
                tempConfig._useUTC = config._useUTC;
            }
            tempConfig._f = config._f[i];
            configFromStringAndFormat(tempConfig);

            if (isValid(tempConfig)) {
                validFormatFound = true;
            }

            // if there is any input that was not parsed add a penalty for that format
            currentScore += getParsingFlags(tempConfig).charsLeftOver;

            //or tokens
            currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;

            getParsingFlags(tempConfig).score = currentScore;

            if (!bestFormatIsValid) {
                if (
                    scoreToBeat == null ||
                    currentScore < scoreToBeat ||
                    validFormatFound
                ) {
                    scoreToBeat = currentScore;
                    bestMoment = tempConfig;
                    if (validFormatFound) {
                        bestFormatIsValid = true;
                    }
                }
            } else {
                if (currentScore < scoreToBeat) {
                    scoreToBeat = currentScore;
                    bestMoment = tempConfig;
                }
            }
        }

        extend(config, bestMoment || tempConfig);
    }

    function configFromObject(config) {
        if (config._d) {
            return;
        }

        var i = normalizeObjectUnits(config._i),
            dayOrDate = i.day === undefined ? i.date : i.day;
        config._a = map(
            [i.year, i.month, dayOrDate, i.hour, i.minute, i.second, i.millisecond],
            function (obj) {
                return obj && parseInt(obj, 10);
            }
        );

        configFromArray(config);
    }

    function createFromConfig(config) {
        var res = new Moment(checkOverflow(prepareConfig(config)));
        if (res._nextDay) {
            // Adding is smart enough around DST
            res.add(1, 'd');
            res._nextDay = undefined;
        }

        return res;
    }

    function prepareConfig(config) {
        var input = config._i,
            format = config._f;

        config._locale = config._locale || getLocale(config._l);

        if (input === null || (format === undefined && input === '')) {
            return createInvalid({ nullInput: true });
        }

        if (typeof input === 'string') {
            config._i = input = config._locale.preparse(input);
        }

        if (isMoment(input)) {
            return new Moment(checkOverflow(input));
        } else if (isDate(input)) {
            config._d = input;
        } else if (isArray(format)) {
            configFromStringAndArray(config);
        } else if (format) {
            configFromStringAndFormat(config);
        } else {
            configFromInput(config);
        }

        if (!isValid(config)) {
            config._d = null;
        }

        return config;
    }

    function configFromInput(config) {
        var input = config._i;
        if (isUndefined(input)) {
            config._d = new Date(hooks.now());
        } else if (isDate(input)) {
            config._d = new Date(input.valueOf());
        } else if (typeof input === 'string') {
            configFromString(config);
        } else if (isArray(input)) {
            config._a = map(input.slice(0), function (obj) {
                return parseInt(obj, 10);
            });
            configFromArray(config);
        } else if (isObject(input)) {
            configFromObject(config);
        } else if (isNumber(input)) {
            // from milliseconds
            config._d = new Date(input);
        } else {
            hooks.createFromInputFallback(config);
        }
    }

    function createLocalOrUTC(input, format, locale, strict, isUTC) {
        var c = {};

        if (format === true || format === false) {
            strict = format;
            format = undefined;
        }

        if (locale === true || locale === false) {
            strict = locale;
            locale = undefined;
        }

        if (
            (isObject(input) && isObjectEmpty(input)) ||
            (isArray(input) && input.length === 0)
        ) {
            input = undefined;
        }
        // object construction must be done this way.
        // https://github.com/moment/moment/issues/1423
        c._isAMomentObject = true;
        c._useUTC = c._isUTC = isUTC;
        c._l = locale;
        c._i = input;
        c._f = format;
        c._strict = strict;

        return createFromConfig(c);
    }

    function createLocal(input, format, locale, strict) {
        return createLocalOrUTC(input, format, locale, strict, false);
    }

    var prototypeMin = deprecate(
            'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',
            function () {
                var other = createLocal.apply(null, arguments);
                if (this.isValid() && other.isValid()) {
                    return other < this ? this : other;
                } else {
                    return createInvalid();
                }
            }
        ),
        prototypeMax = deprecate(
            'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',
            function () {
                var other = createLocal.apply(null, arguments);
                if (this.isValid() && other.isValid()) {
                    return other > this ? this : other;
                } else {
                    return createInvalid();
                }
            }
        );

    // Pick a moment m from moments so that m[fn](other) is true for all
    // other. This relies on the function fn to be transitive.
    //
    // moments should either be an array of moment objects or an array, whose
    // first element is an array of moment objects.
    function pickBy(fn, moments) {
        var res, i;
        if (moments.length === 1 && isArray(moments[0])) {
            moments = moments[0];
        }
        if (!moments.length) {
            return createLocal();
        }
        res = moments[0];
        for (i = 1; i < moments.length; ++i) {
            if (!moments[i].isValid() || moments[i][fn](res)) {
                res = moments[i];
            }
        }
        return res;
    }

    // TODO: Use [].sort instead?
    function min() {
        var args = [].slice.call(arguments, 0);

        return pickBy('isBefore', args);
    }

    function max() {
        var args = [].slice.call(arguments, 0);

        return pickBy('isAfter', args);
    }

    var now = function () {
        return Date.now ? Date.now() : +new Date();
    };

    var ordering = [
        'year',
        'quarter',
        'month',
        'week',
        'day',
        'hour',
        'minute',
        'second',
        'millisecond',
    ];

    function isDurationValid(m) {
        var key,
            unitHasDecimal = false,
            i;
        for (key in m) {
            if (
                hasOwnProp(m, key) &&
                !(
                    indexOf.call(ordering, key) !== -1 &&
                    (m[key] == null || !isNaN(m[key]))
                )
            ) {
                return false;
            }
        }

        for (i = 0; i < ordering.length; ++i) {
            if (m[ordering[i]]) {
                if (unitHasDecimal) {
                    return false; // only allow non-integers for smallest unit
                }
                if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {
                    unitHasDecimal = true;
                }
            }
        }

        return true;
    }

    function isValid$1() {
        return this._isValid;
    }

    function createInvalid$1() {
        return createDuration(NaN);
    }

    function Duration(duration) {
        var normalizedInput = normalizeObjectUnits(duration),
            years = normalizedInput.year || 0,
            quarters = normalizedInput.quarter || 0,
            months = normalizedInput.month || 0,
            weeks = normalizedInput.week || normalizedInput.isoWeek || 0,
            days = normalizedInput.day || 0,
            hours = normalizedInput.hour || 0,
            minutes = normalizedInput.minute || 0,
            seconds = normalizedInput.second || 0,
            milliseconds = normalizedInput.millisecond || 0;

        this._isValid = isDurationValid(normalizedInput);

        // representation for dateAddRemove
        this._milliseconds =
            +milliseconds +
            seconds * 1e3 + // 1000
            minutes * 6e4 + // 1000 * 60
            hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
        // Because of dateAddRemove treats 24 hours as different from a
        // day when working around DST, we need to store them separately
        this._days = +days + weeks * 7;
        // It is impossible to translate months into days without knowing
        // which months you are are talking about, so we have to store
        // it separately.
        this._months = +months + quarters * 3 + years * 12;

        this._data = {};

        this._locale = getLocale();

        this._bubble();
    }

    function isDuration(obj) {
        return obj instanceof Duration;
    }

    function absRound(number) {
        if (number < 0) {
            return Math.round(-1 * number) * -1;
        } else {
            return Math.round(number);
        }
    }

    // compare two arrays, return the number of differences
    function compareArrays(array1, array2, dontConvert) {
        var len = Math.min(array1.length, array2.length),
            lengthDiff = Math.abs(array1.length - array2.length),
            diffs = 0,
            i;
        for (i = 0; i < len; i++) {
            if (
                (dontConvert && array1[i] !== array2[i]) ||
                (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))
            ) {
                diffs++;
            }
        }
        return diffs + lengthDiff;
    }

    // FORMATTING

    function offset(token, separator) {
        addFormatToken(token, 0, 0, function () {
            var offset = this.utcOffset(),
                sign = '+';
            if (offset < 0) {
                offset = -offset;
                sign = '-';
            }
            return (
                sign +
                zeroFill(~~(offset / 60), 2) +
                separator +
                zeroFill(~~offset % 60, 2)
            );
        });
    }

    offset('Z', ':');
    offset('ZZ', '');

    // PARSING

    addRegexToken('Z', matchShortOffset);
    addRegexToken('ZZ', matchShortOffset);
    addParseToken(['Z', 'ZZ'], function (input, array, config) {
        config._useUTC = true;
        config._tzm = offsetFromString(matchShortOffset, input);
    });

    // HELPERS

    // timezone chunker
    // '+10:00' > ['10',  '00']
    // '-1530'  > ['-15', '30']
    var chunkOffset = /([\+\-]|\d\d)/gi;

    function offsetFromString(matcher, string) {
        var matches = (string || '').match(matcher),
            chunk,
            parts,
            minutes;

        if (matches === null) {
            return null;
        }

        chunk = matches[matches.length - 1] || [];
        parts = (chunk + '').match(chunkOffset) || ['-', 0, 0];
        minutes = +(parts[1] * 60) + toInt(parts[2]);

        return minutes === 0 ? 0 : parts[0] === '+' ? minutes : -minutes;
    }

    // Return a moment from input, that is local/utc/zone equivalent to model.
    function cloneWithOffset(input, model) {
        var res, diff;
        if (model._isUTC) {
            res = model.clone();
            diff =
                (isMoment(input) || isDate(input)
                    ? input.valueOf()
                    : createLocal(input).valueOf()) - res.valueOf();
            // Use low-level api, because this fn is low-level api.
            res._d.setTime(res._d.valueOf() + diff);
            hooks.updateOffset(res, false);
            return res;
        } else {
            return createLocal(input).local();
        }
    }

    function getDateOffset(m) {
        // On Firefox.24 Date#getTimezoneOffset returns a floating point.
        // https://github.com/moment/moment/pull/1871
        return -Math.round(m._d.getTimezoneOffset());
    }

    // HOOKS

    // This function will be called whenever a moment is mutated.
    // It is intended to keep the offset in sync with the timezone.
    hooks.updateOffset = function () {};

    // MOMENTS

    // keepLocalTime = true means only change the timezone, without
    // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
    // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
    // +0200, so we adjust the time as needed, to be valid.
    //
    // Keeping the time actually adds/subtracts (one hour)
    // from the actual represented time. That is why we call updateOffset
    // a second time. In case it wants us to change the offset again
    // _changeInProgress == true case, then we have to adjust, because
    // there is no such time in the given timezone.
    function getSetOffset(input, keepLocalTime, keepMinutes) {
        var offset = this._offset || 0,
            localAdjust;
        if (!this.isValid()) {
            return input != null ? this : NaN;
        }
        if (input != null) {
            if (typeof input === 'string') {
                input = offsetFromString(matchShortOffset, input);
                if (input === null) {
                    return this;
                }
            } else if (Math.abs(input) < 16 && !keepMinutes) {
                input = input * 60;
            }
            if (!this._isUTC && keepLocalTime) {
                localAdjust = getDateOffset(this);
            }
            this._offset = input;
            this._isUTC = true;
            if (localAdjust != null) {
                this.add(localAdjust, 'm');
            }
            if (offset !== input) {
                if (!keepLocalTime || this._changeInProgress) {
                    addSubtract(
                        this,
                        createDuration(input - offset, 'm'),
                        1,
                        false
                    );
                } else if (!this._changeInProgress) {
                    this._changeInProgress = true;
                    hooks.updateOffset(this, true);
                    this._changeInProgress = null;
                }
            }
            return this;
        } else {
            return this._isUTC ? offset : getDateOffset(this);
        }
    }

    function getSetZone(input, keepLocalTime) {
        if (input != null) {
            if (typeof input !== 'string') {
                input = -input;
            }

            this.utcOffset(input, keepLocalTime);

            return this;
        } else {
            return -this.utcOffset();
        }
    }

    function setOffsetToUTC(keepLocalTime) {
        return this.utcOffset(0, keepLocalTime);
    }

    function setOffsetToLocal(keepLocalTime) {
        if (this._isUTC) {
            this.utcOffset(0, keepLocalTime);
            this._isUTC = false;

            if (keepLocalTime) {
                this.subtract(getDateOffset(this), 'm');
            }
        }
        return this;
    }

    function setOffsetToParsedOffset() {
        if (this._tzm != null) {
            this.utcOffset(this._tzm, false, true);
        } else if (typeof this._i === 'string') {
            var tZone = offsetFromString(matchOffset, this._i);
            if (tZone != null) {
                this.utcOffset(tZone);
            } else {
                this.utcOffset(0, true);
            }
        }
        return this;
    }

    function hasAlignedHourOffset(input) {
        if (!this.isValid()) {
            return false;
        }
        input = input ? createLocal(input).utcOffset() : 0;

        return (this.utcOffset() - input) % 60 === 0;
    }

    function isDaylightSavingTime() {
        return (
            this.utcOffset() > this.clone().month(0).utcOffset() ||
            this.utcOffset() > this.clone().month(5).utcOffset()
        );
    }

    function isDaylightSavingTimeShifted() {
        if (!isUndefined(this._isDSTShifted)) {
            return this._isDSTShifted;
        }

        var c = {},
            other;

        copyConfig(c, this);
        c = prepareConfig(c);

        if (c._a) {
            other = c._isUTC ? createUTC(c._a) : createLocal(c._a);
            this._isDSTShifted =
                this.isValid() && compareArrays(c._a, other.toArray()) > 0;
        } else {
            this._isDSTShifted = false;
        }

        return this._isDSTShifted;
    }

    function isLocal() {
        return this.isValid() ? !this._isUTC : false;
    }

    function isUtcOffset() {
        return this.isValid() ? this._isUTC : false;
    }

    function isUtc() {
        return this.isValid() ? this._isUTC && this._offset === 0 : false;
    }

    // ASP.NET json date format regex
    var aspNetRegex = /^(-|\+)?(?:(\d*)[. ])?(\d+):(\d+)(?::(\d+)(\.\d*)?)?$/,
        // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
        // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
        // and further modified to allow for strings containing both week and day
        isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;

    function createDuration(input, key) {
        var duration = input,
            // matching against regexp is expensive, do it on demand
            match = null,
            sign,
            ret,
            diffRes;

        if (isDuration(input)) {
            duration = {
                ms: input._milliseconds,
                d: input._days,
                M: input._months,
            };
        } else if (isNumber(input) || !isNaN(+input)) {
            duration = {};
            if (key) {
                duration[key] = +input;
            } else {
                duration.milliseconds = +input;
            }
        } else if ((match = aspNetRegex.exec(input))) {
            sign = match[1] === '-' ? -1 : 1;
            duration = {
                y: 0,
                d: toInt(match[DATE]) * sign,
                h: toInt(match[HOUR]) * sign,
                m: toInt(match[MINUTE]) * sign,
                s: toInt(match[SECOND]) * sign,
                ms: toInt(absRound(match[MILLISECOND] * 1000)) * sign, // the millisecond decimal point is included in the match
            };
        } else if ((match = isoRegex.exec(input))) {
            sign = match[1] === '-' ? -1 : 1;
            duration = {
                y: parseIso(match[2], sign),
                M: parseIso(match[3], sign),
                w: parseIso(match[4], sign),
                d: parseIso(match[5], sign),
                h: parseIso(match[6], sign),
                m: parseIso(match[7], sign),
                s: parseIso(match[8], sign),
            };
        } else if (duration == null) {
            // checks for null or undefined
            duration = {};
        } else if (
            typeof duration === 'object' &&
            ('from' in duration || 'to' in duration)
        ) {
            diffRes = momentsDifference(
                createLocal(duration.from),
                createLocal(duration.to)
            );

            duration = {};
            duration.ms = diffRes.milliseconds;
            duration.M = diffRes.months;
        }

        ret = new Duration(duration);

        if (isDuration(input) && hasOwnProp(input, '_locale')) {
            ret._locale = input._locale;
        }

        if (isDuration(input) && hasOwnProp(input, '_isValid')) {
            ret._isValid = input._isValid;
        }

        return ret;
    }

    createDuration.fn = Duration.prototype;
    createDuration.invalid = createInvalid$1;

    function parseIso(inp, sign) {
        // We'd normally use ~~inp for this, but unfortunately it also
        // converts floats to ints.
        // inp may be undefined, so careful calling replace on it.
        var res = inp && parseFloat(inp.replace(',', '.'));
        // apply sign while we're at it
        return (isNaN(res) ? 0 : res) * sign;
    }

    function positiveMomentsDifference(base, other) {
        var res = {};

        res.months =
            other.month() - base.month() + (other.year() - base.year()) * 12;
        if (base.clone().add(res.months, 'M').isAfter(other)) {
            --res.months;
        }

        res.milliseconds = +other - +base.clone().add(res.months, 'M');

        return res;
    }

    function momentsDifference(base, other) {
        var res;
        if (!(base.isValid() && other.isValid())) {
            return { milliseconds: 0, months: 0 };
        }

        other = cloneWithOffset(other, base);
        if (base.isBefore(other)) {
            res = positiveMomentsDifference(base, other);
        } else {
            res = positiveMomentsDifference(other, base);
            res.milliseconds = -res.milliseconds;
            res.months = -res.months;
        }

        return res;
    }

    // TODO: remove 'name' arg after deprecation is removed
    function createAdder(direction, name) {
        return function (val, period) {
            var dur, tmp;
            //invert the arguments, but complain about it
            if (period !== null && !isNaN(+period)) {
                deprecateSimple(
                    name,
                    'moment().' +
                        name +
                        '(period, number) is deprecated. Please use moment().' +
                        name +
                        '(number, period). ' +
                        'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.'
                );
                tmp = val;
                val = period;
                period = tmp;
            }

            dur = createDuration(val, period);
            addSubtract(this, dur, direction);
            return this;
        };
    }

    function addSubtract(mom, duration, isAdding, updateOffset) {
        var milliseconds = duration._milliseconds,
            days = absRound(duration._days),
            months = absRound(duration._months);

        if (!mom.isValid()) {
            // No op
            return;
        }

        updateOffset = updateOffset == null ? true : updateOffset;

        if (months) {
            setMonth(mom, get(mom, 'Month') + months * isAdding);
        }
        if (days) {
            set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);
        }
        if (milliseconds) {
            mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
        }
        if (updateOffset) {
            hooks.updateOffset(mom, days || months);
        }
    }

    var add = createAdder(1, 'add'),
        subtract = createAdder(-1, 'subtract');

    function isString(input) {
        return typeof input === 'string' || input instanceof String;
    }

    // type MomentInput = Moment | Date | string | number | (number | string)[] | MomentInputObject | void; // null | undefined
    function isMomentInput(input) {
        return (
            isMoment(input) ||
            isDate(input) ||
            isString(input) ||
            isNumber(input) ||
            isNumberOrStringArray(input) ||
            isMomentInputObject(input) ||
            input === null ||
            input === undefined
        );
    }

    function isMomentInputObject(input) {
        var objectTest = isObject(input) && !isObjectEmpty(input),
            propertyTest = false,
            properties = [
                'years',
                'year',
                'y',
                'months',
                'month',
                'M',
                'days',
                'day',
                'd',
                'dates',
                'date',
                'D',
                'hours',
                'hour',
                'h',
                'minutes',
                'minute',
                'm',
                'seconds',
                'second',
                's',
                'milliseconds',
                'millisecond',
                'ms',
            ],
            i,
            property;

        for (i = 0; i < properties.length; i += 1) {
            property = properties[i];
            propertyTest = propertyTest || hasOwnProp(input, property);
        }

        return objectTest && propertyTest;
    }

    function isNumberOrStringArray(input) {
        var arrayTest = isArray(input),
            dataTypeTest = false;
        if (arrayTest) {
            dataTypeTest =
                input.filter(function (item) {
                    return !isNumber(item) && isString(input);
                }).length === 0;
        }
        return arrayTest && dataTypeTest;
    }

    function isCalendarSpec(input) {
        var objectTest = isObject(input) && !isObjectEmpty(input),
            propertyTest = false,
            properties = [
                'sameDay',
                'nextDay',
                'lastDay',
                'nextWeek',
                'lastWeek',
                'sameElse',
            ],
            i,
            property;

        for (i = 0; i < properties.length; i += 1) {
            property = properties[i];
            propertyTest = propertyTest || hasOwnProp(input, property);
        }

        return objectTest && propertyTest;
    }

    function getCalendarFormat(myMoment, now) {
        var diff = myMoment.diff(now, 'days', true);
        return diff < -6
            ? 'sameElse'
            : diff < -1
            ? 'lastWeek'
            : diff < 0
            ? 'lastDay'
            : diff < 1
            ? 'sameDay'
            : diff < 2
            ? 'nextDay'
            : diff < 7
            ? 'nextWeek'
            : 'sameElse';
    }

    function calendar$1(time, formats) {
        // Support for single parameter, formats only overload to the calendar function
        if (arguments.length === 1) {
            if (!arguments[0]) {
                time = undefined;
                formats = undefined;
            } else if (isMomentInput(arguments[0])) {
                time = arguments[0];
                formats = undefined;
            } else if (isCalendarSpec(arguments[0])) {
                formats = arguments[0];
                time = undefined;
            }
        }
        // We want to compare the start of today, vs this.
        // Getting start-of-today depends on whether we're local/utc/offset or not.
        var now = time || createLocal(),
            sod = cloneWithOffset(now, this).startOf('day'),
            format = hooks.calendarFormat(this, sod) || 'sameElse',
            output =
                formats &&
                (isFunction(formats[format])
                    ? formats[format].call(this, now)
                    : formats[format]);

        return this.format(
            output || this.localeData().calendar(format, this, createLocal(now))
        );
    }

    function clone() {
        return new Moment(this);
    }

    function isAfter(input, units) {
        var localInput = isMoment(input) ? input : createLocal(input);
        if (!(this.isValid() && localInput.isValid())) {
            return false;
        }
        units = normalizeUnits(units) || 'millisecond';
        if (units === 'millisecond') {
            return this.valueOf() > localInput.valueOf();
        } else {
            return localInput.valueOf() < this.clone().startOf(units).valueOf();
        }
    }

    function isBefore(input, units) {
        var localInput = isMoment(input) ? input : createLocal(input);
        if (!(this.isValid() && localInput.isValid())) {
            return false;
        }
        units = normalizeUnits(units) || 'millisecond';
        if (units === 'millisecond') {
            return this.valueOf() < localInput.valueOf();
        } else {
            return this.clone().endOf(units).valueOf() < localInput.valueOf();
        }
    }

    function isBetween(from, to, units, inclusivity) {
        var localFrom = isMoment(from) ? from : createLocal(from),
            localTo = isMoment(to) ? to : createLocal(to);
        if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) {
            return false;
        }
        inclusivity = inclusivity || '()';
        return (
            (inclusivity[0] === '('
                ? this.isAfter(localFrom, units)
                : !this.isBefore(localFrom, units)) &&
            (inclusivity[1] === ')'
                ? this.isBefore(localTo, units)
                : !this.isAfter(localTo, units))
        );
    }

    function isSame(input, units) {
        var localInput = isMoment(input) ? input : createLocal(input),
            inputMs;
        if (!(this.isValid() && localInput.isValid())) {
            return false;
        }
        units = normalizeUnits(units) || 'millisecond';
        if (units === 'millisecond') {
            return this.valueOf() === localInput.valueOf();
        } else {
            inputMs = localInput.valueOf();
            return (
                this.clone().startOf(units).valueOf() <= inputMs &&
                inputMs <= this.clone().endOf(units).valueOf()
            );
        }
    }

    function isSameOrAfter(input, units) {
        return this.isSame(input, units) || this.isAfter(input, units);
    }

    function isSameOrBefore(input, units) {
        return this.isSame(input, units) || this.isBefore(input, units);
    }

    function diff(input, units, asFloat) {
        var that, zoneDelta, output;

        if (!this.isValid()) {
            return NaN;
        }

        that = cloneWithOffset(input, this);

        if (!that.isValid()) {
            return NaN;
        }

        zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;

        units = normalizeUnits(units);

        switch (units) {
            case 'year':
                output = monthDiff(this, that) / 12;
                break;
            case 'month':
                output = monthDiff(this, that);
                break;
            case 'quarter':
                output = monthDiff(this, that) / 3;
                break;
            case 'second':
                output = (this - that) / 1e3;
                break; // 1000
            case 'minute':
                output = (this - that) / 6e4;
                break; // 1000 * 60
            case 'hour':
                output = (this - that) / 36e5;
                break; // 1000 * 60 * 60
            case 'day':
                output = (this - that - zoneDelta) / 864e5;
                break; // 1000 * 60 * 60 * 24, negate dst
            case 'week':
                output = (this - that - zoneDelta) / 6048e5;
                break; // 1000 * 60 * 60 * 24 * 7, negate dst
            default:
                output = this - that;
        }

        return asFloat ? output : absFloor(output);
    }

    function monthDiff(a, b) {
        if (a.date() < b.date()) {
            // end-of-month calculations work correct when the start month has more
            // days than the end month.
            return -monthDiff(b, a);
        }
        // difference in months
        var wholeMonthDiff = (b.year() - a.year()) * 12 + (b.month() - a.month()),
            // b is in (anchor - 1 month, anchor + 1 month)
            anchor = a.clone().add(wholeMonthDiff, 'months'),
            anchor2,
            adjust;

        if (b - anchor < 0) {
            anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
            // linear across the month
            adjust = (b - anchor) / (anchor - anchor2);
        } else {
            anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
            // linear across the month
            adjust = (b - anchor) / (anchor2 - anchor);
        }

        //check for negative zero, return zero if negative zero
        return -(wholeMonthDiff + adjust) || 0;
    }

    hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
    hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';

    function toString() {
        return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
    }

    function toISOString(keepOffset) {
        if (!this.isValid()) {
            return null;
        }
        var utc = keepOffset !== true,
            m = utc ? this.clone().utc() : this;
        if (m.year() < 0 || m.year() > 9999) {
            return formatMoment(
                m,
                utc
                    ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]'
                    : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ'
            );
        }
        if (isFunction(Date.prototype.toISOString)) {
            // native implementation is ~50x faster, use it when we can
            if (utc) {
                return this.toDate().toISOString();
            } else {
                return new Date(this.valueOf() + this.utcOffset() * 60 * 1000)
                    .toISOString()
                    .replace('Z', formatMoment(m, 'Z'));
            }
        }
        return formatMoment(
            m,
            utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ'
        );
    }

    /**
     * Return a human readable representation of a moment that can
     * also be evaluated to get a new moment which is the same
     *
     * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects
     */
    function inspect() {
        if (!this.isValid()) {
            return 'moment.invalid(/* ' + this._i + ' */)';
        }
        var func = 'moment',
            zone = '',
            prefix,
            year,
            datetime,
            suffix;
        if (!this.isLocal()) {
            func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';
            zone = 'Z';
        }
        prefix = '[' + func + '("]';
        year = 0 <= this.year() && this.year() <= 9999 ? 'YYYY' : 'YYYYYY';
        datetime = '-MM-DD[T]HH:mm:ss.SSS';
        suffix = zone + '[")]';

        return this.format(prefix + year + datetime + suffix);
    }

    function format(inputString) {
        if (!inputString) {
            inputString = this.isUtc()
                ? hooks.defaultFormatUtc
                : hooks.defaultFormat;
        }
        var output = formatMoment(this, inputString);
        return this.localeData().postformat(output);
    }

    function from(time, withoutSuffix) {
        if (
            this.isValid() &&
            ((isMoment(time) && time.isValid()) || createLocal(time).isValid())
        ) {
            return createDuration({ to: this, from: time })
                .locale(this.locale())
                .humanize(!withoutSuffix);
        } else {
            return this.localeData().invalidDate();
        }
    }

    function fromNow(withoutSuffix) {
        return this.from(createLocal(), withoutSuffix);
    }

    function to(time, withoutSuffix) {
        if (
            this.isValid() &&
            ((isMoment(time) && time.isValid()) || createLocal(time).isValid())
        ) {
            return createDuration({ from: this, to: time })
                .locale(this.locale())
                .humanize(!withoutSuffix);
        } else {
            return this.localeData().invalidDate();
        }
    }

    function toNow(withoutSuffix) {
        return this.to(createLocal(), withoutSuffix);
    }

    // If passed a locale key, it will set the locale for this
    // instance.  Otherwise, it will return the locale configuration
    // variables for this instance.
    function locale(key) {
        var newLocaleData;

        if (key === undefined) {
            return this._locale._abbr;
        } else {
            newLocaleData = getLocale(key);
            if (newLocaleData != null) {
                this._locale = newLocaleData;
            }
            return this;
        }
    }

    var lang = deprecate(
        'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',
        function (key) {
            if (key === undefined) {
                return this.localeData();
            } else {
                return this.locale(key);
            }
        }
    );

    function localeData() {
        return this._locale;
    }

    var MS_PER_SECOND = 1000,
        MS_PER_MINUTE = 60 * MS_PER_SECOND,
        MS_PER_HOUR = 60 * MS_PER_MINUTE,
        MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR;

    // actual modulo - handles negative numbers (for dates before 1970):
    function mod$1(dividend, divisor) {
        return ((dividend % divisor) + divisor) % divisor;
    }

    function localStartOfDate(y, m, d) {
        // the date constructor remaps years 0-99 to 1900-1999
        if (y < 100 && y >= 0) {
            // preserve leap years using a full 400 year cycle, then reset
            return new Date(y + 400, m, d) - MS_PER_400_YEARS;
        } else {
            return new Date(y, m, d).valueOf();
        }
    }

    function utcStartOfDate(y, m, d) {
        // Date.UTC remaps years 0-99 to 1900-1999
        if (y < 100 && y >= 0) {
            // preserve leap years using a full 400 year cycle, then reset
            return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS;
        } else {
            return Date.UTC(y, m, d);
        }
    }

    function startOf(units) {
        var time, startOfDate;
        units = normalizeUnits(units);
        if (units === undefined || units === 'millisecond' || !this.isValid()) {
            return this;
        }

        startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;

        switch (units) {
            case 'year':
                time = startOfDate(this.year(), 0, 1);
                break;
            case 'quarter':
                time = startOfDate(
                    this.year(),
                    this.month() - (this.month() % 3),
                    1
                );
                break;
            case 'month':
                time = startOfDate(this.year(), this.month(), 1);
                break;
            case 'week':
                time = startOfDate(
                    this.year(),
                    this.month(),
                    this.date() - this.weekday()
                );
                break;
            case 'isoWeek':
                time = startOfDate(
                    this.year(),
                    this.month(),
                    this.date() - (this.isoWeekday() - 1)
                );
                break;
            case 'day':
            case 'date':
                time = startOfDate(this.year(), this.month(), this.date());
                break;
            case 'hour':
                time = this._d.valueOf();
                time -= mod$1(
                    time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE),
                    MS_PER_HOUR
                );
                break;
            case 'minute':
                time = this._d.valueOf();
                time -= mod$1(time, MS_PER_MINUTE);
                break;
            case 'second':
                time = this._d.valueOf();
                time -= mod$1(time, MS_PER_SECOND);
                break;
        }

        this._d.setTime(time);
        hooks.updateOffset(this, true);
        return this;
    }

    function endOf(units) {
        var time, startOfDate;
        units = normalizeUnits(units);
        if (units === undefined || units === 'millisecond' || !this.isValid()) {
            return this;
        }

        startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;

        switch (units) {
            case 'year':
                time = startOfDate(this.year() + 1, 0, 1) - 1;
                break;
            case 'quarter':
                time =
                    startOfDate(
                        this.year(),
                        this.month() - (this.month() % 3) + 3,
                        1
                    ) - 1;
                break;
            case 'month':
                time = startOfDate(this.year(), this.month() + 1, 1) - 1;
                break;
            case 'week':
                time =
                    startOfDate(
                        this.year(),
                        this.month(),
                        this.date() - this.weekday() + 7
                    ) - 1;
                break;
            case 'isoWeek':
                time =
                    startOfDate(
                        this.year(),
                        this.month(),
                        this.date() - (this.isoWeekday() - 1) + 7
                    ) - 1;
                break;
            case 'day':
            case 'date':
                time = startOfDate(this.year(), this.month(), this.date() + 1) - 1;
                break;
            case 'hour':
                time = this._d.valueOf();
                time +=
                    MS_PER_HOUR -
                    mod$1(
                        time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE),
                        MS_PER_HOUR
                    ) -
                    1;
                break;
            case 'minute':
                time = this._d.valueOf();
                time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1;
                break;
            case 'second':
                time = this._d.valueOf();
                time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1;
                break;
        }

        this._d.setTime(time);
        hooks.updateOffset(this, true);
        return this;
    }

    function valueOf() {
        return this._d.valueOf() - (this._offset || 0) * 60000;
    }

    function unix() {
        return Math.floor(this.valueOf() / 1000);
    }

    function toDate() {
        return new Date(this.valueOf());
    }

    function toArray() {
        var m = this;
        return [
            m.year(),
            m.month(),
            m.date(),
            m.hour(),
            m.minute(),
            m.second(),
            m.millisecond(),
        ];
    }

    function toObject() {
        var m = this;
        return {
            years: m.year(),
            months: m.month(),
            date: m.date(),
            hours: m.hours(),
            minutes: m.minutes(),
            seconds: m.seconds(),
            milliseconds: m.milliseconds(),
        };
    }

    function toJSON() {
        // new Date(NaN).toJSON() === null
        return this.isValid() ? this.toISOString() : null;
    }

    function isValid$2() {
        return isValid(this);
    }

    function parsingFlags() {
        return extend({}, getParsingFlags(this));
    }

    function invalidAt() {
        return getParsingFlags(this).overflow;
    }

    function creationData() {
        return {
            input: this._i,
            format: this._f,
            locale: this._locale,
            isUTC: this._isUTC,
            strict: this._strict,
        };
    }

    addFormatToken('N', 0, 0, 'eraAbbr');
    addFormatToken('NN', 0, 0, 'eraAbbr');
    addFormatToken('NNN', 0, 0, 'eraAbbr');
    addFormatToken('NNNN', 0, 0, 'eraName');
    addFormatToken('NNNNN', 0, 0, 'eraNarrow');

    addFormatToken('y', ['y', 1], 'yo', 'eraYear');
    addFormatToken('y', ['yy', 2], 0, 'eraYear');
    addFormatToken('y', ['yyy', 3], 0, 'eraYear');
    addFormatToken('y', ['yyyy', 4], 0, 'eraYear');

    addRegexToken('N', matchEraAbbr);
    addRegexToken('NN', matchEraAbbr);
    addRegexToken('NNN', matchEraAbbr);
    addRegexToken('NNNN', matchEraName);
    addRegexToken('NNNNN', matchEraNarrow);

    addParseToken(['N', 'NN', 'NNN', 'NNNN', 'NNNNN'], function (
        input,
        array,
        config,
        token
    ) {
        var era = config._locale.erasParse(input, token, config._strict);
        if (era) {
            getParsingFlags(config).era = era;
        } else {
            getParsingFlags(config).invalidEra = input;
        }
    });

    addRegexToken('y', matchUnsigned);
    addRegexToken('yy', matchUnsigned);
    addRegexToken('yyy', matchUnsigned);
    addRegexToken('yyyy', matchUnsigned);
    addRegexToken('yo', matchEraYearOrdinal);

    addParseToken(['y', 'yy', 'yyy', 'yyyy'], YEAR);
    addParseToken(['yo'], function (input, array, config, token) {
        var match;
        if (config._locale._eraYearOrdinalRegex) {
            match = input.match(config._locale._eraYearOrdinalRegex);
        }

        if (config._locale.eraYearOrdinalParse) {
            array[YEAR] = config._locale.eraYearOrdinalParse(input, match);
        } else {
            array[YEAR] = parseInt(input, 10);
        }
    });

    function localeEras(m, format) {
        var i,
            l,
            date,
            eras = this._eras || getLocale('en')._eras;
        for (i = 0, l = eras.length; i < l; ++i) {
            switch (typeof eras[i].since) {
                case 'string':
                    // truncate time
                    date = hooks(eras[i].since).startOf('day');
                    eras[i].since = date.valueOf();
                    break;
            }

            switch (typeof eras[i].until) {
                case 'undefined':
                    eras[i].until = +Infinity;
                    break;
                case 'string':
                    // truncate time
                    date = hooks(eras[i].until).startOf('day').valueOf();
                    eras[i].until = date.valueOf();
                    break;
            }
        }
        return eras;
    }

    function localeErasParse(eraName, format, strict) {
        var i,
            l,
            eras = this.eras(),
            name,
            abbr,
            narrow;
        eraName = eraName.toUpperCase();

        for (i = 0, l = eras.length; i < l; ++i) {
            name = eras[i].name.toUpperCase();
            abbr = eras[i].abbr.toUpperCase();
            narrow = eras[i].narrow.toUpperCase();

            if (strict) {
                switch (format) {
                    case 'N':
                    case 'NN':
                    case 'NNN':
                        if (abbr === eraName) {
                            return eras[i];
                        }
                        break;

                    case 'NNNN':
                        if (name === eraName) {
                            return eras[i];
                        }
                        break;

                    case 'NNNNN':
                        if (narrow === eraName) {
                            return eras[i];
                        }
                        break;
                }
            } else if ([name, abbr, narrow].indexOf(eraName) >= 0) {
                return eras[i];
            }
        }
    }

    function localeErasConvertYear(era, year) {
        var dir = era.since <= era.until ? +1 : -1;
        if (year === undefined) {
            return hooks(era.since).year();
        } else {
            return hooks(era.since).year() + (year - era.offset) * dir;
        }
    }

    function getEraName() {
        var i,
            l,
            val,
            eras = this.localeData().eras();
        for (i = 0, l = eras.length; i < l; ++i) {
            // truncate time
            val = this.clone().startOf('day').valueOf();

            if (eras[i].since <= val && val <= eras[i].until) {
                return eras[i].name;
            }
            if (eras[i].until <= val && val <= eras[i].since) {
                return eras[i].name;
            }
        }

        return '';
    }

    function getEraNarrow() {
        var i,
            l,
            val,
            eras = this.localeData().eras();
        for (i = 0, l = eras.length; i < l; ++i) {
            // truncate time
            val = this.clone().startOf('day').valueOf();

            if (eras[i].since <= val && val <= eras[i].until) {
                return eras[i].narrow;
            }
            if (eras[i].until <= val && val <= eras[i].since) {
                return eras[i].narrow;
            }
        }

        return '';
    }

    function getEraAbbr() {
        var i,
            l,
            val,
            eras = this.localeData().eras();
        for (i = 0, l = eras.length; i < l; ++i) {
            // truncate time
            val = this.clone().startOf('day').valueOf();

            if (eras[i].since <= val && val <= eras[i].until) {
                return eras[i].abbr;
            }
            if (eras[i].until <= val && val <= eras[i].since) {
                return eras[i].abbr;
            }
        }

        return '';
    }

    function getEraYear() {
        var i,
            l,
            dir,
            val,
            eras = this.localeData().eras();
        for (i = 0, l = eras.length; i < l; ++i) {
            dir = eras[i].since <= eras[i].until ? +1 : -1;

            // truncate time
            val = this.clone().startOf('day').valueOf();

            if (
                (eras[i].since <= val && val <= eras[i].until) ||
                (eras[i].until <= val && val <= eras[i].since)
            ) {
                return (
                    (this.year() - hooks(eras[i].since).year()) * dir +
                    eras[i].offset
                );
            }
        }

        return this.year();
    }

    function erasNameRegex(isStrict) {
        if (!hasOwnProp(this, '_erasNameRegex')) {
            computeErasParse.call(this);
        }
        return isStrict ? this._erasNameRegex : this._erasRegex;
    }

    function erasAbbrRegex(isStrict) {
        if (!hasOwnProp(this, '_erasAbbrRegex')) {
            computeErasParse.call(this);
        }
        return isStrict ? this._erasAbbrRegex : this._erasRegex;
    }

    function erasNarrowRegex(isStrict) {
        if (!hasOwnProp(this, '_erasNarrowRegex')) {
            computeErasParse.call(this);
        }
        return isStrict ? this._erasNarrowRegex : this._erasRegex;
    }

    function matchEraAbbr(isStrict, locale) {
        return locale.erasAbbrRegex(isStrict);
    }

    function matchEraName(isStrict, locale) {
        return locale.erasNameRegex(isStrict);
    }

    function matchEraNarrow(isStrict, locale) {
        return locale.erasNarrowRegex(isStrict);
    }

    function matchEraYearOrdinal(isStrict, locale) {
        return locale._eraYearOrdinalRegex || matchUnsigned;
    }

    function computeErasParse() {
        var abbrPieces = [],
            namePieces = [],
            narrowPieces = [],
            mixedPieces = [],
            i,
            l,
            eras = this.eras();

        for (i = 0, l = eras.length; i < l; ++i) {
            namePieces.push(regexEscape(eras[i].name));
            abbrPieces.push(regexEscape(eras[i].abbr));
            narrowPieces.push(regexEscape(eras[i].narrow));

            mixedPieces.push(regexEscape(eras[i].name));
            mixedPieces.push(regexEscape(eras[i].abbr));
            mixedPieces.push(regexEscape(eras[i].narrow));
        }

        this._erasRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
        this._erasNameRegex = new RegExp('^(' + namePieces.join('|') + ')', 'i');
        this._erasAbbrRegex = new RegExp('^(' + abbrPieces.join('|') + ')', 'i');
        this._erasNarrowRegex = new RegExp(
            '^(' + narrowPieces.join('|') + ')',
            'i'
        );
    }

    // FORMATTING

    addFormatToken(0, ['gg', 2], 0, function () {
        return this.weekYear() % 100;
    });

    addFormatToken(0, ['GG', 2], 0, function () {
        return this.isoWeekYear() % 100;
    });

    function addWeekYearFormatToken(token, getter) {
        addFormatToken(0, [token, token.length], 0, getter);
    }

    addWeekYearFormatToken('gggg', 'weekYear');
    addWeekYearFormatToken('ggggg', 'weekYear');
    addWeekYearFormatToken('GGGG', 'isoWeekYear');
    addWeekYearFormatToken('GGGGG', 'isoWeekYear');

    // ALIASES

    addUnitAlias('weekYear', 'gg');
    addUnitAlias('isoWeekYear', 'GG');

    // PRIORITY

    addUnitPriority('weekYear', 1);
    addUnitPriority('isoWeekYear', 1);

    // PARSING

    addRegexToken('G', matchSigned);
    addRegexToken('g', matchSigned);
    addRegexToken('GG', match1to2, match2);
    addRegexToken('gg', match1to2, match2);
    addRegexToken('GGGG', match1to4, match4);
    addRegexToken('gggg', match1to4, match4);
    addRegexToken('GGGGG', match1to6, match6);
    addRegexToken('ggggg', match1to6, match6);

    addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (
        input,
        week,
        config,
        token
    ) {
        week[token.substr(0, 2)] = toInt(input);
    });

    addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
        week[token] = hooks.parseTwoDigitYear(input);
    });

    // MOMENTS

    function getSetWeekYear(input) {
        return getSetWeekYearHelper.call(
            this,
            input,
            this.week(),
            this.weekday(),
            this.localeData()._week.dow,
            this.localeData()._week.doy
        );
    }

    function getSetISOWeekYear(input) {
        return getSetWeekYearHelper.call(
            this,
            input,
            this.isoWeek(),
            this.isoWeekday(),
            1,
            4
        );
    }

    function getISOWeeksInYear() {
        return weeksInYear(this.year(), 1, 4);
    }

    function getISOWeeksInISOWeekYear() {
        return weeksInYear(this.isoWeekYear(), 1, 4);
    }

    function getWeeksInYear() {
        var weekInfo = this.localeData()._week;
        return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
    }

    function getWeeksInWeekYear() {
        var weekInfo = this.localeData()._week;
        return weeksInYear(this.weekYear(), weekInfo.dow, weekInfo.doy);
    }

    function getSetWeekYearHelper(input, week, weekday, dow, doy) {
        var weeksTarget;
        if (input == null) {
            return weekOfYear(this, dow, doy).year;
        } else {
            weeksTarget = weeksInYear(input, dow, doy);
            if (week > weeksTarget) {
                week = weeksTarget;
            }
            return setWeekAll.call(this, input, week, weekday, dow, doy);
        }
    }

    function setWeekAll(weekYear, week, weekday, dow, doy) {
        var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
            date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);

        this.year(date.getUTCFullYear());
        this.month(date.getUTCMonth());
        this.date(date.getUTCDate());
        return this;
    }

    // FORMATTING

    addFormatToken('Q', 0, 'Qo', 'quarter');

    // ALIASES

    addUnitAlias('quarter', 'Q');

    // PRIORITY

    addUnitPriority('quarter', 7);

    // PARSING

    addRegexToken('Q', match1);
    addParseToken('Q', function (input, array) {
        array[MONTH] = (toInt(input) - 1) * 3;
    });

    // MOMENTS

    function getSetQuarter(input) {
        return input == null
            ? Math.ceil((this.month() + 1) / 3)
            : this.month((input - 1) * 3 + (this.month() % 3));
    }

    // FORMATTING

    addFormatToken('D', ['DD', 2], 'Do', 'date');

    // ALIASES

    addUnitAlias('date', 'D');

    // PRIORITY
    addUnitPriority('date', 9);

    // PARSING

    addRegexToken('D', match1to2);
    addRegexToken('DD', match1to2, match2);
    addRegexToken('Do', function (isStrict, locale) {
        // TODO: Remove "ordinalParse" fallback in next major release.
        return isStrict
            ? locale._dayOfMonthOrdinalParse || locale._ordinalParse
            : locale._dayOfMonthOrdinalParseLenient;
    });

    addParseToken(['D', 'DD'], DATE);
    addParseToken('Do', function (input, array) {
        array[DATE] = toInt(input.match(match1to2)[0]);
    });

    // MOMENTS

    var getSetDayOfMonth = makeGetSet('Date', true);

    // FORMATTING

    addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');

    // ALIASES

    addUnitAlias('dayOfYear', 'DDD');

    // PRIORITY
    addUnitPriority('dayOfYear', 4);

    // PARSING

    addRegexToken('DDD', match1to3);
    addRegexToken('DDDD', match3);
    addParseToken(['DDD', 'DDDD'], function (input, array, config) {
        config._dayOfYear = toInt(input);
    });

    // HELPERS

    // MOMENTS

    function getSetDayOfYear(input) {
        var dayOfYear =
            Math.round(
                (this.clone().startOf('day') - this.clone().startOf('year')) / 864e5
            ) + 1;
        return input == null ? dayOfYear : this.add(input - dayOfYear, 'd');
    }

    // FORMATTING

    addFormatToken('m', ['mm', 2], 0, 'minute');

    // ALIASES

    addUnitAlias('minute', 'm');

    // PRIORITY

    addUnitPriority('minute', 14);

    // PARSING

    addRegexToken('m', match1to2);
    addRegexToken('mm', match1to2, match2);
    addParseToken(['m', 'mm'], MINUTE);

    // MOMENTS

    var getSetMinute = makeGetSet('Minutes', false);

    // FORMATTING

    addFormatToken('s', ['ss', 2], 0, 'second');

    // ALIASES

    addUnitAlias('second', 's');

    // PRIORITY

    addUnitPriority('second', 15);

    // PARSING

    addRegexToken('s', match1to2);
    addRegexToken('ss', match1to2, match2);
    addParseToken(['s', 'ss'], SECOND);

    // MOMENTS

    var getSetSecond = makeGetSet('Seconds', false);

    // FORMATTING

    addFormatToken('S', 0, 0, function () {
        return ~~(this.millisecond() / 100);
    });

    addFormatToken(0, ['SS', 2], 0, function () {
        return ~~(this.millisecond() / 10);
    });

    addFormatToken(0, ['SSS', 3], 0, 'millisecond');
    addFormatToken(0, ['SSSS', 4], 0, function () {
        return this.millisecond() * 10;
    });
    addFormatToken(0, ['SSSSS', 5], 0, function () {
        return this.millisecond() * 100;
    });
    addFormatToken(0, ['SSSSSS', 6], 0, function () {
        return this.millisecond() * 1000;
    });
    addFormatToken(0, ['SSSSSSS', 7], 0, function () {
        return this.millisecond() * 10000;
    });
    addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
        return this.millisecond() * 100000;
    });
    addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
        return this.millisecond() * 1000000;
    });

    // ALIASES

    addUnitAlias('millisecond', 'ms');

    // PRIORITY

    addUnitPriority('millisecond', 16);

    // PARSING

    addRegexToken('S', match1to3, match1);
    addRegexToken('SS', match1to3, match2);
    addRegexToken('SSS', match1to3, match3);

    var token, getSetMillisecond;
    for (token = 'SSSS'; token.length <= 9; token += 'S') {
        addRegexToken(token, matchUnsigned);
    }

    function parseMs(input, array) {
        array[MILLISECOND] = toInt(('0.' + input) * 1000);
    }

    for (token = 'S'; token.length <= 9; token += 'S') {
        addParseToken(token, parseMs);
    }

    getSetMillisecond = makeGetSet('Milliseconds', false);

    // FORMATTING

    addFormatToken('z', 0, 0, 'zoneAbbr');
    addFormatToken('zz', 0, 0, 'zoneName');

    // MOMENTS

    function getZoneAbbr() {
        return this._isUTC ? 'UTC' : '';
    }

    function getZoneName() {
        return this._isUTC ? 'Coordinated Universal Time' : '';
    }

    var proto = Moment.prototype;

    proto.add = add;
    proto.calendar = calendar$1;
    proto.clone = clone;
    proto.diff = diff;
    proto.endOf = endOf;
    proto.format = format;
    proto.from = from;
    proto.fromNow = fromNow;
    proto.to = to;
    proto.toNow = toNow;
    proto.get = stringGet;
    proto.invalidAt = invalidAt;
    proto.isAfter = isAfter;
    proto.isBefore = isBefore;
    proto.isBetween = isBetween;
    proto.isSame = isSame;
    proto.isSameOrAfter = isSameOrAfter;
    proto.isSameOrBefore = isSameOrBefore;
    proto.isValid = isValid$2;
    proto.lang = lang;
    proto.locale = locale;
    proto.localeData = localeData;
    proto.max = prototypeMax;
    proto.min = prototypeMin;
    proto.parsingFlags = parsingFlags;
    proto.set = stringSet;
    proto.startOf = startOf;
    proto.subtract = subtract;
    proto.toArray = toArray;
    proto.toObject = toObject;
    proto.toDate = toDate;
    proto.toISOString = toISOString;
    proto.inspect = inspect;
    if (typeof Symbol !== 'undefined' && Symbol.for != null) {
        proto[Symbol.for('nodejs.util.inspect.custom')] = function () {
            return 'Moment<' + this.format() + '>';
        };
    }
    proto.toJSON = toJSON;
    proto.toString = toString;
    proto.unix = unix;
    proto.valueOf = valueOf;
    proto.creationData = creationData;
    proto.eraName = getEraName;
    proto.eraNarrow = getEraNarrow;
    proto.eraAbbr = getEraAbbr;
    proto.eraYear = getEraYear;
    proto.year = getSetYear;
    proto.isLeapYear = getIsLeapYear;
    proto.weekYear = getSetWeekYear;
    proto.isoWeekYear = getSetISOWeekYear;
    proto.quarter = proto.quarters = getSetQuarter;
    proto.month = getSetMonth;
    proto.daysInMonth = getDaysInMonth;
    proto.week = proto.weeks = getSetWeek;
    proto.isoWeek = proto.isoWeeks = getSetISOWeek;
    proto.weeksInYear = getWeeksInYear;
    proto.weeksInWeekYear = getWeeksInWeekYear;
    proto.isoWeeksInYear = getISOWeeksInYear;
    proto.isoWeeksInISOWeekYear = getISOWeeksInISOWeekYear;
    proto.date = getSetDayOfMonth;
    proto.day = proto.days = getSetDayOfWeek;
    proto.weekday = getSetLocaleDayOfWeek;
    proto.isoWeekday = getSetISODayOfWeek;
    proto.dayOfYear = getSetDayOfYear;
    proto.hour = proto.hours = getSetHour;
    proto.minute = proto.minutes = getSetMinute;
    proto.second = proto.seconds = getSetSecond;
    proto.millisecond = proto.milliseconds = getSetMillisecond;
    proto.utcOffset = getSetOffset;
    proto.utc = setOffsetToUTC;
    proto.local = setOffsetToLocal;
    proto.parseZone = setOffsetToParsedOffset;
    proto.hasAlignedHourOffset = hasAlignedHourOffset;
    proto.isDST = isDaylightSavingTime;
    proto.isLocal = isLocal;
    proto.isUtcOffset = isUtcOffset;
    proto.isUtc = isUtc;
    proto.isUTC = isUtc;
    proto.zoneAbbr = getZoneAbbr;
    proto.zoneName = getZoneName;
    proto.dates = deprecate(
        'dates accessor is deprecated. Use date instead.',
        getSetDayOfMonth
    );
    proto.months = deprecate(
        'months accessor is deprecated. Use month instead',
        getSetMonth
    );
    proto.years = deprecate(
        'years accessor is deprecated. Use year instead',
        getSetYear
    );
    proto.zone = deprecate(
        'moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/',
        getSetZone
    );
    proto.isDSTShifted = deprecate(
        'isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information',
        isDaylightSavingTimeShifted
    );

    function createUnix(input) {
        return createLocal(input * 1000);
    }

    function createInZone() {
        return createLocal.apply(null, arguments).parseZone();
    }

    function preParsePostFormat(string) {
        return string;
    }

    var proto$1 = Locale.prototype;

    proto$1.calendar = calendar;
    proto$1.longDateFormat = longDateFormat;
    proto$1.invalidDate = invalidDate;
    proto$1.ordinal = ordinal;
    proto$1.preparse = preParsePostFormat;
    proto$1.postformat = preParsePostFormat;
    proto$1.relativeTime = relativeTime;
    proto$1.pastFuture = pastFuture;
    proto$1.set = set;
    proto$1.eras = localeEras;
    proto$1.erasParse = localeErasParse;
    proto$1.erasConvertYear = localeErasConvertYear;
    proto$1.erasAbbrRegex = erasAbbrRegex;
    proto$1.erasNameRegex = erasNameRegex;
    proto$1.erasNarrowRegex = erasNarrowRegex;

    proto$1.months = localeMonths;
    proto$1.monthsShort = localeMonthsShort;
    proto$1.monthsParse = localeMonthsParse;
    proto$1.monthsRegex = monthsRegex;
    proto$1.monthsShortRegex = monthsShortRegex;
    proto$1.week = localeWeek;
    proto$1.firstDayOfYear = localeFirstDayOfYear;
    proto$1.firstDayOfWeek = localeFirstDayOfWeek;

    proto$1.weekdays = localeWeekdays;
    proto$1.weekdaysMin = localeWeekdaysMin;
    proto$1.weekdaysShort = localeWeekdaysShort;
    proto$1.weekdaysParse = localeWeekdaysParse;

    proto$1.weekdaysRegex = weekdaysRegex;
    proto$1.weekdaysShortRegex = weekdaysShortRegex;
    proto$1.weekdaysMinRegex = weekdaysMinRegex;

    proto$1.isPM = localeIsPM;
    proto$1.meridiem = localeMeridiem;

    function get$1(format, index, field, setter) {
        var locale = getLocale(),
            utc = createUTC().set(setter, index);
        return locale[field](utc, format);
    }

    function listMonthsImpl(format, index, field) {
        if (isNumber(format)) {
            index = format;
            format = undefined;
        }

        format = format || '';

        if (index != null) {
            return get$1(format, index, field, 'month');
        }

        var i,
            out = [];
        for (i = 0; i < 12; i++) {
            out[i] = get$1(format, i, field, 'month');
        }
        return out;
    }

    // ()
    // (5)
    // (fmt, 5)
    // (fmt)
    // (true)
    // (true, 5)
    // (true, fmt, 5)
    // (true, fmt)
    function listWeekdaysImpl(localeSorted, format, index, field) {
        if (typeof localeSorted === 'boolean') {
            if (isNumber(format)) {
                index = format;
                format = undefined;
            }

            format = format || '';
        } else {
            format = localeSorted;
            index = format;
            localeSorted = false;

            if (isNumber(format)) {
                index = format;
                format = undefined;
            }

            format = format || '';
        }

        var locale = getLocale(),
            shift = localeSorted ? locale._week.dow : 0,
            i,
            out = [];

        if (index != null) {
            return get$1(format, (index + shift) % 7, field, 'day');
        }

        for (i = 0; i < 7; i++) {
            out[i] = get$1(format, (i + shift) % 7, field, 'day');
        }
        return out;
    }

    function listMonths(format, index) {
        return listMonthsImpl(format, index, 'months');
    }

    function listMonthsShort(format, index) {
        return listMonthsImpl(format, index, 'monthsShort');
    }

    function listWeekdays(localeSorted, format, index) {
        return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
    }

    function listWeekdaysShort(localeSorted, format, index) {
        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
    }

    function listWeekdaysMin(localeSorted, format, index) {
        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
    }

    getSetGlobalLocale('en', {
        eras: [
            {
                since: '0001-01-01',
                until: +Infinity,
                offset: 1,
                name: 'Anno Domini',
                narrow: 'AD',
                abbr: 'AD',
            },
            {
                since: '0000-12-31',
                until: -Infinity,
                offset: 1,
                name: 'Before Christ',
                narrow: 'BC',
                abbr: 'BC',
            },
        ],
        dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
        ordinal: function (number) {
            var b = number % 10,
                output =
                    toInt((number % 100) / 10) === 1
                        ? 'th'
                        : b === 1
                        ? 'st'
                        : b === 2
                        ? 'nd'
                        : b === 3
                        ? 'rd'
                        : 'th';
            return number + output;
        },
    });

    // Side effect imports

    hooks.lang = deprecate(
        'moment.lang is deprecated. Use moment.locale instead.',
        getSetGlobalLocale
    );
    hooks.langData = deprecate(
        'moment.langData is deprecated. Use moment.localeData instead.',
        getLocale
    );

    var mathAbs = Math.abs;

    function abs() {
        var data = this._data;

        this._milliseconds = mathAbs(this._milliseconds);
        this._days = mathAbs(this._days);
        this._months = mathAbs(this._months);

        data.milliseconds = mathAbs(data.milliseconds);
        data.seconds = mathAbs(data.seconds);
        data.minutes = mathAbs(data.minutes);
        data.hours = mathAbs(data.hours);
        data.months = mathAbs(data.months);
        data.years = mathAbs(data.years);

        return this;
    }

    function addSubtract$1(duration, input, value, direction) {
        var other = createDuration(input, value);

        duration._milliseconds += direction * other._milliseconds;
        duration._days += direction * other._days;
        duration._months += direction * other._months;

        return duration._bubble();
    }

    // supports only 2.0-style add(1, 's') or add(duration)
    function add$1(input, value) {
        return addSubtract$1(this, input, value, 1);
    }

    // supports only 2.0-style subtract(1, 's') or subtract(duration)
    function subtract$1(input, value) {
        return addSubtract$1(this, input, value, -1);
    }

    function absCeil(number) {
        if (number < 0) {
            return Math.floor(number);
        } else {
            return Math.ceil(number);
        }
    }

    function bubble() {
        var milliseconds = this._milliseconds,
            days = this._days,
            months = this._months,
            data = this._data,
            seconds,
            minutes,
            hours,
            years,
            monthsFromDays;

        // if we have a mix of positive and negative values, bubble down first
        // check: https://github.com/moment/moment/issues/2166
        if (
            !(
                (milliseconds >= 0 && days >= 0 && months >= 0) ||
                (milliseconds <= 0 && days <= 0 && months <= 0)
            )
        ) {
            milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
            days = 0;
            months = 0;
        }

        // The following code bubbles up values, see the tests for
        // examples of what that means.
        data.milliseconds = milliseconds % 1000;

        seconds = absFloor(milliseconds / 1000);
        data.seconds = seconds % 60;

        minutes = absFloor(seconds / 60);
        data.minutes = minutes % 60;

        hours = absFloor(minutes / 60);
        data.hours = hours % 24;

        days += absFloor(hours / 24);

        // convert days to months
        monthsFromDays = absFloor(daysToMonths(days));
        months += monthsFromDays;
        days -= absCeil(monthsToDays(monthsFromDays));

        // 12 months -> 1 year
        years = absFloor(months / 12);
        months %= 12;

        data.days = days;
        data.months = months;
        data.years = years;

        return this;
    }

    function daysToMonths(days) {
        // 400 years have 146097 days (taking into account leap year rules)
        // 400 years have 12 months === 4800
        return (days * 4800) / 146097;
    }

    function monthsToDays(months) {
        // the reverse of daysToMonths
        return (months * 146097) / 4800;
    }

    function as(units) {
        if (!this.isValid()) {
            return NaN;
        }
        var days,
            months,
            milliseconds = this._milliseconds;

        units = normalizeUnits(units);

        if (units === 'month' || units === 'quarter' || units === 'year') {
            days = this._days + milliseconds / 864e5;
            months = this._months + daysToMonths(days);
            switch (units) {
                case 'month':
                    return months;
                case 'quarter':
                    return months / 3;
                case 'year':
                    return months / 12;
            }
        } else {
            // handle milliseconds separately because of floating point math errors (issue #1867)
            days = this._days + Math.round(monthsToDays(this._months));
            switch (units) {
                case 'week':
                    return days / 7 + milliseconds / 6048e5;
                case 'day':
                    return days + milliseconds / 864e5;
                case 'hour':
                    return days * 24 + milliseconds / 36e5;
                case 'minute':
                    return days * 1440 + milliseconds / 6e4;
                case 'second':
                    return days * 86400 + milliseconds / 1000;
                // Math.floor prevents floating point math errors here
                case 'millisecond':
                    return Math.floor(days * 864e5) + milliseconds;
                default:
                    throw new Error('Unknown unit ' + units);
            }
        }
    }

    // TODO: Use this.as('ms')?
    function valueOf$1() {
        if (!this.isValid()) {
            return NaN;
        }
        return (
            this._milliseconds +
            this._days * 864e5 +
            (this._months % 12) * 2592e6 +
            toInt(this._months / 12) * 31536e6
        );
    }

    function makeAs(alias) {
        return function () {
            return this.as(alias);
        };
    }

    var asMilliseconds = makeAs('ms'),
        asSeconds = makeAs('s'),
        asMinutes = makeAs('m'),
        asHours = makeAs('h'),
        asDays = makeAs('d'),
        asWeeks = makeAs('w'),
        asMonths = makeAs('M'),
        asQuarters = makeAs('Q'),
        asYears = makeAs('y');

    function clone$1() {
        return createDuration(this);
    }

    function get$2(units) {
        units = normalizeUnits(units);
        return this.isValid() ? this[units + 's']() : NaN;
    }

    function makeGetter(name) {
        return function () {
            return this.isValid() ? this._data[name] : NaN;
        };
    }

    var milliseconds = makeGetter('milliseconds'),
        seconds = makeGetter('seconds'),
        minutes = makeGetter('minutes'),
        hours = makeGetter('hours'),
        days = makeGetter('days'),
        months = makeGetter('months'),
        years = makeGetter('years');

    function weeks() {
        return absFloor(this.days() / 7);
    }

    var round = Math.round,
        thresholds = {
            ss: 44, // a few seconds to seconds
            s: 45, // seconds to minute
            m: 45, // minutes to hour
            h: 22, // hours to day
            d: 26, // days to month/week
            w: null, // weeks to month
            M: 11, // months to year
        };

    // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
    function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
        return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
    }

    function relativeTime$1(posNegDuration, withoutSuffix, thresholds, locale) {
        var duration = createDuration(posNegDuration).abs(),
            seconds = round(duration.as('s')),
            minutes = round(duration.as('m')),
            hours = round(duration.as('h')),
            days = round(duration.as('d')),
            months = round(duration.as('M')),
            weeks = round(duration.as('w')),
            years = round(duration.as('y')),
            a =
                (seconds <= thresholds.ss && ['s', seconds]) ||
                (seconds < thresholds.s && ['ss', seconds]) ||
                (minutes <= 1 && ['m']) ||
                (minutes < thresholds.m && ['mm', minutes]) ||
                (hours <= 1 && ['h']) ||
                (hours < thresholds.h && ['hh', hours]) ||
                (days <= 1 && ['d']) ||
                (days < thresholds.d && ['dd', days]);

        if (thresholds.w != null) {
            a =
                a ||
                (weeks <= 1 && ['w']) ||
                (weeks < thresholds.w && ['ww', weeks]);
        }
        a = a ||
            (months <= 1 && ['M']) ||
            (months < thresholds.M && ['MM', months]) ||
            (years <= 1 && ['y']) || ['yy', years];

        a[2] = withoutSuffix;
        a[3] = +posNegDuration > 0;
        a[4] = locale;
        return substituteTimeAgo.apply(null, a);
    }

    // This function allows you to set the rounding function for relative time strings
    function getSetRelativeTimeRounding(roundingFunction) {
        if (roundingFunction === undefined) {
            return round;
        }
        if (typeof roundingFunction === 'function') {
            round = roundingFunction;
            return true;
        }
        return false;
    }

    // This function allows you to set a threshold for relative time strings
    function getSetRelativeTimeThreshold(threshold, limit) {
        if (thresholds[threshold] === undefined) {
            return false;
        }
        if (limit === undefined) {
            return thresholds[threshold];
        }
        thresholds[threshold] = limit;
        if (threshold === 's') {
            thresholds.ss = limit - 1;
        }
        return true;
    }

    function humanize(argWithSuffix, argThresholds) {
        if (!this.isValid()) {
            return this.localeData().invalidDate();
        }

        var withSuffix = false,
            th = thresholds,
            locale,
            output;

        if (typeof argWithSuffix === 'object') {
            argThresholds = argWithSuffix;
            argWithSuffix = false;
        }
        if (typeof argWithSuffix === 'boolean') {
            withSuffix = argWithSuffix;
        }
        if (typeof argThresholds === 'object') {
            th = Object.assign({}, thresholds, argThresholds);
            if (argThresholds.s != null && argThresholds.ss == null) {
                th.ss = argThresholds.s - 1;
            }
        }

        locale = this.localeData();
        output = relativeTime$1(this, !withSuffix, th, locale);

        if (withSuffix) {
            output = locale.pastFuture(+this, output);
        }

        return locale.postformat(output);
    }

    var abs$1 = Math.abs;

    function sign(x) {
        return (x > 0) - (x < 0) || +x;
    }

    function toISOString$1() {
        // for ISO strings we do not use the normal bubbling rules:
        //  * milliseconds bubble up until they become hours
        //  * days do not bubble at all
        //  * months bubble up until they become years
        // This is because there is no context-free conversion between hours and days
        // (think of clock changes)
        // and also not between days and months (28-31 days per month)
        if (!this.isValid()) {
            return this.localeData().invalidDate();
        }

        var seconds = abs$1(this._milliseconds) / 1000,
            days = abs$1(this._days),
            months = abs$1(this._months),
            minutes,
            hours,
            years,
            s,
            total = this.asSeconds(),
            totalSign,
            ymSign,
            daysSign,
            hmsSign;

        if (!total) {
            // this is the same as C#'s (Noda) and python (isodate)...
            // but not other JS (goog.date)
            return 'P0D';
        }

        // 3600 seconds -> 60 minutes -> 1 hour
        minutes = absFloor(seconds / 60);
        hours = absFloor(minutes / 60);
        seconds %= 60;
        minutes %= 60;

        // 12 months -> 1 year
        years = absFloor(months / 12);
        months %= 12;

        // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
        s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : '';

        totalSign = total < 0 ? '-' : '';
        ymSign = sign(this._months) !== sign(total) ? '-' : '';
        daysSign = sign(this._days) !== sign(total) ? '-' : '';
        hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : '';

        return (
            totalSign +
            'P' +
            (years ? ymSign + years + 'Y' : '') +
            (months ? ymSign + months + 'M' : '') +
            (days ? daysSign + days + 'D' : '') +
            (hours || minutes || seconds ? 'T' : '') +
            (hours ? hmsSign + hours + 'H' : '') +
            (minutes ? hmsSign + minutes + 'M' : '') +
            (seconds ? hmsSign + s + 'S' : '')
        );
    }

    var proto$2 = Duration.prototype;

    proto$2.isValid = isValid$1;
    proto$2.abs = abs;
    proto$2.add = add$1;
    proto$2.subtract = subtract$1;
    proto$2.as = as;
    proto$2.asMilliseconds = asMilliseconds;
    proto$2.asSeconds = asSeconds;
    proto$2.asMinutes = asMinutes;
    proto$2.asHours = asHours;
    proto$2.asDays = asDays;
    proto$2.asWeeks = asWeeks;
    proto$2.asMonths = asMonths;
    proto$2.asQuarters = asQuarters;
    proto$2.asYears = asYears;
    proto$2.valueOf = valueOf$1;
    proto$2._bubble = bubble;
    proto$2.clone = clone$1;
    proto$2.get = get$2;
    proto$2.milliseconds = milliseconds;
    proto$2.seconds = seconds;
    proto$2.minutes = minutes;
    proto$2.hours = hours;
    proto$2.days = days;
    proto$2.weeks = weeks;
    proto$2.months = months;
    proto$2.years = years;
    proto$2.humanize = humanize;
    proto$2.toISOString = toISOString$1;
    proto$2.toString = toISOString$1;
    proto$2.toJSON = toISOString$1;
    proto$2.locale = locale;
    proto$2.localeData = localeData;

    proto$2.toIsoString = deprecate(
        'toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)',
        toISOString$1
    );
    proto$2.lang = lang;

    // FORMATTING

    addFormatToken('X', 0, 0, 'unix');
    addFormatToken('x', 0, 0, 'valueOf');

    // PARSING

    addRegexToken('x', matchSigned);
    addRegexToken('X', matchTimestamp);
    addParseToken('X', function (input, array, config) {
        config._d = new Date(parseFloat(input) * 1000);
    });
    addParseToken('x', function (input, array, config) {
        config._d = new Date(toInt(input));
    });

    //! moment.js

    hooks.version = '2.29.1';

    setHookCallback(createLocal);

    hooks.fn = proto;
    hooks.min = min;
    hooks.max = max;
    hooks.now = now;
    hooks.utc = createUTC;
    hooks.unix = createUnix;
    hooks.months = listMonths;
    hooks.isDate = isDate;
    hooks.locale = getSetGlobalLocale;
    hooks.invalid = createInvalid;
    hooks.duration = createDuration;
    hooks.isMoment = isMoment;
    hooks.weekdays = listWeekdays;
    hooks.parseZone = createInZone;
    hooks.localeData = getLocale;
    hooks.isDuration = isDuration;
    hooks.monthsShort = listMonthsShort;
    hooks.weekdaysMin = listWeekdaysMin;
    hooks.defineLocale = defineLocale;
    hooks.updateLocale = updateLocale;
    hooks.locales = listLocales;
    hooks.weekdaysShort = listWeekdaysShort;
    hooks.normalizeUnits = normalizeUnits;
    hooks.relativeTimeRounding = getSetRelativeTimeRounding;
    hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;
    hooks.calendarFormat = getCalendarFormat;
    hooks.prototype = proto;

    // currently HTML5 input type only supports 24-hour formats
    hooks.HTML5_FMT = {
        DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm', // <input type="datetime-local" />
        DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss', // <input type="datetime-local" step="1" />
        DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS', // <input type="datetime-local" step="0.001" />
        DATE: 'YYYY-MM-DD', // <input type="date" />
        TIME: 'HH:mm', // <input type="time" />
        TIME_SECONDS: 'HH:mm:ss', // <input type="time" step="1" />
        TIME_MS: 'HH:mm:ss.SSS', // <input type="time" step="0.001" />
        WEEK: 'GGGG-[W]WW', // <input type="week" />
        MONTH: 'YYYY-MM', // <input type="month" />
    };

    return hooks;

})));
public/assets/img/close-button.png000064400000000404151213253550013224 0ustar00�PNG


IHDRP(L"��IDATx��Ы1Fᴰ���ph���
���fs�@C�E��$�5���b�/������B- <Q�����[���2�����"�m�E��>6��bݫ��<�u��t4�)�}��;L��L`E��!���q@��8 Dx,"<��B�
�ID�cГ�b�*X2�P�lP�[���P>ao�ж	��sHIEND�B`�public/assets/img/clock.png000064400000000224151213253550011701 0ustar00�PNG


IHDRP(L"�[IDATx��̱
�0@�_46��O\9+|�o����Cәu��7�	�G�?"�
*�o�0�E2&�B�
�5L��q�U�'�#�*4�V�"��^O��ڛ�]�IEND�B`�public/assets/img/open-button.png000064400000000403151213253550013057 0ustar00�PNG


IHDRP(L"��IDATx��ѭ1�ᴐF(��4�P������h�l~NC7 >f��f�:��G|�r��fL��
ޅz��dDO�v�A�'I��L <�- <�- <�M <�m <�m <�m <�` kn�����xn,��!dx <���A�']k��Up��Up�a��Rn\z
��9��E�<9+�#�T����qS�A�8cOn���~_IEND�B`�public/assets/css/general.css000064400000012455151213253550012254 0ustar00/* Reset ------------------------------------------------------------------------------------------------------------ */

#daextlnl-container,
#daextlnl-container *,
#daextlnl-open{
	
	/* this is useful to prevent div highlighting */
	-webkit-user-select: none; /* Chrome/Safari */        
	-moz-user-select: none; /* Firefox */
	-ms-user-select: none; /* IE10+ */
	-khtml-user-select: none; /* webkit browsers */
	-o-user-select: none;/* not yet implemented */
	user-select: none;/* not yet implemented */	
	-webkit-touch-callout: none;
	
    -webkit-box-sizing: content-box !important;
    -moz-box-sizing: content-box !important;
    box-sizing: content-box !important;  
	
    box-shadow: none !important;
    -webkit-box-shadow: none !important;
    text-shadow: none !important;
    
    border: 0 !important;
    padding: 0 !important;
    margin: 0 !important;

    letter-spacing: normal !important;
    
}

/* Container -------------------------------------------------------------------------------------------------------- */

#daextlnl-container{
    position: fixed;
    bottom: 0;
    left: 0;
    min-height: 140px;
    width: 100%;
    z-index: 999999999998;
}

/* Featured News ---------------------------------------------------------------------------------------------------- */

#daextlnl-featured-container{
    min-height: 100px;
    padding: 0 80px !important;
}

#daextlnl-featured-title-container{
    min-height: 50px;
    text-align: left !important;
    overflow: visible;
}

#daextlnl-featured-title, #daextlnl-featured-title a{
    min-height: 50px;
    line-height: 50px;
    color: #eee;
    display: inline;
    text-transform: uppercase;
    font-weight: 700 !important;
    text-align: left !important;
}

#daextlnl-featured-title a, .daextlnl-slider-single-news a{
    text-decoration: none !important;
}

#daextlnl-featured-title a:hover{
    text-decoration: none !important;
}

#daextlnl-featured-title a:focus{
    outline: 0 !important;
}

.daextlnl-slider-single-news a:hover{
    text-decoration: none !important;
}

.daextlnl-slider-single-news a:focus{
    outline: 0 !important;
}

#daextlnl-container #daextlnl-featured-title,
#daextlnl-container #daextlnl-featured-title a,
#daextlnl-container #daextlnl-featured-excerpt{
    text-shadow: 2.5px 4.33px 5px rgba( 0, 0, 0, 0.30 ) !important;
}

#daextlnl-featured-excerpt-container{
    min-height: 50px;
    text-align: left !important;
}

#daextlnl-featured-excerpt{
    text-align: left !important;
    min-height: 50px;
    line-height: 50px;
    width: 100%;
    color: #eee;
    display: inline;
    font-weight: 600;
}

/* Sliding News ----------------------------------------------------------------------------------------------------- */

#daextlnl-slider{
    width: 1000000px;
    height: 40px;
    position: relative;
    text-transform: uppercase;

}
#daextlnl-slider-floating-content{
    height: 40px;
    position: absolute;
    top: 0;
    left: 0;
}

#daextlnl-slider-floating-content .daextlnl-slider-single-news{
    height: 40px;
    line-height: 40px;
    float: left;
    font-size: 28px;
    font-weight: 700 !important;
}

#daextlnl-slider-floating-content .daextlnl-slider-single-news:last-child{
    margin-right: 0 !important;
}

#daextlnl-slider-floating-content .daextlnl-slider-single-news a{
    font-weight: 700 !important;
}

#daextlnl-container .daextlnl-image-before{
    height: 40px !important;
    padding: 0 !important;
    display: block !important;
    float: left !important;
}

#daextlnl-container .daextlnl-image-after{
    height: 40px !important;
    padding: 0 !important;
    display: block !important;
    float: left !important;
}

.daextlnl-slider-single-news a{
    display: block !important;
    float: left !important;
}

.daextlnl-slider-single-news span{
    display: block !important;
    float: left !important;
}

/* Clock ------------------------------------------------------------------------------------------------------------ */

#daextlnl-clock{
    position: absolute;
    left: 0;
    bottom: 0;
    width: auto;
    padding: 0 4px !important;
    height: 40px;
    line-height: 40px;
    text-align: center;
    font-size: 28px;
    font-weight: 700;
    z-index: 999999999999;
    background-size: 80px 40px !important;
}

#daextlnl-container #daextlnl-clock, #daextlnl-container .daextlnl-slider-single-news{
     text-shadow: none !important;
}

/* Close Button ----------------------------------------------------------------------------------------------------- */
#daextlnl-close{
    cursor: pointer;
    position: absolute;
    right: 0;
    bottom: 0;
    width: 80px;
    height: 40px;
    line-height: 40px;
    text-align: center;
    z-index: 999999999999;
    background-size: 80px 40px !important;
}

/* Open Button ------------------------------------------------------------------------------------------------------ */
#daextlnl-open{
    cursor: pointer;
    position: fixed;
    right: 0;
    bottom: 0;
    width: 80px;
    height: 40px;
    line-height: 40px;
    text-align: center;
    z-index: 999999999999;
    background-size: 80px 40px !important;
}

/* Set transition on all the links ---------------------------------------------------------------------------------- */
#daextlnl-container a{
    -webkit-transition: .3s all ease-in-out;
    -moz-transition: .3s all ease-in-out;
    transition: .3s all ease-in-out;    
}class-daextlnl-ajax.php000064400000017514151213253550011126 0ustar00<?php
/**
 * This file contains the class Daextlnl_Ajax, used to include ajax actions.
 */

/**
 * This class should be used to include ajax actions.
 */
class Daextlnl_Ajax {

	protected static $instance = null;
	private $shared            = null;

	/**
	 * Return an instance of this class.
	 *
	 * @return self|null
	 */
	public static function get_instance() {

		if ( null == self::$instance ) {
			self::$instance = new self();
		}

		return self::$instance;
	}

	private function __construct() {

		// assign an instance of the plugin info.
		$this->shared = Daextlnl_Shared::get_instance();

		// ajax requests --------------------------------------------------------.
		add_action( 'wp_ajax_set_status_cookie', array( $this, 'set_status_cookie' ) );
		add_action( 'wp_ajax_nopriv_set_status_cookie', array( $this, 'set_status_cookie' ) );

		add_action( 'wp_ajax_get_ticker_data', array( $this, 'get_ticker_data' ) );
		add_action( 'wp_ajax_nopriv_get_ticker_data', array( $this, 'get_ticker_data' ) );

		add_action( 'wp_ajax_update_default_colors', array( $this, 'update_default_colors' ) );
	}

	/**
	 * Set the cookie used to determine the status (open or closed) of the news ticker. This request is triggered when
	 * the used clicks on the open or close button.
	 *
	 * @return void
	 */
	public function set_status_cookie() {

		// check the referer.
		check_ajax_referer( 'live-news', 'security' );

		// Save the current status ( open/closed ) in a cookie.
		$status = isset( $_POST['status'] ) ? sanitize_key( $_POST['status'] ) : '';
		if ( $status === 'open' ) {

			setcookie( 'live_news_status', 'open', 0, '/' );

		} else {

			setcookie( 'live_news_status', 'closed', 0, '/' );

		}

		echo 'success';

		die();
	}

	/**
	 * Generate an XML response with included all the data of the ticker. The data are generated based on the options
	 * defined for the specific ticker.
	 *
	 * @return void
	 */
	public function get_ticker_data() {

		// check the referer.
		check_ajax_referer( 'live-news', 'security' );

		// get the ticker id.
		$ticker_id = intval( $_POST['ticker_id'], 10 );

		// get the ticker information.
		global $wpdb;
		$table_name = $wpdb->prefix . $this->shared->get( 'slug' ) . '_tickers';
		$safe_sql   = $wpdb->prepare( "SELECT * FROM $table_name WHERE id = %d", $ticker_id );
		$ticker_obj = $wpdb->get_row( $safe_sql );

		// if there isn't a ticker associated with this ticker_id die().
		if ( $ticker_obj === null ) {
			die( 'Invalid Ticker ID.' );}

		// START OUTPUT.

		// generate the xml header.
		header( 'Content-type: text/xml' );
		header( 'Pragma: public' );
		header( 'Cache-control: private' );
		header( 'Expires: -1' );

		// Get the transient with included the data of the ticker if available.
		$outstr = get_transient( 'daextlnl_ticker_' . $ticker_obj->id );

		// Generate the data of the ticker only if the transient with the data is not available.
		if ( $outstr === false ) {

			$outstr = '<?xml version="1.0" encoding="UTF-8" ?>';

			$outstr .= '<ticker>';

			// generate featured news XML -----------------------------------------------------------------------------.
			$outstr .= '<featurednews>';

			global $wpdb;
			$table_name = $wpdb->prefix . $this->shared->get( 'slug' ) . '_featured_news';
			$results    = $wpdb->get_results( "SELECT id, news_title, news_excerpt, url FROM $table_name WHERE ticker_id = $ticker_obj->id ORDER BY id DESC LIMIT 1", ARRAY_A );

			if ( count( $results ) > 0 ) {
				foreach ( $results as $result ) {

					$outstr .= '<news>';
					$outstr .= '<newstitle>' . esc_attr( $this->shared->strlen_no_truncate( stripslashes( $result['news_title'] ), $ticker_obj->featured_title_maximum_length ) ) . '</newstitle>';
					$outstr .= '<newsexcerpt>' . esc_attr( $this->shared->strlen_no_truncate( stripslashes( $result['news_excerpt'] ), $ticker_obj->featured_excerpt_maximum_length ) ) . '</newsexcerpt>';
					$outstr .= '<url>' . esc_attr( stripslashes( $result['url'] ) ) . '</url>';
					$outstr .= '</news>';

				}
			}

			$outstr .= '</featurednews>';

			// generate sliding news XML ------------------------------------------------------------------------------.
			$outstr .= '<slidingnews>';

			// get number of sliding news from the option.
			$number_of_sliding_news = intval( $ticker_obj->number_of_sliding_news, 10 );

			/*
			 * Set the offset based on the "Hide Featured News" option. If the featured news is hidden then offset is 0,
			 * if the featured news is shown the offset is 1.
			 */
			if ( $ticker_obj->hide_featured_news == 2 ) {
				$offset = 0;
			} else {
				$offset = 1;
			}

			global $wpdb;
			$table_name = $wpdb->prefix . $this->shared->get( 'slug' ) . '_sliding_news';
			$results    = $wpdb->get_results( "SELECT id, news_title, url, text_color, text_color_hover, background_color, background_color_opacity, image_before, image_after FROM $table_name WHERE ticker_id = $ticker_obj->id ORDER BY id DESC LIMIT $number_of_sliding_news", ARRAY_A );

			if ( count( $results ) > 0 ) {
				foreach ( $results as $result ) {

					$outstr .= '<news>';
					$outstr .= '<newstitle>' . esc_attr( $this->shared->strlen_no_truncate( stripslashes( $result['news_title'] ), $ticker_obj->sliding_news_maximum_length ) ) . '</newstitle>';
					$outstr .= '<url>' . esc_attr( stripslashes( $result['url'] ) ) . '</url>';
					$outstr .= '<text_color>' . esc_attr( stripslashes( $result['text_color'] ) ) . '</text_color>';
					$outstr .= '<text_color_hover>' . esc_attr( stripslashes( $result['text_color_hover'] ) ) . '</text_color_hover>';
					$outstr .= '<background_color>' . esc_attr( stripslashes( $result['background_color'] ) ) . '</background_color>';
					$outstr .= '<background_color_opacity>' . esc_attr( $result['background_color_opacity'] ) . '</background_color_opacity>';
					$outstr .= '<image_before>' . esc_attr( stripslashes( $result['image_before'] ) ) . '</image_before>';
					$outstr .= '<image_after>' . esc_attr( stripslashes( $result['image_after'] ) ) . '</image_after>';
					$outstr .= '</news>';

				}
			}

			$outstr .= '</slidingnews>';

			// generate current time XML ------------------------------------------------------------------------------.
			$current_time = current_time( 'timestamp' ) + $ticker_obj->clock_offset;

			$outstr .= '<time>' . esc_attr( stripslashes( $current_time ) ) . '</time>';

			$outstr .= '</ticker>';

			if ( $ticker_obj->transient_expiration > 0 ) {
				set_transient( 'daextlnl_ticker_' . $ticker_obj->id, $outstr, $ticker_obj->transient_expiration );
			}
		}

		echo $outstr;

		die();
	}

	/**
	 * Retrieve the "Sliding News Color", the "Sliding News Color Hover, and the "Sliding News Background Color" from
	 * the tickers to initialize the values of the three fields in the "Sliding News" menu.
	 *
	 * @return void
	 */
	public function update_default_colors() {

		// check the referer.
		check_ajax_referer( 'live-news', 'security' );

		// check the capability.
		if ( ! current_user_can( get_option( $this->shared->get( 'slug' ) . '_sliding_menu_capability' ) ) ) {
			die();}

		// get the missing word id.
		$ticker_id = intval( $_POST['ticker_id'], 10 );

		// get the ticker data.
		global $wpdb;
		$table_name = $wpdb->prefix . $this->shared->get( 'slug' ) . '_tickers';
		$safe_sql   = $wpdb->prepare( "SELECT sliding_news_color, sliding_news_color_hover, sliding_news_background_color FROM $table_name WHERE id = %d ", $ticker_id );
		$ticker_obj = $wpdb->get_row( $safe_sql );

		// remove the slashes before sending the json response.
		$response                                = new stdClass();
		$response->sliding_news_color            = stripslashes( $ticker_obj->sliding_news_color );
		$response->sliding_news_color_hover      = stripslashes( $ticker_obj->sliding_news_color_hover );
		$response->sliding_news_background_color = stripslashes( $ticker_obj->sliding_news_background_color );

		// return the data with json.
		echo json_encode( $response );

		die();
	}
}
init.php000064400000003455151213253550006231 0ustar00<?php
/**
 * Plugin Name: Live News
 * Description: The Live News plugin generates a fixed news ticker that you can use to communicate the latest news, financial news, weather warnings, election results, sports results, etc. (Lite version)
 * Version: 1.08
 * Author: DAEXT
 * Author URI: https://daext.com
 * Text Domain: live-news-lite
 *
 * @package live-news-lite
 */

// Prevent direct access to this file.
if ( ! defined( 'WPINC' ) ) {
	die(); }

// Class shared across public and admin.
require_once plugin_dir_path( __FILE__ ) . 'shared/class-daextlnl-shared.php';

// Public.
require_once plugin_dir_path( __FILE__ ) . 'public/class-daextlnl-public.php';
add_action( 'plugins_loaded', array( 'Daextlnl_Public', 'get_instance' ) );

//Admin
if ( is_admin() ) {

	require_once( plugin_dir_path( __FILE__ ) . 'admin/class-daextlnl-admin.php' );

	// If this is not an AJAX request, create a new singleton instance of the admin class.
	if(! defined( 'DOING_AJAX' ) || ! DOING_AJAX ){
		add_action( 'plugins_loaded', array( 'Daextlnl_Admin', 'get_instance' ) );
	}

	// Activate the plugin using only the class static methods.
	register_activation_hook( __FILE__, array( 'Daextlnl_Admin', 'ac_activate' ) );

}

// Ajax.
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {

	// Admin.
	require_once plugin_dir_path( __FILE__ ) . 'class-daextlnl-ajax.php';
	add_action( 'plugins_loaded', array( 'Daextlnl_Ajax', 'get_instance' ) );

}

/**
 * Customize the action links in the "Plugins" menu.
 *
 * @param $actions
 *
 * @return mixed
 */
function daextlnl_customize_action_links( $actions ) {
	$actions[] = '<a href="https://daext.com/live-news/">' . esc_html__( 'Buy the Pro Version', 'live-news-lite' ) . '</a>';
	return $actions;
}
add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'daextlnl_customize_action_links' );
readme.txt000064400000016476151213253550006562 0ustar00=== Live News ===
Contributors: DAEXT
Tags: news ticker, ticker, news, live, live news ticker, news scroller, television news ticker, digital signage, television, breaking news, scrolling text, breaking news ticker
Donate link: https://daext.com
Requires at least: 5.0
Tested up to: 6.5
Requires PHP: 7.2
Stable tag: 1.08
License: GPLv3

The Live News Lite plugin generates a fixed news ticker that you can use to communicate the latest news, financial news, weather warnings, election results, sports results, etc.

== Description ==
The Live News Lite plugin generates a fixed news ticker that you can use to communicate the latest news, financial news, weather warnings, election results, sports results, etc.

By default, the news ticker includes a **Featured News** section in red and a **Sliding News** in black, and it's similar to the ones used by networks like Fox News, CNN, Sky News, etc.

In terms of content, the news should be manually added by the website administrator or by users that belong to other configured roles.

### Pro Version

The [Pro Version](https://daext.com/live-news/) of this plugin, allows you to:

* Automatically generate news based on the posts
* Automatically generate the news based on a specified RSS feed (E.g., Your own RSS feed, the RSS feed of a tv channel, the RSS feed of a radio station.)
* Automatically generate the news based on a specified Twitter account
* Control the speed and the delay of the sliding news with advanced options of the news ticker

#### Features

This plugin is highly customizable and comes with 46 options per news ticker, 4 options per featured news, 9 options per sliding news, and 4 general options.

#### Customizable Style

All the elements displayed in the news ticker are customizable in terms of colors and typography. The images used to represent the open and close buttons and the clock background are replaceable with your custom images.

#### Links in the News Ticker

You can optionally apply links to the news and open them in the same tab or new tabs based on your selections.

#### Applicable Globally or Only on Specific URLs

The news ticker can be applied to all the pages of your website or only to specific URLs. In case of a setup with news tickers assigned to different URLs, you can create an unlimited number of news tickers.

#### Sliding News Images

You can place small images before and after the text of the sliding news. Use this feature to display the news provider's logo, represent financial trends, categorize different types of communications, and more.

#### Clock

The news ticker has an optional clock that displays the time in a custom format defined with [Moment.js](http://momentjs.com) token.

In the plugin options, you can also decide if you want to display the server time, the user time, if you want to apply a time offset, and the frequency of the time updates.

#### Mobile Device Detection

The plugin uses the Mobile Detect Js library to detect the device of the user. The resulting value is used to display or hide the news ticker or specific news ticker elements based on the device type. This behavior is defined by the administrator in the news ticker settings.

#### Cached Cycled

The news ticker updates the news with AJAX requests at the end of each news cycle. With the **Cached Cycled** option, you can define the number of cycles per AJAX request.

#### WordPress Transients API

You can optionally store the news ticker data in a WordPress transient and limit the number of queries used to retrieve the news.

#### Support for RTL Layouts

We have included the **Enable RTL Layout** to allow the use of the plugin in RTL websites.

#### Suitable for Digital Signage Systems

You can use the plugin locally in a browser-based digital signage system.

#### Advanced Options

Advanced options to further customize the news ticker are also available:

* The **Sliding News Margin** option to define the margin between the sliding news
* The **Sliding News Padding** option determines the padding on the left and the right of each sliding news. This option is also helpful to control the distance between the sliding news text and the optional images.
* Control the opacity of the news ticker with the **Featured News Background Color Opacity** and the **Sliding News Background Color Opacity** options
* And more.

### Documentation

For more information on how to implement this plugin, please see the [plugin documentation](https://daext.com/doc/live-news/) published on our website.

### Credits

This plugin makes use of the following resources:

* [Mobile Detect JS](https://github.com/hgoebl/mobile-detect.js) licensed under the [MIT License](http://www.opensource.org/licenses/mit-license.php)
* [Moment.js](http://momentjs.com) licensed under the [MIT License](http://www.opensource.org/licenses/mit-license.php)
* [Chosen](https://github.com/harvesthq/chosen) licensed under the [MIT License](http://www.opensource.org/licenses/mit-license.php)

== Installation ==
= Installation (Single Site) =

With this procedure you will be able to install the Live News Lite plugin on your WordPress website:

1. Visit the **Plugins -> Add New** menu
2. Click on the **Upload Plugin** button and select the zip file you just downloaded
3. Click on **Install Now**
4. Click on **Activate Plugin**

= Installation (Multisite) =

This plugin supports both a **Network Activation** (the plugin will be activated on all the sites of your WordPress Network) and a **Single Site Activation** in a **WordPress Network** environment (your plugin will be activated on a single site of the network).

With this procedure you will be able to perform a **Network Activation**:

1. Visit the **Plugins -> Add New** menu
2. Click on the **Upload Plugin** button and select the zip file you just downloaded
3. Click on **Install Now**
4. Click on **Network Activate**

With this procedure you will be able to perform a **Single Site Activation** in a **WordPress Network** environment:

1. Visit the specific site of the **WordPress Network** where you want to install the plugin
2. Visit the **Plugins** menu
3. Click on the **Activate** button (just below the name of the plugin)

== Changelog ==

= 1.08 =

*April 8, 2024*

* Fixed a bug (started with WordPress version 6.5) that prevented the creation of the plugin database tables and the initialization of the plugin options during the plugin activation.

= 1.07 =

*October 24, 2023*

* Nonce fields have been added to the "Tickers", "Featured News", and "Sliding News" menus.
* Fixed PHP warnings.
* General refactoring. The phpcs "WordPress-Core" ruleset has been partially applied to the plugin code.

= 1.06 =

*August 29, 2023*

* Minor back-end CSS fixes.
* Menu footer links added.

= 1.05 =

*August 03, 2022*

* The "Cached Cycles" ticker option is now properly used in the front-end scripts. This change solves a bug that prevented the news from being updated at the end of the cycles.
* The translation functions text domain now matches the plugin slug.
* The "Export to Pro" menu has been added.
* The links to the Pro version have been updated with the new Pro version page.
* Minor back-end improvements.

= 1.03 =

*March 19, 2022*

* Plugin renamed to "Live News".
* Improved validation and escaping in the back-end menus.

= 1.02 =

*May 6, 2021*

* Initial release.

== Screenshots ==
1. News Tickers menu
2. Featured News menu
3. Sliding News menu
4. Options menu
5. News ticker in the front-endshared/class-daextlnl-shared.php000064400000025055151213253550012716 0ustar00<?php
/**
 * The Shared class is used to stores properties and methods shared by the admin and public side of WordPress.
 *
 * @package live-news-lite
 */

/**
 * this class should be used to stores properties and methods shared by the
 * admin and public side of WordPress
 */
class Daextlnl_Shared {


	// regex.
	public $hex_rgb_regex     = '/^#(?:[0-9a-fA-F]{3}){1,2}$/';
	public $font_family_regex = '/^([A-Za-z0-9-\'", ]*)$/';

	protected static $instance = null;

	private $data = array();

	private function __construct() {

		// Set plugin textdomain.
		load_plugin_textdomain( 'live-news-lite', false, 'live-news-lite/lang/' );

		$this->data['slug']        = 'daextlnl';
		$this->data['ver']         = '1.08';
		$this->data['dir']         = substr( plugin_dir_path( __FILE__ ), 0, -7 );
		$this->data['url']         = substr( plugin_dir_url( __FILE__ ), 0, -7 );
		$this->data['text_domain'] = 'live-news-lite';
	}

	public static function get_instance() {

		if ( null == self::$instance ) {
			self::$instance = new self();
		}

		return self::$instance;
	}

	// retrieve data.
	public function get( $index ) {
		return $this->data[ $index ];
	}

	/**
	 * Convert a numeric target to a textual target
	 *
	 * @param $target_id int
	 *
	 * @return string|void|null
	 */
	public function get_textual_target( $target_id ) {

		switch ( $target_id ) {

			case 1:
				return __( 'Website', $this->get( 'text_domain' ) );
				break;

			case 2:
				return __( 'URL', $this->get( 'text_domain' ) );
				break;

		}
	}

	/**
	 * Retrieve the ticker name from the ticker id
	 *
	 * @param $ticker_id int
	 *
	 * @return string|null
	 */
	public function get_textual_ticker( $ticker_id ) {

		global $wpdb;
		$table_name = $wpdb->prefix . $this->get( 'slug' ) . '_tickers';
		$safe_sql   = $wpdb->prepare( "SELECT name FROM $table_name WHERE id = %d ", $ticker_id );
		$ticker_obj = $wpdb->get_row( $safe_sql );

		if ( $ticker_obj !== null ) {
			return $ticker_obj->name;
		} else {
			return __( 'Invalid Ticker ID', $this->get( 'text_domain' ) );
		}
	}

	/**
	 * Generate a short version of a string without truncating words
	 *
	 * @param $str The string
	 * @param $length The maximum length of the string
	 * @return string The short version of the string
	 */
	public function strlen_no_truncate( $str, $length ) {

		if ( mb_strlen( $str ) > $length ) {
			$str = wordwrap( $str, $length );
			$str = mb_substr( $str, 0, mb_strpos( $str, "\n" ) );
			$str = $str . ' ...';
		}

		return $str;
	}

	/**
	 * Returns true if the ticker is used in sliding news or in featured news
	 *
	 * @param $ticker_id int
	 * @return bool True if the ticker is used or False if the ticker is not used
	 */
	public function ticker_is_used( $ticker_id ) {

		global $wpdb;

		// verify if the ticker is used in the featured news
		$table_name     = $wpdb->prefix . $this->get( 'slug' ) . '_featured_news';
		$safe_sql       = $wpdb->prepare( "SELECT COUNT(*) FROM $table_name WHERE ticker_id = %d", $ticker_id );
		$number_of_uses = $wpdb->get_var( $safe_sql );
		if ( $number_of_uses > 0 ) {
			return true;}

		// verify if the ticker is used in the sliding news
		$table_name     = $wpdb->prefix . $this->get( 'slug' ) . '_sliding_news';
		$safe_sql       = $wpdb->prepare( "SELECT COUNT(*) FROM $table_name WHERE ticker_id = %d", $ticker_id );
		$number_of_uses = $wpdb->get_var( $safe_sql );
		if ( $number_of_uses > 0 ) {
			return true;}

		return false;
	}

	/**
	 * Given a ticker id returns true if the ticker exists or false if the ticker doesn't exist
	 *
	 * @param $ticker_id int
	 * @return bool True if the ticker exists or False if the ticker doesn't exists
	 */
	public function ticker_exists( $ticker_id ) {

		global $wpdb;

		$table_name = $wpdb->prefix . $this->get( 'slug' ) . '_tickers';
		$safe_sql   = $wpdb->prepare( "SELECT * FROM $table_name WHERE id = %d", $ticker_id );
		$ticker_obj = $wpdb->get_row( $safe_sql );
		if ( $ticker_obj !== null ) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Given a hexadecimal rgb color an array with the 3 components converted in decimal is returned
	 *
	 * @param string The hexadecimal rgb color
	 * @return array An array with the 3 component of the color converted in decimal
	 */
	public function rgb_hex_to_dec( $hex ) {

		if ( mb_strlen( $hex ) == 3 ) {
			$r = hexdec( substr( $hex, 0, 1 ) . substr( $hex, 0, 1 ) );
			$g = hexdec( substr( $hex, 1, 1 ) . substr( $hex, 1, 1 ) );
			$b = hexdec( substr( $hex, 2, 1 ) . substr( $hex, 2, 1 ) );
		} else {
			$r = hexdec( substr( $hex, 0, 2 ) );
			$g = hexdec( substr( $hex, 2, 2 ) );
			$b = hexdec( substr( $hex, 4, 2 ) );
		}

		return array(
			'r' => $r,
			'g' => $g,
			'b' => $b,
		);
	}

	/**
	 * Get the number of tickers
	 *
	 * @return int The number of tickers
	 */
	public function get_number_of_tickers() {

		global $wpdb;
		$table_name        = $wpdb->prefix . $this->get( 'slug' ) . '_tickers';
		$number_of_tickers = $wpdb->get_var( "SELECT COUNT(*) FROM $table_name" );

		return $number_of_tickers;
	}

	/**
	 * Get the number of featured news
	 *
	 * @return int The number of featured news
	 */
	public function get_number_of_featured_news() {

		global $wpdb;
		$table_name              = $wpdb->prefix . $this->get( 'slug' ) . '_featured_news';
		$number_of_featured_news = $wpdb->get_var( "SELECT COUNT(*) FROM $table_name" );

		return $number_of_featured_news;
	}

	/*
	 * Get the number of sliding news
	 *
	 * @return int The number of sliding news
	 */
	public function get_number_of_sliding_news() {

		global $wpdb;
		$table_name             = $wpdb->prefix . $this->get( 'slug' ) . '_sliding_news';
		$number_of_sliding_news = $wpdb->get_var( "SELECT COUNT(*) FROM $table_name" );

		return $number_of_sliding_news;
	}

	/**
	 * Get the current URL with the method specified with the "Detect URL Mode" option
	 */
	public function get_current_url() {

		if ( get_option( $this->get( 'slug' ) . '_detect_url_mode' ) === 'server_variable' ) {

			// Detect the URL using the "Server Variable" method
			return is_ssl() ? 'https' : 'http' . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];

		} else {

			// Detect the URL using the "WP Request" method
			global $wp;
			return trailingslashit( home_url( add_query_arg( array(), $wp->request ) ) );

		}
	}

	/**
	 * Returns the object of the first ticker with the target equal to 2 (url) that can be displayed with the current
	 * url.
	 *
	 * Note that to determine if a ticker can be displayed with the current url the following fields are considered:
	 *
	 * - Target
	 * - Target URL
	 * - Target URL Mode
	 *
	 * @param $current_url The url that should be searched in the target url field of the tickers
	 * @return mixed The object with the data of the news ticker of false.
	 */
	public function get_ticker_with_target_url( $current_url ) {

		$found      = false;
		$ticker_id  = null;
		$ticker_obj = false;

		global $wpdb;
		$table_name = $wpdb->prefix . $this->get( 'slug' ) . '_tickers';
		$safe_sql   = "SELECT * FROM $table_name WHERE target = 2 ORDER BY id ASC";
		$ticker_a   = $wpdb->get_results( $safe_sql, ARRAY_A );

		foreach ( $ticker_a as $key => $ticker ) {

			$url_a = preg_split( '/\r\n|[\r\n]/', $ticker['url'] );

			if ( intval( $ticker['url_mode'], 10 ) === 0 ) {

				// Include.

				// Get the ticker_id of the first news ticker that includes the current url.
				if ( $ticker_id !== null ) {
					break;
				}

				foreach ( $url_a as $key2 => $url ) {
					if ( $url === $current_url ) {
						$found = true;
					}
				}

				if ( $found ) {
					$ticker_id = $ticker['id'];
					break;
				}
			} else {

				// Exclude.

				// Get the ticker_id of the first news ticker that doesn't include the current url.
				foreach ( $url_a as $key2 => $url ) {
					if ( $url === $current_url ) {
						$found = true;
					}
				}

				if ( ! $found ) {
					$ticker_id = $ticker['id'];
					break;
				}
			}
		}

		// Get the object of the news ticker that includes the current url.
		if ( $ticker_id !== null ) {
			global $wpdb;
			$table_name = $wpdb->prefix . $this->get( 'slug' ) . '_tickers';
			$safe_sql   = $wpdb->prepare( "SELECT * FROM $table_name WHERE id = %d", $ticker_id );
			$ticker_obj = $wpdb->get_row( $safe_sql );
		}

		return $ticker_obj;
	}

	/**
	 * Generates the XML version of the data of the table.
	 *
	 * @param db_table_name The name of the db table without the prefix.
	 * @param db_table_primary_key The name of the primary key of the table
	 * @return String The XML version of the data of the db table
	 */
	public function convert_db_table_to_xml( $db_table_name, $db_table_primary_key ) {

		$out = '';

		// Get the data from the db table.
		global $wpdb;
		$table_name = $wpdb->prefix . $this->get( 'slug' ) . "_$db_table_name";
		$data_a     = $wpdb->get_results( "SELECT * FROM $table_name ORDER BY $db_table_primary_key ASC", ARRAY_A );

		// Generate the data of the db table.
		foreach ( $data_a as $record ) {

			$out .= "<$db_table_name>";

			// Get all the indexes of the $data array.
			$record_keys = array_keys( $record );

			// Cycle through all the indexes of the single record and create all the XML tags.
			foreach ( $record_keys as $key ) {
				$out .= '<' . $key . '>' . esc_attr( $record[ $key ] ) . '</' . $key . '>';
			}

			$out .= "</$db_table_name>";

		}

		return $out;
	}

	/**
	 * Objects as a value are set to empty strings. This prevent generating notices with the methods of the wpdb class.
	 *
	 * @param $data An array which includes objects that should be converted to a empty strings.
	 * @return string An array where the objects have been replaced with empty strings.
	 */
	public function replace_objects_with_empty_strings( $data ) {

		foreach ( $data as $key => $value ) {
			if ( gettype( $value ) === 'object' ) {
				$data[ $key ] = '';
			}
		}

		return $data;
	}


	/**
	 * Verifies the number of records available in the database tables of the plugin. If there is at least one record
	 * returns true. Otherwise, returns false.
	 *
	 * @return bool
	 */
	public function plugin_has_data() {

		global $wpdb;

		$table_name    = $wpdb->prefix . $this->get( 'slug' ) . '_tickers';
		$tickers_items = $wpdb->get_var( "SELECT COUNT(*) FROM $table_name" );

		$table_name    = $wpdb->prefix . $this->get( 'slug' ) . '_featured_news';
		$featured_news = $wpdb->get_var( "SELECT COUNT(*) FROM $table_name" );

		$table_name   = $wpdb->prefix . $this->get( 'slug' ) . '_sliding_news';
		$sliding_news = $wpdb->get_var( "SELECT COUNT(*) FROM $table_name" );

		$total_items = intval( $tickers_items, 10 ) +
			intval( $featured_news, 10 ) +
			intval( $sliding_news, 10 );

		if ( $total_items > 0 ) {
			return true;
		} else {
			return false;
		}
	}
}
uninstall.php000064400000000613151213253550007270 0ustar00<?php
/**
 * Uninstall Live News Lite.
 *
 * @package live-news-lite
 */

// exit if this file is called outside WordPress.
if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
	die(); }

require_once plugin_dir_path( __FILE__ ) . 'shared/class-daextlnl-shared.php';
require_once plugin_dir_path( __FILE__ ) . 'admin/class-daextlnl-admin.php';

// delete options and tables.
Daextlnl_Admin::un_delete();

F1le Man4ger