*/
namespace LiteSpeed\Lib;
defined( 'WPINC' ) || exit;
class HTML_MIN {
	/**
	 * @var string
	 */
	protected $_html = '';
	/**
	 * @var boolean
	 */
	protected $_jsCleanComments = true;
	protected $_skipComments    = array();
	/**
	 * "Minify" an HTML page
	 *
	 * @param string $html
	 *
	 * @param array  $options
	 *
	 * 'cssMinifier' : (optional) callback function to process content of STYLE
	 * elements.
	 *
	 * 'jsMinifier' : (optional) callback function to process content of SCRIPT
	 * elements. Note: the type attribute is ignored.
	 *
	 * 'xhtml' : (optional boolean) should content be treated as XHTML1.0? If
	 * unset, minify will sniff for an XHTML doctype.
	 *
	 * @return string
	 */
	public static function minify( $html, $options = array() ) {
		$min = new self( $html, $options );
		return $min->process();
	}
	/**
	 * Create a minifier object
	 *
	 * @param string $html
	 *
	 * @param array  $options
	 *
	 * 'cssMinifier' : (optional) callback function to process content of STYLE
	 * elements.
	 *
	 * 'jsMinifier' : (optional) callback function to process content of SCRIPT
	 * elements. Note: the type attribute is ignored.
	 *
	 * 'jsCleanComments' : (optional) whether to remove HTML comments beginning and end of script block
	 *
	 * 'xhtml' : (optional boolean) should content be treated as XHTML1.0? If
	 * unset, minify will sniff for an XHTML doctype.
	 */
	public function __construct( $html, $options = array() ) {
		$this->_html = str_replace( "\r\n", "\n", trim( $html ) );
		if ( isset( $options['xhtml'] ) ) {
			$this->_isXhtml = (bool) $options['xhtml'];
		}
		if ( isset( $options['cssMinifier'] ) ) {
			$this->_cssMinifier = $options['cssMinifier'];
		}
		if ( isset( $options['jsMinifier'] ) ) {
			$this->_jsMinifier = $options['jsMinifier'];
		}
		if ( isset( $options['jsCleanComments'] ) ) {
			$this->_jsCleanComments = (bool) $options['jsCleanComments'];
		}
		if ( isset( $options['skipComments'] ) ) {
			$this->_skipComments = $options['skipComments'];
		}
	}
	/**
	 * Minify the markeup given in the constructor
	 *
	 * @return string
	 */
	public function process() {
		if ( $this->_isXhtml === null ) {
			$this->_isXhtml = ( false !== strpos( $this->_html, '_html);
		// fill placeholders
		$this->_html = str_replace(
			array_keys( $this->_placeholders ),
			array_values( $this->_placeholders ),
			$this->_html
		);
		// issue 229: multi-pass to catch scripts that didn't get replaced in textareas
		$this->_html = str_replace(
			array_keys( $this->_placeholders ),
			array_values( $this->_placeholders ),
			$this->_html
		);
		return $this->_html;
	}
	/**
	 * From LSCWP 6.2: Changed the function to test for special comments that will be skipped. See: https://github.com/litespeedtech/lscache_wp/pull/622
	 */
	protected function _commentCB( $m ) {
		// If is IE conditional comment return it.
		if ( 0 === strpos( $m[1], '[' ) || false !== strpos( $m[1], ' HTML Settings -> HTML Keep comments
		if ( count( $this->_skipComments ) > 0 ) {
			foreach ( $this->_skipComments as $comment ) {
				if ( $comment && strpos( $m[1], $comment ) !== false ) {
					return $m[0];
				}
			}
		}
		// Comment can be removed.
		return '';
	}
	protected function _reservePlace( $content ) {
		$placeholder                         = '%' . $this->_replacementHash . count( $this->_placeholders ) . '%';
		$this->_placeholders[ $placeholder ] = $content;
		return $placeholder;
	}
	protected $_isXhtml         = null;
	protected $_replacementHash = null;
	protected $_placeholders    = array();
	protected $_cssMinifier     = null;
	protected $_jsMinifier      = null;
	protected function _removePreCB( $m ) {
		return $this->_reservePlace( "_reservePlace( "