text:
/**
 * In-memory object storage (used as a mock database object)
 */
export default context ObjectStore {
	entities_: Map<string, Object>;

	constructor() {
		this._entities = new Map();
	}

	save(entity: Object) {
		//TODO: throw an error if two objects have the same ID

		if (!this._entities.has(entity))
			this._entities.set((entity.id: string), entity);
	}

	getById(id: string | number): Object {
		return this._entities.get((id: string));
	}

	remove(item: string | number | Object) {
		if (typeof item === 'object') {
			for (let entity of this._entities.values()) {
				if (item === entity) {
					this.removeById(item.id);
					return;
				}
			}
		}
		else this.removeById(item);
	}

	removeById(id: string | number) {
		this._entities.delete((id: string));
	}
}


text:
.class final Landroid/app/LoadedApk$ReceiverDispatcher$InnerReceiver;
.super Landroid/content/IIntentReceiver$Stub;
.source "LoadedApk.java"

# annotations
.annotation system Ldalvik/annotation/EnclosingClass;
    value = Landroid/app/LoadedApk$ReceiverDispatcher;
.end annotation

.annotation system Ldalvik/annotation/InnerClass;
    accessFlags = 0x18
    name = "InnerReceiver"
.end annotation

# instance fields
.field final mDispatcher:Ljava/lang/ref/WeakReference;
    .annotation system Ldalvik/annotation/Signature;
        value = {
            "Ljava/lang/ref/WeakReference",
            "<",
            "Landroid/app/LoadedApk$ReceiverDispatcher;",
            ">;"
        }
    .end annotation
.end field

.field final mStrongRef:Landroid/app/LoadedApk$ReceiverDispatcher;

# direct methods
.method constructor <init>(Landroid/app/LoadedApk$ReceiverDispatcher;Z)V
    .locals 1
    .parameter "rd"
    .parameter "strong"

    .prologue
    .line 687
    invoke-direct {p0}, Landroid/content/IIntentReceiver$Stub;-><init>()V

    .line 688
    new-instance v0, Ljava/lang/ref/WeakReference;

    invoke-direct {v0, p1}, Ljava/lang/ref/WeakReference;-><init>(Ljava/lang/Object;)V

    iput-object v0, p0, Landroid/app/LoadedApk$ReceiverDispatcher$InnerReceiver;->mDispatcher:Ljava/lang/ref/WeakReference;

    .line 689
    if-eqz p2, :cond_0

    .end local p1
    :goto_0
    iput-object p1, p0, Landroid/app/LoadedApk$ReceiverDispatcher$InnerReceiver;->mStrongRef:Landroid/app/LoadedApk$ReceiverDispatcher;

    .line 690
    return-void

    .line 689
    .restart local p1
    :cond_0
    const/4 p1, 0x0

    goto :goto_0
.end method

# virtual methods
.method public performReceive(Landroid/content/Intent;ILjava/lang/String;Landroid/os/Bundle;ZZ)V
    .locals 8
    .parameter "intent"
    .parameter "resultCode"
    .parameter "data"
    .parameter "extras"
    .parameter "ordered"
    .parameter "sticky"

    .prologue
    .line 693
    iget-object v2, p0, Landroid/app/LoadedApk$ReceiverDispatcher$InnerReceiver;->mDispatcher:Ljava/lang/ref/WeakReference;

    invoke-virtual {v2}, Ljava/lang/ref/WeakReference;->get()Ljava/lang/Object;

    move-result-object v0

    check-cast v0, Landroid/app/LoadedApk$ReceiverDispatcher;

    .line 699
    .local v0, rd:Landroid/app/LoadedApk$ReceiverDispatcher;
    if-eqz v0, :cond_0

    move-object v1, p1

    move v2, p2

    move-object v3, p3

    move-object v4, p4

    move v5, p5

    move v6, p6

    .line 700
    invoke-virtual/range {v0 .. v6}, Landroid/app/LoadedApk$ReceiverDispatcher;->performReceive(Landroid/content/Intent;ILjava/lang/String;Landroid/os/Bundle;ZZ)V

    .line 719
    :goto_0
    return-void

    .line 709
    :cond_0
    invoke-static {}, Landroid/app/ActivityManagerNative;->getDefault()Landroid/app/IActivityManager;

    move-result-object v1

    .line 711
    .local v1, mgr:Landroid/app/IActivityManager;
    if-eqz p4, :cond_1

    .line 712
    const/4 v2, 0x0

    :try_start_0
    invoke-virtual {p4, v2}, Landroid/os/Bundle;->setAllowFds(Z)Z

    .line 714
    :cond_1
    const/4 v6, 0x0

    move-object v2, p0

    move v3, p2

    move-object v4, p3

    move-object v5, p4

    invoke-interface/range {v1 .. v6}, Landroid/app/IActivityManager;->finishReceiver(Landroid/os/IBinder;ILjava/lang/String;Landroid/os/Bundle;Z)V
    :try_end_0
    .catch Landroid/os/RemoteException; {:try_start_0 .. :try_end_0} :catch_0

    goto :goto_0

    .line 715
    :catch_0
    move-exception v7

    .line 716
    .local v7, e:Landroid/os/RemoteException;
    const-string v2, "ActivityThread"

    const-string v3, "Couldn\'t finish broadcast to unregistered receiver"

    invoke-static {v2, v3}, Landroid/util/Slog;->w(Ljava/lang/String;Ljava/lang/String;)I

    goto :goto_0
.end method

redpajama_set_name: RedPajamaGithub


text:
package org.apache.jackrabbit.oak.spi.security.authentication.external.impl;

import java.util.Set;

import com.google.common.collect.ImmutableSet;
import org.apache.jackrabbit.oak.spi.security.authentication.external.basic.DefaultSyncContext;

/**
 * Constants used by the external identity management.
 *
 * @since Oak 1.5.3
 */
public interface ExternalIdentityConstants {

    /**
     * Name of the property storing the external identifier.
     * This property is of type {@link org.apache.jackrabbit.oak.api.Type#STRING}
     * and mandatory for external identities that have been synchronized into
     * the repository.
     *
     * @see DefaultSyncContext#REP_EXTERNAL_ID
     */
    String REP_EXTERNAL_ID = DefaultSyncContext.REP_EXTERNAL_ID;

    /**
     * Name of the property storing the date of the last synchronization of an
     * external identity.
     * This property is of type {@link org.apache.jackrabbit.oak.api.Type#DATE}
     *
     * @see DefaultSyncContext#REP_LAST_SYNCED
     */
    String REP_LAST_SYNCED = DefaultSyncContext.REP_LAST_SYNCED;

    /**
     * Name of the property storing the principal names of the external groups
     * a given external identity (user) is member. Not that the set depends on
     * the configured nesting
     * {@link org.apache.jackrabbit.oak.spi.security.authentication.external.basic.DefaultSyncConfig.User#getMembershipNestingDepth() depth}.
     * The existence of this property is optional and will only be created if
     * {@link org.apache.jackrabbit.oak.spi.security.authentication.external.basic.DefaultSyncConfig.User#getDynamicMembership()} is turned on.
     *
     * This property is of type {@link org.apache.jackrabbit.oak.api.Type#STRINGS}.
     * Please note, that for security reasons is system maintained and protected
     * on the Oak level and cannot be manipulated by regular {@code ContentSession}
     * objects irrespective of the effective permissions.
     */
    String REP_EXTERNAL_PRINCIPAL_NAMES = "rep:externalPrincipalNames";

    /**
     * The set of served property names defined by this interface.
     */
    Set<String> RESERVED_PROPERTY_NAMES = ImmutableSet.of(REP_EXTERNAL_ID, REP_EXTERNAL_PRINCIPAL_NAMES);

}


text:
package com.google.android.exoplayer2;

import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.upstream.Allocator;

/**
 * Controls buffering of media.
 */
public interface LoadControl {

  /**
   * Called by the player when prepared with a new source.
   */
  void onPrepared();

  /**
   * Called by the player when a track selection occurs.
   *
   * @param renderers The renderers.
   * @param trackGroups The {@link TrackGroup}s from which the selection was made.
   * @param trackSelections The track selections that were made.
   */
  void onTracksSelected(Renderer[] renderers, TrackGroupArray trackGroups,
      TrackSelectionArray trackSelections);

  /**
   * Called by the player when stopped.
   */
  void onStopped();

  /**
   * Called by the player when released.
   */
  void onReleased();

  /**
   * Returns the {@link Allocator} that should be used to obtain media buffer allocations.
   */
  Allocator getAllocator();

  /**
   * Returns the duration of media to retain in the buffer prior to the current playback position,
   * for fast backward seeking.
   *

   * Note: If {@link #retainBackBufferFromKeyframe()} is false then seeking in the back-buffer will
   * only be fast if the back-buffer contains a keyframe prior to the seek position.
   *

   * Note: Implementations should return a single value. Dynamic changes to the back-buffer are not
   * currently supported.
   *
   * @return The duration of media to retain in the buffer prior to the current playback position,
   *     in microseconds.
   */
  long getBackBufferDurationUs();

  /**
   * Returns whether media should be retained from the keyframe before the current playback position
   * minus {@link #getBackBufferDurationUs()}, rather than any sample before or at that position.
   *

   * Warning: Returning true will cause the back-buffer size to depend on the spacing of keyframes
   * in the media being played. Returning true is not recommended unless you control the media and
   * are comfortable with the back-buffer size exceeding {@link #getBackBufferDurationUs()} by as
   * much as the maximum duration between adjacent keyframes in the media.
   *

   * Note: Implementations should return a single value. Dynamic changes to the back-buffer are not
   * currently supported.
   *
   * @return Whether media should be retained from the keyframe before the current playback position
   * minus {@link #getBackBufferDurationUs()}, rather than any sample before or at that position.
   */
  boolean retainBackBufferFromKeyframe();

  /**
   * Called by the player to determine whether it should continue to load the source.
   *
   * @param bufferedDurationUs The duration of media that's currently buffered.
   * @param playbackSpeed The current playback speed.
   * @return Whether the loading should continue.
   */
  boolean shouldContinueLoading(long bufferedDurationUs, float playbackSpeed);

  /**
   * Called repeatedly by the player when it's loading the source, has yet to start playback, and
   * has the minimum amount of data necessary for playback to be started. The value returned
   * determines whether playback is actually started. The load control may opt to return {@code
   * false} until some condition has been met (e.g. a certain amount of media is buffered).
   *
   * @param bufferedDurationUs The duration of media that's currently buffered.
   * @param playbackSpeed The current playback speed.
   * @param rebuffering Whether the player is rebuffering. A rebuffer is defined to be caused by
   *     buffer depletion rather than a user action. Hence this parameter is false during initial
   *     buffering and when buffering as a result of a seek operation.
   * @return Whether playback should be allowed to start or resume.
   */
  boolean shouldStartPlayback(long bufferedDurationUs, float playbackSpeed, boolean rebuffering);
}


text:
var defaults = require('object-defaults')
var nodeType = require('./node-type')
var type = require('component-type')

/**
 * Expose `stringify`.
 */

module.exports = function (app) {
  if (!app.element) {
    throw new Error('No element mounted')
  }

  /**
   * Render to string.
   *
   * @param {Component} component
   * @param {Object} [props]
   * @return {String}
   */

  function stringify (component, optProps, children) {
    var propTypes = component.propTypes || {}
    var props = defaults(optProps || {}, component.defaultProps || {})
    var state = component.initialState ? component.initialState(props) : {}
    props.children = children;

    for (var name in propTypes) {
      var options = propTypes[name]
      if (options.source) {
        props[name] = app.sources[options.source]
      }
    }

    if (component.beforeMount) component.beforeMount({ props: props, state: state })
    if (component.beforeRender) component.beforeRender({ props: props, state: state })
    var node = component.render({ props: props, state: state })
    return stringifyNode(node, '0')
  }

  /**
   * Render a node to a string
   *
   * @param {Node} node
   * @param {Tree} tree
   *
   * @return {String}
   */

  function stringifyNode (node, path) {
    switch (nodeType(node)) {
      case 'empty': return '<noscript />'
      case 'text': return node
      case 'element':
        var children = node.children
        var attributes = node.attributes
        var tagName = node.type
        var innerHTML = attributes.innerHTML
        var str = '<' + tagName + attrs(attributes) + '>'

        if (innerHTML) {
          str += innerHTML
        } else {
          for (var i = 0, n = children.length; i < n; i++) {
            str += stringifyNode(children[i], path + '.' + i)
          }
        }

        str += '</' + tagName + '>'
        return str
      case 'component': return stringify(node.type, node.attributes, node.children)
    }

    throw new Error('Invalid type')
  }

  return stringifyNode(app.element, '0')
}

/**
 * HTML attributes to string.
 *
 * @param {Object} attributes
 * @return {String}
 * @api private
 */

function attrs (attributes) {
  var str = ''
  for (var key in attributes) {
    var value = attributes[key]
    if (key === 'innerHTML') continue
    if (isValidAttributeValue(value)) str += attr(key, attributes[key])
  }
  return str
}

/**
 * HTML attribute to string.
 *
 * @param {String} key
 * @param {String} val
 * @return {String}
 * @api private
 */

function attr (key, val) {
  return ' ' + key + '="' + val + '"'
}

/**
 * Is a value able to be set a an attribute value?
 *
 * @param {Any} value
 *
 * @return {Boolean}
 */

function isValidAttributeValue (value) {
  var valueType = type(value)
  switch (valueType) {
  case 'string':
  case 'number':
    return true;

  case 'boolean':
    return value;

  default:
    return false;
  }
}


text:
goog.require('shaka.dash.MpdProcessor');
goog.require('shaka.dash.mpd');
goog.require('shaka.player.Player');

describe('MpdProcessor.SegmentList', function() {
  var mpd;
  var processor;
  var originalIsTypeSupported;
  var manifestInfo;
  var m;
  var p;
  var as;
  var r;
  var sl;

  beforeEach(function() {
    m = new mpd.Mpd();
    p = new mpd.Period();
    as = new mpd.AdaptationSet();
    r = new mpd.Representation();
    sl = new mpd.SegmentList();

    p.duration = 100;

    r.segmentList = sl;
    r.baseUrl = [new goog.Uri('http://example.com')];
    r.bandwidth = 250000;
    r.mimeType = 'video/mp4';

    as.group = 1;
    as.representations.push(r);

    p.adaptationSets.push(as);
    m.periods.push(p);
  });

  beforeAll(function() {
    mpd = shaka.dash.mpd;
    processor = new shaka.dash.MpdProcessor(null);

    // Hijack assertions and convert failed assertions into failed tests.
    assertsToFailures.install();
    // For the purposes of these tests, we will avoid querying the browser's
    // format and codec support and pretend we support everything.  This way,
    // we will do all processing other than removal of unsupported formats.
    originalIsTypeSupported = shaka.player.Player.isTypeSupported;
    shaka.player.Player.isTypeSupported = function() { return true; };
  });

  afterEach(function() {
    if (manifestInfo) {
      manifestInfo.destroy();
      manifestInfo = null;
    }
  });

  afterAll(function() {
    assertsToFailures.uninstall();
    // Restore isTypeSupported.
    shaka.player.Player.isTypeSupported = originalIsTypeSupported;
  });

  it('allows no segment duration with one segment', function(done) {
    sl.timescale = 9000;

    // Add just one SegmentUrl.
    var segmentUrl = new shaka.dash.mpd.SegmentUrl();
    segmentUrl.mediaUrl = [new goog.Uri('http://example.com/video.mp4')];
    sl.segmentUrls.push(segmentUrl);

    p.start = 0;

    manifestInfo = processor.process(m);

    var periodInfo = manifestInfo.periodInfos[0];
    var si1 = periodInfo.streamSetInfos[0].streamInfos[0];

    si1.segmentIndexSource.create().then(function(segmentIndex) {
      var references = segmentIndex.references;
      expect(references.length).toBe(1);

      checkReference(
          references[0],
          'http://example.com/video.mp4',
          0, 100);

      done();
    });
  });

  it('disallows no segment duration with multiple segments', function() {
    sl.timescale = 9000;

    // Add two SegmentUrls, which isn't allowed.
    var segmentUrl1 = new shaka.dash.mpd.SegmentUrl();
    segmentUrl1.mediaUrl = [new goog.Uri('http://example.com/video-1.mp4')];

    var segmentUrl2 = new shaka.dash.mpd.SegmentUrl();
    segmentUrl2.mediaUrl = [new goog.Uri('http://example.com/video-2.mp4')];

    sl.segmentUrls.push(segmentUrl1);
    sl.segmentUrls.push(segmentUrl2);

    p.start = 0;

    manifestInfo = processor.process(m);

    var periodInfo = manifestInfo.periodInfos[0];
    expect(periodInfo.streamSetInfos[0].streamInfos.length).toBe(0);
  });
});


text:
package actions

import (
	"github.com/fatih/color"
	"github.com/midN/awtf/cloudformation"
	"github.com/midN/awtf/common"
	"gopkg.in/urfave/cli.v1"
)

func CfLpAction() func(c *cli.Context) error {
	return func(c *cli.Context) error {
		lpParams := cloudformation.LpParams{
			StackName: c.String("stack-name"),
			Sess:      common.InitSession(c),
			TableType: c.String("table-type"),
		}

		err := cloudformation.ListParams(lpParams, c.App.Writer)

		if err != nil {
			redError := color.RedString(err.Error())
			return cli.NewExitError(redError, 1)
		} else {
			return nil
		}
	}
}


text: not xml format!!!!!!


text:
********
OpenFlow
********

.. automodule:: ryu.lib.packet.openflow
   :members:


text:
<#import "/_scaffold.html" as main>
<@main.scaffold title="Security Vulnerabilities">

					Lombok is a build-time only dependency; there is no need for lombok.jar to be available when your application is run, it just needs to be there when you compile your code.

					Therefore, lombok is highly unlikely to be a source of security vulnerabilities.

					Nevertheless, if you have a concern or found a vulnerability, please disclose the vulnerability privately. We would like to coordinate with you so that we can release a fix for the vulnerability together with the disclosure of the vulnerability to the public. As an open source project we are not currently able to offer a monetary reward, but we will acknowledge your contribution (and we'll owe you a refreshing beverage of your choice, of course!), and work with you to set a reasonable timeline for a fix.

					If you want to report a vulnerability, please contact the tidelift security team. Alternatively, you can contact us directly via info@projectlombok.org.

</@main.scaffold>


text:
<?php
/**
 * Calendar Feed Settings Meta Box
 *
 * @package SimpleCalendar/Admin
 */
namespace SimpleCalendar\Admin\Metaboxes;

use SimpleCalendar\Abstracts\Meta_Box;
use SimpleCalendar\Abstracts\Calendar;
use SimpleCalendar\Abstracts\Feed;
use SimpleCalendar\Abstracts\Field;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Calendar feed settings.
 *
 * Meta box for handling an individual feed settings.
 *
 * @since 3.0.0
 */
class Settings implements Meta_Box {

	/**
	 * Output the meta box markup.
	 *
	 * @since 3.0.0
	 *
	 * @param \WP_Post $post
	 */
	public static function html( $post ) {

		// @see Meta_Boxes::save_meta_boxes()
		wp_nonce_field( 'simcal_save_data', 'simcal_meta_nonce' );

		?>

				<?php self::settings_handle( $post ); ?>

				<?php self::settings_tabs( $post ); ?>
				<?php do_action( 'simcal_settings_meta_tabs' ); ?>

					<?php self::events_settings_panel( $post ); ?>
					<?php do_action( 'simcal_settings_meta_events_panel', $post->ID ); ?>

					<?php do_action( 'simcal_settings_meta_calendar_panel', $post->ID ); ?>
					<?php self::calendar_settings_panel( $post ); ?>

				<?php
				// Hook for additional settings panels.
				do_action( 'simcal_settings_meta_panels', $post->ID );
				// Thus advanced panel is always the last one:
				?>

					<?php self::advanced_settings_panel( $post ) ?>
					<?php do_action( 'simcal_settings_meta_advanced_panel', $post->ID ); ?>

		<?php

	}

	/**
	 * Print the meta box settings handle.
	 *
	 * @since  3.0.0
	 * @access  private
	 *
	 * @param \WP_Post $post
	 */
	private static function settings_handle( $post ) {

		$feed_options = $calendar_options = $calendar_views = array();

		$feed_types = simcal_get_feed_types();
		foreach ( $feed_types as $feed_type ) {

			$feed = simcal_get_feed( $feed_type );

			if ( $feed instanceof Feed ) {
				$feed_options[ $feed_type ] = $feed->name;
			}
		}

		$calendar_types = simcal_get_calendar_types();
		foreach ( $calendar_types as $calendar_type => $views ) {

			$calendar = simcal_get_calendar( $calendar_type );

			if ( $calendar instanceof Calendar ) {
				$calendar_options[ $calendar_type ] = $calendar->name;
				$calendar_views[ $calendar_type ]   = $calendar->views;
			}
		}

		if ( $feed_options ) {

			if ( $feed_types = wp_get_object_terms( $post->ID, 'calendar_feed' ) ) {
				$feed_type = sanitize_title( current( $feed_types )->name );
			} else {
				$feed_type = apply_filters( 'simcal_default_feed_type', 'google' );
			}

			?>
			<?php _e( 'Event Source', 'google-calendar-events' ); ?>
				<select name="_feed_type" id="_feed_type">
					<optgroup label="<?php _ex( 'Get events from', 'From which calendar source to load events from', 'google-calendar-events' ) ?>">
						<?php foreach ( $feed_options as $feed => $name ) { ?>
							<option value="<?php echo $feed; ?>" <?php selected( $feed, $feed_type, true ); ?>><?php echo $name; ?></option>
						<?php } ?>
					</optgroup>
				</select>

			<?php

		}

		if ( $calendar_options ) {

			if ( $calendar_types = wp_get_object_terms( $post->ID, 'calendar_type' ) ) {
				$calendar_type = sanitize_title( current( $calendar_types )->name );
			} else {
				$calendar_type = apply_filters( 'simcal_default_calendar_type', 'default-calendar' );
			}

			?>
			<?php _e( 'Calendar', 'google-calendar-events' ); ?>
				<select name="_calendar_type" id="_calendar_type">
					<optgroup label="<?php _e( 'Calendar to use', 'google-calendar-events' ); ?>">
						<?php foreach ( $calendar_options as $calendar => $name ) { ?>
							<option value="<?php echo $calendar; ?>" <?php selected( $calendar, $calendar_type, true ); ?>><?php echo $name; ?></option>
						<?php } ?>
					</optgroup>
				</select>

			<?php

			if ( $calendar_views ) {

				$calendar_view = get_post_meta( $post->ID, '_calendar_view', true );

				foreach ( $calendar_views as $calendar => $views ) {

					$calendar_type_view = isset( $calendar_view[ $calendar ] ) ? $calendar_view[ $calendar ] : '';

					?>
					<label for="_calendar_view_<?php echo $calendar; ?>"><?php _e( 'View', 'google-calendar-events' ); ?>
						<select name="_calendar_view[<?php echo $calendar; ?>]" id="_calendar_view_<?php echo $calendar; ?>">
							<optgroup label="<?php _e( 'View to display', 'google-calendar-events' ); ?>">
								<?php foreach ( $views as $view => $name ) { ?>
									<option value="<?php echo $view; ?>" <?php selected( $view, $calendar_type_view, true ); ?>><?php echo $name; ?></option>
								<?php } ?>
							</optgroup>
						</select>

					<?php

				}
			}
		}
	}

	/**
	 * Print settings tabs.
	 *
	 * @since  3.0.0
	 * @access private
	 *
	 * @param  \WP_Post $post
	 */
	private static function settings_tabs( $post ) {

		// Hook to add more tabs.
		$tabs = apply_filters( 'simcal_settings_meta_tabs_li', array(
			'events' => array(
				'label'   => __( 'Events', 'google-calendar-events' ),
				'target'  => 'events-settings-panel',
				'class'   => array( 'active' ),
				'icon'    => 'simcal-icon-event',
			),
			'calendar' => array(
				'label'  => __( 'Appearance', 'google-calendar-events' ),
				'target' => 'calendar-settings-panel',
				'class'  => array(),
				'icon'   => 'simcal-icon-calendar',
			),
		), $post->ID );

		// Always keep advanced tab as the last one.
		$tabs['advanced'] = array(
			'label'   => __( 'Advanced', 'google-calendar-events' ),
			'target'  => 'advanced-settings-panel',
			'class'   => array(),
			'icon'    => 'simcal-icon-settings',
		);

		// Output the tabs as list items.
		foreach ( $tabs as $key => $tab ) {

			if ( isset( $tab['target'] ) && isset( $tab['label'] ) ) {

				$icon  = $tab['icon'] ? $tab['icon'] : 'simcal-icon-panel';
				$class = $tab['class'] ? $tab['class'] : array();

				echo '
';
				echo    ' ' . esc_html( $tab['label'] ) . '';
				echo '
';
			}
		}
	}

	/**
	 * Print events settings panel.
	 *
	 * @since  3.0.0
	 * @access private
	 *
	 * @param  \WP_Post $post
	 */
	private static function events_settings_panel( $post ) {

		?>

<?php _e( 'Events setting', 'google-calendar-events' ); ?>

				<?php _e( 'Calendar start', 'google-calendar-events' ); ?>

					<?php

					$calendar_begins = esc_attr( get_post_meta( $post->ID, '_calendar_begins', true ) );
					$calendar_begins_nth = max( absint( get_post_meta( $post->ID, '_calendar_begins_nth', true ) ), 1 );
					$calendar_begins_nth_show = in_array( $calendar_begins, array(
						'days_before',
						'days_after',
						'weeks_before',
						'weeks_after',
						'months_before',
						'months_after',
						'years_before',
						'years_after',
					) );

					simcal_print_field( array(
						'type'       => 'standard',
						'subtype'    => 'number',
						'name'       => '_calendar_begins_nth',
						'id'         => '_calendar_begins_nth',
						'value'      => strval( $calendar_begins_nth ),
						'attributes' => array(
							'min' => '1',
						),
						'class'   => array(
							'simcal-field-inline',
							'simcal-field-tiny',
						),
						'style'      => ! $calendar_begins_nth_show ? array( 'display' => 'none' ) : '',
					) );

					?>
					<select name="_calendar_begins"
							id="_calendar_begins"
							class="simcal-field simcal-field-select simcal-field-inline simcal-field-switch-other">
						<optgroup label="<?php _e( 'Days', 'google-calendar-events' ); ?>">
							<option value="today"
									data-hide-fields="_calendar_begins_custom_date,_calendar_begins_nth"
								<?php selected( 'today', $calendar_begins, true ); ?>><?php _e( 'Today', 'google-calendar-events' ); ?></option>
							<option value="now"
									data-hide-fields="_calendar_begins_custom_date,_calendar_begins_nth"
								<?php selected( 'now', $calendar_begins, true ); ?>><?php _e( 'Now', 'google-calendar-events' ); ?></option>
							<option value="days_before"
									data-hide-field="_calendar_begins_custom_date"
									data-show-field="_calendar_begins_nth" <?php selected( 'days_before', $calendar_begins, true ); ?>><?php _e( 'Day(s) before today', 'google-calendar-events' ); ?></option>
							<option value="days_after"
									data-hide-field="_calendar_begins_custom_date"
									data-show-field="_calendar_begins_nth" <?php selected( 'days_after', $calendar_begins, true ); ?>><?php _e( 'Day(s) after today', 'google-calendar-events' ); ?></option>
						</optgroup>
						<optgroup label="<?php _e( 'Weeks', 'google-calendar-events' ); ?>">
							<option value="this_week"
									data-hide-fields="_calendar_begins_custom_date,_calendar_begins_nth"
								<?php selected( 'this_week', $calendar_begins, true ); ?>><?php _e( 'This week', 'google-calendar-events' ); ?></option>
							<option value="weeks_before"
									data-hide-field="_calendar_begins_custom_date"
									data-show-field="_calendar_begins_nth" <?php selected( 'weeks_before', $calendar_begins, true ); ?>><?php _e( 'Week(s) before current', 'google-calendar-events' ); ?></option>
							<option value="weeks_after"
									data-hide-field="_calendar_begins_custom_date"
									data-show-field="_calendar_begins_nth" <?php selected( 'weeks_after', $calendar_begins, true ); ?>><?php _e( 'Week(s) after current', 'google-calendar-events' ); ?></option>
						</optgroup>
						<optgroup label="<?php _e( 'Months', 'google-calendar-events' ); ?>">
							<option value="this_month"
									data-hide-fields="_calendar_begins_custom_date,_calendar_begins_nth"
								<?php selected( 'this_month', $calendar_begins, true ); ?>><?php _e( 'This month', 'google-calendar-events' ); ?></option>
							<option value="months_before"
									data-hide-field="_calendar_begins_custom_date"
									data-show-field="_calendar_begins_nth" <?php selected( 'months_before', $calendar_begins, true ); ?>><?php _e( 'Month(s) before current', 'google-calendar-events' ); ?></option>
							<option value="months_after"
									data-hide-field="_calendar_begins_custom_date"
									data-show-field="_calendar_begins_nth" <?php selected( 'months_after', $calendar_begins, true ); ?>><?php _e( 'Month(s) after current', 'google-calendar-events' ); ?></option>
						</optgroup>
						<optgroup label="<?php _e( 'Years', 'google-calendar-events' ); ?>">
							<option value="this_year"
									data-hide-fields="_calendar_begins_custom_date,_calendar_begins_nth"
								<?php selected( 'this_year', $calendar_begins, true ); ?>><?php _e( 'This year', 'google-calendar-events' ); ?></option>
							<option value="years_before"
									data-show-field="_calendar_begins_nth" <?php selected( 'years_before', $calendar_begins, true ); ?>><?php _e( 'Year(s) before current', 'google-calendar-events' ); ?></option>
							<option value="years_after"
									data-hide-field="_calendar_begins_custom_date"
									data-show-field="_calendar_begins_nth" <?php selected( 'years_after', $calendar_begins, true ); ?>><?php _e( 'Year(s) after current', 'google-calendar-events' ); ?></option>
						</optgroup>
						<optgroup label="<?php _e( 'Other', 'google-calendar-events' ); ?>">
							<option value="custom_date"
									data-hide-field="_calendar_begins_nth"
									data-show-field="_calendar_begins_custom_date" <?php selected( 'custom_date', $calendar_begins, true ); ?>><?php _e( 'Specific date', 'google-calendar-events' ); ?></option>
						</optgroup>
					</select>
					<?php

					simcal_print_field( array(
						'type'    => 'date-picker',
						'name'    => '_calendar_begins_custom_date',
						'id'      => '_calendar_begins_custom_date',
						'value'   => get_post_meta( $post->ID, '_calendar_begins_custom_date', true ),
						'class' => array(
							'simcal-field-inline',
						),
						'style'   => 'custom_date' != $calendar_begins ? array( 'display' => 'none' ) : '',
					) );

					?>
					<i class="simcal-icon-help simcal-help-tip"
					   data-tip="<?php _e( 'The calendar default opening date. It will automatically adapt based on the chosen calendar type.', 'google-calendar-events' ); ?>">

				<?php _e( 'Earliest event', 'google-calendar-events' ); ?>

					<?php

					$earliest_event_saved = get_post_meta( $post->ID, '_feed_earliest_event_date', true );
					$earliest_event = false == $earliest_event_saved ? 'months_before' : esc_attr( $earliest_event_saved );

					simcal_print_field( array(
						'type'       => 'standard',
						'subtype'    => 'number',
						'name'       => '_feed_earliest_event_date_range',
						'id'         => '_feed_earliest_event_date_range',
						'value'      => strval( max( absint( get_post_meta( $post->ID, '_feed_earliest_event_date_range', true ) ), 1 ) ),
						'attributes' => array(
							'min' => '1',
						),
						'class'   => array(
							'simcal-field-inline',
							'simcal-field-tiny',
						),
						'style'      => ( 'now' != $earliest_event ) && ( 'today' != $earliest_event ) ? array( 'display' => 'none' ) : '',
					) );

					?>
					<select name="_feed_earliest_event_date"
							id="_feed_earliest_event_date"
							class="simcal-field simcal-field-select simcal-field-inline simcal-field-switch-other">
						<option value="calendar_start" data-hide-field="_feed_earliest_event_date_range" <?php selected( 'calendar_start', $earliest_event, true ); ?>><?php _e( 'Same as start date', 'google-calendar-events' ); ?></option>
						<option value="days_before"    data-show-field="_feed_earliest_event_date_range" <?php selected( 'days_before', $earliest_event, true ); ?>><?php _e( 'Day(s) before start date', 'google-calendar-events' ); ?></option>
						<option value="weeks_before"   data-show-field="_feed_earliest_event_date_range" <?php selected( 'weeks_before', $earliest_event, true ); ?>><?php _e( 'Week(s) before start date', 'google-calendar-events' ); ?></option>
						<option value="months_before"  data-show-field="_feed_earliest_event_date_range" <?php selected( 'months_before', $earliest_event, true ); ?>><?php _e( 'Month(s) before start date', 'google-calendar-events' ); ?></option>
						<option value="years_before"   data-show-field="_feed_earliest_event_date_range" <?php selected( 'years_before', $earliest_event, true ); ?>><?php _e( 'Year(s) before start date', 'google-calendar-events' ); ?></option>
					</select>
					<i class="simcal-icon-help simcal-help-tip"
					   data-tip="<?php _e( 'Set the date for the earliest possible event to show in calendar. There will not be events before this date.', 'google-calendar-events' ); ?>">

				<?php _e( 'Latest event', 'google-calendar-events' ); ?>

					<?php

					$latest_event_saved = get_post_meta( $post->ID, '_feed_latest_event_date', true );
					$latest_event = false == $latest_event_saved ? 'years_after' : esc_attr( $latest_event_saved );

					simcal_print_field( array(
						'type'       => 'standard',
						'subtype'    => 'number',
						'name'       => '_feed_latest_event_date_range',
						'id'         => '_feed_latest_event_date_range',
						'value'      => strval( max( absint( get_post_meta( $post->ID, '_feed_latest_event_date_range', true ) ), 1 ) ),
						'attributes' => array(
							'min' => '1',
						),
						'class'      => array(
							'simcal-field-inline',
							'simcal-field-tiny',
						),
						'style'      => 'indefinite' != $latest_event ? array( 'display' => 'none' ) : '',
					) );

					?>
					<select name="_feed_latest_event_date"
							id="_feed_latest_event_date"
							class="simcal-field simcal-field-select simcal-field-inline simcal-field-switch-other">
						<option value="calendar_start" data-hide-field="_feed_latest_event_date_range" <?php selected( 'calendar_start', $earliest_event, true ); ?>><?php _e( 'Day end of start date', 'google-calendar-events' ); ?></option>
						<option value="days_after"     data-show-field="_feed_latest_event_date_range" <?php selected( 'days_after', $latest_event, true ); ?>><?php _e( 'Day(s) after start date', 'google-calendar-events' ); ?></option>
						<option value="weeks_after"    data-show-field="_feed_latest_event_date_range" <?php selected( 'weeks_after', $latest_event, true ); ?>><?php _e( 'Weeks(s) after start date', 'google-calendar-events' ); ?></option>
						<option value="months_after"   data-show-field="_feed_latest_event_date_range" <?php selected( 'months_after', $latest_event, true ); ?>><?php _e( 'Month(s) after start date', 'google-calendar-events' ); ?></option>
						<option value="years_after"    data-show-field="_feed_latest_event_date_range" <?php selected( 'years_after', $latest_event, true ); ?>><?php _e( 'Year(s) after start date', 'google-calendar-events' ); ?></option>
					</select>
					<i class="simcal-icon-help simcal-help-tip"
					   data-tip="<?php _e( 'Set the date for the latest possible event to show on calendar. There will not be events after this date.', 'google-calendar-events' ); ?>">

		<?php

	}

	/**
	 * Print the calendar settings panel.
	 *
	 * @since  3.0.0
	 * @access private
	 *
	 * @param  \WP_Post $post
	 */
	private static function calendar_settings_panel( $post ) {

		?>

<?php _e( 'Miscellaneous', 'google-calendar-events' ); ?>

				<?php _e( 'Static calendar', 'google-calendar-events' ); ?>

					<?php

					$fixed = get_post_meta( $post->ID, '_calendar_is_static', true );

					simcal_print_field( array(
						'type'    => 'checkbox',
						'name'    => '_calendar_is_static',
						'id'      => '_calendar_is_static',
						'tooltip' => __( 'Remove the navigation arrows and fix the calendar view to its initial state.', 'google-calendar-events' ),
						'value'   => 'yes' == $fixed ? 'yes' : 'no',
					) );

					?>

				<?php _e( 'No events message', 'google-calendar-events' ); ?>

					<?php

					simcal_print_field( array(
						'type'    => 'textarea',
						'name'    => '_no_events_message',
						'id'      => '_no_events_message',
						'tooltip' => __( 'Some calendars may display a message when no events are found. You can change the default message here.', 'google-calendar-events' ),
						'value'   => get_post_meta( $post->ID, '_no_events_message', true ),
					) );

					?>

				<?php _e( 'Event Formatting', 'google-calendar-events' ); ?>

					<?php

					$event_formatting = get_post_meta( $post->ID, '_event_formatting', true );

					simcal_print_field( array(
						'type'    => 'select',
						'name'    => '_event_formatting',
						'id'      => '_event_formatting',
						'tooltip' => __( 'How to preserve line breaks and paragraphs in the event template builder.', 'google-calendar-events' ),
						'value'   => $event_formatting,
						'default' => 'preserve_linebreaks',
						'options' => array(
							'preserve_linebreaks' => __( 'Preserve line breaks, auto paragraphs (default)', 'google-calendar-events' ),
							'no_linebreaks'       => __( 'No line breaks, auto paragraphs', 'google-calendar-events' ),
							'none'                => __( 'No line breaks, no auto paragraphs', 'google-calendar-events' ),
						),
					) );

					?>

		<?php

	}

	/**
	 * Print the advanced settings panel.
	 *
	 * @since  3.0.0
	 * @access private
	 *
	 * @param  \WP_Post $post
	 */
	private static function advanced_settings_panel( $post ) {

		?>

<?php _e( 'Date and Time', 'google-calendar-events' ); ?>

				<?php _e( 'Timezone', 'google-calendar-events' ); ?>

					<?php

					$timezone_wordpress = simcal_get_wp_timezone();
					$timezone_default   = $timezone_wordpress ? $timezone_wordpress : 'UTC';
					$timezone_setting   = esc_attr( get_post_meta( $post->ID, '_feed_timezone_setting', true ) );
					$timezone           = esc_attr( get_post_meta( $post->ID, '_feed_timezone', true ) );
					$timezone           = $timezone ? $timezone : $timezone_default;
					$show_use_calendar  = isset( simcal_get_feed( $post )->type );

					if ( $show_use_calendar ) {
						$show_use_calendar = ( simcal_get_feed( $post )->type !== 'grouped-calendars' ? 1 : 0 );
					} else {
						$show_use_calendar = true;
					}

					?>
					<select name="_feed_timezone_setting"
							id="_feed_timezone_setting"
							class="simcal-field simcal-field-select simcal-field-inline simcal-field-show-other"
							data-show-field-on-choice="true">
						<option value="use_site" <?php selected( 'use_site', $timezone_setting, true ); ?>><?php printf( _x( 'Site default', 'Use this site default setting', 'google-calendar-events' ) . ' (%s)', $timezone_default ); ?></option>
						<?php if ( $show_use_calendar ) { ?>
							<option id="use_calendar" value="use_calendar" data-show-field="_use_calendar_warning" <?php selected( 'use_calendar', $timezone_setting, true ); ?>><?php _ex( 'Events source default', 'Use the calendar default setting', 'google-calendar-events' ); ?></option>
						<?php } ?>
						<option value="use_custom" data-show-field="_feed_timezone" <?php selected( 'use_custom', $timezone_setting, true ); ?>><?php _ex( 'Custom', 'Use a custom setting', 'google-calendar-events' ); ?></option>
					</select>
					<select name="_feed_timezone"
							id="_feed_timezone"
							class="simcal-field simcal-field-select simcal-field-inline"
						<?php echo 'use_custom' != $timezone_setting ? 'style="display: none;"' : ''; ?>>
						<?php echo wp_timezone_choice( $timezone ); ?>
					</select>
					<i class="simcal-icon-help simcal-help-tip" data-tip="<?php _e( 'Using a different timezone may alter the date and time display of your calendar events. It is recommended to keep the calendar default timezone.', 'google-calendar-events' ); ?>">

						<?php printf( __( 'Warning: Using this option can return unexpected results if you have specified event level timezones.', 'google-calendar-events' ), 'http://docs.simplecalendar.io/timezone-settings/' ); ?>

				<?php _e( 'Date format', 'google-calendar-events' ); ?>

					<?php

					$date_format_setting = esc_attr( get_post_meta( $post->ID, '_calendar_date_format_setting', true ) );
					$date_format_default = esc_attr( get_option( 'date_format' ) );
					$date_format = esc_attr( get_post_meta( $post->ID, '_calendar_date_format', true ) );
					$date_format_php = esc_attr( get_post_meta( $post->ID, '_calendar_date_format_php', true ) );
					$date_format_php = $date_format_php ? $date_format_php : $date_format_default;

					?>
					<select name="_calendar_date_format_setting"
							id="_calendar_date_format_setting"
							class="simcal-field simcal-field-select simcal-field-show-other">
						<option value="use_site" data-show-field="_calendar_date_format_default" <?php selected( 'use_site', $date_format_setting, true ); ?>><?php  _ex( 'Site default', 'Use this site default setting', 'google-calendar-events' ); ?></option>
						<option value="use_custom" data-show-field="_calendar_date_format" <?php selected( 'use_custom', $date_format_setting, true ); ?>><?php _ex( 'Custom', 'Use a custom setting', 'google-calendar-events' ); ?></option>
						<option value="use_custom_php" data-show-field="_calendar_date_format_php_field" <?php selected( 'use_custom_php', $date_format_setting, true ); ?>><?php _e( 'Custom (PHP format)', 'google-calendar-events' ); ?></option>
					</select>
					<i class="simcal-icon-help simcal-help-tip" data-tip="<?php _e( 'This option sets how calendars display event dates. It is recommended to keep your site default setting.', 'google-calendar-events' ); ?>">
					<p id="_calendar_date_format_default" style="<?php echo $date_format_setting != 'use_site' ? 'display: none;' : ''; ?>">
						<?php _e( 'Preview', 'google-calendar-events' ) ?>:
						<?php echo date_i18n( $date_format_default, time() ); ?>

					<?php simcal_print_field( array(
						'type'    => 'datetime-format',
						'subtype' => 'date',
						'name'    => '_calendar_date_format',
						'id'      => '_calendar_date_format',
						'value'   => $date_format,
						'style'   => $date_format_setting != 'use_custom' ? array( 'display' => 'none' ) : '',
					) ); ?>
					<div class="simcal-field-datetime-format-php" id="_calendar_date_format_php_field" style="<?php echo $date_format_setting != 'use_custom_php' ? 'display: none;' : ''; ?>">

							<input type="text"
								   name="_calendar_date_format_php"
								   id="_calendar_date_format_php"
								   class="simcal-field simcal-field-text simcal-field-small"
								   value="<?php echo $date_format_php; ?>" />
							<?php printf( __( 'Enter a date format using %s values.', 'google-calendar-events' ), 'PHP' ); ?>

							<?php _e( 'Preview', 'google-calendar-events' ) ?>:
							<?php echo date_i18n( $date_format_php, time() ); ?>

				<?php _e( 'Separator', 'google-calendar-events' ); ?>

					<?php

					$separator = get_post_meta( $post->ID, '_calendar_datetime_separator', true );
					$separator = false == $separator ? '@' : $separator;

					simcal_print_field( array(
						'type'    => 'standard',
						'subtype' => 'text',
						'name'    => '_calendar_datetime_separator',
						'id'      => '_calendar_datetime_separator',
						'value'   => $separator,
						'tooltip' => __( 'Used to divide date and time when both are shown.', 'google-calendar-events' ),
						'class'   => array(
							'simcal-field-tiny',
						),
					) );

					?>

				<?php _e( 'Time format', 'google-calendar-events' ); ?>

					<?php

					$time_format_setting = esc_attr( get_post_meta( $post->ID, '_calendar_time_format_setting', true ) );
					$time_format_default = esc_attr( get_option( 'time_format' ) );
					$time_format = esc_attr( get_post_meta( $post->ID, '_calendar_time_format', true ) );
					$time_format_php = esc_attr( get_post_meta( $post->ID, '_calendar_time_format_php', true ) );
					$time_format_php = $time_format_php ? $time_format_php : $time_format_default;

					?>
					<select name="_calendar_time_format_setting"
							id="_calendar_time_format_setting"
							class="simcal-field simcal-field-select simcal-field-show-other">
						<option value="use_site" data-show-field="_calendar_time_format_default" <?php selected( 'use_site', $time_format_setting, true ); ?>><?php _ex( 'Site default', 'Use this site default setting', 'google-calendar-events' ); ?></option>
						<option value="use_custom" data-show-field="_calendar_time_format" <?php selected( 'use_custom', $time_format_setting, true ); ?>><?php _ex( 'Custom', 'Use a custom setting', 'google-calendar-events' ); ?></option>
						<option value="use_custom_php" data-show-field="_calendar_time_format_php_field" <?php selected( 'use_custom_php', $time_format_setting, true ); ?>><?php _e( 'Custom (PHP format)', 'google-calendar-events' ); ?></option>
					</select>
					<i class="simcal-icon-help simcal-help-tip" data-tip="<?php _e( 'This option sets how calendars display event times. It is recommended to keep your site default setting.', 'google-calendar-events' ); ?>">
					<p id="_calendar_time_format_default" style="<?php echo $time_format_setting != 'use_site' ? 'display: none;' : ''; ?>">
						<?php _e( 'Preview', 'google-calendar-events' ) ?>:
						<?php echo date_i18n( $time_format_default, time() ); ?>

					<?php simcal_print_field( array(
						'type'    => 'datetime-format',
						'subtype' => 'time',
						'name'    => '_calendar_time_format',
						'id'      => '_calendar_time_format',
						'value'   => $time_format,
						'style'   => $time_format_setting != 'use_custom' ? array( 'display' => 'none' ) : '',
					) ); ?>
					<div class="simcal-field-datetime-format-php" id="_calendar_time_format_php_field" style="<?php echo $time_format_setting != 'use_custom_php' ? 'display: none;' : ''; ?>">

							<input type="text"
								   name="_calendar_time_format_php"
								   id="_calendar_time_format_php"
								   class="simcal-field simcal-field-text simcal-field-small"
								   value="<?php echo $time_format_php; ?>"/>
							<?php printf( __( 'Enter a time format using %s values.', 'google-calendar-events' ), 'PHP' ); ?>

							<?php _e( 'Preview', 'google-calendar-events' ) ?>:
							<?php echo date_i18n( $time_format_php, time() ); ?>

				<?php _e( 'Week starts on', 'google-calendar-events' ); ?>

					<?php

					$week_starts_setting = esc_attr( get_post_meta( $post->ID, '_calendar_week_starts_on_setting', true ) );
					$week_starts_default = esc_attr( get_option( 'start_of_week' ) );
					$week_starts = intval( get_post_meta( $post->ID, '_calendar_week_starts_on', true ) );
					$week_starts = is_numeric( $week_starts ) ? strval( $week_starts ) : $week_starts_default;

					?>
					<select
						name="_calendar_week_starts_on_setting"
						id="_calendar_week_starts_on_setting"
						class="simcal-field simcal-field-select simcal-field-inline simcal-field-show-next"
						data-show-next-if-value="use_custom">
						<option value="use_site" <?php selected( 'use_site', $week_starts_setting, true ); ?>><?php printf( _x( 'Site default', 'Use this site default setting', 'google-calendar-events' ) . ' (%s)', date_i18n( 'l', strtotime( "Sunday + $week_starts_default Days" ) ) ); ?></option>
						<option value="use_custom" <?php selected( 'use_custom', $week_starts_setting, true ); ?>><?php _ex( 'Custom', 'Use a custom setting', 'google-calendar-events' ); ?></option>
					</select>
					<select
						name="_calendar_week_starts_on"
						id="_calendar_week_starts_on"
						class="simcal-field simcal-field-select simcal-field-inline"
						<?php echo 'use_custom' != $week_starts_setting ? 'style="display: none;"' : ''; ?>>
						<?php $day_names = simcal_get_calendar_names_i18n( 'day', 'full' ); ?>
						<?php for ( $i = 0; $i <= 6; $i++ ) : ?>
							<option value="<?php echo $i; ?>" <?php selected( $i, $week_starts, true ); ?>><?php echo $day_names[ $i ]; ?></option>
						<?php endfor; ?>
					</select>
					<i class="simcal-icon-help simcal-help-tip" data-tip="<?php _e( 'Some calendars may use this setting to display the start of the week. It is recommended to keep the site default setting.', 'google-calendar-events' ); ?>">

<?php _e( 'Cache', 'google-calendar-events' ); ?>

			<?php

			$cache_freq = esc_attr( get_post_meta( $post->ID, '_feed_cache_user_amount', true ) );
			$cache_unit = esc_attr( get_post_meta( $post->ID, '_feed_cache_user_unit', true ) );
			$cache_freq = is_int( $cache_freq ) && $cache_freq >= 0 ? $cache_freq : '2';
			$cache_unit = $cache_unit ? $cache_unit : '3600';

			?>

				<?php _ex( 'Refresh interval', 'Cache maximum interval', 'google-calendar-events' ); ?>

					<input type="number"
						   name="_feed_cache_user_amount"
						   id="_feed_cache_user_amount"
						   class="simcal-field simcal-field-number simcal-field-tiny simcal-field-inline"
						   value="<?php echo $cache_freq; ?>"
						   min="0" />
					<select name="_feed_cache_user_unit"
							id="_feed_cache_user_unit"
							class="simcal-field simcalfield-select simcal-field-inline">
						<option value="60" <?php selected( '60', $cache_unit, true ); ?>><?php _e( 'Minute(s)', 'google-calendar-events' ); ?></option>
						<option value="3600" <?php selected( '3600', $cache_unit, true ); ?>><?php _e( 'Hour(s)', 'google-calendar-events' ); ?></option>
						<option value="86400" <?php selected( '86400', $cache_unit, true ); ?>><?php _e( 'Day(s)', 'google-calendar-events' ); ?></option>
						<option value="604800" <?php selected( '604800', $cache_unit, true ); ?>><?php _e( 'Week(s)', 'google-calendar-events' ); ?></option>
					</select>
					<i class="simcal-icon-help simcal-help-tip" data-tip="<?php _e( 'If you add, edit or remove events in your calendar very often, you can set a lower interval to refresh the events displayed. Set a higher interval for best performance.', 'google-calendar-events' ); ?>">

		<?php

	}

	/**
	 * Print fields in a panel.
	 *
	 * @since  3.0.0
	 *
	 * @param  array $array
	 * @param  int   $post_id
	 *
	 * @return void
	 */
	public static function print_panel_fields( $array, $post_id ) {

		foreach ( $array as $section => $fields ) :

			if ( $fields && is_array( $fields ) ) :

				?>
				<tbody class="simcal-panel-section simcal-panel-section-<?php echo esc_attr( $section ); ?>">
				<?php foreach ( $fields as $key => $field ) :

					$value            = get_post_meta( $post_id, $key, true );
					$field['value']   = $value ? $value : ( isset( $field['default'] ) ? $field['default'] : '' );
					$the_field = simcal_get_field( $field ); ?>

					<?php if ( $the_field instanceof Field ) : ?>

						<label for="<?php echo $the_field->id ?>"><?php echo $the_field->title; ?>
						<?php $the_field->html(); ?>

				<?php endif; ?>

				<?php endforeach; ?>

				<?php

			endif;

		endforeach;

	}

	/**
	 * Validate and save the meta box fields.
	 *
	 * @since  3.0.0
	 *
	 * @param  int      $post_id
	 * @param  \WP_Post $post
	 *
	 * @return void
	 */
	public static function save( $post_id, $post ) {

		/* ====================== *
		 * Calendar type and view *
		 * ====================== */

		// Unlink existing terms for feed type and calendar type.
		wp_delete_object_term_relationships( $post_id, array(
			'calendar_feed',
			'calendar_type',
		) );

		// Set the feed type as term.
		$feed_type = isset( $_POST['_feed_type'] ) ? sanitize_title( stripslashes( $_POST['_feed_type'] ) ) : apply_filters( 'simcal_default_feed_type', 'google' );
		wp_set_object_terms( $post_id, $feed_type, 'calendar_feed' );

		// Set the calendar type as a term.
		$calendar_type = isset( $_POST['_calendar_type'] ) ? sanitize_title( stripslashes( $_POST['_calendar_type'] ) ) : apply_filters( 'simcal_default_calendar_type', 'default-calendar' );
		wp_set_object_terms( $post_id, $calendar_type, 'calendar_type' );
		// Set the calendar type view as post meta.
		$calendar_view = isset( $_POST['_calendar_view'] ) ? $_POST['_calendar_view'] : '';
		if ( $calendar_view && is_array( $calendar_view ) ) {
			$views = array_map( 'sanitize_title', $calendar_view );
			update_post_meta( $post_id, '_calendar_view', $views );
		}

		/* ===================== *
		 * Events settings panel *
		 * ===================== */

		// Calendar opening.
		$calendar_begins = isset( $_POST['_calendar_begins'] ) ? sanitize_key( $_POST['_calendar_begins'] ) : 'this_month';
		update_post_meta( $post_id, '_calendar_begins', $calendar_begins );
		$calendar_begins_nth = isset( $_POST['_calendar_begins_nth'] ) ? absint( $_POST['_calendar_begins_nth'] ) : 2;
		update_post_meta( $post_id, '_calendar_begins_nth', $calendar_begins_nth );
		$calendar_begins_custom_date = isset( $_POST['_calendar_begins_custom_date'] ) ? sanitize_title( $_POST['_calendar_begins_custom_date'] ) : '';
		update_post_meta( $post_id, '_calendar_begins_custom_date', $calendar_begins_custom_date );

		// Feed earliest events date.
		$earliest_events = isset( $_POST['_feed_earliest_event_date'] ) ? sanitize_key( $_POST['_feed_earliest_event_date'] ) : '';
		update_post_meta( $post_id, '_feed_earliest_event_date', $earliest_events );
		$earliest_events_range = isset( $_POST['_feed_earliest_event_date_range'] ) ? max( absint( $_POST['_feed_earliest_event_date_range'] ), 1 ) : 1;
		update_post_meta( $post_id, '_feed_earliest_event_date_range', $earliest_events_range );

		// Feed latest events date.
		$latest_events = isset( $_POST['_feed_latest_event_date'] ) ? sanitize_key( $_POST['_feed_latest_event_date'] ) : '';
		update_post_meta( $post_id, '_feed_latest_event_date', $latest_events );
		$latest_events_range = isset( $_POST['_feed_latest_event_date_range'] ) ? max( absint( $_POST['_feed_latest_event_date_range'] ), 1 ) : 1;
		update_post_meta( $post_id, '_feed_latest_event_date_range', $latest_events_range );

		/* ======================= *
		 * Calendar settings panel *
		 * ======================= */

		// Static calendar.
		$static = isset( $_POST['_calendar_is_static'] ) ? 'yes' : 'no';
		update_post_meta( $post_id, '_calendar_is_static', $static );

		// No events message.
		$message = isset( $_POST['_no_events_message'] ) ? wp_kses_post( $_POST['_no_events_message'] ) : '';
		update_post_meta( $post_id, '_no_events_message', $message );

		// _event_formatting
		$event_formatting = isset( $_POST['_event_formatting'] ) ? sanitize_key( $_POST['_event_formatting'] ) : 'preserve_linebreaks';
		update_post_meta( $post_id, '_event_formatting', $event_formatting );

		/* ======================= *
		 * Advanced settings panel *
		 * ======================= */

		// Timezone.
		$feed_timezone_setting = isset( $_POST['_feed_timezone_setting'] ) ? sanitize_key( $_POST['_feed_timezone_setting'] ) : 'use_calendar';
		update_post_meta( $post_id, '_feed_timezone_setting', $feed_timezone_setting );
		$default_timezone = simcal_get_wp_timezone();
		$feed_timezone = $default_timezone ? $default_timezone : 'UTC';
		$feed_timezone = isset( $_POST['_feed_timezone'] ) ? sanitize_text_field( $_POST['_feed_timezone'] ) : $feed_timezone;
		update_post_meta( $post_id, '_feed_timezone', $feed_timezone );

		// Date format.
		$date_format_setting = isset( $_POST['_calendar_date_format_setting'] ) ? sanitize_key( $_POST['_calendar_date_format_setting'] ) : 'use_site';
		update_post_meta( $post_id, '_calendar_date_format_setting', $date_format_setting );
		$date_format = isset( $_POST['_calendar_date_format'] ) ? sanitize_text_field( trim( $_POST['_calendar_date_format'] ) ) : get_option( 'date_format' );
		update_post_meta( $post_id, '_calendar_date_format', $date_format );
		$date_format_php = isset( $_POST['_calendar_date_format_php'] ) ? sanitize_text_field( trim( $_POST['_calendar_date_format_php'] ) ) : get_option( 'date_format' );
		update_post_meta( $post_id, '_calendar_date_format_php', $date_format_php );

		// Time format.
		$time_format_setting = isset( $_POST['_calendar_time_format_setting'] ) ? sanitize_key( $_POST['_calendar_time_format_setting'] ) : 'use_site';
		update_post_meta( $post_id, '_calendar_time_format_setting', $time_format_setting );
		$time_format = isset( $_POST['_calendar_time_format'] ) ? sanitize_text_field( trim( $_POST['_calendar_time_format'] ) ) : get_option( 'time_format' );
		update_post_meta( $post_id, '_calendar_time_format', $time_format );
		$time_format_php = isset( $_POST['_calendar_time_format_php'] ) ? sanitize_text_field( trim( $_POST['_calendar_time_format_php'] ) ) : get_option( 'time_format' );
		update_post_meta( $post_id, '_calendar_time_format_php', $time_format_php );

		// Date-time separator.
		$datetime_separator = isset( $_POST['_calendar_datetime_separator'] ) ? sanitize_text_field( $_POST['_calendar_datetime_separator'] ) : ' ';
		update_post_meta( $post_id, '_calendar_datetime_separator', $datetime_separator );

		// Week start.
		$week_start_setting = isset( $_POST['_calendar_week_starts_on_setting'] ) ? sanitize_key( $_POST['_calendar_week_starts_on_setting'] ) : 'use_site';
		update_post_meta( $post_id, '_calendar_week_starts_on_setting', $week_start_setting );
		$week_start = isset( $_POST['_calendar_week_starts_on'] ) ? intval( $_POST['_calendar_week_starts_on'] ) : get_option( 'start_of_week' );
		update_post_meta( $post_id, '_calendar_week_starts_on', $week_start );

		// Cache interval.
		$cache = 7200;
		if ( isset( $_POST['_feed_cache_user_amount'] ) && isset( $_POST['_feed_cache_user_unit'] ) ) {
			$amount = is_numeric( $_POST['_feed_cache_user_amount'] ) || $_POST['_feed_cache_user_amount'] == 0 ? absint( $_POST['_feed_cache_user_amount'] ) : 1;
			$unit   = is_numeric( $_POST['_feed_cache_user_unit'] ) ? absint( $_POST['_feed_cache_user_unit'] ) : 3600;
			update_post_meta( $post_id, '_feed_cache_user_amount', $amount );
			update_post_meta( $post_id, '_feed_cache_user_unit', $unit );
			$cache  = ( ( $amount * $unit ) > 0 ) ? $amount * $unit : 1;
		}
		update_post_meta( $post_id, '_feed_cache', $cache );

		/* ============= *
		 * Miscellaneous *
		 * ============= */

		// Update version.
		update_post_meta( $post_id, '_calendar_version', SIMPLE_CALENDAR_VERSION );

		// Action hook.
		do_action( 'simcal_process_settings_meta', $post_id );

		// Clear cache.
		simcal_delete_feed_transients( $post_id );
	}

}