Your IP : 216.73.216.61


Current Path : /home/w/u/e/wuectly/www/03cbe/
Upload File :
Current File : /home/w/u/e/wuectly/www/03cbe/jacssjanus.zip

PKY~!]*=�5&&
csslex.phpnu&1i�<?php
class CSSLEX {
	private $csslex = array();
	function __construct () {
		$csslex = array();

		$csslex['keyword'] = '(?:\@(?:import|page|media|charset))';

		# nl                      \n|\r\n|\r|\f ; a newline
		$csslex['newline'] = '\n|\r\n|\r|\f';

		# h                       [0-9a-f]      ; a hexadecimal digit
		$csslex['hex'] = '[0-9a-f]';

		# nonascii                [\200-\377]
		$csslex['non_ascii'] = '[\200-\377]';

		# unicode                 \\{h}{1,6}(\r\n|[ \t\r\n\f])?
		$csslex['unicode'] = '(?:(?:\\' . $csslex['hex'] . '{1,6})(?:\r\n|[ \t\r\n\f])?)';

		# escape                  {unicode}|\\[^\r\n\f0-9a-f]
		$csslex['escape'] = '(?:' . $csslex['unicode'] . '|\\[^\r\n\f0-9a-f])';

		# nmstart                 [_a-z]|{nonascii}|{escape}
		$csslex['nmstart'] = '(?:[_a-z]|' . $csslex['non_ascii'] . '|' . $csslex['escape'] . ')';

		# nmchar                  [_a-z0-9-]|{nonascii}|{escape}
		$csslex['nmchar'] = '(?:[_a-z0-9-]|' . $csslex['non_ascii'] . '|' . $csslex['escape'] . ')';

		# ident                   -?{nmstart}{nmchar}*
		$csslex['ident'] = '-?' . $csslex['nmstart'] . $csslex['nmchar'] . '*';

		# name                    {nmchar}+
		$csslex['name'] = $csslex['nmchar'] . '+';

		# hash
		$csslex['hash'] = '#' . $csslex['name'];

		# string1                 \"([^\n\r\f\\"]|\\{nl}|{escape})*\"  ; "string"
		$csslex['string1'] = '"(?:[^\"\\]|\\.)*"';

		# string2                 \'([^\n\r\f\\']|\\{nl}|{escape})*\'  ; 'string'
		$csslex['string2'] = "'(?:[^\'\\]|\\.)*'";

		# string                  {string1}|{string2}
		$csslex['string'] = '(?:' . $csslex['string1'] . '|' . $csslex['string2'] . ')';

		# num                     [0-9]+|[0-9]*"."[0-9]+
		$csslex['num'] = '(?:[0-9]*\.[0-9]+|[0-9]+)';

		# s                       [ \t\r\n\f]
		$csslex['space'] = '[ \t\r\n\f]';

		# w                       {s}*
		$csslex['whitespace'] = '(?:' . $csslex['space'] . '*)';

		# url special chars
		$csslex['url_special_chars'] = '[!#$%&*-~]';

		# url chars               ({url_special_chars}|{nonascii}|{escape})*
		$csslex['url_chars'] = sprintf('(?:%s|%s|%s)*', $csslex['url_special_chars'], $csslex['non_ascii'], $csslex['escape']);

		# url
		$csslex['url'] = sprintf('url\(%s(%s|%s)%s\)', $csslex['whitespace'], $csslex['string'], $csslex['url_chars'], $csslex['whitespace']);

		# comments
		# see http://www.w3.org/tr/css21/grammar.html
		$csslex['comment'] = '\/\*[^\*]*\*+([^\/\*][^\*]*\*+)*\/';

		# {e}{m}             {return ems;}
		# {e}{x}             {return exs;}
		# {p}{x}             {return length;}
		# {c}{m}             {return length;}
		# {m}{m}             {return length;}
		# {i}{n}             {return length;}
		# {p}{t}             {return length;}
		# {p}{c}             {return length;}
		# {d}{e}{g}          {return angle;}
		# {r}{a}{d}          {return angle;}
		# {g}{r}{a}{d}       {return angle;}
		# {m}{s}             {return time;}
		# {s}                {return time;}
		# {h}{z}             {return freq;}
		# {k}{h}{z}          {return freq;}
		# %                  {return percentage;}
		$csslex['unit'] = '(?:em|ex|px|cm|mm|in|pt|pc|deg|rad|grad|ms|s|hz|khz|%)';

		# {num}{unit|ident}                   {return number;}
		$csslex['quantity'] = sprintf('%s(?:%s%s|%s)?', $csslex['num'], $csslex['whitespace'], $csslex['unit'], $csslex['ident']);

		# "<!--"                  {return cdo;}
		# "-->"                   {return cdc;}
		# "~="                    {return includes;}
		# "|="                    {return dashmatch;}
		# {w}"{"                  {return lbrace;}
		# {w}"+"                  {return plus;}
		# {w}">"                  {return greater;}
		# {w}","                  {return comma;}
		$csslex['punc'] = '<!--|-->|~=|\|=|[\{\+>,:;]';

		$this->csslex = $csslex;
	}

	function __get ($name) {
		return isset($this->csslex[$name]) ? $this->csslex[$name] : null;
	}
}
PKY~!]��Ƙ�=�=test.phpnu&1i�<style type="text/css">
.pass {color: green;}
.fail {color: red;}

table.result {
  font-family: verdana,arial,sans-serif;
  font-size:11px;
  color:#333333;
  border-width: 1px;
  border-color: #666666;
  border-collapse: collapse;
}
table.result td {
  border-width: 1px;
  padding: 8px;
  border-style: solid;
  border-color: #666666;
  background-color: #ffffff;
  width: 400px;
}
table.result tr td:first-child {
  border-width: 1px;
  padding: 8px;
  border-style: solid;
  border-color: #666666;
  background-color: #dedede;
  width: 50px;
}

</style>

<?php
require_once 'ja.cssjanus.php';

$test = '';
$testcase = '';
$shouldbe = '';
$swap_ltr_rtl_in_url = False;
$swap_left_right_in_url = False;

function test () {
  global $test, $testcase, $shouldbe, $swap_ltr_rtl_in_url, $swap_left_right_in_url;

  $input = implode ("\n", $testcase);
  $expect = implode ("\n", $shouldbe);
  $output = JACSSJanus::transform ($input, $swap_ltr_rtl_in_url, $swap_left_right_in_url);
  $pass = ($output == $expect);
  $result = $pass ? '<span class="pass">pass</span>' : '<span class="fail">fail</span>';
?>
  <h2 class="<?php echo $pass ? 'pass':'fail' ?>"><?php echo $test ?></h2>
  <table class="result">
    <tr><td>Input</td><td><?php echo str_replace("\n", "<br />\n", $input) ?></td></tr>
    <tr><td>Expect</td><td><?php echo str_replace("\n", "<br />\n", $expect) ?></td></tr>
    <tr><td>Output</td><td><?php echo str_replace("\n", "<br />\n", $output) ?></td></tr>
    <tr><td>Result</td><td><?php echo $result ?></td></tr>
  </table>
  <br /><br />
<?php
}


$test = 'testPreserveComments';
$testcase = array('/* left /* right */left: 10px');
$shouldbe = array('/* left /* right */right: 10px');
test();

$testcase = array('/*left*//*left*/left: 10px');
$shouldbe = array('/*left*//*left*/right: 10px');
test();

$testcase = array('/* Going right is cool */\n#test {left: 10px}');
$shouldbe = array('/* Going right is cool */\n#test {right: 10px}');

$testcase = array('/* padding-right 1 2 3 4 */\n#test {left: 10px}\n/*right*/');
$shouldbe = array('/* padding-right 1 2 3 4 */\n#test {right: 10px}\n/*right*/');
test();

$testcase = array('/** Two line comment\n * left\n \*/\n#test {left: 10px}');
$shouldbe = array('/** Two line comment\n * left\n \*/\n#test {right: 10px}');
test();

$test = 'testPositionAbsoluteOrRelativeValues';
$testcase = array('left: 10px');
$shouldbe = array('right: 10px');
test();


$test = 'testFourNotation';
$testcase = array('padding: .25em 15px 0pt 0ex');
$shouldbe = array('padding: .25em 0ex 0pt 15px');
test();

$testcase = array('margin: 1px -4px 3px 2px');
$shouldbe = array('margin: 1px 2px 3px -4px');
test();

$testcase = array('padding:0 15px .25em 0');
$shouldbe = array('padding:0 0 .25em 15px');
test();

$testcase = array('padding: 1px 4.1grad 3px 2%');
$shouldbe = array('padding: 1px 2% 3px 4.1grad');
test();

$testcase = array('padding: 1px 2px 3px auto');
$shouldbe = array('padding: 1px auto 3px 2px');
test();

$testcase = array('padding: 1px inherit 3px auto');
$shouldbe = array('padding: 1px auto 3px inherit');
test();

# not really four notation
$testcase = array('#settings td p strong');
$shouldbe = $testcase;
test();

$test = 'testThreeNotation';
$testcase = array('margin: 1em 0 .25em');
$shouldbe = array('margin: 1em 0 .25em');
test();

$testcase = array('margin:-1.5em 0 -.75em');
$shouldbe = array('margin:-1.5em 0 -.75em');
test();

$test = 'testTwoNotation';
$testcase = array('padding: 1px 2px');
$shouldbe = array('padding: 1px 2px');
test();

$test = 'testOneNotation';
$testcase = array('padding: 1px');
$shouldbe = array('padding: 1px');
test();

$test = 'testDirection';
# we don't want direction to be changed other than in body
$testcase = array('direction: ltr');
$shouldbe = array('direction: ltr');
test();

# we don't want direction to be changed other than in body
$testcase = array('direction: rtl');
$shouldbe = array('direction: rtl');
test();

# we don't want direction to be changed other than in body
$testcase = array('input { direction: ltr }');
$shouldbe = array('input { direction: ltr }');
test();

$testcase = array('body { direction: ltr }');
$shouldbe = array('body { direction: rtl }');
test();

$testcase = array('body { padding: 10px; direction: ltr; }');
$shouldbe = array('body { padding: 10px; direction: rtl; }');
test();

$testcase = array('body { direction: ltr } .myClass { direction: ltr }');
$shouldbe = array('body { direction: rtl } .myClass { direction: ltr }');
test();

$testcase = array('body{\n direction: ltr\n}');
$shouldbe = array('body{\n direction: rtl\n}');
test();

$test = 'testDoubleDash';
$testcase = array('border-left-color: red');
$shouldbe = array('border-right-color: red');
test();

$testcase = array('border-right-color: red');
$shouldbe = array('border-left-color: red');
test();

# This is for compatibility strength, in reality CSS has no properties
# that are currently like this.
$test = 'testCSSProperty';
$testcase = array('alright: 10px');
$shouldbe = array('alright: 10px');
test();

$testcase = array('alleft: 10px');
$shouldbe = array('alleft: 10px');
test();

$test = 'testFloat';
$testcase = array('float: right');
$shouldbe = array('float: left');
test();

$testcase = array('float: left');
$shouldbe = array('float: right');
test();

$test = 'testUrlWithFlagOff';
$swap_ltr_rtl_in_url = False;
$swap_left_right_in_url = False;

$testcase = array('background: url(/foo/bar-left.png)');
$shouldbe = array('background: url(/foo/bar-left.png)');
test();

$testcase = array('background: url(/foo/left-bar.png)');
$shouldbe = array('background: url(/foo/left-bar.png)');
test();

$testcase = array('url("http://www.blogger.com/img/triangle_ltr.gif")');
$shouldbe = array('url("http://www.blogger.com/img/triangle_ltr.gif")');
test();

$testcase = array("url('http://www.blogger.com/img/triangle_ltr.gif')");
$shouldbe = array("url('http://www.blogger.com/img/triangle_ltr.gif')");
test();

$testcase = array("url('http://www.blogger.com/img/triangle_ltr.gif'  )");
$shouldbe = array("url('http://www.blogger.com/img/triangle_ltr.gif'  )");
test();

$testcase = array('background: url(/foo/bar.left.png)');
$shouldbe = array('background: url(/foo/bar.left.png)');
test();

$testcase = array('background: url(/foo/bar-rtl.png)');
$shouldbe = array('background: url(/foo/bar-rtl.png)');
test();

$testcase = array('background: url(/foo/bar-rtl.png); left: 10px');
$shouldbe = array('background: url(/foo/bar-rtl.png); right: 10px');
test();

$testcase = array('background: url(/foo/bar-right.png); direction: ltr');
$shouldbe = array('background: url(/foo/bar-right.png); direction: ltr');
test();

$testcase = array('background: url(/foo/bar-rtl_right.png);',
          'left:10px; direction: ltr');
$shouldbe = array('background: url(/foo/bar-rtl_right.png);',
          'right:10px; direction: ltr');
test();

$test = 'testUrlWithFlagOn';
$swap_ltr_rtl_in_url = True;
$swap_left_right_in_url = True;

$testcase = array('background: url(/foo/bar-left.png)');
$shouldbe = array('background: url(/foo/bar-right.png)');
test();

$testcase = array('background: url(/foo/left-bar.png)');
$shouldbe = array('background: url(/foo/right-bar.png)');
test();

$testcase = array('url("http://www.blogger.com/img/triangle_ltr.gif")');
$shouldbe = array('url("http://www.blogger.com/img/triangle_rtl.gif")');
test();

$testcase = array("url('http://www.blogger.com/img/triangle_ltr.gif')");
$shouldbe = array("url('http://www.blogger.com/img/triangle_rtl.gif')");
test();

$testcase = array("url('http://www.blogger.com/img/triangle_ltr.gif'  )");
$shouldbe = array("url('http://www.blogger.com/img/triangle_rtl.gif'  )");
test();

$testcase = array('background: url(/foo/bar.left.png)');
$shouldbe = array('background: url(/foo/bar.right.png)');
test();

$testcase = array('background: url(/foo/bright.png)');
$shouldbe = array('background: url(/foo/bright.png)');
test();

$testcase = array('background: url(/foo/bar-rtl.png)');
$shouldbe = array('background: url(/foo/bar-ltr.png)');
test();

$testcase = array('background: url(/foo/bar-rtl.png); left: 10px');
$shouldbe = array('background: url(/foo/bar-ltr.png); right: 10px');
test();

$testcase = array('background: url(/foo/bar-right.png); direction: ltr');
$shouldbe = array('background: url(/foo/bar-left.png); direction: ltr');
test();

$testcase = array('background: url(/foo/bar-rtl_right.png);',
          'left:10px; direction: ltr');
$shouldbe = array('background: url(/foo/bar-ltr_left.png);',
          'right:10px; direction: ltr');
test();

$test = 'testPadding';
$testcase = array('padding-right: bar');
$shouldbe = array('padding-left: bar');
test();

$testcase = array('padding-left: bar');
$shouldbe = array('padding-right: bar');
test();

$test = 'testMargin';
$testcase = array('margin-left: bar');
$shouldbe = array('margin-right: bar');
test();

$testcase = array('margin-right: bar');
$shouldbe = array('margin-left: bar');
test();

$test = 'testBorder';
$testcase = array('border-left: bar');
$shouldbe = array('border-right: bar');
test();

$testcase = array('border-right: bar');
$shouldbe = array('border-left: bar');
test();

$test = 'testCursor';
$testcase = array('cursor: e-resize');
$shouldbe = array('cursor: w-resize');
test();

$testcase = array('cursor: w-resize');
$shouldbe = array('cursor: e-resize');
test();

$testcase = array('cursor: se-resize');
$shouldbe = array('cursor: sw-resize');
test();

$testcase = array('cursor: sw-resize');
$shouldbe = array('cursor: se-resize');
test();

$testcase = array('cursor: ne-resize');
$shouldbe = array('cursor: nw-resize');
test();

$testcase = array('cursor: nw-resize');
$shouldbe = array('cursor: ne-resize');
test();

$test = 'testBGPosition';
$testcase = array('background: url(/foo/bar.png) top left');
$shouldbe = array('background: url(/foo/bar.png) top right');
test();

$testcase = array('background: url(/foo/bar.png) top right');
$shouldbe = array('background: url(/foo/bar.png) top left');
test();

$testcase = array('background-position: top left');
$shouldbe = array('background-position: top right');
test();

$testcase = array('background-position: top right');
$shouldbe = array('background-position: top left');
test();

$test = 'testBGPositionPercentage';
$testcase = array('background-position: 100% 40%');
$shouldbe = array('background-position: 0% 40%');
test();

$testcase = array('background-position: 0% 40%');
$shouldbe = array('background-position: 100% 40%');
test();

$testcase = array('background-position: 23% 0');
$shouldbe = array('background-position: 77% 0');
test();

$testcase = array('background-position: 23% auto');
$shouldbe = array('background-position: 77% auto');
test();

$testcase = array('background-position-x: 23%');
$shouldbe = array('background-position-x: 77%');
test();

$testcase = array('background-position-y: 23%');
$shouldbe = array('background-position-y: 23%');
test();

$testcase = array('background:url(../foo-bar_baz.2008.gif) no-repeat 75% 50%');
$shouldbe = array('background:url(../foo-bar_baz.2008.gif) no-repeat 25% 50%');
test();

$testcase = array('.test { background: 10% 20% } .test2 { background: 40% 30% }');
$shouldbe = array('.test { background: 90% 20% } .test2 { background: 60% 30% }');
test();

$testcase = array('.test { background: 0% 20% } .test2 { background: 40% 30% }');
$shouldbe = array('.test { background: 100% 20% } .test2 { background: 60% 30% }');
test();

$test = 'testDirectionalClassnames';
/*
"""Makes sure we don't unnecessarily destroy classnames with tokens in them.

Despite the fact that that is a bad classname in CSS, we don't want to
break anybody.
"""
*/
$testcase = array('.column-left { float: left }');
$shouldbe = array('.column-left { float: right }');
test();

$testcase = array('#bright-light { float: left }');
$shouldbe = array('#bright-light { float: right }');
test();

$testcase = array('a.left:hover { float: left }');
$shouldbe = array('a.left:hover { float: right }');
test();

#tests newlines
$testcase = array("#bright-left,\n.test-me { float: left }");
$shouldbe = array("#bright-left,\n.test-me { float: right }");
test();

#tests newlines
$testcase = array("#bright-left,", '.test-me { float: left }');
$shouldbe = array("#bright-left,", '.test-me { float: right }');
test();

#tests multiple names and commas
$testcase = array('div.leftpill, div.leftpillon {margin-right: 0 !important}');
$shouldbe = array('div.leftpill, div.leftpillon {margin-left: 0 !important}');
test();

$testcase = array('div.left > span.right+span.left { float: left }');
$shouldbe = array('div.left > span.right+span.left { float: right }');
test();

$testcase = array('.thisclass .left .myclass {background:#fff;}');
$shouldbe = array('.thisclass .left .myclass {background:#fff;}');
test();

$testcase = array('.thisclass .left .myclass #myid {background:#fff;}');
$shouldbe = array('.thisclass .left .myclass #myid {background:#fff;}');
test();


$test = 'testLongLineWithMultipleDefs';
$testcase = array('body{direction:rtl;float:right}
          .b2{direction:ltr;float:right}');
$shouldbe = array('body{direction:ltr;float:left}
          .b2{direction:ltr;float:left}');
test();

$test = 'testNoFlip';
# """Tests the /* @noflip */ annotation on classnames."""
$testcase = array('/* @noflip */ div { float: left; }');
$shouldbe = array('/* @noflip */ div { float: left; }');
test();

$testcase = array('/* @noflip */ div, .notme { float: left; }');
$shouldbe = array('/* @noflip */ div, .notme { float: left; }');
test();

$testcase = array('/* @noflip */ div { float: left; } div { float: left; }');
$shouldbe = array('/* @noflip */ div { float: left; } div { float: right; }');
test();

$testcase = array('/* @noflip */\ndiv { float: left; }\ndiv { float: left; }');
$shouldbe = array('/* @noflip */\ndiv { float: left; }\ndiv { float: right; }');
test();

# Test @noflip on single rules within classes
$testcase = array('div { float: left; /* @noflip */ float: left; }');
$shouldbe = array('div { float: right; /* @noflip */ float: left; }');
test();

$testcase = array('div\n{ float: left;\n/* @noflip */\n float: left;\n }');
$shouldbe = array('div\n{ float: right;\n/* @noflip */\n float: left;\n }');
test();

$testcase = array('div\n{ float: left;\n/* @noflip */\n text-align: left\n }');
$shouldbe = array('div\n{ float: right;\n/* @noflip */\n text-align: left\n }');
test();

$testcase = array('div\n{ /* @noflip */\ntext-align: left;\nfloat: left\n  }');
$shouldbe = array('div\n{ /* @noflip */\ntext-align: left;\nfloat: right\n  }');
test();

$testcase = array('/* @noflip */div{float:left;text-align:left;}div{float:left}');
$shouldbe = array('/* @noflip */div{float:left;text-align:left;}div{float:right}');
test();

$testcase = array('/* @noflip */','div{float:left;text-align:left;}a{foo:left}');
$shouldbe = array('/* @noflip */','div{float:left;text-align:left;}a{foo:right}');
test();

$test = 'testBorderRadiusNotation';
$testcase = array('border-radius: .25em 15px 0pt 0ex');
$shouldbe = array('border-radius: 15px .25em 0ex 0pt');
test();

$testcase = array('border-radius: 10px 15px 0px');
$shouldbe = array('border-radius: 15px 10px 15px 0px');
test();

$testcase = array('border-radius: 7px 8px');
$shouldbe = array('border-radius: 8px 7px');
test();

$testcase = array('border-radius: 5px');
$shouldbe = array('border-radius: 5px');
test();

$test = 'testGradientNotation';
$testcase = array('background-image: -moz-linear-gradient(#326cc1, #234e8c)');
$shouldbe = array('background-image: -moz-linear-gradient(#326cc1, #234e8c)');
test();

$testcase = array('background-image: -webkit-gradient(linear, 100% 0%, 0% 0%, from(#666666), to(#ffffff))');
$shouldbe = array('background-image: -webkit-gradient(linear, 100% 0%, 0% 0%, from(#666666), to(#ffffff))');
test();
PKY~!]=�� j jja.cssjanus.phpnu&1i�<?php
/**
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 * http://www.gnu.org/copyleft/gpl.html
 *
 */

/**
 * This is a rewrite & update version of PHP port of CSSJanus, a utility that transforms CSS style sheets
 * written for LTR to RTL.
 *
 * The original Python version of CSSJanus is Copyright 2008 by Google Inc. and
 * is distributed under the Apache license.
 *
 * The original PHP version of CSSJanus: https://doc.wikimedia.org/mediawiki-core/master/php/html/CSSJanus_8php.html.
 *
 * Original code: http://code.google.com/p/cssjanus/source/browse/trunk/cssjanus.py
 * License of original code: http://code.google.com/p/cssjanus/source/browse/trunk/LICENSE
 * @author Khanh Le
 *
 */
require_once 'csslex.php';

class JACSSJanus {
	// Patterns defined as null are built dynamically by buildPatterns()

	private static $patterns = array(

	);

	public static function getPatterns () {
		self::buildPatterns();
		return self::$patterns;
	}
	/**
	 * Build patterns we can't define above because they depend on other patterns.
	 */
	private static function buildPatterns() {
		//increase the backtrack limit
		@ini_set('pcre.backtrack_limit', '2M');

		if ( isset( self::$patterns['token_delimiter'] ) ) {
			// Patterns have already been built
			return;
		}
		$csslex = new CSSLEX;

		$patterns =& self::$patterns;
		$patterns['token_delimiter'] = '`';
		$patterns['tmp_token'] = sprintf('%sTMP%s', $patterns['token_delimiter'], $patterns['token_delimiter']);
		$patterns['token_lines'] = sprintf('%sj%s', $patterns['token_delimiter'], $patterns['token_delimiter']);

		# global constant text strings for css value matches.
		$patterns['ltr'] = 'ltr';
		$patterns['rtl'] = 'rtl';
		$patterns['left'] = 'left';
		$patterns['right'] = 'right';

		# this is a lookbehind match to ensure that we don't replace instances
		# of our string token (left, rtl, etc...) if there's a letter in front of it.
		# specifically, this prevents replacements like 'background: url(bright.png)'.
		$patterns['lookbehind_not_letter'] = '(?<![a-za-z])';

		# this is a lookahead match to make sure we don't replace left and right
		# in actual classnames, so that we don't break the html/css dependencies.
		# read literally, it says ignore cases where the word left, for instance, is
		# directly followed by valid classname characters and a curly brace.
		# ex: .column-left {float: left} will become .column-left {float: right}
		$patterns['lookahead_not_open_brace'] = sprintf('(?!(?:%s|%s|%s|#|\:|\.|\,|\+|]|=|>)*?(\,|{))',
		                            $csslex->nmchar, $patterns['token_lines'], $csslex->space);


		# these two lookaheads are to test whether or not we are within a
		# background: url(here) situation.
		# ref: http://www.w3.org/tr/css21/syndata.html#uri
		$patterns['valid_after_uri_chars'] = sprintf("[\'\"]?%s", $csslex->whitespace);
		$patterns['lookahead_not_closing_paren'] = sprintf("(?!%s?%s\))", $csslex->url_chars,
		                                                $patterns['valid_after_uri_chars']);
		$patterns['lookahead_for_closing_paren'] = sprintf("(?=%s?%s\))", $csslex->url_chars,
		                                                $patterns['valid_after_uri_chars']);

		# compile a regex to swap left and right values in 4 part notations.
		# we need to match negatives and decimal numeric values.
		# the case of border-radius is extra complex, so we handle it separately below.
		# ex. 'margin: .25em -2px 3px 0' becomes 'margin: .25em 0 3px -2px'.

		$patterns['possibly_negative_quantity'] = sprintf('((?:-?%s)|(?:inherit|auto))', $csslex->quantity);
		$patterns['possibly_negative_quantity_space'] = sprintf('%s%s%s', $patterns['possibly_negative_quantity'],
		                                                $csslex->space,
		                                                $csslex->whitespace);
		$patterns['four_notation_quantity_re'] = sprintf('/%s%s%s%s/i',
		                                        $patterns['possibly_negative_quantity_space'],
		                                        $patterns['possibly_negative_quantity_space'],
		                                        $patterns['possibly_negative_quantity_space'],
		                                        $patterns['possibly_negative_quantity']
		                                       );
		$patterns['color'] = sprintf('(%s|%s)', $csslex->name, $csslex->hash);
		$patterns['color_space'] = sprintf('%s%s', $patterns['color'], $csslex->space);
		$patterns['four_notation_color_re'] = sprintf('/(-color%s:%s)%s%s%s(%s)/i',
		                                     $csslex->whitespace,
		                                     $csslex->whitespace,
		                                     $patterns['color_space'],
		                                     $patterns['color_space'],
		                                     $patterns['color_space'],
		                                     $patterns['color']
		                                    );

		# border-radius is very different from usual 4 part notation: abcd should
		# change to badc (while it would be adcb in normal 4 part notation), abc
		# should change to babc, and ab should change to ba
		$patterns['border_radius_re'] = sprintf('/((?:%s)?)border-radius(%s:%s)'
		                               .'(?:%s)?(?:%s)?(?:%s)?(?:%s)'
		                               .'(?:%s\/%s(?:%s)?(?:%s)?(?:%s)?(?:%s))?/i',$csslex->ident,
		                                                                          $csslex->whitespace,
		                                                                          $csslex->whitespace,
		                                                                          $patterns['possibly_negative_quantity_space'],
		                                                                          $patterns['possibly_negative_quantity_space'],
		                                                                          $patterns['possibly_negative_quantity_space'],
		                                                                          $patterns['possibly_negative_quantity'],
		                                                                          $csslex->whitespace,
		                                                                          $csslex->whitespace,
		                                                                          $patterns['possibly_negative_quantity_space'],
		                                                                          $patterns['possibly_negative_quantity_space'],
		                                                                          $patterns['possibly_negative_quantity_space'],
		                                                                          $patterns['possibly_negative_quantity']
		                              );

		# compile the cursor resize regexes
		$patterns['cursor_east_re'] = '/' . $patterns['lookbehind_not_letter'] . '([ns]?)e-resize/';
		$patterns['cursor_west_re'] = '/' . $patterns['lookbehind_not_letter'] . '([ns]?)w-resize/';

		# matches the condition where we need to replace the horizontal component
		# of a background-position value when expressed in horizontal percentage.
		# had to make two regexes because in the case of position-x there is only
		# one quantity, and otherwise we don't want to match and change cases with only
		# one quantity.
		$patterns['bg_horizontal_percentage_re'] = sprintf('/background(-position)?(%s:%s)'
		                                                   .'([^%%]*?)(%s)%%'
		                                                   .'(%s(?:%s|top|center|bottom))/',
		                                                   $csslex->whitespace,
		                                                   $csslex->whitespace,
		                                                   $csslex->num,
		                                                   $csslex->whitespace,
		                                                   $patterns['possibly_negative_quantity']
		                                                   );

		$patterns['bg_horizontal_percentage_x_re'] = sprintf('/background-position-x(%s:%s)(%s)%%/', $csslex->whitespace,
		                                                       $csslex->whitespace,
		                                                       $csslex->num);

		# non-percentage units used for css lengths
		$patterns['length_unit'] = '(?:em|ex|px|cm|mm|in|pt|pc)';
		# to make sure the lone 0 is not just starting a number (like "02") or a percentage like ("0 %");
		$patterns['lookahead_end_of_zero'] = sprintf('(?![0-9]|%s%%)', $csslex->whitespace);
		# a length with a unit specified. matches "0" too, as it's a length, not a percentage.
		$patterns['length'] = sprintf('(?:-?%s(?:%s%s)|0+%s)', $csslex->num,
		                                    $csslex->whitespace,
		                                    $patterns['length_unit'],
		                                    $patterns['lookahead_end_of_zero']);

		# zero length. used in the replacement functions.
		$patterns['zero_length'] = sprintf('/(?:-?0+(?:%s%s)|0+%s)$/', $csslex->whitespace,
		                                                      $patterns['length_unit'],
		                                                      $patterns['lookahead_end_of_zero']);

		# matches background, background-position, and background-position-x
		# properties when using a css length for its horizontal positioning.
		$patterns['bg_horizontal_length_re'] = sprintf('/background(-position)?(%s:%s)'
		                                      .'((?:.+?%s+)??)(%s)'
		                                      .'((?:%s+)(?:%s|top|center|bottom))/', $csslex->whitespace,
		                                                                            $csslex->whitespace,
		                                                                            $csslex->space,
		                                                                            $patterns['length'],
		                                                                            $csslex->space,
		                                                                            $patterns['possibly_negative_quantity']);

		$patterns['bg_horizontal_length_x_re'] = sprintf('/background-position-x(%s:%s)(%s)/', $csslex->whitespace,
		                                                  $csslex->whitespace,
		                                                  $patterns['length']);

		# matches the opening of a body selector.
		$patterns['body_selector'] = sprintf('body%s{%s', $csslex->whitespace, $csslex->whitespace);

		# matches anything up until the closing of a selector.
		$patterns['chars_within_selector'] = '[^\}]*?';

		# matches the direction property in a selector.
		$patterns['direction_re'] = sprintf('direction%s:%s', $csslex->whitespace, $csslex->whitespace);

		# these allow us to swap "ltr" with "rtl" and vice versa only within the
		# body selector and on the same line.
		$patterns['body_direction_ltr_re'] = sprintf('/(%s)(%s)(%s)(ltr)/i',
		                                    $patterns['body_selector'], 
		                                    $patterns['chars_within_selector'],
		                                    $patterns['direction_re']
		                                   );
		$patterns['body_direction_rtl_re'] = sprintf('/(%s)(%s)(%s)(rtl)/i',
		                                    $patterns['body_selector'],
		                                    $patterns['chars_within_selector'],
		                                    $patterns['direction_re']
		                                   );


		# allows us to swap "direction:ltr" with "direction:rtl" and
		# vice versa anywhere in a line.
		$patterns['direction_ltr_re'] = sprintf('/%s(ltr)/', $patterns['direction_re']);
		$patterns['direction_rtl_re'] = sprintf('/%s(rtl)/', $patterns['direction_re']);

		# we want to be able to switch left with right and vice versa anywhere
		# we encounter left/right strings, except inside the background:url(). the next
		# two regexes are for that purpose. we have alternate in_url versions of the
		# regexes compiled in case the user passes the flag that they do
		# actually want to have left and right swapped inside of background:urls.
		$patterns['left_re'] = sprintf('/%s((?:top|bottom)?)(%s)%s%s/i', $patterns['lookbehind_not_letter'],
		                                                      $patterns['left'],
		                                                      $patterns['lookahead_not_closing_paren'],
		                                                      $patterns['lookahead_not_open_brace']
		                     );
		$patterns['right_re'] = sprintf('/%s((?:top|bottom)?)(%s)%s%s/i', $patterns['lookbehind_not_letter'],
		                                                       $patterns['right'],
		                                                       $patterns['lookahead_not_closing_paren'],
		                                                       $patterns['lookahead_not_open_brace']);
		$patterns['left_in_url_re'] = sprintf('/%s(%s)%s/i', $patterns['lookbehind_not_letter'],
		                                          $patterns['left'],
		                                          $patterns['lookahead_for_closing_paren']);
		$patterns['right_in_url_re'] = sprintf('/%s(%s)%s/i', $patterns['lookbehind_not_letter'],
		                                           $patterns['right'],
		                                           $patterns['lookahead_for_closing_paren']);
		$patterns['ltr_in_url_re'] = sprintf('/%s(%s)%s/i', $patterns['lookbehind_not_letter'],
		                                         $patterns['ltr'],
		                                         $patterns['lookahead_for_closing_paren']);
		$patterns['rtl_in_url_re'] = sprintf('/%s(%s)%s/i', $patterns['lookbehind_not_letter'],
		                                         $patterns['rtl'],
		                                         $patterns['lookahead_for_closing_paren']);

		$patterns['comment_re'] = sprintf('/(%s)/i', $csslex->comment);

		$patterns['noflip_token'] = '\@noflip';
		# the noflip_token inside of a comment. for now, this requires that comments
		# be in the input, which means users of a css compiler would have to run
		# this script first if they want this functionality.
		$patterns['noflip_annotation'] = sprintf('\/\*%s%s%s\*\/', $csslex->whitespace,
		                                       $patterns['noflip_token'],
		                                       $csslex->whitespace);

		# after a noflip_annotation, and within a class selector, we want to be able
		# to set aside a single rule not to be flipped. we can do this by matching
		# our noflip annotation and then using a lookahead to make sure there is not
		# an opening brace before the match.
		$patterns['noflip_single_re'] = sprintf('/(%s%s[^;}]+;?)/i', $patterns['noflip_annotation'],
		                                                   $patterns['lookahead_not_open_brace']);

		# after a noflip_annotation, we want to grab anything up until the next } which
		# means the entire following class block. this will prevent all of its
		# declarations from being flipped.
		$patterns['noflip_class_re'] = sprintf('/(%s%s})/i', $patterns['noflip_annotation'],
		                                           $patterns['chars_within_selector']);

		# border-radis properties and their values
		$patterns['border_radius_tokenizer_re'] = sprintf('/((?:%s)?border-radius%s:[^;}]+;?)/i', $csslex->ident,
		                                                                                $csslex->whitespace);
		$patterns['gradient_re'] = sprintf('/%s[\.-]gradient%s\(/i', $csslex->ident, $csslex->whitespace);

	}

	/**
	 * Transform an LTR stylesheet to RTL
	 * @param $css String: stylesheet to transform
	 * @param $swapLtrRtlInURL Boolean: If true, swap 'ltr' and 'rtl' in URLs
	 * @param $swapLeftRightInURL Boolean: If true, swap 'left' and 'right' in URLs
	 * @return Transformed stylesheet
	 */
	public static function transform( $css, $swapLtrRtlInURL = false, $swapLeftRightInURL = false ) {
		self::buildPatterns();
		// We wrap tokens in ` , not ~ like the original implementation does.
		// This was done because ` is not a legal character in CSS and can only
		// occur in URLs, where we escape it to %60 before inserting our tokens.
		$css = str_replace( self::$patterns['token_delimiter'], '%60', $css );


		// Tokenize single line rules with /* @noflip */
		$noFlipSingle = new CSSJanus_Tokenizer( self::$patterns['noflip_single_re'], '`NOFLIP_SINGLE`' );
		$css = $noFlipSingle->tokenize( $css );

		// Tokenize class rules with /* @noflip */
		$noFlipClass = new CSSJanus_Tokenizer( self::$patterns['noflip_class_re'], '`NOFLIP_CLASS`' );
		$css = $noFlipClass->tokenize( $css );

		// Tokenize comments
		$comments = new CSSJanus_Tokenizer( self::$patterns['comment_re'], '`C`' );
		$css = $comments->tokenize( $css );

	  # Tokenize gradients since we don't want to mirror the values inside
		//$comments = new CSSJanus_Tokenizer( self::$patterns['comment_re']GradientMatcher(), '`GRADIENT`' );
		//$css = $comments->tokenize( $css );

		// LTR->RTL fixes start here
		$css = self::FixBodyDirectionLtrAndRtl( $css );

		if ( $swapLtrRtlInURL ) {
			$css = self::fixLtrRtlInURL( $css );
		}

		if ( $swapLeftRightInURL ) {
			$css = self::fixLeftRightInURL( $css );
		}
		$css = self::fixLeftAndRight( $css );
		$css = self::fixCursorProperties( $css );

		$css = self::fixBorderRadius( $css );
		# Since FourPartNotation conflicts with BorderRadius, we tokenize border-radius properties here.
		$border_radius_tokenizer = new CSSJanus_Tokenizer( self::$patterns['border_radius_tokenizer_re'], '`BORDER_RADIUS`' );
		$css = $border_radius_tokenizer->tokenize( $css );

		$css = self::fixFourPartNotation( $css );

		$css = $border_radius_tokenizer->detokenize( $css );

		$css = self::fixBackgroundPosition( $css );

		// Detokenize stuff we tokenized before
		$css = $comments->detokenize( $css );
		$css = $noFlipClass->detokenize( $css );
		$css = $noFlipSingle->detokenize( $css );

		return $css;
	}

	/**
	 * Replaces ltr with rtl and vice versa ONLY in the body direction.
	 *
	 */
	private static function FixBodyDirectionLtrAndRtl( $css ) {
		$css = preg_replace( self::$patterns['body_direction_ltr_re'], '\1\2\3' . self::$patterns['tmp_token'], $css );
		$css = preg_replace( self::$patterns['body_direction_rtl_re'], '\1\2\3' . self::$patterns['ltr'], $css );
		$css = str_replace( self::$patterns['tmp_token'], self::$patterns['rtl'], $css );

		return $css;
	}

	/**
	 * Flip rules like left: , padding-right: , etc.
	 */
	private static function fixLeftAndRight( $css ) {
		$css = preg_replace( self::$patterns['left_re'], '\1' . self::$patterns['tmp_token'], $css );
		$css = preg_replace( self::$patterns['right_re'], '\1' . self::$patterns['left'], $css );
		$css = str_replace( self::$patterns['tmp_token'], self::$patterns['right'], $css );

		return $css;
	}

	/**
	 * Replace 'left' with 'right' and vice versa in background URLs
	 */
	private static function fixleftrightinurl( $css ) {
		$css = preg_replace( self::$patterns['left_in_url_re'], self::$patterns['tmp_token'], $css );
		$css = preg_replace( self::$patterns['right_in_url_re'], self::$patterns['left'], $css );
		$css = str_replace( self::$patterns['tmp_token'], self::$patterns['right'], $css );

		return $css;
	}

	/**
	 * replace 'ltr' with 'rtl' and vice versa in background urls
	 */
	private static function fixltrrtlinurl( $css ) {
		$css = preg_replace( self::$patterns['ltr_in_url_re'], self::$patterns['tmp_token'], $css );
		$css = preg_replace( self::$patterns['rtl_in_url_re'], self::$patterns['ltr'], $css );
		$css = str_replace( self::$patterns['tmp_token'], self::$patterns['rtl'], $css );

		return $css;
	}

	/**
	 * flip east and west in rules like cursor: nw-resize;
	 */
	private static function fixcursorproperties( $css ) {
		$css = preg_replace( self::$patterns['cursor_east_re'], '\1' . self::$patterns['tmp_token'], $css );
		$css = preg_replace( self::$patterns['cursor_west_re'], '\1e-resize', $css );
		$css = str_replace( self::$patterns['tmp_token'], 'w-resize', $css );

		return $css;
	}

	/**
	 * Fixes border-radius and its browser-specific variants.
	 */
	private static function fixBorderRadius( $css ) {
//echo self::$patterns['border_radius_re']; die();		
		$css = preg_replace_callback(self::$patterns['border_radius_re'], array( 'self', 'reorderBorderRadius' ), $css );

		return $css;
	}

	/**
	 * Fixes border-radius and its browser-specific variants.
	 */
	private static function reorderBorderRadius( $matches ) {
	  $first_group = self::reorderBorderRadiusPart(array_slice ($matches, 3, 4));
  	$second_group = self::reorderBorderRadiusPart(array_slice  ($matches, 7));
  	if ($second_group == '') 
    	return sprintf('%sborder-radius%s%s', $matches[1], $matches[2], $first_group);
  	else
    	return sprintf('%sborder-radius%s%s / %s', $matches[1], $matches[2], $first_group, $second_group);
	}

	/**
	 * Fixes border-radius and its browser-specific variants.
	 */
	private static function reorderBorderRadiusPart( $ps ) {
	  # Remove any piece which may be 'None'
	  $part = array();
	  foreach ($ps as $p) {
	  	if ($p != '') $part[] = $p;
	  }
	  
	  if (count($part) == 4) {
	    return sprintf('%s %s %s %s', $part[1], $part[0], $part[3], $part[2]);
	  } elseif (count($part) == 3) {
	    return sprintf('%s %s %s %s', $part[1], $part[0], $part[1], $part[2]);
	  } elseif (count($part) == 2) {
	    return sprintf('%s %s', $part[1], $part[0]);
	  } elseif (count($part) == 1) {
	    return $part[0];
	  } elseif (count($part) == 0) {
	    return '';
	  } else {
	  	return null;
	  }
	}

	/**
	 * Swap the second and fourth parts in four-part notation rules like
	 * padding: 1px 2px 3px 4px;
	 *
	 * Unlike the original implementation, this function doesn't suffer from
	 * the bug where whitespace is not preserved when flipping four-part rules
	 * and four-part color rules with multiple whitespace characters between
	 * colors are not recognized.
	 * See http://code.google.com/p/cssjanus/issues/detail?id=16
	 */
	private static function fixFourPartNotation( $css ) {
		$css = preg_replace( self::$patterns['four_notation_quantity_re'], '\1 \4 \3 \2', $css );
		$css = preg_replace( self::$patterns['four_notation_color_re'], '\1\2 \5 \4 \3', $css );

		return $css;
	}

	/**
	 * Flip horizontal background percentages.
	 */
	private static function fixBackgroundPosition( $css ) {
		$css = preg_replace_callback( self::$patterns['bg_horizontal_percentage_re'],
			array( 'self', 'calculateNewBackgroundPosition' ), $css );
		$css = preg_replace_callback( self::$patterns['bg_horizontal_percentage_x_re'],
			array( 'self', 'calculateNewBackgroundPositionX' ), $css );
		$css = preg_replace_callback( self::$patterns['bg_horizontal_length_re'],
			array( 'self', 'calculateNewBackgroundLengthPosition' ), $css );
		$css = preg_replace_callback( self::$patterns['bg_horizontal_length_x_re'],
			array( 'self', 'calculateNewBackgroundLengthPositionX' ), $css );

		return $css;
	}

	/**
	 * Callback for calculateNewBackgroundPosition()
	 */
	private static function calculateNewBackgroundPosition( $matches ) {
	  # The flipped value is the offset from 100%
	  $new_x = 100-intval($matches[4]);

	  # Since m.group(1) may very well be None type and we need a string..
	  if ($matches[1]){
	    $position_string = $matches[1];
	  } else {
	    $position_string = '';
		}
	  return sprintf('background%s%s%s%s%%%s', $position_string, $matches[2], $matches[3], $new_x, $matches[5]);
	}

	/**
	 * Callback for calculateNewBackgroundPosition()
	 */
	private static function calculateNewBackgroundPositionX( $matches ) {
	  # The flipped value is the offset from 100%
	  $new_x = 100-intval($matches[2]);

	  return sprintf('background-position-x%s%s%%', $matches[1], $new_x);
	}

	/**
	 * Fixes horizontal background-position lengths.
	 * Return: A string with the horizontal background position set to 100%, if zero. 
	 */
	private static function calculateNewBackgroundLengthPosition( $matches ) {
	  # return original if error
	  if ($matches[4]) {
	    return $matches[0];
	  }

	  # Since m.group(1) may very well be None type and we need a string..
	  if ($matches[1]){
	    $position_string = $matches[1];
	  } else {
	    $position_string = '';
		}
	  return sprintf('background%s%s%s100%%%s', $position_string, $matches[2], $matches[3], $matches[5]);

	}

	/**
	 * Fixes background-position-x lengths
	 * Return: A string with the background-position-x set to 100%, if zero.
	 */
	private static function calculateNewBackgroundLengthPositionX( $matches ) {
	  # return original if error
	  if ($matches[2]) {
	    return $matches[0];
	  }
	  
  	return sprintf('background-position-x%s100%%', $matches[1]);
	}
}




/**
 * Utility class used by CSSJanus that tokenizes and untokenizes things we want
 * to protect from being janused.
 * @author Roan Kattouw
 */
class CSSJanus_Tokenizer {
	private $regex, $token;
	private $originals;

	/**
	 * Constructor
	 * @param $regex string Regular expression whose matches to replace by a token.
	 * @param $token string Token
	 */
	public function __construct( $regex, $token ) {
		$this->regex = $regex;
		$this->token = $token;
		$this->originals = array();
	}

	/**
	 * Replace all occurrences of $regex in $str with a token and remember
	 * the original strings.
	 * @param $str String to tokenize
	 * @return string Tokenized string
	 */
	public function tokenize( $str ) {
		return preg_replace_callback( $this->regex, array( $this, 'tokenizeCallback' ), $str );
	}

	private function tokenizeCallback( $matches ) {
		$this->originals[] = $matches[0];
		return $this->token;
	}

	/**
	 * Replace tokens with their originals. If multiple strings were tokenized, it's important they be
	 * detokenized in exactly the SAME ORDER.
	 * @param $str String: previously run through tokenize()
	 * @return string Original string
	 */
	public function detokenize( $str ) {
		// PHP has no function to replace only the first occurrence or to
		// replace occurrences of the same string with different values,
		// so we use preg_replace_callback() even though we don't really need a regex
		return preg_replace_callback( '/' . preg_quote( $this->token, '/' ) . '/',
			array( $this, 'detokenizeCallback' ), $str );
	}

	private function detokenizeCallback( $matches ) {
		$retval = current( $this->originals );
		next( $this->originals );

		return $retval;
	}
}PKY~!]*=�5&&
csslex.phpnu&1i�PKY~!]��Ƙ�=�=`test.phpnu&1i�PKY~!]=�� j j?Mja.cssjanus.phpnu&1i�PK���