Passed
Pull Request — patch_1-1-9 (#3692)
by Spuds
05:44
created
sources/subs/Unread.class.php 1 patch
Indentation   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -358,7 +358,7 @@  discard block
 block discarded – undo
358 358
 	 */
359 359
 	private function _getUnreadReplies($start, $limit, $include_avatars = false)
360 360
 	{
361
-        $request = $this->_db->query('unread_replies', '
361
+		$request = $this->_db->query('unread_replies', '
362 362
 				SELECT DISTINCT t.id_topic
363 363
 				FROM {db_prefix}topics AS t
364 364
 					INNER JOIN {db_prefix}messages AS m ON (m.id_topic = t.id_topic AND m.id_member = {int:current_member})' . (strpos($this->_sort_query, 'ms.') === false ? '' : '
@@ -369,19 +369,19 @@  discard block
 block discarded – undo
369 369
 				WHERE t.id_board IN ({array_int:boards})
370 370
 					AND t.id_last_msg >= {int:min_message}
371 371
 					AND COALESCE(lt.id_msg, lmr.id_msg, 0) < t.id_last_msg' .
372
-            ($this->_post_mod ? ' AND t.approved = {int:is_approved}' : '') .
373
-            ($this->_unwatch ? ' AND COALESCE(lt.unwatched, 0) != 1' : '') . '
372
+			($this->_post_mod ? ' AND t.approved = {int:is_approved}' : '') .
373
+			($this->_unwatch ? ' AND COALESCE(lt.unwatched, 0) != 1' : '') . '
374 374
 				ORDER BY {raw:order}
375 375
 				LIMIT {int:offset}, {int:limit}',
376
-            array_merge($this->_query_parameters, array(
377
-                'current_member' => $this->_user_id,
378
-                'min_message' => $this->_min_message,
379
-                'is_approved' => 1,
380
-                'order' => $this->_sort_query . ($this->_ascending ? '' : ' DESC'),
381
-                'offset' => $start,
382
-                'limit' => $limit,
383
-            ))
384
-        );
376
+			array_merge($this->_query_parameters, array(
377
+				'current_member' => $this->_user_id,
378
+				'min_message' => $this->_min_message,
379
+				'is_approved' => 1,
380
+				'order' => $this->_sort_query . ($this->_ascending ? '' : ' DESC'),
381
+				'offset' => $start,
382
+				'limit' => $limit,
383
+			))
384
+		);
385 385
 
386 386
 		$topics = array();
387 387
 		while ($row = $this->_db->fetch_assoc($request))
Please login to merge, or discard this patch.
sources/subs/Topic.subs.php 1 patch
Indentation   +21 added lines, -21 removed lines patch added patch discarded remove patch
@@ -1591,7 +1591,7 @@  discard block
 block discarded – undo
1591 1591
 	$db = database();
1592 1592
 
1593 1593
 	// Get the messages and stick them into an array.
1594
-    $request = $db->query('', '
1594
+	$request = $db->query('', '
1595 1595
 		SELECT 
1596 1596
 			m.subject, COALESCE(mem.real_name, m.poster_name) AS real_name, m.poster_time, m.body, 
1597 1597
 			m.id_msg, m.smileys_enabled, m.id_member 
@@ -1610,17 +1610,17 @@  discard block
 block discarded – undo
1610 1610
 		JOIN {db_prefix}messages as m ON o.id_msg=m.id_msg 
1611 1611
 		LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)
1612 1612
 		ORDER BY m.id_msg DESC',
1613
-        array(
1614
-            'current_topic' => $topic,
1615
-            'no_split_msgs' => !empty($messages['excluded']) ? $messages['excluded'] : array(),
1616
-            'split_msgs' => !empty($messages['included']) ? $messages['included'] : array(),
1617
-            'is_approved' => 1,
1618
-            'start' => $start,
1619
-            'messages_per_page' => $items_per_page,
1620
-            'msg_before' => !empty($messages['before']) ? (int) $messages['before'] : 0,
1621
-            'msg_after' => !empty($messages['after']) ? (int) $messages['after'] : 0,
1622
-        )
1623
-    );
1613
+		array(
1614
+			'current_topic' => $topic,
1615
+			'no_split_msgs' => !empty($messages['excluded']) ? $messages['excluded'] : array(),
1616
+			'split_msgs' => !empty($messages['included']) ? $messages['included'] : array(),
1617
+			'is_approved' => 1,
1618
+			'start' => $start,
1619
+			'messages_per_page' => $items_per_page,
1620
+			'msg_before' => !empty($messages['before']) ? (int) $messages['before'] : 0,
1621
+			'msg_after' => !empty($messages['after']) ? (int) $messages['after'] : 0,
1622
+		)
1623
+	);
1624 1624
 
1625 1625
 	$messages = array();
1626 1626
 	$parser = \BBC\ParserWrapper::instance();
@@ -2176,9 +2176,9 @@  discard block
 block discarded – undo
2176 2176
 	);
2177 2177
 
2178 2178
 	// When evaluating potentially huge offsets, grab the ids only, first.
2179
-    // The performance impact is still significant going from three columns to one.
2179
+	// The performance impact is still significant going from three columns to one.
2180 2180
 	$postMod = $modSettings['postmod_active'] && allowedTo('approve_posts');
2181
-    $request = $db->query('display_get_post_poster', '
2181
+	$request = $db->query('display_get_post_poster', '
2182 2182
 		SELECT 
2183 2183
 			m.id_msg, m.id_member
2184 2184
 		FROM (
@@ -2191,13 +2191,13 @@  discard block
 block discarded – undo
2191 2191
 			LIMIT ' . $limit['start'] . ', ' . $limit['offset']) . ') AS o 
2192 2192
 		JOIN {db_prefix}messages as m ON o.id_msg=m.id_msg
2193 2193
 		ORDER BY m.id_msg ' . ($sort ? '' : 'DESC'),
2194
-        array(
2195
-            'current_member' => $user_info['id'],
2196
-            'current_topic' => $topic,
2197
-            'is_approved' => 1,
2198
-            'blank_id_member' => 0,
2199
-        )
2200
-    );
2194
+		array(
2195
+			'current_member' => $user_info['id'],
2196
+			'current_topic' => $topic,
2197
+			'is_approved' => 1,
2198
+			'blank_id_member' => 0,
2199
+		)
2200
+	);
2201 2201
 	while ($row = $db->fetch_assoc($request))
2202 2202
 	{
2203 2203
 		if (!empty($row['id_member']))
Please login to merge, or discard this patch.
sources/ext/cssmin/tubalmartin/Minifier.php 1 patch
Indentation   +846 added lines, -846 removed lines patch added patch discarded remove patch
@@ -24,872 +24,872 @@
 block discarded – undo
24 24
 
25 25
 class Minifier
26 26
 {
27
-    const QUERY_FRACTION = '_CSSMIN_QF_';
28
-    const COMMENT_TOKEN = '_CSSMIN_CMT_%d_';
29
-    const COMMENT_TOKEN_START = '_CSSMIN_CMT_';
30
-    const RULE_BODY_TOKEN = '_CSSMIN_RBT_%d_';
31
-    const PRESERVED_TOKEN = '_CSSMIN_PTK_%d_';
27
+	const QUERY_FRACTION = '_CSSMIN_QF_';
28
+	const COMMENT_TOKEN = '_CSSMIN_CMT_%d_';
29
+	const COMMENT_TOKEN_START = '_CSSMIN_CMT_';
30
+	const RULE_BODY_TOKEN = '_CSSMIN_RBT_%d_';
31
+	const PRESERVED_TOKEN = '_CSSMIN_PTK_%d_';
32 32
     
33
-    // Token lists
34
-    private $comments = array();
35
-    private $ruleBodies = array();
36
-    private $preservedTokens = array();
33
+	// Token lists
34
+	private $comments = array();
35
+	private $ruleBodies = array();
36
+	private $preservedTokens = array();
37 37
     
38
-    // Output options
39
-    private $keepImportantComments = true;
40
-    private $keepSourceMapComment = false;
41
-    private $linebreakPosition = 0;
38
+	// Output options
39
+	private $keepImportantComments = true;
40
+	private $keepSourceMapComment = false;
41
+	private $linebreakPosition = 0;
42 42
     
43
-    // PHP ini limits
44
-    private $raisePhpLimits;
45
-    private $memoryLimit;
46
-    private $maxExecutionTime = 60; // 1 min
47
-    private $pcreBacktrackLimit;
48
-    private $pcreRecursionLimit;
43
+	// PHP ini limits
44
+	private $raisePhpLimits;
45
+	private $memoryLimit;
46
+	private $maxExecutionTime = 60; // 1 min
47
+	private $pcreBacktrackLimit;
48
+	private $pcreRecursionLimit;
49 49
     
50
-    // Color maps
51
-    private $hexToNamedColorsMap;
52
-    private $namedToHexColorsMap;
50
+	// Color maps
51
+	private $hexToNamedColorsMap;
52
+	private $namedToHexColorsMap;
53 53
     
54
-    // Regexes
55
-    private $numRegex;
56
-    private $charsetRegex = '/@charset [^;]+;/Si';
57
-    private $importRegex = '/@import [^;]+;/Si';
58
-    private $namespaceRegex = '/@namespace [^;]+;/Si';
59
-    private $namedToHexColorsRegex;
60
-    private $shortenOneZeroesRegex;
61
-    private $shortenTwoZeroesRegex;
62
-    private $shortenThreeZeroesRegex;
63
-    private $shortenFourZeroesRegex;
64
-    private $unitsGroupRegex = '(?:ch|cm|em|ex|gd|in|mm|px|pt|pc|q|rem|vh|vmax|vmin|vw|%)';
65
-
66
-    /**
67
-     * @param bool|int $raisePhpLimits If true, PHP settings will be raised if needed
68
-     */
69
-    public function __construct($raisePhpLimits = true)
70
-    {
71
-        $this->raisePhpLimits = (bool) $raisePhpLimits;
72
-        $this->memoryLimit = 128 * 1048576; // 128MB in bytes
73
-        $this->pcreBacktrackLimit = 1000 * 1000;
74
-        $this->pcreRecursionLimit = 500 * 1000;
75
-        $this->hexToNamedColorsMap = Colors::getHexToNamedMap();
76
-        $this->namedToHexColorsMap = Colors::getNamedToHexMap();
77
-        $this->namedToHexColorsRegex = sprintf(
78
-            '/([:,( ])(%s)( |,|\)|;|$)/Si',
79
-            implode('|', array_keys($this->namedToHexColorsMap))
80
-        );
81
-        $this->numRegex = sprintf('-?\d*\.?\d+%s?', $this->unitsGroupRegex);
82
-        $this->setShortenZeroValuesRegexes();
83
-    }
84
-
85
-    /**
86
-     * Parses & minifies the given input CSS string
87
-     * @param string $css
88
-     * @return string
89
-     */
90
-    public function run($css = '')
91
-    {
92
-        if (empty($css) || !is_string($css)) {
93
-            return '';
94
-        }
95
-
96
-        $this->resetRunProperties();
97
-
98
-        if ($this->raisePhpLimits) {
99
-            $this->doRaisePhpLimits();
100
-        }
101
-
102
-        return $this->minify($css);
103
-    }
104
-
105
-    /**
106
-     * Sets whether to keep or remove sourcemap special comment.
107
-     * Sourcemap comments are removed by default.
108
-     * @param bool $keepSourceMapComment
109
-     */
110
-    public function keepSourceMapComment($keepSourceMapComment = true)
111
-    {
112
-        $this->keepSourceMapComment = (bool) $keepSourceMapComment;
113
-    }
114
-
115
-    /**
116
-     * Sets whether to keep or remove important comments.
117
-     * Important comments outside of a declaration block are kept by default.
118
-     * @param bool $removeImportantComments
119
-     */
120
-    public function removeImportantComments($removeImportantComments = true)
121
-    {
122
-        $this->keepImportantComments = !(bool) $removeImportantComments;
123
-    }
124
-
125
-    /**
126
-     * Sets the approximate column after which long lines will be splitted in the output
127
-     * with a linebreak.
128
-     * @param int $position
129
-     */
130
-    public function setLineBreakPosition($position)
131
-    {
132
-        $this->linebreakPosition = (int) $position;
133
-    }
134
-
135
-    /**
136
-     * Sets the memory limit for this script
137
-     * @param int|string $limit
138
-     */
139
-    public function setMemoryLimit($limit)
140
-    {
141
-        $this->memoryLimit = Utils::normalizeInt($limit);
142
-    }
143
-
144
-    /**
145
-     * Sets the maximum execution time for this script
146
-     * @param int|string $seconds
147
-     */
148
-    public function setMaxExecutionTime($seconds)
149
-    {
150
-        $this->maxExecutionTime = (int) $seconds;
151
-    }
152
-
153
-    /**
154
-     * Sets the PCRE backtrack limit for this script
155
-     * @param int $limit
156
-     */
157
-    public function setPcreBacktrackLimit($limit)
158
-    {
159
-        $this->pcreBacktrackLimit = (int) $limit;
160
-    }
161
-
162
-    /**
163
-     * Sets the PCRE recursion limit for this script
164
-     * @param int $limit
165
-     */
166
-    public function setPcreRecursionLimit($limit)
167
-    {
168
-        $this->pcreRecursionLimit = (int) $limit;
169
-    }
170
-
171
-    /**
172
-     * Builds regular expressions needed for shortening zero values
173
-     */
174
-    private function setShortenZeroValuesRegexes()
175
-    {
176
-        $zeroRegex = '0'. $this->unitsGroupRegex;
177
-        $numOrPosRegex = '('. $this->numRegex .'|top|left|bottom|right|center) ';
178
-        $oneZeroSafeProperties = array(
179
-            '(?:line-)?height',
180
-            '(?:(?:min|max)-)?width',
181
-            'top',
182
-            'left',
183
-            'background-position',
184
-            'bottom',
185
-            'right',
186
-            'border(?:-(?:top|left|bottom|right))?(?:-width)?',
187
-            'border-(?:(?:top|bottom)-(?:left|right)-)?radius',
188
-            'column-(?:gap|width)',
189
-            'margin(?:-(?:top|left|bottom|right))?',
190
-            'outline-width',
191
-            'padding(?:-(?:top|left|bottom|right))?'
192
-        );
193
-
194
-        // First zero regex
195
-        $regex = '/(^|;)('. implode('|', $oneZeroSafeProperties) .'):%s/Si';
196
-        $this->shortenOneZeroesRegex = sprintf($regex, $zeroRegex);
197
-
198
-        // Multiple zeroes regexes
199
-        $regex = '/(^|;)(margin|padding|border-(?:width|radius)|background-position):%s/Si';
200
-        $this->shortenTwoZeroesRegex = sprintf($regex, $numOrPosRegex . $zeroRegex);
201
-        $this->shortenThreeZeroesRegex = sprintf($regex, $numOrPosRegex . $numOrPosRegex . $zeroRegex);
202
-        $this->shortenFourZeroesRegex = sprintf($regex, $numOrPosRegex . $numOrPosRegex . $numOrPosRegex . $zeroRegex);
203
-    }
204
-
205
-    /**
206
-     * Resets properties whose value may change between runs
207
-     */
208
-    private function resetRunProperties()
209
-    {
210
-        $this->comments = array();
211
-        $this->ruleBodies = array();
212
-        $this->preservedTokens = array();
213
-    }
214
-
215
-    /**
216
-     * Tries to configure PHP to use at least the suggested minimum settings
217
-     * @return void
218
-     */
219
-    private function doRaisePhpLimits()
220
-    {
221
-        $phpLimits = array(
222
-            'memory_limit' => $this->memoryLimit,
223
-            'max_execution_time' => $this->maxExecutionTime,
224
-            'pcre.backtrack_limit' => $this->pcreBacktrackLimit,
225
-            'pcre.recursion_limit' =>  $this->pcreRecursionLimit
226
-        );
227
-
228
-        // If current settings are higher respect them.
229
-        foreach ($phpLimits as $name => $suggested) {
230
-            $current = Utils::normalizeInt(ini_get($name));
231
-
232
-            if ($current >= $suggested) {
233
-                continue;
234
-            }
235
-
236
-            // memoryLimit exception: allow -1 for "no memory limit".
237
-            if ($name === 'memory_limit' && $current === -1) {
238
-                continue;
239
-            }
240
-
241
-            // maxExecutionTime exception: allow 0 for "no memory limit".
242
-            if ($name === 'max_execution_time' && $current === 0) {
243
-                continue;
244
-            }
245
-
246
-            ini_set($name, $suggested);
247
-        }
248
-    }
249
-
250
-    /**
251
-     * Registers a preserved token
252
-     * @param string $token
253
-     * @return string The token ID string
254
-     */
255
-    private function registerPreservedToken($token)
256
-    {
257
-        $tokenId = sprintf(self::PRESERVED_TOKEN, count($this->preservedTokens));
258
-        $this->preservedTokens[$tokenId] = $token;
259
-        return $tokenId;
260
-    }
261
-
262
-    /**
263
-     * Registers a candidate comment token
264
-     * @param string $comment
265
-     * @return string The comment token ID string
266
-     */
267
-    private function registerCommentToken($comment)
268
-    {
269
-        $tokenId = sprintf(self::COMMENT_TOKEN, count($this->comments));
270
-        $this->comments[$tokenId] = $comment;
271
-        return $tokenId;
272
-    }
273
-
274
-    /**
275
-     * Registers a rule body token
276
-     * @param string $body the minified rule body
277
-     * @return string The rule body token ID string
278
-     */
279
-    private function registerRuleBodyToken($body)
280
-    {
281
-        if (empty($body)) {
282
-            return '';
283
-        }
284
-
285
-        $tokenId = sprintf(self::RULE_BODY_TOKEN, count($this->ruleBodies));
286
-        $this->ruleBodies[$tokenId] = $body;
287
-        return $tokenId;
288
-    }
289
-
290
-    /**
291
-     * Parses & minifies the given input CSS string
292
-     * @param string $css
293
-     * @return string
294
-     */
295
-    private function minify($css)
296
-    {
297
-        // Process data urls
298
-        $css = $this->processDataUrls($css);
299
-
300
-        // Process comments
301
-        $css = preg_replace_callback(
302
-            '/(?<!\\\\)\/\*(.*?)\*(?<!\\\\)\//Ss',
303
-            array($this, 'processCommentsCallback'),
304
-            $css
305
-        );
306
-
307
-        // IE7: Process Microsoft matrix filters (whitespaces between Matrix parameters). Can contain strings inside.
308
-        $css = preg_replace_callback(
309
-            '/filter:\s*progid:DXImageTransform\.Microsoft\.Matrix\(([^)]+)\)/Ss',
310
-            array($this, 'processOldIeSpecificMatrixDefinitionCallback'),
311
-            $css
312
-        );
313
-
314
-        // Process quoted unquotable attribute selectors to unquote them. Covers most common cases.
315
-        // Likelyhood of a quoted attribute selector being a substring in a string: Very very low.
316
-        $css = preg_replace(
317
-            '/\[\s*([a-z][a-z-]+)\s*([\*\|\^\$~]?=)\s*[\'"](-?[a-z_][a-z0-9-_]+)[\'"]\s*\]/Ssi',
318
-            '[$1$2$3]',
319
-            $css
320
-        );
321
-
322
-        // Process strings so their content doesn't get accidentally minified
323
-        $css = preg_replace_callback(
324
-            '/(?:"(?:[^\\\\"]|\\\\.|\\\\)*")|'."(?:'(?:[^\\\\']|\\\\.|\\\\)*')/S",
325
-            array($this, 'processStringsCallback'),
326
-            $css
327
-        );
328
-
329
-        // Normalize all whitespace strings to single spaces. Easier to work with that way.
330
-        $css = preg_replace('/\s+/S', ' ', $css);
331
-
332
-        // Process import At-rules with unquoted URLs so URI reserved characters such as a semicolon may be used safely.
333
-        $css = preg_replace_callback(
334
-            '/@import url\(([^\'"]+?)\)( |;)/Si',
335
-            array($this, 'processImportUnquotedUrlAtRulesCallback'),
336
-            $css
337
-        );
54
+	// Regexes
55
+	private $numRegex;
56
+	private $charsetRegex = '/@charset [^;]+;/Si';
57
+	private $importRegex = '/@import [^;]+;/Si';
58
+	private $namespaceRegex = '/@namespace [^;]+;/Si';
59
+	private $namedToHexColorsRegex;
60
+	private $shortenOneZeroesRegex;
61
+	private $shortenTwoZeroesRegex;
62
+	private $shortenThreeZeroesRegex;
63
+	private $shortenFourZeroesRegex;
64
+	private $unitsGroupRegex = '(?:ch|cm|em|ex|gd|in|mm|px|pt|pc|q|rem|vh|vmax|vmin|vw|%)';
65
+
66
+	/**
67
+	 * @param bool|int $raisePhpLimits If true, PHP settings will be raised if needed
68
+	 */
69
+	public function __construct($raisePhpLimits = true)
70
+	{
71
+		$this->raisePhpLimits = (bool) $raisePhpLimits;
72
+		$this->memoryLimit = 128 * 1048576; // 128MB in bytes
73
+		$this->pcreBacktrackLimit = 1000 * 1000;
74
+		$this->pcreRecursionLimit = 500 * 1000;
75
+		$this->hexToNamedColorsMap = Colors::getHexToNamedMap();
76
+		$this->namedToHexColorsMap = Colors::getNamedToHexMap();
77
+		$this->namedToHexColorsRegex = sprintf(
78
+			'/([:,( ])(%s)( |,|\)|;|$)/Si',
79
+			implode('|', array_keys($this->namedToHexColorsMap))
80
+		);
81
+		$this->numRegex = sprintf('-?\d*\.?\d+%s?', $this->unitsGroupRegex);
82
+		$this->setShortenZeroValuesRegexes();
83
+	}
84
+
85
+	/**
86
+	 * Parses & minifies the given input CSS string
87
+	 * @param string $css
88
+	 * @return string
89
+	 */
90
+	public function run($css = '')
91
+	{
92
+		if (empty($css) || !is_string($css)) {
93
+			return '';
94
+		}
95
+
96
+		$this->resetRunProperties();
97
+
98
+		if ($this->raisePhpLimits) {
99
+			$this->doRaisePhpLimits();
100
+		}
101
+
102
+		return $this->minify($css);
103
+	}
104
+
105
+	/**
106
+	 * Sets whether to keep or remove sourcemap special comment.
107
+	 * Sourcemap comments are removed by default.
108
+	 * @param bool $keepSourceMapComment
109
+	 */
110
+	public function keepSourceMapComment($keepSourceMapComment = true)
111
+	{
112
+		$this->keepSourceMapComment = (bool) $keepSourceMapComment;
113
+	}
114
+
115
+	/**
116
+	 * Sets whether to keep or remove important comments.
117
+	 * Important comments outside of a declaration block are kept by default.
118
+	 * @param bool $removeImportantComments
119
+	 */
120
+	public function removeImportantComments($removeImportantComments = true)
121
+	{
122
+		$this->keepImportantComments = !(bool) $removeImportantComments;
123
+	}
124
+
125
+	/**
126
+	 * Sets the approximate column after which long lines will be splitted in the output
127
+	 * with a linebreak.
128
+	 * @param int $position
129
+	 */
130
+	public function setLineBreakPosition($position)
131
+	{
132
+		$this->linebreakPosition = (int) $position;
133
+	}
134
+
135
+	/**
136
+	 * Sets the memory limit for this script
137
+	 * @param int|string $limit
138
+	 */
139
+	public function setMemoryLimit($limit)
140
+	{
141
+		$this->memoryLimit = Utils::normalizeInt($limit);
142
+	}
143
+
144
+	/**
145
+	 * Sets the maximum execution time for this script
146
+	 * @param int|string $seconds
147
+	 */
148
+	public function setMaxExecutionTime($seconds)
149
+	{
150
+		$this->maxExecutionTime = (int) $seconds;
151
+	}
152
+
153
+	/**
154
+	 * Sets the PCRE backtrack limit for this script
155
+	 * @param int $limit
156
+	 */
157
+	public function setPcreBacktrackLimit($limit)
158
+	{
159
+		$this->pcreBacktrackLimit = (int) $limit;
160
+	}
161
+
162
+	/**
163
+	 * Sets the PCRE recursion limit for this script
164
+	 * @param int $limit
165
+	 */
166
+	public function setPcreRecursionLimit($limit)
167
+	{
168
+		$this->pcreRecursionLimit = (int) $limit;
169
+	}
170
+
171
+	/**
172
+	 * Builds regular expressions needed for shortening zero values
173
+	 */
174
+	private function setShortenZeroValuesRegexes()
175
+	{
176
+		$zeroRegex = '0'. $this->unitsGroupRegex;
177
+		$numOrPosRegex = '('. $this->numRegex .'|top|left|bottom|right|center) ';
178
+		$oneZeroSafeProperties = array(
179
+			'(?:line-)?height',
180
+			'(?:(?:min|max)-)?width',
181
+			'top',
182
+			'left',
183
+			'background-position',
184
+			'bottom',
185
+			'right',
186
+			'border(?:-(?:top|left|bottom|right))?(?:-width)?',
187
+			'border-(?:(?:top|bottom)-(?:left|right)-)?radius',
188
+			'column-(?:gap|width)',
189
+			'margin(?:-(?:top|left|bottom|right))?',
190
+			'outline-width',
191
+			'padding(?:-(?:top|left|bottom|right))?'
192
+		);
193
+
194
+		// First zero regex
195
+		$regex = '/(^|;)('. implode('|', $oneZeroSafeProperties) .'):%s/Si';
196
+		$this->shortenOneZeroesRegex = sprintf($regex, $zeroRegex);
197
+
198
+		// Multiple zeroes regexes
199
+		$regex = '/(^|;)(margin|padding|border-(?:width|radius)|background-position):%s/Si';
200
+		$this->shortenTwoZeroesRegex = sprintf($regex, $numOrPosRegex . $zeroRegex);
201
+		$this->shortenThreeZeroesRegex = sprintf($regex, $numOrPosRegex . $numOrPosRegex . $zeroRegex);
202
+		$this->shortenFourZeroesRegex = sprintf($regex, $numOrPosRegex . $numOrPosRegex . $numOrPosRegex . $zeroRegex);
203
+	}
204
+
205
+	/**
206
+	 * Resets properties whose value may change between runs
207
+	 */
208
+	private function resetRunProperties()
209
+	{
210
+		$this->comments = array();
211
+		$this->ruleBodies = array();
212
+		$this->preservedTokens = array();
213
+	}
214
+
215
+	/**
216
+	 * Tries to configure PHP to use at least the suggested minimum settings
217
+	 * @return void
218
+	 */
219
+	private function doRaisePhpLimits()
220
+	{
221
+		$phpLimits = array(
222
+			'memory_limit' => $this->memoryLimit,
223
+			'max_execution_time' => $this->maxExecutionTime,
224
+			'pcre.backtrack_limit' => $this->pcreBacktrackLimit,
225
+			'pcre.recursion_limit' =>  $this->pcreRecursionLimit
226
+		);
227
+
228
+		// If current settings are higher respect them.
229
+		foreach ($phpLimits as $name => $suggested) {
230
+			$current = Utils::normalizeInt(ini_get($name));
231
+
232
+			if ($current >= $suggested) {
233
+				continue;
234
+			}
235
+
236
+			// memoryLimit exception: allow -1 for "no memory limit".
237
+			if ($name === 'memory_limit' && $current === -1) {
238
+				continue;
239
+			}
240
+
241
+			// maxExecutionTime exception: allow 0 for "no memory limit".
242
+			if ($name === 'max_execution_time' && $current === 0) {
243
+				continue;
244
+			}
245
+
246
+			ini_set($name, $suggested);
247
+		}
248
+	}
249
+
250
+	/**
251
+	 * Registers a preserved token
252
+	 * @param string $token
253
+	 * @return string The token ID string
254
+	 */
255
+	private function registerPreservedToken($token)
256
+	{
257
+		$tokenId = sprintf(self::PRESERVED_TOKEN, count($this->preservedTokens));
258
+		$this->preservedTokens[$tokenId] = $token;
259
+		return $tokenId;
260
+	}
261
+
262
+	/**
263
+	 * Registers a candidate comment token
264
+	 * @param string $comment
265
+	 * @return string The comment token ID string
266
+	 */
267
+	private function registerCommentToken($comment)
268
+	{
269
+		$tokenId = sprintf(self::COMMENT_TOKEN, count($this->comments));
270
+		$this->comments[$tokenId] = $comment;
271
+		return $tokenId;
272
+	}
273
+
274
+	/**
275
+	 * Registers a rule body token
276
+	 * @param string $body the minified rule body
277
+	 * @return string The rule body token ID string
278
+	 */
279
+	private function registerRuleBodyToken($body)
280
+	{
281
+		if (empty($body)) {
282
+			return '';
283
+		}
284
+
285
+		$tokenId = sprintf(self::RULE_BODY_TOKEN, count($this->ruleBodies));
286
+		$this->ruleBodies[$tokenId] = $body;
287
+		return $tokenId;
288
+	}
289
+
290
+	/**
291
+	 * Parses & minifies the given input CSS string
292
+	 * @param string $css
293
+	 * @return string
294
+	 */
295
+	private function minify($css)
296
+	{
297
+		// Process data urls
298
+		$css = $this->processDataUrls($css);
299
+
300
+		// Process comments
301
+		$css = preg_replace_callback(
302
+			'/(?<!\\\\)\/\*(.*?)\*(?<!\\\\)\//Ss',
303
+			array($this, 'processCommentsCallback'),
304
+			$css
305
+		);
306
+
307
+		// IE7: Process Microsoft matrix filters (whitespaces between Matrix parameters). Can contain strings inside.
308
+		$css = preg_replace_callback(
309
+			'/filter:\s*progid:DXImageTransform\.Microsoft\.Matrix\(([^)]+)\)/Ss',
310
+			array($this, 'processOldIeSpecificMatrixDefinitionCallback'),
311
+			$css
312
+		);
313
+
314
+		// Process quoted unquotable attribute selectors to unquote them. Covers most common cases.
315
+		// Likelyhood of a quoted attribute selector being a substring in a string: Very very low.
316
+		$css = preg_replace(
317
+			'/\[\s*([a-z][a-z-]+)\s*([\*\|\^\$~]?=)\s*[\'"](-?[a-z_][a-z0-9-_]+)[\'"]\s*\]/Ssi',
318
+			'[$1$2$3]',
319
+			$css
320
+		);
321
+
322
+		// Process strings so their content doesn't get accidentally minified
323
+		$css = preg_replace_callback(
324
+			'/(?:"(?:[^\\\\"]|\\\\.|\\\\)*")|'."(?:'(?:[^\\\\']|\\\\.|\\\\)*')/S",
325
+			array($this, 'processStringsCallback'),
326
+			$css
327
+		);
328
+
329
+		// Normalize all whitespace strings to single spaces. Easier to work with that way.
330
+		$css = preg_replace('/\s+/S', ' ', $css);
331
+
332
+		// Process import At-rules with unquoted URLs so URI reserved characters such as a semicolon may be used safely.
333
+		$css = preg_replace_callback(
334
+			'/@import url\(([^\'"]+?)\)( |;)/Si',
335
+			array($this, 'processImportUnquotedUrlAtRulesCallback'),
336
+			$css
337
+		);
338 338
         
339
-        // Process comments
340
-        $css = $this->processComments($css);
339
+		// Process comments
340
+		$css = $this->processComments($css);
341 341
         
342
-        // Process rule bodies
343
-        $css = $this->processRuleBodies($css);
342
+		// Process rule bodies
343
+		$css = $this->processRuleBodies($css);
344 344
         
345
-        // Process at-rules and selectors
346
-        $css = $this->processAtRulesAndSelectors($css);
347
-
348
-        // Restore preserved rule bodies before splitting
349
-        $css = strtr($css, $this->ruleBodies);
350
-
351
-        // Split long lines in output if required
352
-        $css = $this->processLongLineSplitting($css);
353
-
354
-        // Restore preserved comments and strings
355
-        $css = strtr($css, $this->preservedTokens);
356
-
357
-        return trim($css);
358
-    }
359
-
360
-    /**
361
-     * Searches & replaces all data urls with tokens before we start compressing,
362
-     * to avoid performance issues running some of the subsequent regexes against large string chunks.
363
-     * @param string $css
364
-     * @return string
365
-     */
366
-    private function processDataUrls($css)
367
-    {
368
-        $ret = '';
369
-        $searchOffset = $substrOffset = 0;
370
-
371
-        // Since we need to account for non-base64 data urls, we need to handle
372
-        // ' and ) being part of the data string.
373
-        while (preg_match('/url\(\s*(["\']?)data:/Si', $css, $m, PREG_OFFSET_CAPTURE, $searchOffset)) {
374
-            $matchStartIndex = $m[0][1];
375
-            $dataStartIndex = $matchStartIndex + 4; // url( length
376
-            $searchOffset = $matchStartIndex + strlen($m[0][0]);
377
-            $terminator = $m[1][0]; // ', " or empty (not quoted)
378
-            $terminatorRegex = '/(?<!\\\\)'. (strlen($terminator) === 0 ? '' : $terminator.'\s*') .'(\))/S';
345
+		// Process at-rules and selectors
346
+		$css = $this->processAtRulesAndSelectors($css);
347
+
348
+		// Restore preserved rule bodies before splitting
349
+		$css = strtr($css, $this->ruleBodies);
350
+
351
+		// Split long lines in output if required
352
+		$css = $this->processLongLineSplitting($css);
353
+
354
+		// Restore preserved comments and strings
355
+		$css = strtr($css, $this->preservedTokens);
356
+
357
+		return trim($css);
358
+	}
359
+
360
+	/**
361
+	 * Searches & replaces all data urls with tokens before we start compressing,
362
+	 * to avoid performance issues running some of the subsequent regexes against large string chunks.
363
+	 * @param string $css
364
+	 * @return string
365
+	 */
366
+	private function processDataUrls($css)
367
+	{
368
+		$ret = '';
369
+		$searchOffset = $substrOffset = 0;
370
+
371
+		// Since we need to account for non-base64 data urls, we need to handle
372
+		// ' and ) being part of the data string.
373
+		while (preg_match('/url\(\s*(["\']?)data:/Si', $css, $m, PREG_OFFSET_CAPTURE, $searchOffset)) {
374
+			$matchStartIndex = $m[0][1];
375
+			$dataStartIndex = $matchStartIndex + 4; // url( length
376
+			$searchOffset = $matchStartIndex + strlen($m[0][0]);
377
+			$terminator = $m[1][0]; // ', " or empty (not quoted)
378
+			$terminatorRegex = '/(?<!\\\\)'. (strlen($terminator) === 0 ? '' : $terminator.'\s*') .'(\))/S';
379 379
             
380
-            $ret .= substr($css, $substrOffset, $matchStartIndex - $substrOffset);
381
-
382
-            // Terminator found
383
-            if (preg_match($terminatorRegex, $css, $matches, PREG_OFFSET_CAPTURE, $searchOffset)) {
384
-                $matchEndIndex = $matches[1][1];
385
-                $searchOffset = $matchEndIndex + 1;
386
-                $token = substr($css, $dataStartIndex, $matchEndIndex - $dataStartIndex);
387
-
388
-                // Remove all spaces only for base64 encoded URLs.
389
-                if (stripos($token, 'base64,') !== false) {
390
-                    $token = preg_replace('/\s+/S', '', $token);
391
-                }
392
-
393
-                $ret .= 'url('. $this->registerPreservedToken(trim($token)) .')';
394
-            // No end terminator found, re-add the whole match. Should we throw/warn here?
395
-            } else {
396
-                $ret .= substr($css, $matchStartIndex, $searchOffset - $matchStartIndex);
397
-            }
398
-
399
-            $substrOffset = $searchOffset;
400
-        }
401
-
402
-        $ret .= substr($css, $substrOffset);
403
-
404
-        return $ret;
405
-    }
406
-
407
-    /**
408
-     * Registers all comments found as candidates to be preserved.
409
-     * @param array $matches
410
-     * @return string
411
-     */
412
-    private function processCommentsCallback($matches)
413
-    {
414
-        return '/*'. $this->registerCommentToken($matches[1]) .'*/';
415
-    }
416
-
417
-    /**
418
-     * Preserves old IE Matrix string definition
419
-     * @param array $matches
420
-     * @return string
421
-     */
422
-    private function processOldIeSpecificMatrixDefinitionCallback($matches)
423
-    {
424
-        return 'filter:progid:DXImageTransform.Microsoft.Matrix('. $this->registerPreservedToken($matches[1]) .')';
425
-    }
426
-
427
-    /**
428
-     * Preserves strings found
429
-     * @param array $matches
430
-     * @return string
431
-     */
432
-    private function processStringsCallback($matches)
433
-    {
434
-        $match = $matches[0];
435
-        $quote = substr($match, 0, 1);
436
-        $match = substr($match, 1, -1);
437
-
438
-        // maybe the string contains a comment-like substring?
439
-        // one, maybe more? put'em back then
440
-        if (strpos($match, self::COMMENT_TOKEN_START) !== false) {
441
-            $match = strtr($match, $this->comments);
442
-        }
443
-
444
-        // minify alpha opacity in filter strings
445
-        $match = str_ireplace('progid:DXImageTransform.Microsoft.Alpha(Opacity=', 'alpha(opacity=', $match);
446
-
447
-        return $quote . $this->registerPreservedToken($match) . $quote;
448
-    }
449
-
450
-    /**
451
-     * Searches & replaces all import at-rule unquoted urls with tokens so URI reserved characters such as a semicolon
452
-     * may be used safely in a URL.
453
-     * @param array $matches
454
-     * @return string
455
-     */
456
-    private function processImportUnquotedUrlAtRulesCallback($matches)
457
-    {
458
-        return '@import url('. $this->registerPreservedToken($matches[1]) .')'. $matches[2];
459
-    }
460
-
461
-    /**
462
-     * Preserves or removes comments found.
463
-     * @param string $css
464
-     * @return string
465
-     */
466
-    private function processComments($css)
467
-    {
468
-        foreach ($this->comments as $commentId => $comment) {
469
-            $commentIdString = '/*'. $commentId .'*/';
380
+			$ret .= substr($css, $substrOffset, $matchStartIndex - $substrOffset);
381
+
382
+			// Terminator found
383
+			if (preg_match($terminatorRegex, $css, $matches, PREG_OFFSET_CAPTURE, $searchOffset)) {
384
+				$matchEndIndex = $matches[1][1];
385
+				$searchOffset = $matchEndIndex + 1;
386
+				$token = substr($css, $dataStartIndex, $matchEndIndex - $dataStartIndex);
387
+
388
+				// Remove all spaces only for base64 encoded URLs.
389
+				if (stripos($token, 'base64,') !== false) {
390
+					$token = preg_replace('/\s+/S', '', $token);
391
+				}
392
+
393
+				$ret .= 'url('. $this->registerPreservedToken(trim($token)) .')';
394
+			// No end terminator found, re-add the whole match. Should we throw/warn here?
395
+			} else {
396
+				$ret .= substr($css, $matchStartIndex, $searchOffset - $matchStartIndex);
397
+			}
398
+
399
+			$substrOffset = $searchOffset;
400
+		}
401
+
402
+		$ret .= substr($css, $substrOffset);
403
+
404
+		return $ret;
405
+	}
406
+
407
+	/**
408
+	 * Registers all comments found as candidates to be preserved.
409
+	 * @param array $matches
410
+	 * @return string
411
+	 */
412
+	private function processCommentsCallback($matches)
413
+	{
414
+		return '/*'. $this->registerCommentToken($matches[1]) .'*/';
415
+	}
416
+
417
+	/**
418
+	 * Preserves old IE Matrix string definition
419
+	 * @param array $matches
420
+	 * @return string
421
+	 */
422
+	private function processOldIeSpecificMatrixDefinitionCallback($matches)
423
+	{
424
+		return 'filter:progid:DXImageTransform.Microsoft.Matrix('. $this->registerPreservedToken($matches[1]) .')';
425
+	}
426
+
427
+	/**
428
+	 * Preserves strings found
429
+	 * @param array $matches
430
+	 * @return string
431
+	 */
432
+	private function processStringsCallback($matches)
433
+	{
434
+		$match = $matches[0];
435
+		$quote = substr($match, 0, 1);
436
+		$match = substr($match, 1, -1);
437
+
438
+		// maybe the string contains a comment-like substring?
439
+		// one, maybe more? put'em back then
440
+		if (strpos($match, self::COMMENT_TOKEN_START) !== false) {
441
+			$match = strtr($match, $this->comments);
442
+		}
443
+
444
+		// minify alpha opacity in filter strings
445
+		$match = str_ireplace('progid:DXImageTransform.Microsoft.Alpha(Opacity=', 'alpha(opacity=', $match);
446
+
447
+		return $quote . $this->registerPreservedToken($match) . $quote;
448
+	}
449
+
450
+	/**
451
+	 * Searches & replaces all import at-rule unquoted urls with tokens so URI reserved characters such as a semicolon
452
+	 * may be used safely in a URL.
453
+	 * @param array $matches
454
+	 * @return string
455
+	 */
456
+	private function processImportUnquotedUrlAtRulesCallback($matches)
457
+	{
458
+		return '@import url('. $this->registerPreservedToken($matches[1]) .')'. $matches[2];
459
+	}
460
+
461
+	/**
462
+	 * Preserves or removes comments found.
463
+	 * @param string $css
464
+	 * @return string
465
+	 */
466
+	private function processComments($css)
467
+	{
468
+		foreach ($this->comments as $commentId => $comment) {
469
+			$commentIdString = '/*'. $commentId .'*/';
470 470
             
471
-            // ! in the first position of the comment means preserve
472
-            // so push to the preserved tokens keeping the !
473
-            if ($this->keepImportantComments && strpos($comment, '!') === 0) {
474
-                $preservedTokenId = $this->registerPreservedToken($comment);
475
-                // Put new lines before and after /*! important comments
476
-                $css = str_replace($commentIdString, "\n/*$preservedTokenId*/\n", $css);
477
-                continue;
478
-            }
479
-
480
-            // # sourceMappingURL= in the first position of the comment means sourcemap
481
-            // so push to the preserved tokens if {$this->keepSourceMapComment} is truthy.
482
-            if ($this->keepSourceMapComment && strpos($comment, '# sourceMappingURL=') === 0) {
483
-                $preservedTokenId = $this->registerPreservedToken($comment);
484
-                // Add new line before the sourcemap comment
485
-                $css = str_replace($commentIdString, "\n/*$preservedTokenId*/", $css);
486
-                continue;
487
-            }
488
-
489
-            // Keep empty comments after child selectors (IE7 hack)
490
-            // e.g. html >/**/ body
491
-            if (strlen($comment) === 0 && strpos($css, '>/*'.$commentId) !== false) {
492
-                $css = str_replace($commentId, $this->registerPreservedToken(''), $css);
493
-                continue;
494
-            }
495
-
496
-            // in all other cases kill the comment
497
-            $css = str_replace($commentIdString, '', $css);
498
-        }
499
-
500
-        // Normalize whitespace again
501
-        $css = preg_replace('/ +/S', ' ', $css);
502
-
503
-        return $css;
504
-    }
505
-
506
-    /**
507
-     * Finds, minifies & preserves all rule bodies.
508
-     * @param string $css the whole stylesheet.
509
-     * @return string
510
-     */
511
-    private function processRuleBodies($css)
512
-    {
513
-        $ret = '';
514
-        $searchOffset = $substrOffset = 0;
515
-
516
-        while (($blockStartPos = strpos($css, '{', $searchOffset)) !== false) {
517
-            $blockEndPos = strpos($css, '}', $blockStartPos);
518
-            $nextBlockStartPos = strpos($css, '{', $blockStartPos + 1);
519
-            $ret .= substr($css, $substrOffset, $blockStartPos - $substrOffset);
520
-
521
-            if ($nextBlockStartPos !== false && $nextBlockStartPos < $blockEndPos) {
522
-                $ret .= substr($css, $blockStartPos, $nextBlockStartPos - $blockStartPos);
523
-                $searchOffset = $nextBlockStartPos;
524
-            } else {
525
-                $ruleBody = substr($css, $blockStartPos + 1, $blockEndPos - $blockStartPos - 1);
526
-                $ruleBodyToken = $this->registerRuleBodyToken($this->processRuleBody($ruleBody));
527
-                $ret .= '{'. $ruleBodyToken .'}';
528
-                $searchOffset = $blockEndPos + 1;
529
-            }
530
-
531
-            $substrOffset = $searchOffset;
532
-        }
533
-
534
-        $ret .= substr($css, $substrOffset);
535
-
536
-        return $ret;
537
-    }
538
-
539
-    /**
540
-     * Compresses non-group rule bodies.
541
-     * @param string $body The rule body without curly braces
542
-     * @return string
543
-     */
544
-    private function processRuleBody($body)
545
-    {
546
-        $body = trim($body);
547
-
548
-        // Remove spaces before the things that should not have spaces before them.
549
-        $body = preg_replace('/ ([:=,)*\/;\n])/S', '$1', $body);
550
-
551
-        // Remove the spaces after the things that should not have spaces after them.
552
-        $body = preg_replace('/([:=,(*\/!;\n]) /S', '$1', $body);
471
+			// ! in the first position of the comment means preserve
472
+			// so push to the preserved tokens keeping the !
473
+			if ($this->keepImportantComments && strpos($comment, '!') === 0) {
474
+				$preservedTokenId = $this->registerPreservedToken($comment);
475
+				// Put new lines before and after /*! important comments
476
+				$css = str_replace($commentIdString, "\n/*$preservedTokenId*/\n", $css);
477
+				continue;
478
+			}
479
+
480
+			// # sourceMappingURL= in the first position of the comment means sourcemap
481
+			// so push to the preserved tokens if {$this->keepSourceMapComment} is truthy.
482
+			if ($this->keepSourceMapComment && strpos($comment, '# sourceMappingURL=') === 0) {
483
+				$preservedTokenId = $this->registerPreservedToken($comment);
484
+				// Add new line before the sourcemap comment
485
+				$css = str_replace($commentIdString, "\n/*$preservedTokenId*/", $css);
486
+				continue;
487
+			}
488
+
489
+			// Keep empty comments after child selectors (IE7 hack)
490
+			// e.g. html >/**/ body
491
+			if (strlen($comment) === 0 && strpos($css, '>/*'.$commentId) !== false) {
492
+				$css = str_replace($commentId, $this->registerPreservedToken(''), $css);
493
+				continue;
494
+			}
495
+
496
+			// in all other cases kill the comment
497
+			$css = str_replace($commentIdString, '', $css);
498
+		}
499
+
500
+		// Normalize whitespace again
501
+		$css = preg_replace('/ +/S', ' ', $css);
502
+
503
+		return $css;
504
+	}
505
+
506
+	/**
507
+	 * Finds, minifies & preserves all rule bodies.
508
+	 * @param string $css the whole stylesheet.
509
+	 * @return string
510
+	 */
511
+	private function processRuleBodies($css)
512
+	{
513
+		$ret = '';
514
+		$searchOffset = $substrOffset = 0;
515
+
516
+		while (($blockStartPos = strpos($css, '{', $searchOffset)) !== false) {
517
+			$blockEndPos = strpos($css, '}', $blockStartPos);
518
+			$nextBlockStartPos = strpos($css, '{', $blockStartPos + 1);
519
+			$ret .= substr($css, $substrOffset, $blockStartPos - $substrOffset);
520
+
521
+			if ($nextBlockStartPos !== false && $nextBlockStartPos < $blockEndPos) {
522
+				$ret .= substr($css, $blockStartPos, $nextBlockStartPos - $blockStartPos);
523
+				$searchOffset = $nextBlockStartPos;
524
+			} else {
525
+				$ruleBody = substr($css, $blockStartPos + 1, $blockEndPos - $blockStartPos - 1);
526
+				$ruleBodyToken = $this->registerRuleBodyToken($this->processRuleBody($ruleBody));
527
+				$ret .= '{'. $ruleBodyToken .'}';
528
+				$searchOffset = $blockEndPos + 1;
529
+			}
530
+
531
+			$substrOffset = $searchOffset;
532
+		}
533
+
534
+		$ret .= substr($css, $substrOffset);
535
+
536
+		return $ret;
537
+	}
538
+
539
+	/**
540
+	 * Compresses non-group rule bodies.
541
+	 * @param string $body The rule body without curly braces
542
+	 * @return string
543
+	 */
544
+	private function processRuleBody($body)
545
+	{
546
+		$body = trim($body);
547
+
548
+		// Remove spaces before the things that should not have spaces before them.
549
+		$body = preg_replace('/ ([:=,)*\/;\n])/S', '$1', $body);
550
+
551
+		// Remove the spaces after the things that should not have spaces after them.
552
+		$body = preg_replace('/([:=,(*\/!;\n]) /S', '$1', $body);
553 553
         
554
-        // Replace multiple semi-colons in a row by a single one
555
-        $body = preg_replace('/;;+/S', ';', $body);
556
-
557
-        // Remove semicolon before closing brace except when:
558
-        // - The last property is prefixed with a `*` (lte IE7 hack) to avoid issues on Symbian S60 3.x browsers.
559
-        if (!preg_match('/\*[a-z0-9-]+:[^;]+;$/Si', $body)) {
560
-            $body = rtrim($body, ';');
561
-        }
562
-
563
-        // Remove important comments inside a rule body (because they make no sense here).
564
-        if (strpos($body, '/*') !== false) {
565
-            $body = preg_replace('/\n?\/\*[A-Z0-9_]+\*\/\n?/S', '', $body);
566
-        }
554
+		// Replace multiple semi-colons in a row by a single one
555
+		$body = preg_replace('/;;+/S', ';', $body);
556
+
557
+		// Remove semicolon before closing brace except when:
558
+		// - The last property is prefixed with a `*` (lte IE7 hack) to avoid issues on Symbian S60 3.x browsers.
559
+		if (!preg_match('/\*[a-z0-9-]+:[^;]+;$/Si', $body)) {
560
+			$body = rtrim($body, ';');
561
+		}
562
+
563
+		// Remove important comments inside a rule body (because they make no sense here).
564
+		if (strpos($body, '/*') !== false) {
565
+			$body = preg_replace('/\n?\/\*[A-Z0-9_]+\*\/\n?/S', '', $body);
566
+		}
567 567
         
568
-        // Empty rule body? Exit :)
569
-        if (empty($body)) {
570
-            return '';
571
-        }
572
-
573
-        // Shorten font-weight values
574
-        $body = preg_replace(
575
-            array('/(font-weight:)bold\b/Si', '/(font-weight:)normal\b/Si'),
576
-            array('${1}700', '${1}400'),
577
-            $body
578
-        );
579
-
580
-        // Shorten background property
581
-        $body = preg_replace('/(background:)(?:none|transparent)( !|;|$)/Si', '${1}0 0$2', $body);
582
-
583
-        // Shorten opacity IE filter
584
-        $body = str_ireplace('progid:DXImageTransform.Microsoft.Alpha(Opacity=', 'alpha(opacity=', $body);
585
-
586
-        // Shorten colors from rgb(51,102,153) to #336699, rgb(100%,0%,0%) to #ff0000 (sRGB color space)
587
-        // Shorten colors from hsl(0, 100%, 50%) to #ff0000 (sRGB color space)
588
-        // This makes it more likely that it'll get further compressed in the next step.
589
-        $body = preg_replace_callback(
590
-            '/(rgb|hsl)\(([0-9,.% -]+)\)(.|$)/Si',
591
-            array($this, 'shortenHslAndRgbToHexCallback'),
592
-            $body
593
-        );
594
-
595
-        // Shorten colors from #AABBCC to #ABC or shorter color name:
596
-        // - Look for hex colors which don't have a "=" in front of them (to avoid MSIE filters)
597
-        $body = preg_replace_callback(
598
-            '/(?<!=)#([0-9a-f]{3,6})( |,|\)|;|$)/Si',
599
-            array($this, 'shortenHexColorsCallback'),
600
-            $body
601
-        );
602
-
603
-        // Shorten long named colors with a shorter HEX counterpart: white -> #fff.
604
-        // Run at least 2 times to cover most cases
605
-        $body = preg_replace_callback(
606
-            array($this->namedToHexColorsRegex, $this->namedToHexColorsRegex),
607
-            array($this, 'shortenNamedColorsCallback'),
608
-            $body
609
-        );
610
-
611
-        // Replace positive sign from numbers before the leading space is removed.
612
-        // +1.2em to 1.2em, +.8px to .8px, +2% to 2%
613
-        $body = preg_replace('/([ :,(])\+(\.?\d+)/S', '$1$2', $body);
614
-
615
-        // shorten ms to s
616
-        $body = preg_replace_callback('/([ :,(])(-?)(\d{3,})ms/Si', function ($matches) {
617
-            return $matches[1] . $matches[2] . ((int) $matches[3] / 1000) .'s';
618
-        }, $body);
619
-
620
-        // Remove leading zeros from integer and float numbers.
621
-        // 000.6 to .6, -0.8 to -.8, 0050 to 50, -01.05 to -1.05
622
-        $body = preg_replace('/([ :,(])(-?)0+([1-9]?\.?\d+)/S', '$1$2$3', $body);
623
-
624
-        // Remove trailing zeros from float numbers.
625
-        // -6.0100em to -6.01em, .0100 to .01, 1.200px to 1.2px
626
-        $body = preg_replace('/([ :,(])(-?\d?\.\d+?)0+([^\d])/S', '$1$2$3', $body);
627
-
628
-        // Remove trailing .0 -> -9.0 to -9
629
-        $body = preg_replace('/([ :,(])(-?\d+)\.0([^\d])/S', '$1$2$3', $body);
630
-
631
-        // Replace 0 length numbers with 0
632
-        $body = preg_replace('/([ :,(])-?\.?0+([^\d])/S', '${1}0$2', $body);
633
-
634
-        // Shorten zero values for safe properties only
635
-        $body = preg_replace(
636
-            array(
637
-                $this->shortenOneZeroesRegex,
638
-                $this->shortenTwoZeroesRegex,
639
-                $this->shortenThreeZeroesRegex,
640
-                $this->shortenFourZeroesRegex
641
-            ),
642
-            array(
643
-                '$1$2:0',
644
-                '$1$2:$3 0',
645
-                '$1$2:$3 $4 0',
646
-                '$1$2:$3 $4 $5 0'
647
-            ),
648
-            $body
649
-        );
650
-
651
-        // Replace 0 0 0; or 0 0 0 0; with 0 0 for background-position property.
652
-        $body = preg_replace('/(background-position):0(?: 0){2,3}( !|;|$)/Si', '$1:0 0$2', $body);
653
-
654
-        // Shorten suitable shorthand properties with repeated values
655
-        $body = preg_replace(
656
-            array(
657
-                '/(margin|padding|border-(?:width|radius)):('.$this->numRegex.')(?: \2)+( !|;|$)/Si',
658
-                '/(border-(?:style|color)):([#a-z0-9]+)(?: \2)+( !|;|$)/Si'
659
-            ),
660
-            '$1:$2$3',
661
-            $body
662
-        );
663
-        $body = preg_replace(
664
-            array(
665
-                '/(margin|padding|border-(?:width|radius)):'.
666
-                '('.$this->numRegex.') ('.$this->numRegex.') \2 \3( !|;|$)/Si',
667
-                '/(border-(?:style|color)):([#a-z0-9]+) ([#a-z0-9]+) \2 \3( !|;|$)/Si'
668
-            ),
669
-            '$1:$2 $3$4',
670
-            $body
671
-        );
672
-        $body = preg_replace(
673
-            array(
674
-                '/(margin|padding|border-(?:width|radius)):'.
675
-                '('.$this->numRegex.') ('.$this->numRegex.') ('.$this->numRegex.') \3( !|;|$)/Si',
676
-                '/(border-(?:style|color)):([#a-z0-9]+) ([#a-z0-9]+) ([#a-z0-9]+) \3( !|;|$)/Si'
677
-            ),
678
-            '$1:$2 $3 $4$5',
679
-            $body
680
-        );
681
-
682
-        // Lowercase some common functions that can be values
683
-        $body = preg_replace_callback(
684
-            '/(?:attr|blur|brightness|circle|contrast|cubic-bezier|drop-shadow|ellipse|from|grayscale|'.
685
-            'hsla?|hue-rotate|inset|invert|local|minmax|opacity|perspective|polygon|rgba?|rect|repeat|saturate|sepia|'.
686
-            'steps|to|url|var|-webkit-gradient|'.
687
-            '(?:-(?:atsc|khtml|moz|ms|o|wap|webkit)-)?(?:calc|(?:repeating-)?(?:linear|radial)-gradient))\(/Si',
688
-            array($this, 'strtolowerCallback'),
689
-            $body
690
-        );
691
-
692
-        // Lowercase all uppercase properties
693
-        $body = preg_replace_callback('/(?:^|;)[A-Z-]+:/S', array($this, 'strtolowerCallback'), $body);
694
-
695
-        return $body;
696
-    }
697
-
698
-    /**
699
-     * Compresses At-rules and selectors.
700
-     * @param string $css the whole stylesheet with rule bodies tokenized.
701
-     * @return string
702
-     */
703
-    private function processAtRulesAndSelectors($css)
704
-    {
705
-        $charset = '';
706
-        $imports = '';
707
-        $namespaces = '';
568
+		// Empty rule body? Exit :)
569
+		if (empty($body)) {
570
+			return '';
571
+		}
572
+
573
+		// Shorten font-weight values
574
+		$body = preg_replace(
575
+			array('/(font-weight:)bold\b/Si', '/(font-weight:)normal\b/Si'),
576
+			array('${1}700', '${1}400'),
577
+			$body
578
+		);
579
+
580
+		// Shorten background property
581
+		$body = preg_replace('/(background:)(?:none|transparent)( !|;|$)/Si', '${1}0 0$2', $body);
582
+
583
+		// Shorten opacity IE filter
584
+		$body = str_ireplace('progid:DXImageTransform.Microsoft.Alpha(Opacity=', 'alpha(opacity=', $body);
585
+
586
+		// Shorten colors from rgb(51,102,153) to #336699, rgb(100%,0%,0%) to #ff0000 (sRGB color space)
587
+		// Shorten colors from hsl(0, 100%, 50%) to #ff0000 (sRGB color space)
588
+		// This makes it more likely that it'll get further compressed in the next step.
589
+		$body = preg_replace_callback(
590
+			'/(rgb|hsl)\(([0-9,.% -]+)\)(.|$)/Si',
591
+			array($this, 'shortenHslAndRgbToHexCallback'),
592
+			$body
593
+		);
594
+
595
+		// Shorten colors from #AABBCC to #ABC or shorter color name:
596
+		// - Look for hex colors which don't have a "=" in front of them (to avoid MSIE filters)
597
+		$body = preg_replace_callback(
598
+			'/(?<!=)#([0-9a-f]{3,6})( |,|\)|;|$)/Si',
599
+			array($this, 'shortenHexColorsCallback'),
600
+			$body
601
+		);
602
+
603
+		// Shorten long named colors with a shorter HEX counterpart: white -> #fff.
604
+		// Run at least 2 times to cover most cases
605
+		$body = preg_replace_callback(
606
+			array($this->namedToHexColorsRegex, $this->namedToHexColorsRegex),
607
+			array($this, 'shortenNamedColorsCallback'),
608
+			$body
609
+		);
610
+
611
+		// Replace positive sign from numbers before the leading space is removed.
612
+		// +1.2em to 1.2em, +.8px to .8px, +2% to 2%
613
+		$body = preg_replace('/([ :,(])\+(\.?\d+)/S', '$1$2', $body);
614
+
615
+		// shorten ms to s
616
+		$body = preg_replace_callback('/([ :,(])(-?)(\d{3,})ms/Si', function ($matches) {
617
+			return $matches[1] . $matches[2] . ((int) $matches[3] / 1000) .'s';
618
+		}, $body);
619
+
620
+		// Remove leading zeros from integer and float numbers.
621
+		// 000.6 to .6, -0.8 to -.8, 0050 to 50, -01.05 to -1.05
622
+		$body = preg_replace('/([ :,(])(-?)0+([1-9]?\.?\d+)/S', '$1$2$3', $body);
623
+
624
+		// Remove trailing zeros from float numbers.
625
+		// -6.0100em to -6.01em, .0100 to .01, 1.200px to 1.2px
626
+		$body = preg_replace('/([ :,(])(-?\d?\.\d+?)0+([^\d])/S', '$1$2$3', $body);
627
+
628
+		// Remove trailing .0 -> -9.0 to -9
629
+		$body = preg_replace('/([ :,(])(-?\d+)\.0([^\d])/S', '$1$2$3', $body);
630
+
631
+		// Replace 0 length numbers with 0
632
+		$body = preg_replace('/([ :,(])-?\.?0+([^\d])/S', '${1}0$2', $body);
633
+
634
+		// Shorten zero values for safe properties only
635
+		$body = preg_replace(
636
+			array(
637
+				$this->shortenOneZeroesRegex,
638
+				$this->shortenTwoZeroesRegex,
639
+				$this->shortenThreeZeroesRegex,
640
+				$this->shortenFourZeroesRegex
641
+			),
642
+			array(
643
+				'$1$2:0',
644
+				'$1$2:$3 0',
645
+				'$1$2:$3 $4 0',
646
+				'$1$2:$3 $4 $5 0'
647
+			),
648
+			$body
649
+		);
650
+
651
+		// Replace 0 0 0; or 0 0 0 0; with 0 0 for background-position property.
652
+		$body = preg_replace('/(background-position):0(?: 0){2,3}( !|;|$)/Si', '$1:0 0$2', $body);
653
+
654
+		// Shorten suitable shorthand properties with repeated values
655
+		$body = preg_replace(
656
+			array(
657
+				'/(margin|padding|border-(?:width|radius)):('.$this->numRegex.')(?: \2)+( !|;|$)/Si',
658
+				'/(border-(?:style|color)):([#a-z0-9]+)(?: \2)+( !|;|$)/Si'
659
+			),
660
+			'$1:$2$3',
661
+			$body
662
+		);
663
+		$body = preg_replace(
664
+			array(
665
+				'/(margin|padding|border-(?:width|radius)):'.
666
+				'('.$this->numRegex.') ('.$this->numRegex.') \2 \3( !|;|$)/Si',
667
+				'/(border-(?:style|color)):([#a-z0-9]+) ([#a-z0-9]+) \2 \3( !|;|$)/Si'
668
+			),
669
+			'$1:$2 $3$4',
670
+			$body
671
+		);
672
+		$body = preg_replace(
673
+			array(
674
+				'/(margin|padding|border-(?:width|radius)):'.
675
+				'('.$this->numRegex.') ('.$this->numRegex.') ('.$this->numRegex.') \3( !|;|$)/Si',
676
+				'/(border-(?:style|color)):([#a-z0-9]+) ([#a-z0-9]+) ([#a-z0-9]+) \3( !|;|$)/Si'
677
+			),
678
+			'$1:$2 $3 $4$5',
679
+			$body
680
+		);
681
+
682
+		// Lowercase some common functions that can be values
683
+		$body = preg_replace_callback(
684
+			'/(?:attr|blur|brightness|circle|contrast|cubic-bezier|drop-shadow|ellipse|from|grayscale|'.
685
+			'hsla?|hue-rotate|inset|invert|local|minmax|opacity|perspective|polygon|rgba?|rect|repeat|saturate|sepia|'.
686
+			'steps|to|url|var|-webkit-gradient|'.
687
+			'(?:-(?:atsc|khtml|moz|ms|o|wap|webkit)-)?(?:calc|(?:repeating-)?(?:linear|radial)-gradient))\(/Si',
688
+			array($this, 'strtolowerCallback'),
689
+			$body
690
+		);
691
+
692
+		// Lowercase all uppercase properties
693
+		$body = preg_replace_callback('/(?:^|;)[A-Z-]+:/S', array($this, 'strtolowerCallback'), $body);
694
+
695
+		return $body;
696
+	}
697
+
698
+	/**
699
+	 * Compresses At-rules and selectors.
700
+	 * @param string $css the whole stylesheet with rule bodies tokenized.
701
+	 * @return string
702
+	 */
703
+	private function processAtRulesAndSelectors($css)
704
+	{
705
+		$charset = '';
706
+		$imports = '';
707
+		$namespaces = '';
708 708
         
709
-        // Remove spaces before the things that should not have spaces before them.
710
-        $css = preg_replace('/ ([@{};>+)\]~=,\/\n])/S', '$1', $css);
709
+		// Remove spaces before the things that should not have spaces before them.
710
+		$css = preg_replace('/ ([@{};>+)\]~=,\/\n])/S', '$1', $css);
711 711
 
712
-        // Remove the spaces after the things that should not have spaces after them.
713
-        $css = preg_replace('/([{}:;>+(\[~=,\/\n]) /S', '$1', $css);
712
+		// Remove the spaces after the things that should not have spaces after them.
713
+		$css = preg_replace('/([{}:;>+(\[~=,\/\n]) /S', '$1', $css);
714 714
         
715
-        // Shorten shortable double colon (CSS3) pseudo-elements to single colon (CSS2)
716
-        $css = preg_replace('/::(before|after|first-(?:line|letter))(\{|,)/Si', ':$1$2', $css);
717
-
718
-        // Retain space for special IE6 cases
719
-        $css = preg_replace_callback('/:first-(line|letter)(\{|,)/Si', function ($matches) {
720
-            return ':first-'. strtolower($matches[1]) .' '. $matches[2];
721
-        }, $css);
722
-
723
-        // Find a fraction that may used in some @media queries such as: (min-aspect-ratio: 1/1)
724
-        // Add token to add the "/" back in later
725
-        $css = preg_replace('/\(([a-z-]+):([0-9]+)\/([0-9]+)\)/Si', '($1:$2'. self::QUERY_FRACTION .'$3)', $css);
726
-
727
-        // Remove empty rule blocks up to 2 levels deep.
728
-        $css = preg_replace(array_fill(0, 2, '/(\{)[^{};\/\n]+\{\}/S'), '$1', $css);
729
-        $css = preg_replace('/[^{};\/\n]+\{\}/S', '', $css);
730
-
731
-        // Two important comments next to each other? Remove extra newline.
732
-        if ($this->keepImportantComments) {
733
-            $css = str_replace("\n\n", "\n", $css);
734
-        }
715
+		// Shorten shortable double colon (CSS3) pseudo-elements to single colon (CSS2)
716
+		$css = preg_replace('/::(before|after|first-(?:line|letter))(\{|,)/Si', ':$1$2', $css);
717
+
718
+		// Retain space for special IE6 cases
719
+		$css = preg_replace_callback('/:first-(line|letter)(\{|,)/Si', function ($matches) {
720
+			return ':first-'. strtolower($matches[1]) .' '. $matches[2];
721
+		}, $css);
722
+
723
+		// Find a fraction that may used in some @media queries such as: (min-aspect-ratio: 1/1)
724
+		// Add token to add the "/" back in later
725
+		$css = preg_replace('/\(([a-z-]+):([0-9]+)\/([0-9]+)\)/Si', '($1:$2'. self::QUERY_FRACTION .'$3)', $css);
726
+
727
+		// Remove empty rule blocks up to 2 levels deep.
728
+		$css = preg_replace(array_fill(0, 2, '/(\{)[^{};\/\n]+\{\}/S'), '$1', $css);
729
+		$css = preg_replace('/[^{};\/\n]+\{\}/S', '', $css);
730
+
731
+		// Two important comments next to each other? Remove extra newline.
732
+		if ($this->keepImportantComments) {
733
+			$css = str_replace("\n\n", "\n", $css);
734
+		}
735 735
         
736
-        // Restore fraction
737
-        $css = str_replace(self::QUERY_FRACTION, '/', $css);
738
-
739
-        // Lowercase some popular @directives
740
-        $css = preg_replace_callback(
741
-            '/(?<!\\\\)@(?:charset|document|font-face|import|(?:-(?:atsc|khtml|moz|ms|o|wap|webkit)-)?keyframes|media|'.
742
-            'namespace|page|supports|viewport)/Si',
743
-            array($this, 'strtolowerCallback'),
744
-            $css
745
-        );
746
-
747
-        // Lowercase some popular media types
748
-        $css = preg_replace_callback(
749
-            '/[ ,](?:all|aural|braille|handheld|print|projection|screen|tty|tv|embossed|speech)[ ,;{]/Si',
750
-            array($this, 'strtolowerCallback'),
751
-            $css
752
-        );
753
-
754
-        // Lowercase some common pseudo-classes & pseudo-elements
755
-        $css = preg_replace_callback(
756
-            '/(?<!\\\\):(?:active|after|before|checked|default|disabled|empty|enabled|first-(?:child|of-type)|'.
757
-            'focus(?:-within)?|hover|indeterminate|in-range|invalid|lang\(|last-(?:child|of-type)|left|link|not\(|'.
758
-            'nth-(?:child|of-type)\(|nth-last-(?:child|of-type)\(|only-(?:child|of-type)|optional|out-of-range|'.
759
-            'read-(?:only|write)|required|right|root|:selection|target|valid|visited)/Si',
760
-            array($this, 'strtolowerCallback'),
761
-            $css
762
-        );
736
+		// Restore fraction
737
+		$css = str_replace(self::QUERY_FRACTION, '/', $css);
738
+
739
+		// Lowercase some popular @directives
740
+		$css = preg_replace_callback(
741
+			'/(?<!\\\\)@(?:charset|document|font-face|import|(?:-(?:atsc|khtml|moz|ms|o|wap|webkit)-)?keyframes|media|'.
742
+			'namespace|page|supports|viewport)/Si',
743
+			array($this, 'strtolowerCallback'),
744
+			$css
745
+		);
746
+
747
+		// Lowercase some popular media types
748
+		$css = preg_replace_callback(
749
+			'/[ ,](?:all|aural|braille|handheld|print|projection|screen|tty|tv|embossed|speech)[ ,;{]/Si',
750
+			array($this, 'strtolowerCallback'),
751
+			$css
752
+		);
753
+
754
+		// Lowercase some common pseudo-classes & pseudo-elements
755
+		$css = preg_replace_callback(
756
+			'/(?<!\\\\):(?:active|after|before|checked|default|disabled|empty|enabled|first-(?:child|of-type)|'.
757
+			'focus(?:-within)?|hover|indeterminate|in-range|invalid|lang\(|last-(?:child|of-type)|left|link|not\(|'.
758
+			'nth-(?:child|of-type)\(|nth-last-(?:child|of-type)\(|only-(?:child|of-type)|optional|out-of-range|'.
759
+			'read-(?:only|write)|required|right|root|:selection|target|valid|visited)/Si',
760
+			array($this, 'strtolowerCallback'),
761
+			$css
762
+		);
763 763
         
764
-        // @charset handling
765
-        if (preg_match($this->charsetRegex, $css, $matches)) {
766
-            // Keep the first @charset at-rule found
767
-            $charset = $matches[0];
768
-            // Delete all @charset at-rules
769
-            $css = preg_replace($this->charsetRegex, '', $css);
770
-        }
771
-
772
-        // @import handling
773
-        $css = preg_replace_callback($this->importRegex, function ($matches) use (&$imports) {
774
-            // Keep all @import at-rules found for later
775
-            $imports .= $matches[0];
776
-            // Delete all @import at-rules
777
-            return '';
778
-        }, $css);
779
-
780
-        // @namespace handling
781
-        $css = preg_replace_callback($this->namespaceRegex, function ($matches) use (&$namespaces) {
782
-            // Keep all @namespace at-rules found for later
783
-            $namespaces .= $matches[0];
784
-            // Delete all @namespace at-rules
785
-            return '';
786
-        }, $css);
764
+		// @charset handling
765
+		if (preg_match($this->charsetRegex, $css, $matches)) {
766
+			// Keep the first @charset at-rule found
767
+			$charset = $matches[0];
768
+			// Delete all @charset at-rules
769
+			$css = preg_replace($this->charsetRegex, '', $css);
770
+		}
771
+
772
+		// @import handling
773
+		$css = preg_replace_callback($this->importRegex, function ($matches) use (&$imports) {
774
+			// Keep all @import at-rules found for later
775
+			$imports .= $matches[0];
776
+			// Delete all @import at-rules
777
+			return '';
778
+		}, $css);
779
+
780
+		// @namespace handling
781
+		$css = preg_replace_callback($this->namespaceRegex, function ($matches) use (&$namespaces) {
782
+			// Keep all @namespace at-rules found for later
783
+			$namespaces .= $matches[0];
784
+			// Delete all @namespace at-rules
785
+			return '';
786
+		}, $css);
787 787
         
788
-        // Order critical at-rules:
789
-        // 1. @charset first
790
-        // 2. @imports below @charset
791
-        // 3. @namespaces below @imports
792
-        $css = $charset . $imports . $namespaces . $css;
793
-
794
-        return $css;
795
-    }
796
-
797
-    /**
798
-     * Splits long lines after a specific column.
799
-     *
800
-     * Some source control tools don't like it when files containing lines longer
801
-     * than, say 8000 characters, are checked in. The linebreak option is used in
802
-     * that case to split long lines after a specific column.
803
-     *
804
-     * @param string $css the whole stylesheet.
805
-     * @return string
806
-     */
807
-    private function processLongLineSplitting($css)
808
-    {
809
-        if ($this->linebreakPosition > 0) {
810
-            $l = strlen($css);
811
-            $offset = $this->linebreakPosition;
812
-            while (preg_match('/(?<!\\\\)\}(?!\n)/S', $css, $matches, PREG_OFFSET_CAPTURE, $offset)) {
813
-                $matchIndex = $matches[0][1];
814
-                $css = substr_replace($css, "\n", $matchIndex + 1, 0);
815
-                $offset = $matchIndex + 2 + $this->linebreakPosition;
816
-                $l += 1;
817
-                if ($offset > $l) {
818
-                    break;
819
-                }
820
-            }
821
-        }
822
-
823
-        return $css;
824
-    }
825
-
826
-    /**
827
-     * Converts hsl() & rgb() colors to HEX format.
828
-     * @param $matches
829
-     * @return string
830
-     */
831
-    private function shortenHslAndRgbToHexCallback($matches)
832
-    {
833
-        $type = $matches[1];
834
-        $values = explode(',', $matches[2]);
835
-        $terminator = $matches[3];
788
+		// Order critical at-rules:
789
+		// 1. @charset first
790
+		// 2. @imports below @charset
791
+		// 3. @namespaces below @imports
792
+		$css = $charset . $imports . $namespaces . $css;
793
+
794
+		return $css;
795
+	}
796
+
797
+	/**
798
+	 * Splits long lines after a specific column.
799
+	 *
800
+	 * Some source control tools don't like it when files containing lines longer
801
+	 * than, say 8000 characters, are checked in. The linebreak option is used in
802
+	 * that case to split long lines after a specific column.
803
+	 *
804
+	 * @param string $css the whole stylesheet.
805
+	 * @return string
806
+	 */
807
+	private function processLongLineSplitting($css)
808
+	{
809
+		if ($this->linebreakPosition > 0) {
810
+			$l = strlen($css);
811
+			$offset = $this->linebreakPosition;
812
+			while (preg_match('/(?<!\\\\)\}(?!\n)/S', $css, $matches, PREG_OFFSET_CAPTURE, $offset)) {
813
+				$matchIndex = $matches[0][1];
814
+				$css = substr_replace($css, "\n", $matchIndex + 1, 0);
815
+				$offset = $matchIndex + 2 + $this->linebreakPosition;
816
+				$l += 1;
817
+				if ($offset > $l) {
818
+					break;
819
+				}
820
+			}
821
+		}
822
+
823
+		return $css;
824
+	}
825
+
826
+	/**
827
+	 * Converts hsl() & rgb() colors to HEX format.
828
+	 * @param $matches
829
+	 * @return string
830
+	 */
831
+	private function shortenHslAndRgbToHexCallback($matches)
832
+	{
833
+		$type = $matches[1];
834
+		$values = explode(',', $matches[2]);
835
+		$terminator = $matches[3];
836 836
         
837
-        if ($type === 'hsl') {
838
-            $values = Utils::hslToRgb($values);
839
-        }
837
+		if ($type === 'hsl') {
838
+			$values = Utils::hslToRgb($values);
839
+		}
840 840
         
841
-        $hexColors = Utils::rgbToHex($values);
842
-
843
-        // Restore space after rgb() or hsl() function in some cases such as:
844
-        // background-image: linear-gradient(to bottom, rgb(210,180,140) 10%, rgb(255,0,0) 90%);
845
-        if (!empty($terminator) && !preg_match('/[ ,);]/S', $terminator)) {
846
-            $terminator = ' '. $terminator;
847
-        }
848
-
849
-        return '#'. implode('', $hexColors) . $terminator;
850
-    }
851
-
852
-    /**
853
-     * Compresses HEX color values of the form #AABBCC to #ABC or short color name.
854
-     * @param $matches
855
-     * @return string
856
-     */
857
-    private function shortenHexColorsCallback($matches)
858
-    {
859
-        $hex = $matches[1];
841
+		$hexColors = Utils::rgbToHex($values);
842
+
843
+		// Restore space after rgb() or hsl() function in some cases such as:
844
+		// background-image: linear-gradient(to bottom, rgb(210,180,140) 10%, rgb(255,0,0) 90%);
845
+		if (!empty($terminator) && !preg_match('/[ ,);]/S', $terminator)) {
846
+			$terminator = ' '. $terminator;
847
+		}
848
+
849
+		return '#'. implode('', $hexColors) . $terminator;
850
+	}
851
+
852
+	/**
853
+	 * Compresses HEX color values of the form #AABBCC to #ABC or short color name.
854
+	 * @param $matches
855
+	 * @return string
856
+	 */
857
+	private function shortenHexColorsCallback($matches)
858
+	{
859
+		$hex = $matches[1];
860 860
         
861
-        // Shorten suitable 6 chars HEX colors
862
-        if (strlen($hex) === 6 && preg_match('/^([0-9a-f])\1([0-9a-f])\2([0-9a-f])\3$/Si', $hex, $m)) {
863
-            $hex = $m[1] . $m[2] . $m[3];
864
-        }
861
+		// Shorten suitable 6 chars HEX colors
862
+		if (strlen($hex) === 6 && preg_match('/^([0-9a-f])\1([0-9a-f])\2([0-9a-f])\3$/Si', $hex, $m)) {
863
+			$hex = $m[1] . $m[2] . $m[3];
864
+		}
865 865
         
866
-        // Lowercase
867
-        $hex = '#'. strtolower($hex);
868
-
869
-        // Replace Hex colors with shorter color names
870
-        $color = array_key_exists($hex, $this->hexToNamedColorsMap) ? $this->hexToNamedColorsMap[$hex] : $hex;
871
-
872
-        return $color . $matches[2];
873
-    }
874
-
875
-    /**
876
-     * Shortens all named colors with a shorter HEX counterpart for a set of safe properties
877
-     * e.g. white -> #fff
878
-     * @param array $matches
879
-     * @return string
880
-     */
881
-    private function shortenNamedColorsCallback($matches)
882
-    {
883
-        return $matches[1] . $this->namedToHexColorsMap[strtolower($matches[2])] . $matches[3];
884
-    }
885
-
886
-    /**
887
-     * Makes a string lowercase
888
-     * @param array $matches
889
-     * @return string
890
-     */
891
-    private function strtolowerCallback($matches)
892
-    {
893
-        return strtolower($matches[0]);
894
-    }
866
+		// Lowercase
867
+		$hex = '#'. strtolower($hex);
868
+
869
+		// Replace Hex colors with shorter color names
870
+		$color = array_key_exists($hex, $this->hexToNamedColorsMap) ? $this->hexToNamedColorsMap[$hex] : $hex;
871
+
872
+		return $color . $matches[2];
873
+	}
874
+
875
+	/**
876
+	 * Shortens all named colors with a shorter HEX counterpart for a set of safe properties
877
+	 * e.g. white -> #fff
878
+	 * @param array $matches
879
+	 * @return string
880
+	 */
881
+	private function shortenNamedColorsCallback($matches)
882
+	{
883
+		return $matches[1] . $this->namedToHexColorsMap[strtolower($matches[2])] . $matches[3];
884
+	}
885
+
886
+	/**
887
+	 * Makes a string lowercase
888
+	 * @param array $matches
889
+	 * @return string
890
+	 */
891
+	private function strtolowerCallback($matches)
892
+	{
893
+		return strtolower($matches[0]);
894
+	}
895 895
 }
Please login to merge, or discard this patch.
sources/ext/cssmin/tubalmartin/Utils.php 1 patch
Indentation   +142 added lines, -142 removed lines patch added patch discarded remove patch
@@ -4,146 +4,146 @@
 block discarded – undo
4 4
 
5 5
 class Utils
6 6
 {
7
-    /**
8
-     * Clamps a number between a minimum and a maximum value.
9
-     * @param int|float $n the number to clamp
10
-     * @param int|float $min the lower end number allowed
11
-     * @param int|float $max the higher end number allowed
12
-     * @return int|float
13
-     */
14
-    public static function clampNumber($n, $min, $max)
15
-    {
16
-        return min(max($n, $min), $max);
17
-    }
18
-
19
-    /**
20
-     * Clamps a RGB color number outside the sRGB color space
21
-     * @param int|float $n the number to clamp
22
-     * @return int|float
23
-     */
24
-    public static function clampNumberSrgb($n)
25
-    {
26
-        return self::clampNumber($n, 0, 255);
27
-    }
28
-
29
-    /**
30
-     * Converts a HSL color into a RGB color
31
-     * @param array $hslValues
32
-     * @return array
33
-     */
34
-    public static function hslToRgb($hslValues)
35
-    {
36
-        $h = floatval($hslValues[0]);
37
-        $s = floatval(str_replace('%', '', $hslValues[1]));
38
-        $l = floatval(str_replace('%', '', $hslValues[2]));
39
-
40
-        // Wrap and clamp, then fraction!
41
-        $h = ((($h % 360) + 360) % 360) / 360;
42
-        $s = self::clampNumber($s, 0, 100) / 100;
43
-        $l = self::clampNumber($l, 0, 100) / 100;
44
-
45
-        if ($s == 0) {
46
-            $r = $g = $b = self::roundNumber(255 * $l);
47
-        } else {
48
-            $v2 = $l < 0.5 ? $l * (1 + $s) : ($l + $s) - ($s * $l);
49
-            $v1 = (2 * $l) - $v2;
50
-            $r = self::roundNumber(255 * self::hueToRgb($v1, $v2, $h + (1/3)));
51
-            $g = self::roundNumber(255 * self::hueToRgb($v1, $v2, $h));
52
-            $b = self::roundNumber(255 * self::hueToRgb($v1, $v2, $h - (1/3)));
53
-        }
54
-
55
-        return array($r, $g, $b);
56
-    }
57
-
58
-    /**
59
-     * Tests and selects the correct formula for each RGB color channel
60
-     * @param $v1
61
-     * @param $v2
62
-     * @param $vh
63
-     * @return mixed
64
-     */
65
-    public static function hueToRgb($v1, $v2, $vh)
66
-    {
67
-        $vh = $vh < 0 ? $vh + 1 : ($vh > 1 ? $vh - 1 : $vh);
68
-
69
-        if ($vh * 6 < 1) {
70
-            return $v1 + ($v2 - $v1) * 6 * $vh;
71
-        }
72
-
73
-        if ($vh * 2 < 1) {
74
-            return $v2;
75
-        }
76
-
77
-        if ($vh * 3 < 2) {
78
-            return $v1 + ($v2 - $v1) * ((2 / 3) - $vh) * 6;
79
-        }
80
-
81
-        return $v1;
82
-    }
83
-
84
-    /**
85
-     * Convert strings like "64M" or "30" to int values
86
-     * @param mixed $size
87
-     * @return int
88
-     */
89
-    public static function normalizeInt($size)
90
-    {
91
-        if (is_string($size)) {
92
-            $letter = substr($size, -1);
93
-            $size = intval($size);
94
-            switch ($letter) {
95
-                case 'M':
96
-                case 'm':
97
-                    return (int) $size * 1048576;
98
-                case 'K':
99
-                case 'k':
100
-                    return (int) $size * 1024;
101
-                case 'G':
102
-                case 'g':
103
-                    return (int) $size * 1073741824;
104
-            }
105
-        }
106
-        return (int) $size;
107
-    }
108
-
109
-    /**
110
-     * Converts a string containing and RGB percentage value into a RGB integer value i.e. '90%' -> 229.5
111
-     * @param $rgbPercentage
112
-     * @return int
113
-     */
114
-    public static function rgbPercentageToRgbInteger($rgbPercentage)
115
-    {
116
-        if (strpos($rgbPercentage, '%') !== false) {
117
-            $rgbPercentage = self::roundNumber(floatval(str_replace('%', '', $rgbPercentage)) * 2.55);
118
-        }
119
-
120
-        return intval($rgbPercentage, 10);
121
-    }
122
-
123
-    /**
124
-     * Converts a RGB color into a HEX color
125
-     * @param array $rgbColors
126
-     * @return array
127
-     */
128
-    public static function rgbToHex($rgbColors)
129
-    {
130
-        $hexColors = array();
131
-
132
-        // Values outside the sRGB color space should be clipped (0-255)
133
-        for ($i = 0, $l = count($rgbColors); $i < $l; $i++) {
134
-            $hexColors[$i] = sprintf("%02x", self::clampNumberSrgb(self::rgbPercentageToRgbInteger($rgbColors[$i])));
135
-        }
136
-
137
-        return $hexColors;
138
-    }
139
-
140
-    /**
141
-     * Rounds a number to its closest integer
142
-     * @param $n
143
-     * @return int
144
-     */
145
-    public static function roundNumber($n)
146
-    {
147
-        return intval(round(floatval($n)), 10);
148
-    }
7
+	/**
8
+	 * Clamps a number between a minimum and a maximum value.
9
+	 * @param int|float $n the number to clamp
10
+	 * @param int|float $min the lower end number allowed
11
+	 * @param int|float $max the higher end number allowed
12
+	 * @return int|float
13
+	 */
14
+	public static function clampNumber($n, $min, $max)
15
+	{
16
+		return min(max($n, $min), $max);
17
+	}
18
+
19
+	/**
20
+	 * Clamps a RGB color number outside the sRGB color space
21
+	 * @param int|float $n the number to clamp
22
+	 * @return int|float
23
+	 */
24
+	public static function clampNumberSrgb($n)
25
+	{
26
+		return self::clampNumber($n, 0, 255);
27
+	}
28
+
29
+	/**
30
+	 * Converts a HSL color into a RGB color
31
+	 * @param array $hslValues
32
+	 * @return array
33
+	 */
34
+	public static function hslToRgb($hslValues)
35
+	{
36
+		$h = floatval($hslValues[0]);
37
+		$s = floatval(str_replace('%', '', $hslValues[1]));
38
+		$l = floatval(str_replace('%', '', $hslValues[2]));
39
+
40
+		// Wrap and clamp, then fraction!
41
+		$h = ((($h % 360) + 360) % 360) / 360;
42
+		$s = self::clampNumber($s, 0, 100) / 100;
43
+		$l = self::clampNumber($l, 0, 100) / 100;
44
+
45
+		if ($s == 0) {
46
+			$r = $g = $b = self::roundNumber(255 * $l);
47
+		} else {
48
+			$v2 = $l < 0.5 ? $l * (1 + $s) : ($l + $s) - ($s * $l);
49
+			$v1 = (2 * $l) - $v2;
50
+			$r = self::roundNumber(255 * self::hueToRgb($v1, $v2, $h + (1/3)));
51
+			$g = self::roundNumber(255 * self::hueToRgb($v1, $v2, $h));
52
+			$b = self::roundNumber(255 * self::hueToRgb($v1, $v2, $h - (1/3)));
53
+		}
54
+
55
+		return array($r, $g, $b);
56
+	}
57
+
58
+	/**
59
+	 * Tests and selects the correct formula for each RGB color channel
60
+	 * @param $v1
61
+	 * @param $v2
62
+	 * @param $vh
63
+	 * @return mixed
64
+	 */
65
+	public static function hueToRgb($v1, $v2, $vh)
66
+	{
67
+		$vh = $vh < 0 ? $vh + 1 : ($vh > 1 ? $vh - 1 : $vh);
68
+
69
+		if ($vh * 6 < 1) {
70
+			return $v1 + ($v2 - $v1) * 6 * $vh;
71
+		}
72
+
73
+		if ($vh * 2 < 1) {
74
+			return $v2;
75
+		}
76
+
77
+		if ($vh * 3 < 2) {
78
+			return $v1 + ($v2 - $v1) * ((2 / 3) - $vh) * 6;
79
+		}
80
+
81
+		return $v1;
82
+	}
83
+
84
+	/**
85
+	 * Convert strings like "64M" or "30" to int values
86
+	 * @param mixed $size
87
+	 * @return int
88
+	 */
89
+	public static function normalizeInt($size)
90
+	{
91
+		if (is_string($size)) {
92
+			$letter = substr($size, -1);
93
+			$size = intval($size);
94
+			switch ($letter) {
95
+				case 'M':
96
+				case 'm':
97
+					return (int) $size * 1048576;
98
+				case 'K':
99
+				case 'k':
100
+					return (int) $size * 1024;
101
+				case 'G':
102
+				case 'g':
103
+					return (int) $size * 1073741824;
104
+			}
105
+		}
106
+		return (int) $size;
107
+	}
108
+
109
+	/**
110
+	 * Converts a string containing and RGB percentage value into a RGB integer value i.e. '90%' -> 229.5
111
+	 * @param $rgbPercentage
112
+	 * @return int
113
+	 */
114
+	public static function rgbPercentageToRgbInteger($rgbPercentage)
115
+	{
116
+		if (strpos($rgbPercentage, '%') !== false) {
117
+			$rgbPercentage = self::roundNumber(floatval(str_replace('%', '', $rgbPercentage)) * 2.55);
118
+		}
119
+
120
+		return intval($rgbPercentage, 10);
121
+	}
122
+
123
+	/**
124
+	 * Converts a RGB color into a HEX color
125
+	 * @param array $rgbColors
126
+	 * @return array
127
+	 */
128
+	public static function rgbToHex($rgbColors)
129
+	{
130
+		$hexColors = array();
131
+
132
+		// Values outside the sRGB color space should be clipped (0-255)
133
+		for ($i = 0, $l = count($rgbColors); $i < $l; $i++) {
134
+			$hexColors[$i] = sprintf("%02x", self::clampNumberSrgb(self::rgbPercentageToRgbInteger($rgbColors[$i])));
135
+		}
136
+
137
+		return $hexColors;
138
+	}
139
+
140
+	/**
141
+	 * Rounds a number to its closest integer
142
+	 * @param $n
143
+	 * @return int
144
+	 */
145
+	public static function roundNumber($n)
146
+	{
147
+		return intval(round(floatval($n)), 10);
148
+	}
149 149
 }
Please login to merge, or discard this patch.
sources/ext/cssmin/tubalmartin/Command.php 1 patch
Indentation   +166 added lines, -166 removed lines patch added patch discarded remove patch
@@ -4,188 +4,188 @@  discard block
 block discarded – undo
4 4
 
5 5
 class Command
6 6
 {
7
-    const SUCCESS_EXIT = 0;
8
-    const FAILURE_EXIT = 1;
7
+	const SUCCESS_EXIT = 0;
8
+	const FAILURE_EXIT = 1;
9 9
     
10
-    protected $stats = array();
10
+	protected $stats = array();
11 11
     
12
-    public static function main()
13
-    {
14
-        $command = new self;
15
-        $command->run();
16
-    }
17
-
18
-    public function run()
19
-    {
20
-        $opts = getopt(
21
-            'hi:o:',
22
-            array(
23
-                'help',
24
-                'input:',
25
-                'output:',
26
-                'dry-run',
27
-                'keep-sourcemap',
28
-                'keep-sourcemap-comment',
29
-                'linebreak-position:',
30
-                'memory-limit:',
31
-                'pcre-backtrack-limit:',
32
-                'pcre-recursion-limit:',
33
-                'remove-important-comments'
34
-            )
35
-        );
36
-
37
-        $help = $this->getOpt(array('h', 'help'), $opts);
38
-        $input = $this->getOpt(array('i', 'input'), $opts);
39
-        $output = $this->getOpt(array('o', 'output'), $opts);
40
-        $dryrun = $this->getOpt('dry-run', $opts);
41
-        $keepSourceMapComment = $this->getOpt(array('keep-sourcemap', 'keep-sourcemap-comment'), $opts);
42
-        $linebreakPosition = $this->getOpt('linebreak-position', $opts);
43
-        $memoryLimit = $this->getOpt('memory-limit', $opts);
44
-        $backtrackLimit = $this->getOpt('pcre-backtrack-limit', $opts);
45
-        $recursionLimit = $this->getOpt('pcre-recursion-limit', $opts);
46
-        $removeImportantComments = $this->getOpt('remove-important-comments', $opts);
47
-
48
-        if (!is_null($help)) {
49
-            $this->showHelp();
50
-            die(self::SUCCESS_EXIT);
51
-        }
52
-
53
-        if (is_null($input)) {
54
-            fwrite(STDERR, '-i <file> argument is missing' . PHP_EOL);
55
-            $this->showHelp();
56
-            die(self::FAILURE_EXIT);
57
-        }
58
-
59
-        if (!is_readable($input)) {
60
-            fwrite(STDERR, 'Input file is not readable' . PHP_EOL);
61
-            die(self::FAILURE_EXIT);
62
-        }
63
-
64
-        $css = file_get_contents($input);
65
-
66
-        if ($css === false) {
67
-            fwrite(STDERR, 'Input CSS code could not be retrieved from input file' . PHP_EOL);
68
-            die(self::FAILURE_EXIT);
69
-        }
12
+	public static function main()
13
+	{
14
+		$command = new self;
15
+		$command->run();
16
+	}
17
+
18
+	public function run()
19
+	{
20
+		$opts = getopt(
21
+			'hi:o:',
22
+			array(
23
+				'help',
24
+				'input:',
25
+				'output:',
26
+				'dry-run',
27
+				'keep-sourcemap',
28
+				'keep-sourcemap-comment',
29
+				'linebreak-position:',
30
+				'memory-limit:',
31
+				'pcre-backtrack-limit:',
32
+				'pcre-recursion-limit:',
33
+				'remove-important-comments'
34
+			)
35
+		);
36
+
37
+		$help = $this->getOpt(array('h', 'help'), $opts);
38
+		$input = $this->getOpt(array('i', 'input'), $opts);
39
+		$output = $this->getOpt(array('o', 'output'), $opts);
40
+		$dryrun = $this->getOpt('dry-run', $opts);
41
+		$keepSourceMapComment = $this->getOpt(array('keep-sourcemap', 'keep-sourcemap-comment'), $opts);
42
+		$linebreakPosition = $this->getOpt('linebreak-position', $opts);
43
+		$memoryLimit = $this->getOpt('memory-limit', $opts);
44
+		$backtrackLimit = $this->getOpt('pcre-backtrack-limit', $opts);
45
+		$recursionLimit = $this->getOpt('pcre-recursion-limit', $opts);
46
+		$removeImportantComments = $this->getOpt('remove-important-comments', $opts);
47
+
48
+		if (!is_null($help)) {
49
+			$this->showHelp();
50
+			die(self::SUCCESS_EXIT);
51
+		}
52
+
53
+		if (is_null($input)) {
54
+			fwrite(STDERR, '-i <file> argument is missing' . PHP_EOL);
55
+			$this->showHelp();
56
+			die(self::FAILURE_EXIT);
57
+		}
58
+
59
+		if (!is_readable($input)) {
60
+			fwrite(STDERR, 'Input file is not readable' . PHP_EOL);
61
+			die(self::FAILURE_EXIT);
62
+		}
63
+
64
+		$css = file_get_contents($input);
65
+
66
+		if ($css === false) {
67
+			fwrite(STDERR, 'Input CSS code could not be retrieved from input file' . PHP_EOL);
68
+			die(self::FAILURE_EXIT);
69
+		}
70 70
         
71
-        $this->setStat('original-size', strlen($css));
71
+		$this->setStat('original-size', strlen($css));
72 72
         
73
-        $cssmin = new Minifier;
73
+		$cssmin = new Minifier;
74 74
 
75
-        if (!is_null($keepSourceMapComment)) {
76
-            $cssmin->keepSourceMapComment();
77
-        }
75
+		if (!is_null($keepSourceMapComment)) {
76
+			$cssmin->keepSourceMapComment();
77
+		}
78 78
 
79
-        if (!is_null($removeImportantComments)) {
80
-            $cssmin->removeImportantComments();
81
-        }
79
+		if (!is_null($removeImportantComments)) {
80
+			$cssmin->removeImportantComments();
81
+		}
82 82
 
83
-        if (!is_null($linebreakPosition)) {
84
-            $cssmin->setLineBreakPosition($linebreakPosition);
85
-        }
83
+		if (!is_null($linebreakPosition)) {
84
+			$cssmin->setLineBreakPosition($linebreakPosition);
85
+		}
86 86
         
87
-        if (!is_null($memoryLimit)) {
88
-            $cssmin->setMemoryLimit($memoryLimit);
89
-        }
87
+		if (!is_null($memoryLimit)) {
88
+			$cssmin->setMemoryLimit($memoryLimit);
89
+		}
90 90
 
91
-        if (!is_null($backtrackLimit)) {
92
-            $cssmin->setPcreBacktrackLimit($backtrackLimit);
93
-        }
91
+		if (!is_null($backtrackLimit)) {
92
+			$cssmin->setPcreBacktrackLimit($backtrackLimit);
93
+		}
94 94
 
95
-        if (!is_null($recursionLimit)) {
96
-            $cssmin->setPcreRecursionLimit($recursionLimit);
97
-        }
95
+		if (!is_null($recursionLimit)) {
96
+			$cssmin->setPcreRecursionLimit($recursionLimit);
97
+		}
98 98
         
99
-        $this->setStat('compression-time-start', microtime(true));
99
+		$this->setStat('compression-time-start', microtime(true));
100 100
         
101
-        $css = $cssmin->run($css);
101
+		$css = $cssmin->run($css);
102 102
 
103
-        $this->setStat('compression-time-end', microtime(true));
104
-        $this->setStat('peak-memory-usage', memory_get_peak_usage(true));
105
-        $this->setStat('compressed-size', strlen($css));
103
+		$this->setStat('compression-time-end', microtime(true));
104
+		$this->setStat('peak-memory-usage', memory_get_peak_usage(true));
105
+		$this->setStat('compressed-size', strlen($css));
106 106
         
107
-        if (!is_null($dryrun)) {
108
-            $this->showStats();
109
-            die(self::SUCCESS_EXIT);
110
-        }
111
-
112
-        if (is_null($output)) {
113
-            fwrite(STDOUT, $css . PHP_EOL);
114
-            $this->showStats();
115
-            die(self::SUCCESS_EXIT);
116
-        }
117
-
118
-        if (!is_writable(dirname($output))) {
119
-            fwrite(STDERR, 'Output file is not writable' . PHP_EOL);
120
-            die(self::FAILURE_EXIT);
121
-        }
122
-
123
-        if (file_put_contents($output, $css) === false) {
124
-            fwrite(STDERR, 'Compressed CSS code could not be saved to output file' . PHP_EOL);
125
-            die(self::FAILURE_EXIT);
126
-        }
127
-
128
-        $this->showStats();
129
-
130
-        die(self::SUCCESS_EXIT);
131
-    }
132
-
133
-    protected function getOpt($opts, $options)
134
-    {
135
-        $value = null;
136
-
137
-        if (is_string($opts)) {
138
-            $opts = array($opts);
139
-        }
140
-
141
-        foreach ($opts as $opt) {
142
-            if (array_key_exists($opt, $options)) {
143
-                $value = $options[$opt];
144
-                break;
145
-            }
146
-        }
147
-
148
-        return $value;
149
-    }
107
+		if (!is_null($dryrun)) {
108
+			$this->showStats();
109
+			die(self::SUCCESS_EXIT);
110
+		}
111
+
112
+		if (is_null($output)) {
113
+			fwrite(STDOUT, $css . PHP_EOL);
114
+			$this->showStats();
115
+			die(self::SUCCESS_EXIT);
116
+		}
117
+
118
+		if (!is_writable(dirname($output))) {
119
+			fwrite(STDERR, 'Output file is not writable' . PHP_EOL);
120
+			die(self::FAILURE_EXIT);
121
+		}
122
+
123
+		if (file_put_contents($output, $css) === false) {
124
+			fwrite(STDERR, 'Compressed CSS code could not be saved to output file' . PHP_EOL);
125
+			die(self::FAILURE_EXIT);
126
+		}
127
+
128
+		$this->showStats();
129
+
130
+		die(self::SUCCESS_EXIT);
131
+	}
132
+
133
+	protected function getOpt($opts, $options)
134
+	{
135
+		$value = null;
136
+
137
+		if (is_string($opts)) {
138
+			$opts = array($opts);
139
+		}
140
+
141
+		foreach ($opts as $opt) {
142
+			if (array_key_exists($opt, $options)) {
143
+				$value = $options[$opt];
144
+				break;
145
+			}
146
+		}
147
+
148
+		return $value;
149
+	}
150 150
     
151
-    protected function setStat($statName, $statValue)
152
-    {
153
-        $this->stats[$statName] = $statValue;
154
-    }
151
+	protected function setStat($statName, $statValue)
152
+	{
153
+		$this->stats[$statName] = $statValue;
154
+	}
155 155
     
156
-    protected function formatBytes($size, $precision = 2)
157
-    {
158
-        $base = log($size, 1024);
159
-        $suffixes = array('B', 'K', 'M', 'G', 'T');
160
-        return round(pow(1024, $base - floor($base)), $precision) .' '. $suffixes[floor($base)];
161
-    }
156
+	protected function formatBytes($size, $precision = 2)
157
+	{
158
+		$base = log($size, 1024);
159
+		$suffixes = array('B', 'K', 'M', 'G', 'T');
160
+		return round(pow(1024, $base - floor($base)), $precision) .' '. $suffixes[floor($base)];
161
+	}
162 162
     
163
-    protected function formatMicroSeconds($microSecs, $precision = 2)
164
-    {
165
-        // ms
166
-        $time = round($microSecs * 1000, $precision);
163
+	protected function formatMicroSeconds($microSecs, $precision = 2)
164
+	{
165
+		// ms
166
+		$time = round($microSecs * 1000, $precision);
167 167
         
168
-        if ($time >= 60 * 1000) {
169
-            $time = round($time / 60 * 1000, $precision) .' m'; // m
170
-        } elseif ($time >= 1000) {
171
-            $time = round($time / 1000, $precision) .' s'; // s
172
-        } else {
173
-            $time .= ' ms';
174
-        }
168
+		if ($time >= 60 * 1000) {
169
+			$time = round($time / 60 * 1000, $precision) .' m'; // m
170
+		} elseif ($time >= 1000) {
171
+			$time = round($time / 1000, $precision) .' s'; // s
172
+		} else {
173
+			$time .= ' ms';
174
+		}
175 175
         
176
-        return $time;
177
-    }
176
+		return $time;
177
+	}
178 178
     
179
-    protected function showStats()
180
-    {
181
-        $spaceSavings = round((1 - ($this->stats['compressed-size'] / $this->stats['original-size'])) * 100, 2);
182
-        $compressionRatio = round($this->stats['original-size'] / $this->stats['compressed-size'], 2);
183
-        $compressionTime = $this->formatMicroSeconds(
184
-            $this->stats['compression-time-end'] - $this->stats['compression-time-start']
185
-        );
186
-        $peakMemoryUsage = $this->formatBytes($this->stats['peak-memory-usage']);
179
+	protected function showStats()
180
+	{
181
+		$spaceSavings = round((1 - ($this->stats['compressed-size'] / $this->stats['original-size'])) * 100, 2);
182
+		$compressionRatio = round($this->stats['original-size'] / $this->stats['compressed-size'], 2);
183
+		$compressionTime = $this->formatMicroSeconds(
184
+			$this->stats['compression-time-end'] - $this->stats['compression-time-start']
185
+		);
186
+		$peakMemoryUsage = $this->formatBytes($this->stats['peak-memory-usage']);
187 187
         
188
-        print <<<EOT
188
+		print <<<EOT
189 189
         
190 190
 ------------------------------
191 191
 CSSMIN STATS        
@@ -197,11 +197,11 @@  discard block
 block discarded – undo
197 197
 
198 198
 
199 199
 EOT;
200
-    }
200
+	}
201 201
 
202
-    protected function showHelp()
203
-    {
204
-        print <<<'EOT'
202
+	protected function showHelp()
203
+	{
204
+		print <<<'EOT'
205 205
 Usage: cssmin [options] -i <file> [-o <file>]
206 206
   
207 207
   -i|--input <file>              File containing uncompressed CSS code.
@@ -219,5 +219,5 @@  discard block
 block discarded – undo
219 219
   --remove-important-comments    Removes !important comments from output.
220 220
 
221 221
 EOT;
222
-    }
222
+	}
223 223
 }
Please login to merge, or discard this patch.
sources/ext/cssmin/tubalmartin/Colors.php 1 patch
Indentation   +147 added lines, -147 removed lines patch added patch discarded remove patch
@@ -4,152 +4,152 @@
 block discarded – undo
4 4
 
5 5
 class Colors
6 6
 {
7
-    public static function getHexToNamedMap()
8
-    {
9
-        // Hex colors longer than named counterpart
10
-        return array(
11
-            '#f0ffff' => 'azure',
12
-            '#f5f5dc' => 'beige',
13
-            '#ffe4c4' => 'bisque',
14
-            '#a52a2a' => 'brown',
15
-            '#ff7f50' => 'coral',
16
-            '#ffd700' => 'gold',
17
-            '#808080' => 'gray',
18
-            '#008000' => 'green',
19
-            '#4b0082' => 'indigo',
20
-            '#fffff0' => 'ivory',
21
-            '#f0e68c' => 'khaki',
22
-            '#faf0e6' => 'linen',
23
-            '#800000' => 'maroon',
24
-            '#000080' => 'navy',
25
-            '#fdf5e6' => 'oldlace',
26
-            '#808000' => 'olive',
27
-            '#ffa500' => 'orange',
28
-            '#da70d6' => 'orchid',
29
-            '#cd853f' => 'peru',
30
-            '#ffc0cb' => 'pink',
31
-            '#dda0dd' => 'plum',
32
-            '#800080' => 'purple',
33
-            '#f00'    => 'red',
34
-            '#fa8072' => 'salmon',
35
-            '#a0522d' => 'sienna',
36
-            '#c0c0c0' => 'silver',
37
-            '#fffafa' => 'snow',
38
-            '#d2b48c' => 'tan',
39
-            '#008080' => 'teal',
40
-            '#ff6347' => 'tomato',
41
-            '#ee82ee' => 'violet',
42
-            '#f5deb3' => 'wheat'
43
-        );
44
-    }
7
+	public static function getHexToNamedMap()
8
+	{
9
+		// Hex colors longer than named counterpart
10
+		return array(
11
+			'#f0ffff' => 'azure',
12
+			'#f5f5dc' => 'beige',
13
+			'#ffe4c4' => 'bisque',
14
+			'#a52a2a' => 'brown',
15
+			'#ff7f50' => 'coral',
16
+			'#ffd700' => 'gold',
17
+			'#808080' => 'gray',
18
+			'#008000' => 'green',
19
+			'#4b0082' => 'indigo',
20
+			'#fffff0' => 'ivory',
21
+			'#f0e68c' => 'khaki',
22
+			'#faf0e6' => 'linen',
23
+			'#800000' => 'maroon',
24
+			'#000080' => 'navy',
25
+			'#fdf5e6' => 'oldlace',
26
+			'#808000' => 'olive',
27
+			'#ffa500' => 'orange',
28
+			'#da70d6' => 'orchid',
29
+			'#cd853f' => 'peru',
30
+			'#ffc0cb' => 'pink',
31
+			'#dda0dd' => 'plum',
32
+			'#800080' => 'purple',
33
+			'#f00'    => 'red',
34
+			'#fa8072' => 'salmon',
35
+			'#a0522d' => 'sienna',
36
+			'#c0c0c0' => 'silver',
37
+			'#fffafa' => 'snow',
38
+			'#d2b48c' => 'tan',
39
+			'#008080' => 'teal',
40
+			'#ff6347' => 'tomato',
41
+			'#ee82ee' => 'violet',
42
+			'#f5deb3' => 'wheat'
43
+		);
44
+	}
45 45
 
46
-    public static function getNamedToHexMap()
47
-    {
48
-        // Named colors longer than hex counterpart
49
-        return array(
50
-            'aliceblue' => '#f0f8ff',
51
-            'antiquewhite' => '#faebd7',
52
-            'aquamarine' => '#7fffd4',
53
-            'black' => '#000',
54
-            'blanchedalmond' => '#ffebcd',
55
-            'blueviolet' => '#8a2be2',
56
-            'burlywood' => '#deb887',
57
-            'cadetblue' => '#5f9ea0',
58
-            'chartreuse' => '#7fff00',
59
-            'chocolate' => '#d2691e',
60
-            'cornflowerblue' => '#6495ed',
61
-            'cornsilk' => '#fff8dc',
62
-            'darkblue' => '#00008b',
63
-            'darkcyan' => '#008b8b',
64
-            'darkgoldenrod' => '#b8860b',
65
-            'darkgray' => '#a9a9a9',
66
-            'darkgreen' => '#006400',
67
-            'darkgrey' => '#a9a9a9',
68
-            'darkkhaki' => '#bdb76b',
69
-            'darkmagenta' => '#8b008b',
70
-            'darkolivegreen' => '#556b2f',
71
-            'darkorange' => '#ff8c00',
72
-            'darkorchid' => '#9932cc',
73
-            'darksalmon' => '#e9967a',
74
-            'darkseagreen' => '#8fbc8f',
75
-            'darkslateblue' => '#483d8b',
76
-            'darkslategray' => '#2f4f4f',
77
-            'darkslategrey' => '#2f4f4f',
78
-            'darkturquoise' => '#00ced1',
79
-            'darkviolet' => '#9400d3',
80
-            'deeppink' => '#ff1493',
81
-            'deepskyblue' => '#00bfff',
82
-            'dodgerblue' => '#1e90ff',
83
-            'firebrick' => '#b22222',
84
-            'floralwhite' => '#fffaf0',
85
-            'forestgreen' => '#228b22',
86
-            'fuchsia' => '#f0f',
87
-            'gainsboro' => '#dcdcdc',
88
-            'ghostwhite' => '#f8f8ff',
89
-            'goldenrod' => '#daa520',
90
-            'greenyellow' => '#adff2f',
91
-            'honeydew' => '#f0fff0',
92
-            'indianred' => '#cd5c5c',
93
-            'lavender' => '#e6e6fa',
94
-            'lavenderblush' => '#fff0f5',
95
-            'lawngreen' => '#7cfc00',
96
-            'lemonchiffon' => '#fffacd',
97
-            'lightblue' => '#add8e6',
98
-            'lightcoral' => '#f08080',
99
-            'lightcyan' => '#e0ffff',
100
-            'lightgoldenrodyellow' => '#fafad2',
101
-            'lightgray' => '#d3d3d3',
102
-            'lightgreen' => '#90ee90',
103
-            'lightgrey' => '#d3d3d3',
104
-            'lightpink' => '#ffb6c1',
105
-            'lightsalmon' => '#ffa07a',
106
-            'lightseagreen' => '#20b2aa',
107
-            'lightskyblue' => '#87cefa',
108
-            'lightslategray' => '#778899',
109
-            'lightslategrey' => '#778899',
110
-            'lightsteelblue' => '#b0c4de',
111
-            'lightyellow' => '#ffffe0',
112
-            'limegreen' => '#32cd32',
113
-            'mediumaquamarine' => '#66cdaa',
114
-            'mediumblue' => '#0000cd',
115
-            'mediumorchid' => '#ba55d3',
116
-            'mediumpurple' => '#9370db',
117
-            'mediumseagreen' => '#3cb371',
118
-            'mediumslateblue' => '#7b68ee',
119
-            'mediumspringgreen' => '#00fa9a',
120
-            'mediumturquoise' => '#48d1cc',
121
-            'mediumvioletred' => '#c71585',
122
-            'midnightblue' => '#191970',
123
-            'mintcream' => '#f5fffa',
124
-            'mistyrose' => '#ffe4e1',
125
-            'moccasin' => '#ffe4b5',
126
-            'navajowhite' => '#ffdead',
127
-            'olivedrab' => '#6b8e23',
128
-            'orangered' => '#ff4500',
129
-            'palegoldenrod' => '#eee8aa',
130
-            'palegreen' => '#98fb98',
131
-            'paleturquoise' => '#afeeee',
132
-            'palevioletred' => '#db7093',
133
-            'papayawhip' => '#ffefd5',
134
-            'peachpuff' => '#ffdab9',
135
-            'powderblue' => '#b0e0e6',
136
-            'rebeccapurple' => '#663399',
137
-            'rosybrown' => '#bc8f8f',
138
-            'royalblue' => '#4169e1',
139
-            'saddlebrown' => '#8b4513',
140
-            'sandybrown' => '#f4a460',
141
-            'seagreen' => '#2e8b57',
142
-            'seashell' => '#fff5ee',
143
-            'slateblue' => '#6a5acd',
144
-            'slategray' => '#708090',
145
-            'slategrey' => '#708090',
146
-            'springgreen' => '#00ff7f',
147
-            'steelblue' => '#4682b4',
148
-            'turquoise' => '#40e0d0',
149
-            'white' => '#fff',
150
-            'whitesmoke' => '#f5f5f5',
151
-            'yellow' => '#ff0',
152
-            'yellowgreen' => '#9acd32'
153
-        );
154
-    }
46
+	public static function getNamedToHexMap()
47
+	{
48
+		// Named colors longer than hex counterpart
49
+		return array(
50
+			'aliceblue' => '#f0f8ff',
51
+			'antiquewhite' => '#faebd7',
52
+			'aquamarine' => '#7fffd4',
53
+			'black' => '#000',
54
+			'blanchedalmond' => '#ffebcd',
55
+			'blueviolet' => '#8a2be2',
56
+			'burlywood' => '#deb887',
57
+			'cadetblue' => '#5f9ea0',
58
+			'chartreuse' => '#7fff00',
59
+			'chocolate' => '#d2691e',
60
+			'cornflowerblue' => '#6495ed',
61
+			'cornsilk' => '#fff8dc',
62
+			'darkblue' => '#00008b',
63
+			'darkcyan' => '#008b8b',
64
+			'darkgoldenrod' => '#b8860b',
65
+			'darkgray' => '#a9a9a9',
66
+			'darkgreen' => '#006400',
67
+			'darkgrey' => '#a9a9a9',
68
+			'darkkhaki' => '#bdb76b',
69
+			'darkmagenta' => '#8b008b',
70
+			'darkolivegreen' => '#556b2f',
71
+			'darkorange' => '#ff8c00',
72
+			'darkorchid' => '#9932cc',
73
+			'darksalmon' => '#e9967a',
74
+			'darkseagreen' => '#8fbc8f',
75
+			'darkslateblue' => '#483d8b',
76
+			'darkslategray' => '#2f4f4f',
77
+			'darkslategrey' => '#2f4f4f',
78
+			'darkturquoise' => '#00ced1',
79
+			'darkviolet' => '#9400d3',
80
+			'deeppink' => '#ff1493',
81
+			'deepskyblue' => '#00bfff',
82
+			'dodgerblue' => '#1e90ff',
83
+			'firebrick' => '#b22222',
84
+			'floralwhite' => '#fffaf0',
85
+			'forestgreen' => '#228b22',
86
+			'fuchsia' => '#f0f',
87
+			'gainsboro' => '#dcdcdc',
88
+			'ghostwhite' => '#f8f8ff',
89
+			'goldenrod' => '#daa520',
90
+			'greenyellow' => '#adff2f',
91
+			'honeydew' => '#f0fff0',
92
+			'indianred' => '#cd5c5c',
93
+			'lavender' => '#e6e6fa',
94
+			'lavenderblush' => '#fff0f5',
95
+			'lawngreen' => '#7cfc00',
96
+			'lemonchiffon' => '#fffacd',
97
+			'lightblue' => '#add8e6',
98
+			'lightcoral' => '#f08080',
99
+			'lightcyan' => '#e0ffff',
100
+			'lightgoldenrodyellow' => '#fafad2',
101
+			'lightgray' => '#d3d3d3',
102
+			'lightgreen' => '#90ee90',
103
+			'lightgrey' => '#d3d3d3',
104
+			'lightpink' => '#ffb6c1',
105
+			'lightsalmon' => '#ffa07a',
106
+			'lightseagreen' => '#20b2aa',
107
+			'lightskyblue' => '#87cefa',
108
+			'lightslategray' => '#778899',
109
+			'lightslategrey' => '#778899',
110
+			'lightsteelblue' => '#b0c4de',
111
+			'lightyellow' => '#ffffe0',
112
+			'limegreen' => '#32cd32',
113
+			'mediumaquamarine' => '#66cdaa',
114
+			'mediumblue' => '#0000cd',
115
+			'mediumorchid' => '#ba55d3',
116
+			'mediumpurple' => '#9370db',
117
+			'mediumseagreen' => '#3cb371',
118
+			'mediumslateblue' => '#7b68ee',
119
+			'mediumspringgreen' => '#00fa9a',
120
+			'mediumturquoise' => '#48d1cc',
121
+			'mediumvioletred' => '#c71585',
122
+			'midnightblue' => '#191970',
123
+			'mintcream' => '#f5fffa',
124
+			'mistyrose' => '#ffe4e1',
125
+			'moccasin' => '#ffe4b5',
126
+			'navajowhite' => '#ffdead',
127
+			'olivedrab' => '#6b8e23',
128
+			'orangered' => '#ff4500',
129
+			'palegoldenrod' => '#eee8aa',
130
+			'palegreen' => '#98fb98',
131
+			'paleturquoise' => '#afeeee',
132
+			'palevioletred' => '#db7093',
133
+			'papayawhip' => '#ffefd5',
134
+			'peachpuff' => '#ffdab9',
135
+			'powderblue' => '#b0e0e6',
136
+			'rebeccapurple' => '#663399',
137
+			'rosybrown' => '#bc8f8f',
138
+			'royalblue' => '#4169e1',
139
+			'saddlebrown' => '#8b4513',
140
+			'sandybrown' => '#f4a460',
141
+			'seagreen' => '#2e8b57',
142
+			'seashell' => '#fff5ee',
143
+			'slateblue' => '#6a5acd',
144
+			'slategray' => '#708090',
145
+			'slategrey' => '#708090',
146
+			'springgreen' => '#00ff7f',
147
+			'steelblue' => '#4682b4',
148
+			'turquoise' => '#40e0d0',
149
+			'white' => '#fff',
150
+			'whitesmoke' => '#f5f5f5',
151
+			'yellow' => '#ff0',
152
+			'yellowgreen' => '#9acd32'
153
+		);
154
+	}
155 155
 }
Please login to merge, or discard this patch.