diff --git a/boards.php b/boards.php index 86eb69fd..87ba7ddf 100644 --- a/boards.php +++ b/boards.php @@ -12,6 +12,7 @@ $boards = listBoards(); $all_tags = array(); $total_posts_hour = 0; $total_posts = 0; +$write_maxes = false; function to_tag($str) { $str = trim($str); @@ -20,14 +21,15 @@ function to_tag($str) { return $str; } +if (!file_exists('maxes.txt') || filemtime('maxes.txt') < (time() - (60*60))) { + $fp = fopen('maxes.txt', 'w+'); + $write_maxes = true; +} + foreach ($boards as $i => $board) { - - //$query = prepare(sprintf("SELECT (SELECT MAX(id) from ``posts_%s``) AS max, (SELECT MAX(id) FROM ``posts_%s`` WHERE FROM_UNIXTIME(time) < DATE_SUB(NOW(), INTERVAL 1 HOUR)) AS oldmax, (SELECT MAX(id) from ``posts_%s``) AS max_d, (SELECT MAX(id) FROM ``posts_%s`` WHERE FROM_UNIXTIME(time) < DATE_SUB(NOW(), INTERVAL 1 DAY)) AS oldmax_d, (SELECT count(id) FROM ``posts_%s``) AS count;", $board['uri'], $board['uri'], $board['uri'], $board['uri'], $board['uri'])); - $query = prepare(sprintf(" -SELECT MAX(id) max, (SELECT COUNT(*) FROM ``posts_%s`` WHERE FROM_UNIXTIME(time) > DATE_SUB(NOW(), INTERVAL 1 DAY)) ppd, +SELECT IFNULL(MAX(id),0) max, (SELECT COUNT(*) FROM ``posts_%s`` WHERE FROM_UNIXTIME(time) > DATE_SUB(NOW(), INTERVAL 1 HOUR)) pph, -(SELECT count(id) FROM ``posts_%s``) count, (SELECT COUNT(DISTINCT ip) FROM ``posts_%s`` WHERE FROM_UNIXTIME(time) > DATE_SUB(NOW(), INTERVAL 3 DAY)) uniq_ip FROM ``posts_%s`` ", $board['uri'], $board['uri'], $board['uri'], $board['uri'], $board['uri'])); @@ -52,17 +54,19 @@ SELECT MAX(id) max, (SELECT COUNT(*) FROM ``posts_%s`` WHERE FROM_UNIXTIME(time) } $pph = $r['pph']; - $ppd = $r['ppd']; $total_posts_hour += $pph; $total_posts += $r['max']; $boards[$i]['pph'] = $pph; - $boards[$i]['ppd'] = $ppd; + $boards[$i]['ppd'] = $pph*24; $boards[$i]['max'] = $r['max']; $boards[$i]['uniq_ip'] = $r['uniq_ip']; $boards[$i]['tags'] = $tags; + + if ($write_maxes) fwrite($fp, $board['uri'] . ':' . $boards[$i]['max'] . "\n"); } +if ($write_maxes) fclose($fp); usort($boards, function ($a, $b) { @@ -117,14 +121,16 @@ $config['additional_javascript'] = array('js/jquery.min.js', 'js/jquery.tablesor $body = Element("8chan/boards-tags.html", array("config" => $config, "n_boards" => $n_boards, "t_boards" => $t_boards, "hidden_boards_total" => $hidden_boards_total, "total_posts" => $total_posts, "total_posts_hour" => $total_posts_hour, "boards" => $boards, "last_update" => date('r'), "uptime_p" => shell_exec('uptime -p'), 'tags' => $all_tags, 'top2k' => false)); $html = Element("page.html", array("config" => $config, "body" => $body, "title" => "Boards on ∞chan")); -array_splice($boards, 2000); -$boards = array_values($boards); -$body = Element("8chan/boards-tags.html", array("config" => $config, "n_boards" => $n_boards, "t_boards" => $t_boards, "hidden_boards_total" => $hidden_boards_total, "total_posts" => $total_posts, "total_posts_hour" => $total_posts_hour, "boards" => $boards, "last_update" => date('r'), "uptime_p" => shell_exec('uptime -p'), 'tags' => $all_tags, 'top2k' => true)); +$boards_top2k = $boards; +array_splice($boards_top2k, 2000); +$boards_top2k = array_values($boards_top2k); +$body = Element("8chan/boards-tags.html", array("config" => $config, "n_boards" => $n_boards, "t_boards" => $t_boards, "hidden_boards_total" => $hidden_boards_total, "total_posts" => $total_posts, "total_posts_hour" => $total_posts_hour, "boards" => $boards_top2k, "last_update" => date('r'), "uptime_p" => shell_exec('uptime -p'), 'tags' => $all_tags, 'top2k' => true)); $html_top2k = Element("page.html", array("config" => $config, "body" => $body, "title" => "Boards on ∞chan")); if ($admin) { echo $html; } else { + foreach ($boards as $i => &$b) { unset($b['img']); } file_write("boards.json", json_encode($boards)); file_write("tags.json", json_encode($all_tags)); foreach ($boards as $i => $b) { diff --git a/faq.php b/faq.php index b2087c4a..646a9e6c 100644 --- a/faq.php +++ b/faq.php @@ -103,14 +103,14 @@ $body = <<~~strikethrough~~ -> strikethrough
  • [aa] tags for ASCII/JIS art (escape formatting)
  • [code] tags if enabled by board owner
  • -
  • [tex] tags if enabled by board owner (currently globally disabled)
  • +
  • $$ and \( \) LaTeX tags if enabled by board owner
  • How are featured boards chosen?

    -

    Top twenty-five boards excluding /meta/, /b/ and /news+/.

    +

    Top twenty-five boards excluding /meta/, /b/, /operate/, /boards/ and /news+/.

    -

    Who owns /meta/, /b/ and /news+/?

    -

    No one, so they are de facto property of the administration.

    +

    Who owns boards like /b/, /news+/ and /operate/?

    +

    No one, so they are de facto managed by the administration.

    Why does https://8ch.net/banned say that I'm banned? I can still use the boards?

    8chan is centered around user created boards. That's a board with CSS that makes it look like the ban page, not an official page. You've been tricked. 8chan has no official ban check page.

    @@ -124,6 +124,25 @@ $body = <<There isn't one yet and there will never be an official archive.

    Given that archives are inevitable and will be created anyway via archive.today, Google cache, and anyone who installs Asagi, I'm softening my stance on this. Currently, 8archive.moe provides our archive, and I may set up an official one. All archives officially partnered with us will be opt-in by our board owners, not opt-out. Archives who archive boards that have not opted in will be considered pirate archives, and legal action may be taken.

    +

    Can I have a list of all API endpoints for getting raw data from 8chan?

    +

    +Assuming the /b/ board, they are as follows:

    + + +

    There are also endpoints for getting information about 8chan's boards:

    + + +

    Just read the data to get an idea of what is exposed and under what attribute names. It should be self explanatory.

    +

    Endpoints not listed here, like post.php, catalog.json or boards-top20.json are subject to change or removal at any time!

    +

    I got an email from an @8chan.co email address, is that you?

    8chan.co uses cock.li to manage our domain's email. cock.li allows anyone to create an email account @8chan.co.

    That said, we have quite a few official 8chan.co email addresses. They are:

    diff --git a/inc/functions.php b/inc/functions.php index 3c53043c..382725e2 100755 --- a/inc/functions.php +++ b/inc/functions.php @@ -2410,33 +2410,19 @@ function shell_exec_error($command, $suppress_stdout = false) { */ function diceRoller($post) { global $config; - if(strpos(strtolower($post->email), 'dice%20') === 0) { - $dicestr = str_split(substr($post->email, strlen('dice%20'))); - + if (isset($_POST['dx'], $_POST['dy'], $_POST['dz']) && !empty($_POST['dy'])) { // Get params - $diceX = ''; - $diceY = ''; - $diceZ = ''; - - $curd = 'diceX'; - for($i = 0; $i < count($dicestr); $i ++) { - if(is_numeric($dicestr[$i])) { - $$curd .= $dicestr[$i]; - } else if($dicestr[$i] == 'd') { - $curd = 'diceY'; - } else if($dicestr[$i] == '-' || $dicestr[$i] == '+') { - $curd = 'diceZ'; - $$curd = $dicestr[$i]; - } - } + $diceX = $_POST['dx']; + $diceY = $_POST['dy']; + $diceZ = $_POST['dz']; // Default values for X and Z if($diceX == '') { - $diceX = '1'; + $diceX = 1; } if($diceZ == '') { - $diceZ = '+0'; + $diceZ = 0; } // Intify them @@ -2453,6 +2439,10 @@ function diceRoller($post) { $diceX = 200; } + if (abs($diceZ) > 1000000) { + $diceZ = 0; + } + // Continue only if we have valid values if($diceX > 0 && $diceY > 0) { $dicerolls = array(); @@ -2466,7 +2456,8 @@ function diceRoller($post) { // Prepend the result to the post body $modifier = ($diceZ != 0) ? ((($diceZ < 0) ? ' - ' : ' + ') . abs($diceZ)) : ''; $dicesum = ($diceX > 1) ? ' = ' . $dicesum : ''; - $post->body = '
    Dice rollRolled ' . implode(', ', $dicerolls) . $modifier . $dicesum . '

    ' . $post->body; + $rollstring = "{$diceX}d{$diceY}"; + $post->body = '
    Dice rollRolled ' . implode(', ', $dicerolls) . $modifier . $dicesum . " ($rollstring)

    " . $post->body; } } } diff --git a/inc/instance-config.php b/inc/instance-config.php index ad78b452..ad46a030 100644 --- a/inc/instance-config.php +++ b/inc/instance-config.php @@ -137,13 +137,13 @@ $config['additional_javascript'][] = 'js/catalog-search.js'; $config['additional_javascript'][] = 'js/thread-stats.js'; $config['additional_javascript'][] = 'js/quote-selection.js'; - $config['additional_javascript'][] = 'js/twemoji/twemoji.js'; $config['additional_javascript'][] = 'js/flag-previews.js'; $config['additional_javascript'][] = 'js/post-menu.js'; $config['additional_javascript'][] = 'js/post-filter.js'; $config['additional_javascript'][] = 'js/fix-report-delete-submit.js'; $config['additional_javascript'][] = 'js/image-hover.js'; $config['additional_javascript'][] = 'js/auto-scroll.js'; + $config['additional_javascript'][] = 'js/twemoji/twemoji.js'; //$config['font_awesome_css'] = '/netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css'; diff --git a/inc/lib/Twig/Autoloader.php b/inc/lib/Twig/Autoloader.php index 7007d315..87f74153 100644 --- a/inc/lib/Twig/Autoloader.php +++ b/inc/lib/Twig/Autoloader.php @@ -19,14 +19,14 @@ class Twig_Autoloader /** * Registers Twig_Autoloader as an SPL autoloader. * - * @param Boolean $prepend Whether to prepend the autoloader or not. + * @param bool $prepend Whether to prepend the autoloader or not. */ public static function register($prepend = false) { - if (version_compare(phpversion(), '5.3.0', '>=')) { - spl_autoload_register(array(new self, 'autoload'), true, $prepend); + if (PHP_VERSION_ID < 50300) { + spl_autoload_register(array(__CLASS__, 'autoload')); } else { - spl_autoload_register(array(new self, 'autoload')); + spl_autoload_register(array(__CLASS__, 'autoload'), true, $prepend); } } diff --git a/inc/lib/Twig/Compiler.php b/inc/lib/Twig/Compiler.php index b80210b1..2514c31e 100644 --- a/inc/lib/Twig/Compiler.php +++ b/inc/lib/Twig/Compiler.php @@ -66,7 +66,7 @@ class Twig_Compiler implements Twig_CompilerInterface * Compiles a node. * * @param Twig_NodeInterface $node The node to compile - * @param integer $indentation The current indentation + * @param int $indentation The current indentation * * @return Twig_Compiler The current compiler instance */ @@ -74,6 +74,7 @@ class Twig_Compiler implements Twig_CompilerInterface { $this->lastLine = null; $this->source = ''; + $this->debugInfo = array(); $this->sourceOffset = 0; // source code starts at 1 (as we then increment it when we encounter new lines) $this->sourceLine = 1; @@ -181,14 +182,14 @@ class Twig_Compiler implements Twig_CompilerInterface } elseif (is_array($value)) { $this->raw('array('); $first = true; - foreach ($value as $key => $value) { + foreach ($value as $key => $v) { if (!$first) { $this->raw(', '); } $first = false; $this->repr($key); $this->raw(' => '); - $this->repr($value); + $this->repr($v); } $this->raw(')'); } else { @@ -208,7 +209,7 @@ class Twig_Compiler implements Twig_CompilerInterface public function addDebugInfo(Twig_NodeInterface $node) { if ($node->getLine() != $this->lastLine) { - $this->write("// line {$node->getLine()}\n"); + $this->write(sprintf("// line %d\n", $node->getLine())); // when mbstring.func_overload is set to 2 // mb_substr_count() replaces substr_count() @@ -230,13 +231,15 @@ class Twig_Compiler implements Twig_CompilerInterface public function getDebugInfo() { + ksort($this->debugInfo); + return $this->debugInfo; } /** * Indents the generated code. * - * @param integer $step The number of indentation to add + * @param int $step The number of indentation to add * * @return Twig_Compiler The current compiler instance */ @@ -250,9 +253,11 @@ class Twig_Compiler implements Twig_CompilerInterface /** * Outdents the generated code. * - * @param integer $step The number of indentation to remove + * @param int $step The number of indentation to remove * * @return Twig_Compiler The current compiler instance + * + * @throws LogicException When trying to outdent too much so the indentation would become negative */ public function outdent($step = 1) { @@ -265,4 +270,9 @@ class Twig_Compiler implements Twig_CompilerInterface return $this; } + + public function getVarName() + { + return sprintf('__internal_%s', hash('sha256', uniqid(mt_rand(), true), false)); + } } diff --git a/inc/lib/Twig/CompilerInterface.php b/inc/lib/Twig/CompilerInterface.php index e293ec91..272c7672 100644 --- a/inc/lib/Twig/CompilerInterface.php +++ b/inc/lib/Twig/CompilerInterface.php @@ -13,7 +13,8 @@ * Interface implemented by compiler classes. * * @author Fabien Potencier - * @deprecated since 1.12 (to be removed in 2.0) + * + * @deprecated since 1.12 (to be removed in 3.0) */ interface Twig_CompilerInterface { diff --git a/inc/lib/Twig/Environment.php b/inc/lib/Twig/Environment.php index 09ea4a25..f72c9e80 100644 --- a/inc/lib/Twig/Environment.php +++ b/inc/lib/Twig/Environment.php @@ -16,7 +16,7 @@ */ class Twig_Environment { - const VERSION = '1.14.0-DEV'; + const VERSION = '1.18.1-DEV'; protected $charset; protected $loader; @@ -44,7 +44,6 @@ class Twig_Environment protected $functionCallbacks; protected $filterCallbacks; protected $staging; - protected $templateClasses; /** * Constructor. @@ -62,9 +61,9 @@ class Twig_Environment * * cache: An absolute path where to store the compiled templates, or * false to disable compilation cache (default). * - * * auto_reload: Whether to reload the template is the original source changed. + * * auto_reload: Whether to reload the template if the original source changed. * If you don't provide the auto_reload option, it will be - * determined automatically base on the debug value. + * determined automatically based on the debug value. * * * strict_variables: Whether to ignore invalid variables in templates * (default to false). @@ -73,6 +72,7 @@ class Twig_Environment * * false: disable auto-escaping * * true: equivalent to html * * html, js: set the autoescaping to one of the supported strategies + * * filename: set the autoescaping strategy based on the template filename extension * * PHP callback: a PHP callback that returns an escaping strategy based on the template "filename" * * * optimizations: A flag that indicates which optimizations to apply @@ -108,7 +108,6 @@ class Twig_Environment $this->setCache($options['cache']); $this->functionCallbacks = array(); $this->filterCallbacks = array(); - $this->templateClasses = array(); $this->addExtension(new Twig_Extension_Core()); $this->addExtension(new Twig_Extension_Escaper($options['autoescape'])); @@ -156,7 +155,7 @@ class Twig_Environment /** * Checks if debug mode is enabled. * - * @return Boolean true if debug mode is enabled, false otherwise + * @return bool true if debug mode is enabled, false otherwise */ public function isDebug() { @@ -182,7 +181,7 @@ class Twig_Environment /** * Checks if the auto_reload option is enabled. * - * @return Boolean true if auto_reload is enabled, false otherwise + * @return bool true if auto_reload is enabled, false otherwise */ public function isAutoReload() { @@ -208,7 +207,7 @@ class Twig_Environment /** * Checks if the strict_variables option is enabled. * - * @return Boolean true if strict_variables is enabled, false otherwise + * @return bool true if strict_variables is enabled, false otherwise */ public function isStrictVariables() { @@ -225,12 +224,12 @@ class Twig_Environment return $this->cache; } - /** - * Sets the cache directory or false if cache is disabled. - * - * @param string|false $cache The absolute path to the compiled templates, - * or false to disable cache - */ + /** + * Sets the cache directory or false if cache is disabled. + * + * @param string|false $cache The absolute path to the compiled templates, + * or false to disable cache + */ public function setCache($cache) { $this->cache = $cache ? $cache : false; @@ -241,7 +240,7 @@ class Twig_Environment * * @param string $name The template name * - * @return string The cache file name + * @return string|false The cache file name or false when caching is disabled */ public function getCacheFilename($name) { @@ -257,20 +256,14 @@ class Twig_Environment /** * Gets the template class associated with the given string. * - * @param string $name The name for which to calculate the template class name - * @param integer $index The index if it is an embedded template + * @param string $name The name for which to calculate the template class name + * @param int $index The index if it is an embedded template * * @return string The template class name */ public function getTemplateClass($name, $index = null) { - $suffix = null === $index ? '' : '_'.$index; - $cls = $name.$suffix; - if (isset($this->templateClasses[$cls])) { - return $this->templateClasses[$cls]; - } - - return $this->templateClasses[$cls] = $this->templateClassPrefix.hash('sha256', $this->getLoader()->getCacheKey($name)).$suffix; + return $this->templateClassPrefix.hash('sha256', $this->getLoader()->getCacheKey($name)).(null === $index ? '' : '_'.$index); } /** @@ -290,6 +283,10 @@ class Twig_Environment * @param array $context An array of parameters to pass to the template * * @return string The rendered template + * + * @throws Twig_Error_Loader When the template cannot be found + * @throws Twig_Error_Syntax When an error occurred during compilation + * @throws Twig_Error_Runtime When an error occurred during rendering */ public function render($name, array $context = array()) { @@ -301,6 +298,10 @@ class Twig_Environment * * @param string $name The template name * @param array $context An array of parameters to pass to the template + * + * @throws Twig_Error_Loader When the template cannot be found + * @throws Twig_Error_Syntax When an error occurred during compilation + * @throws Twig_Error_Runtime When an error occurred during rendering */ public function display($name, array $context = array()) { @@ -310,10 +311,13 @@ class Twig_Environment /** * Loads a template by name. * - * @param string $name The template name - * @param integer $index The index if it is an embedded template + * @param string $name The template name + * @param int $index The index if it is an embedded template * * @return Twig_TemplateInterface A template instance representing the given template name + * + * @throws Twig_Error_Loader When the template cannot be found + * @throws Twig_Error_Syntax When an error occurred during compilation */ public function loadTemplate($name, $index = null) { @@ -342,6 +346,41 @@ class Twig_Environment return $this->loadedTemplates[$cls] = new $cls($this); } + /** + * Creates a template from source. + * + * This method should not be used as a generic way to load templates. + * + * @param string $name The template name + * @param int $index The index if it is an embedded template + * + * @return Twig_Template A template instance representing the given template name + * + * @throws Twig_Error_Loader When the template cannot be found + * @throws Twig_Error_Syntax When an error occurred during compilation + */ + public function createTemplate($template) + { + $name = sprintf('__string_template__%s', hash('sha256', uniqid(mt_rand(), true), false)); + + $loader = new Twig_Loader_Chain(array( + new Twig_Loader_Array(array($name => $template)), + $current = $this->getLoader(), + )); + + $this->setLoader($loader); + try { + $template = $this->loadTemplate($name); + } catch (Exception $e) { + $this->setLoader($current); + + throw $e; + } + $this->setLoader($current); + + return $template; + } + /** * Returns true if the template is still fresh. * @@ -349,10 +388,10 @@ class Twig_Environment * this method also checks if the enabled extensions have * not changed. * - * @param string $name The template name - * @param timestamp $time The last modification time of the cached template + * @param string $name The template name + * @param int $time The last modification time of the cached template * - * @return Boolean true if the template is fresh, false otherwise + * @return bool true if the template is fresh, false otherwise */ public function isTemplateFresh($name, $time) { @@ -366,6 +405,19 @@ class Twig_Environment return $this->getLoader()->isFresh($name, $time); } + /** + * Tries to load a template consecutively from an array. + * + * Similar to loadTemplate() but it also accepts Twig_TemplateInterface instances and an array + * of templates where each is tried to be loaded. + * + * @param string|Twig_Template|array $names A template or an array of templates to try consecutively + * + * @return Twig_Template + * + * @throws Twig_Error_Loader When none of the templates can be found + * @throws Twig_Error_Syntax When an error occurred during compilation + */ public function resolveTemplate($names) { if (!is_array($names)) { @@ -445,6 +497,8 @@ class Twig_Environment * @param string $name The template name * * @return Twig_TokenStream A Twig_TokenStream instance + * + * @throws Twig_Error_Syntax When the code is syntactically wrong */ public function tokenize($source, $name = null) { @@ -476,15 +530,17 @@ class Twig_Environment } /** - * Parses a token stream. + * Converts a token stream to a node tree. * - * @param Twig_TokenStream $tokens A Twig_TokenStream instance + * @param Twig_TokenStream $stream A token stream instance * - * @return Twig_Node_Module A Node tree + * @return Twig_Node_Module A node tree + * + * @throws Twig_Error_Syntax When the token stream is syntactically or semantically wrong */ - public function parse(Twig_TokenStream $tokens) + public function parse(Twig_TokenStream $stream) { - return $this->getParser()->parse($tokens); + return $this->getParser()->parse($stream); } /** @@ -512,7 +568,7 @@ class Twig_Environment } /** - * Compiles a Node. + * Compiles a node and returns the PHP code. * * @param Twig_NodeInterface $node A Twig_NodeInterface instance * @@ -530,6 +586,8 @@ class Twig_Environment * @param string $name The template name * * @return string The compiled PHP source code + * + * @throws Twig_Error_Syntax When there was an error during tokenizing, parsing or compiling */ public function compileSource($source, $name = null) { @@ -539,7 +597,7 @@ class Twig_Environment $e->setTemplateFile($name); throw $e; } catch (Exception $e) { - throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the compilation of a template ("%s").', $e->getMessage()), -1, $name, $e); + throw new Twig_Error_Syntax(sprintf('An exception has been thrown during the compilation of a template ("%s").', $e->getMessage()), -1, $name, $e); } } @@ -604,7 +662,7 @@ class Twig_Environment * * @param string $name The extension name * - * @return Boolean Whether the extension is registered or not + * @return bool Whether the extension is registered or not */ public function hasExtension($name) { @@ -772,11 +830,11 @@ class Twig_Environment $filter = $name; $name = $filter->getName(); } - + if ($this->extensionInitialized) { throw new LogicException(sprintf('Unable to add filter "%s" as extensions have already been initialized.', $name)); } - + $this->staging->addFilter($name, $filter); } @@ -861,7 +919,7 @@ class Twig_Environment $test = $name; $name = $test->getName(); } - + if ($this->extensionInitialized) { throw new LogicException(sprintf('Unable to add test "%s" as extensions have already been initialized.', $name)); } @@ -919,11 +977,11 @@ class Twig_Environment $function = $name; $name = $function->getName(); } - + if ($this->extensionInitialized) { throw new LogicException(sprintf('Unable to add function "%s" as extensions have already been initialized.', $name)); } - + $this->staging->addFunction($name, $function); } @@ -1210,14 +1268,17 @@ class Twig_Environment { $dir = dirname($file); if (!is_dir($dir)) { - if (false === @mkdir($dir, 0777, true) && !is_dir($dir)) { - throw new RuntimeException(sprintf("Unable to create the cache directory (%s).", $dir)); + if (false === @mkdir($dir, 0777, true)) { + clearstatcache(false, $dir); + if (!is_dir($dir)) { + throw new RuntimeException(sprintf("Unable to create the cache directory (%s).", $dir)); + } } } elseif (!is_writable($dir)) { throw new RuntimeException(sprintf("Unable to write in the cache directory (%s).", $dir)); } - $tmpFile = tempnam(dirname($file), basename($file)); + $tmpFile = tempnam($dir, basename($file)); if (false !== @file_put_contents($tmpFile, $content)) { // rename does not work on Win32 before 5.2.6 if (@rename($tmpFile, $file) || (@copy($tmpFile, $file) && unlink($tmpFile))) { diff --git a/inc/lib/Twig/Error.php b/inc/lib/Twig/Error.php index 61a4cfa0..90650c5f 100644 --- a/inc/lib/Twig/Error.php +++ b/inc/lib/Twig/Error.php @@ -51,13 +51,13 @@ class Twig_Error extends Exception * By default, automatic guessing is enabled. * * @param string $message The error message - * @param integer $lineno The template line where the error occurred + * @param int $lineno The template line where the error occurred * @param string $filename The template file name where the error occurred * @param Exception $previous The previous exception */ public function __construct($message, $lineno = -1, $filename = null, Exception $previous = null) { - if (version_compare(PHP_VERSION, '5.3.0', '<')) { + if (PHP_VERSION_ID < 50300) { $this->previous = $previous; parent::__construct(''); } else { @@ -111,7 +111,7 @@ class Twig_Error extends Exception /** * Gets the template line where the error occurred. * - * @return integer The template line + * @return int The template line */ public function getTemplateLine() { @@ -121,7 +121,7 @@ class Twig_Error extends Exception /** * Sets the template line where the error occurred. * - * @param integer $lineno The template line + * @param int $lineno The template line */ public function setTemplateLine($lineno) { @@ -188,7 +188,7 @@ class Twig_Error extends Exception $template = null; $templateClass = null; - if (version_compare(phpversion(), '5.3.6', '>=')) { + if (PHP_VERSION_ID >= 50306) { $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS | DEBUG_BACKTRACE_PROVIDE_OBJECT); } else { $backtrace = debug_backtrace(); @@ -217,6 +217,11 @@ class Twig_Error extends Exception $r = new ReflectionObject($template); $file = $r->getFileName(); + // hhvm has a bug where eval'ed files comes out as the current directory + if (is_dir($file)) { + $file = ''; + } + $exceptions = array($e = $this); while (($e instanceof self || method_exists($e, 'getPrevious')) && $e = $e->getPrevious()) { $exceptions[] = $e; @@ -224,6 +229,8 @@ class Twig_Error extends Exception while ($e = array_pop($exceptions)) { $traces = $e->getTrace(); + array_unshift($traces, array('file' => $e->getFile(), 'line' => $e->getLine())); + while ($trace = array_shift($traces)) { if (!isset($trace['file']) || !isset($trace['line']) || $file != $trace['file']) { continue; diff --git a/inc/lib/Twig/ExistsLoaderInterface.php b/inc/lib/Twig/ExistsLoaderInterface.php index ce434765..b168c3c3 100644 --- a/inc/lib/Twig/ExistsLoaderInterface.php +++ b/inc/lib/Twig/ExistsLoaderInterface.php @@ -13,7 +13,8 @@ * Adds an exists() method for loaders. * * @author Florin Patan - * @deprecated since 1.12 (to be removed in 2.0) + * + * @deprecated since 1.12 (to be removed in 3.0) */ interface Twig_ExistsLoaderInterface { @@ -22,7 +23,7 @@ interface Twig_ExistsLoaderInterface * * @param string $name The name of the template to check if we can load * - * @return boolean If the template source code is handled by this loader or not + * @return bool If the template source code is handled by this loader or not */ public function exists($name); } diff --git a/inc/lib/Twig/ExpressionParser.php b/inc/lib/Twig/ExpressionParser.php index 9deab09c..fa9fa35e 100644 --- a/inc/lib/Twig/ExpressionParser.php +++ b/inc/lib/Twig/ExpressionParser.php @@ -86,18 +86,15 @@ class Twig_ExpressionParser protected function parseConditionalExpression($expr) { - while ($this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, '?')) { - $this->parser->getStream()->next(); - if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, ':')) { + while ($this->parser->getStream()->nextIf(Twig_Token::PUNCTUATION_TYPE, '?')) { + if (!$this->parser->getStream()->nextIf(Twig_Token::PUNCTUATION_TYPE, ':')) { $expr2 = $this->parseExpression(); - if ($this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, ':')) { - $this->parser->getStream()->next(); + if ($this->parser->getStream()->nextIf(Twig_Token::PUNCTUATION_TYPE, ':')) { $expr3 = $this->parseExpression(); } else { $expr3 = new Twig_Node_Expression_Constant('', $this->parser->getCurrentToken()->getLine()); } } else { - $this->parser->getStream()->next(); $expr2 = $expr; $expr3 = $this->parseExpression(); } @@ -161,13 +158,36 @@ class Twig_ExpressionParser $node = $this->parseStringExpression(); break; + case Twig_Token::OPERATOR_TYPE: + if (preg_match(Twig_Lexer::REGEX_NAME, $token->getValue(), $matches) && $matches[0] == $token->getValue()) { + // in this context, string operators are variable names + $this->parser->getStream()->next(); + $node = new Twig_Node_Expression_Name($token->getValue(), $token->getLine()); + break; + } elseif (isset($this->unaryOperators[$token->getValue()])) { + $class = $this->unaryOperators[$token->getValue()]['class']; + + $ref = new ReflectionClass($class); + $negClass = 'Twig_Node_Expression_Unary_Neg'; + $posClass = 'Twig_Node_Expression_Unary_Pos'; + if (!(in_array($ref->getName(), array($negClass, $posClass)) || $ref->isSubclassOf($negClass) || $ref->isSubclassOf($posClass))) { + throw new Twig_Error_Syntax(sprintf('Unexpected unary operator "%s"', $token->getValue()), $token->getLine(), $this->parser->getFilename()); + } + + $this->parser->getStream()->next(); + $expr = $this->parsePrimaryExpression(); + + $node = new $class($expr, $token->getLine()); + break; + } + default: if ($token->test(Twig_Token::PUNCTUATION_TYPE, '[')) { $node = $this->parseArrayExpression(); } elseif ($token->test(Twig_Token::PUNCTUATION_TYPE, '{')) { $node = $this->parseHashExpression(); } else { - throw new Twig_Error_Syntax(sprintf('Unexpected token "%s" of value "%s"', Twig_Token::typeToEnglish($token->getType(), $token->getLine()), $token->getValue()), $token->getLine(), $this->parser->getFilename()); + throw new Twig_Error_Syntax(sprintf('Unexpected token "%s" of value "%s"', Twig_Token::typeToEnglish($token->getType()), $token->getValue()), $token->getLine(), $this->parser->getFilename()); } } @@ -182,12 +202,10 @@ class Twig_ExpressionParser // a string cannot be followed by another string in a single expression $nextCanBeString = true; while (true) { - if ($stream->test(Twig_Token::STRING_TYPE) && $nextCanBeString) { - $token = $stream->next(); + if ($nextCanBeString && $token = $stream->nextIf(Twig_Token::STRING_TYPE)) { $nodes[] = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine()); $nextCanBeString = false; - } elseif ($stream->test(Twig_Token::INTERPOLATION_START_TYPE)) { - $stream->next(); + } elseif ($stream->nextIf(Twig_Token::INTERPOLATION_START_TYPE)) { $nodes[] = $this->parseExpression(); $stream->expect(Twig_Token::INTERPOLATION_END_TYPE); $nextCanBeString = true; @@ -253,15 +271,14 @@ class Twig_ExpressionParser // * a string -- 'a' // * a name, which is equivalent to a string -- a // * an expression, which must be enclosed in parentheses -- (1 + 2) - if ($stream->test(Twig_Token::STRING_TYPE) || $stream->test(Twig_Token::NAME_TYPE) || $stream->test(Twig_Token::NUMBER_TYPE)) { - $token = $stream->next(); + if (($token = $stream->nextIf(Twig_Token::STRING_TYPE)) || ($token = $stream->nextIf(Twig_Token::NAME_TYPE)) || $token = $stream->nextIf(Twig_Token::NUMBER_TYPE)) { $key = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine()); } elseif ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) { $key = $this->parseExpression(); } else { $current = $stream->getCurrent(); - throw new Twig_Error_Syntax(sprintf('A hash key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "%s" of value "%s"', Twig_Token::typeToEnglish($current->getType(), $current->getLine()), $current->getValue()), $current->getLine(), $this->parser->getFilename()); + throw new Twig_Error_Syntax(sprintf('A hash key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "%s" of value "%s"', Twig_Token::typeToEnglish($current->getType()), $current->getValue()), $current->getLine(), $this->parser->getFilename()); } $stream->expect(Twig_Token::PUNCTUATION_TYPE, ':', 'A hash key must be followed by a colon (:)'); @@ -316,23 +333,23 @@ class Twig_ExpressionParser throw new Twig_Error_Syntax('The "attribute" function takes at least two arguments (the variable and the attributes)', $line, $this->parser->getFilename()); } - return new Twig_Node_Expression_GetAttr($args->getNode(0), $args->getNode(1), count($args) > 2 ? $args->getNode(2) : new Twig_Node_Expression_Array(array(), $line), Twig_Template::ANY_CALL, $line); + return new Twig_Node_Expression_GetAttr($args->getNode(0), $args->getNode(1), count($args) > 2 ? $args->getNode(2) : null, Twig_Template::ANY_CALL, $line); default: - $args = $this->parseArguments(true); - if (null !== $alias = $this->parser->getImportedSymbol('macro', $name)) { - return new Twig_Node_Expression_MacroCall($alias['node'], $alias['name'], $this->createArrayFromArguments($args), $line); - } - - try { - $class = $this->getFunctionNodeClass($name, $line); - } catch (Twig_Error_Syntax $e) { - if (!$this->parser->hasMacro($name)) { - throw $e; + if (null !== $alias = $this->parser->getImportedSymbol('function', $name)) { + $arguments = new Twig_Node_Expression_Array(array(), $line); + foreach ($this->parseArguments() as $n) { + $arguments->addElement($n); } - return new Twig_Node_Expression_MacroCall(new Twig_Node_Expression_Name('_self', $line), $name, $this->createArrayFromArguments($args), $line); + $node = new Twig_Node_Expression_MethodCall($alias['node'], $alias['name'], $arguments, $line); + $node->setAttribute('safe', true); + + return $node; } + $args = $this->parseArguments(true); + $class = $this->getFunctionNodeClass($name, $line); + return new $class($name, $args, $line); } } @@ -354,6 +371,13 @@ class Twig_ExpressionParser ($token->getType() == Twig_Token::OPERATOR_TYPE && preg_match(Twig_Lexer::REGEX_NAME, $token->getValue())) ) { $arg = new Twig_Node_Expression_Constant($token->getValue(), $lineno); + + if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) { + $type = Twig_TemplateInterface::METHOD_CALL; + foreach ($this->parseArguments() as $n) { + $arguments->addElement($n); + } + } } else { throw new Twig_Error_Syntax('Expected name or number', $lineno, $this->parser->getFilename()); } @@ -363,14 +387,10 @@ class Twig_ExpressionParser throw new Twig_Error_Syntax(sprintf('Dynamic macro names are not supported (called on "%s")', $node->getAttribute('name')), $token->getLine(), $this->parser->getFilename()); } - $arguments = $this->createArrayFromArguments($this->parseArguments(true)); + $node = new Twig_Node_Expression_MethodCall($node, 'get'.$arg->getAttribute('value'), $arguments, $lineno); + $node->setAttribute('safe', true); - return new Twig_Node_Expression_MacroCall($node, $arg->getAttribute('value'), $arguments, $lineno); - } - - if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) { - $type = Twig_Template::METHOD_CALL; - $arguments = $this->createArrayFromArguments($this->parseArguments()); + return $node; } } else { $type = Twig_Template::ARRAY_CALL; @@ -384,9 +404,8 @@ class Twig_ExpressionParser $arg = $this->parseExpression(); } - if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ':')) { + if ($stream->nextIf(Twig_Token::PUNCTUATION_TYPE, ':')) { $slice = true; - $stream->next(); } if ($slice) { @@ -447,10 +466,8 @@ class Twig_ExpressionParser /** * Parses arguments. * - * @param Boolean $namedArguments Whether to allow named arguments or not - * @param Boolean $definition Whether we are parsing arguments for a function definition - * - * @return Twig_Node + * @param bool $namedArguments Whether to allow named arguments or not + * @param bool $definition Whether we are parsing arguments for a function definition */ public function parseArguments($namedArguments = false, $definition = false) { @@ -471,8 +488,7 @@ class Twig_ExpressionParser } $name = null; - if ($namedArguments && $stream->test(Twig_Token::OPERATOR_TYPE, '=')) { - $token = $stream->next(); + if ($namedArguments && $token = $stream->nextIf(Twig_Token::OPERATOR_TYPE, '=')) { if (!$value instanceof Twig_Node_Expression_Name) { throw new Twig_Error_Syntax(sprintf('A parameter name must be a string, "%s" given', get_class($value)), $token->getLine(), $this->parser->getFilename()); } @@ -482,26 +498,25 @@ class Twig_ExpressionParser $value = $this->parsePrimaryExpression(); if (!$this->checkConstantExpression($value)) { - throw new Twig_Error_Syntax('A default value for an argument must be a constant (a boolean, a string, a number, or an array).', $token->getLine(), $this->parser->getFilename()); + throw new Twig_Error_Syntax(sprintf('A default value for an argument must be a constant (a boolean, a string, a number, or an array).'), $token->getLine(), $this->parser->getFilename()); } } else { $value = $this->parseExpression(); } } - if ($definition && null === $name) { - $name = $value->getAttribute('name'); - $value = new Twig_Node_Expression_Constant(null, $this->parser->getCurrentToken()->getLine()); - } - - if (null === $name) { - $args[] = $value; - } else { - if ($definition && isset($args[$name])) { - throw new Twig_Error_Syntax(sprintf('Arguments cannot contain the same argument name more than once ("%s" is defined twice).', $name), $token->getLine(), $this->parser->getFilename()); + if ($definition) { + if (null === $name) { + $name = $value->getAttribute('name'); + $value = new Twig_Node_Expression_Constant(null, $this->parser->getCurrentToken()->getLine()); } - $args[$name] = $value; + } else { + if (null === $name) { + $args[] = $value; + } else { + $args[$name] = $value; + } } } $stream->expect(Twig_Token::PUNCTUATION_TYPE, ')', 'A list of arguments must be closed by a parenthesis'); @@ -519,10 +534,9 @@ class Twig_ExpressionParser } $targets[] = new Twig_Node_Expression_AssignName($token->getValue(), $token->getLine()); - if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, ',')) { + if (!$this->parser->getStream()->nextIf(Twig_Token::PUNCTUATION_TYPE, ',')) { break; } - $this->parser->getStream()->next(); } return new Twig_Node($targets); @@ -533,10 +547,9 @@ class Twig_ExpressionParser $targets = array(); while (true) { $targets[] = $this->parseExpression(); - if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, ',')) { + if (!$this->parser->getStream()->nextIf(Twig_Token::PUNCTUATION_TYPE, ',')) { break; } - $this->parser->getStream()->next(); } return new Twig_Node($targets); @@ -585,7 +598,9 @@ class Twig_ExpressionParser // checks that the node only contains "constant" elements protected function checkConstantExpression(Twig_NodeInterface $node) { - if (!($node instanceof Twig_Node_Expression_Constant || $node instanceof Twig_Node_Expression_Array)) { + if (!($node instanceof Twig_Node_Expression_Constant || $node instanceof Twig_Node_Expression_Array + || $node instanceof Twig_Node_Expression_Unary_Neg || $node instanceof Twig_Node_Expression_Unary_Pos + )) { return false; } @@ -597,15 +612,4 @@ class Twig_ExpressionParser return true; } - - private function createArrayFromArguments(Twig_Node $arguments, $line = null) - { - $line = null === $line ? $arguments->getLine() : $line; - $array = new Twig_Node_Expression_Array(array(), $line); - foreach ($arguments as $key => $value) { - $array->addElement($value, new Twig_Node_Expression_Constant($key, $value->getLine())); - } - - return $array; - } } diff --git a/inc/lib/Twig/Extension.php b/inc/lib/Twig/Extension.php index 931fc033..5c8ad5c9 100644 --- a/inc/lib/Twig/Extension.php +++ b/inc/lib/Twig/Extension.php @@ -34,7 +34,7 @@ abstract class Twig_Extension implements Twig_ExtensionInterface /** * Returns the node visitor instances to add to the existing list. * - * @return array An array of Twig_NodeVisitorInterface instances + * @return Twig_NodeVisitorInterface[] An array of Twig_NodeVisitorInterface instances */ public function getNodeVisitors() { diff --git a/inc/lib/Twig/Extension/Core.php b/inc/lib/Twig/Extension/Core.php index 60fe1936..346006d3 100644 --- a/inc/lib/Twig/Extension/Core.php +++ b/inc/lib/Twig/Extension/Core.php @@ -1,7 +1,8 @@ escapers[$strategy] = $callable; + } + + /** + * Gets all defined escapers. + * + * @return array An array of escapers + */ + public function getEscapers() + { + return $this->escapers; + } /** * Sets the default format to be used by the date filter. @@ -72,9 +95,9 @@ class Twig_Extension_Core extends Twig_Extension /** * Sets the default format to be used by the number_format filter. * - * @param integer $decimal The number of decimal places to use. - * @param string $decimalPoint The character(s) to use for the decimal point. - * @param string $thousandSep The character(s) to use for the thousands separator. + * @param int $decimal The number of decimal places to use. + * @param string $decimalPoint The character(s) to use for the decimal point. + * @param string $thousandSep The character(s) to use for the thousands separator. */ public function setNumberFormat($decimal, $decimalPoint, $thousandSep) { @@ -94,7 +117,7 @@ class Twig_Extension_Core extends Twig_Extension /** * Returns the token parser instance to add to the existing list. * - * @return array An array of Twig_TokenParser instances + * @return Twig_TokenParser[] An array of Twig_TokenParser instances */ public function getTokenParsers() { @@ -132,6 +155,7 @@ class Twig_Extension_Core extends Twig_Extension new Twig_SimpleFilter('replace', 'strtr'), new Twig_SimpleFilter('number_format', 'twig_number_format_filter', array('needs_environment' => true)), new Twig_SimpleFilter('abs', 'abs'), + new Twig_SimpleFilter('round', 'twig_round'), // encoding new Twig_SimpleFilter('url_encode', 'twig_urlencode_filter'), @@ -149,7 +173,7 @@ class Twig_Extension_Core extends Twig_Extension // array helpers new Twig_SimpleFilter('join', 'twig_join_filter'), - new Twig_SimpleFilter('split', 'twig_split_filter'), + new Twig_SimpleFilter('split', 'twig_split_filter', array('needs_environment' => true)), new Twig_SimpleFilter('sort', 'twig_sort_filter'), new Twig_SimpleFilter('merge', 'twig_array_merge'), new Twig_SimpleFilter('batch', 'twig_array_batch'), @@ -186,12 +210,15 @@ class Twig_Extension_Core extends Twig_Extension public function getFunctions() { return array( + new Twig_SimpleFunction('max', 'max'), + new Twig_SimpleFunction('min', 'min'), new Twig_SimpleFunction('range', 'range'), new Twig_SimpleFunction('constant', 'twig_constant'), new Twig_SimpleFunction('cycle', 'twig_cycle'), new Twig_SimpleFunction('random', 'twig_random', array('needs_environment' => true)), new Twig_SimpleFunction('date', 'twig_date_converter', array('needs_environment' => true)), new Twig_SimpleFunction('include', 'twig_include', array('needs_environment' => true, 'needs_context' => true, 'is_safe' => array('all'))), + new Twig_SimpleFunction('source', 'twig_source', array('needs_environment' => true, 'is_safe' => array('all'))), ); } @@ -207,9 +234,11 @@ class Twig_Extension_Core extends Twig_Extension new Twig_SimpleTest('odd', null, array('node_class' => 'Twig_Node_Expression_Test_Odd')), new Twig_SimpleTest('defined', null, array('node_class' => 'Twig_Node_Expression_Test_Defined')), new Twig_SimpleTest('sameas', null, array('node_class' => 'Twig_Node_Expression_Test_Sameas')), + new Twig_SimpleTest('same as', null, array('node_class' => 'Twig_Node_Expression_Test_Sameas')), new Twig_SimpleTest('none', null, array('node_class' => 'Twig_Node_Expression_Test_Null')), new Twig_SimpleTest('null', null, array('node_class' => 'Twig_Node_Expression_Test_Null')), new Twig_SimpleTest('divisibleby', null, array('node_class' => 'Twig_Node_Expression_Test_Divisibleby')), + new Twig_SimpleTest('divisible by', null, array('node_class' => 'Twig_Node_Expression_Test_Divisibleby')), new Twig_SimpleTest('constant', null, array('node_class' => 'Twig_Node_Expression_Test_Constant')), new Twig_SimpleTest('empty', 'twig_test_empty'), new Twig_SimpleTest('iterable', 'twig_test_iterable'), @@ -230,65 +259,89 @@ class Twig_Extension_Core extends Twig_Extension '+' => array('precedence' => 500, 'class' => 'Twig_Node_Expression_Unary_Pos'), ), array( - 'or' => array('precedence' => 10, 'class' => 'Twig_Node_Expression_Binary_Or', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - 'and' => array('precedence' => 15, 'class' => 'Twig_Node_Expression_Binary_And', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - 'b-or' => array('precedence' => 16, 'class' => 'Twig_Node_Expression_Binary_BitwiseOr', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - 'b-xor' => array('precedence' => 17, 'class' => 'Twig_Node_Expression_Binary_BitwiseXor', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - 'b-and' => array('precedence' => 18, 'class' => 'Twig_Node_Expression_Binary_BitwiseAnd', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - '==' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Equal', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - '!=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - '<' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Less', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - '>' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Greater', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - '>=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_GreaterEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - '<=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_LessEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - 'not in' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotIn', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - 'in' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_In', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - '..' => array('precedence' => 25, 'class' => 'Twig_Node_Expression_Binary_Range', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - '+' => array('precedence' => 30, 'class' => 'Twig_Node_Expression_Binary_Add', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - '-' => array('precedence' => 30, 'class' => 'Twig_Node_Expression_Binary_Sub', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - '~' => array('precedence' => 40, 'class' => 'Twig_Node_Expression_Binary_Concat', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - '*' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mul', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - '/' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Div', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - '//' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_FloorDiv', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - '%' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mod', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - 'is' => array('precedence' => 100, 'callable' => array($this, 'parseTestExpression'), 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - 'is not' => array('precedence' => 100, 'callable' => array($this, 'parseNotTestExpression'), 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - '**' => array('precedence' => 200, 'class' => 'Twig_Node_Expression_Binary_Power', 'associativity' => Twig_ExpressionParser::OPERATOR_RIGHT), + 'or' => array('precedence' => 10, 'class' => 'Twig_Node_Expression_Binary_Or', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + 'and' => array('precedence' => 15, 'class' => 'Twig_Node_Expression_Binary_And', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + 'b-or' => array('precedence' => 16, 'class' => 'Twig_Node_Expression_Binary_BitwiseOr', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + 'b-xor' => array('precedence' => 17, 'class' => 'Twig_Node_Expression_Binary_BitwiseXor', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + 'b-and' => array('precedence' => 18, 'class' => 'Twig_Node_Expression_Binary_BitwiseAnd', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + '==' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Equal', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + '!=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + '<' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Less', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + '>' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Greater', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + '>=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_GreaterEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + '<=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_LessEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + 'not in' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotIn', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + 'in' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_In', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + 'matches' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Matches', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + 'starts with' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_StartsWith', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + 'ends with' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_EndsWith', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + '..' => array('precedence' => 25, 'class' => 'Twig_Node_Expression_Binary_Range', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + '+' => array('precedence' => 30, 'class' => 'Twig_Node_Expression_Binary_Add', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + '-' => array('precedence' => 30, 'class' => 'Twig_Node_Expression_Binary_Sub', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + '~' => array('precedence' => 40, 'class' => 'Twig_Node_Expression_Binary_Concat', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + '*' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mul', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + '/' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Div', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + '//' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_FloorDiv', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + '%' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mod', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + 'is' => array('precedence' => 100, 'callable' => array($this, 'parseTestExpression'), 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + 'is not' => array('precedence' => 100, 'callable' => array($this, 'parseNotTestExpression'), 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + '**' => array('precedence' => 200, 'class' => 'Twig_Node_Expression_Binary_Power', 'associativity' => Twig_ExpressionParser::OPERATOR_RIGHT), ), ); } - public function parseNotTestExpression(Twig_Parser $parser, $node) + public function parseNotTestExpression(Twig_Parser $parser, Twig_NodeInterface $node) { return new Twig_Node_Expression_Unary_Not($this->parseTestExpression($parser, $node), $parser->getCurrentToken()->getLine()); } - public function parseTestExpression(Twig_Parser $parser, $node) + public function parseTestExpression(Twig_Parser $parser, Twig_NodeInterface $node) { $stream = $parser->getStream(); - $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); + $name = $this->getTestName($parser, $node->getLine()); + $class = $this->getTestNodeClass($parser, $name); $arguments = null; if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) { $arguments = $parser->getExpressionParser()->parseArguments(true); } - $class = $this->getTestNodeClass($parser, $name, $node->getLine()); - return new $class($node, $name, $arguments, $parser->getCurrentToken()->getLine()); } - protected function getTestNodeClass(Twig_Parser $parser, $name, $line) + protected function getTestName(Twig_Parser $parser, $line) + { + $stream = $parser->getStream(); + $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); + $env = $parser->getEnvironment(); + $testMap = $env->getTests(); + + if (isset($testMap[$name])) { + return $name; + } + + if ($stream->test(Twig_Token::NAME_TYPE)) { + // try 2-words tests + $name = $name.' '.$parser->getCurrentToken()->getValue(); + + if (isset($testMap[$name])) { + $parser->getStream()->next(); + + return $name; + } + } + + $message = sprintf('The test "%s" does not exist', $name); + if ($alternatives = $env->computeAlternatives($name, array_keys($testMap))) { + $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives)); + } + + throw new Twig_Error_Syntax($message, $line, $parser->getFilename()); + } + + protected function getTestNodeClass(Twig_Parser $parser, $name) { $env = $parser->getEnvironment(); $testMap = $env->getTests(); - if (!isset($testMap[$name])) { - $message = sprintf('The test "%s" does not exist', $name); - if ($alternatives = $env->computeAlternatives($name, array_keys($env->getTests()))) { - $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives)); - } - - throw new Twig_Error_Syntax($message, $line, $parser->getFilename()); - } if ($testMap[$name] instanceof Twig_SimpleTest) { return $testMap[$name]->getNodeClass(); @@ -312,7 +365,7 @@ class Twig_Extension_Core extends Twig_Extension * Cycles over a value. * * @param ArrayAccess|array $values An array or an ArrayAccess instance - * @param integer $position The cycle position + * @param int $position The cycle position * * @return string The next value in the cycle */ @@ -332,7 +385,7 @@ function twig_cycle($values, $position) * - a random integer between 0 and the integer parameter * * @param Twig_Environment $env A Twig_Environment instance - * @param Traversable|array|integer|string $values The values to pick a random item from + * @param Traversable|array|int|string $values The values to pick a random item from * * @throws Twig_Error_Runtime When $values is an empty array (does not apply to an empty string which is returned as is). * @@ -348,7 +401,7 @@ function twig_random(Twig_Environment $env, $values = null) return $values < 0 ? mt_rand($values, 0) : mt_rand(0, $values); } - if (is_object($values) && $values instanceof Traversable) { + if ($values instanceof Traversable) { $values = iterator_to_array($values); } elseif (is_string($values)) { if ('' === $values) { @@ -391,10 +444,10 @@ function twig_random(Twig_Environment $env, $values = null) * {{ post.published_at|date("m/d/Y") }} * * - * @param Twig_Environment $env A Twig_Environment instance - * @param DateTime|DateInterval|string $date A date - * @param string $format A format - * @param DateTimeZone|string $timezone A timezone + * @param Twig_Environment $env A Twig_Environment instance + * @param DateTime|DateTimeInterface|DateInterval|string $date A date + * @param string|null $format The target format, null to use the default + * @param DateTimeZone|string|null|false $timezone The target timezone, null to use the default, false to leave unchanged * * @return string The formatted date */ @@ -428,9 +481,12 @@ function twig_date_format_filter(Twig_Environment $env, $date, $format = null, $ function twig_date_modify_filter(Twig_Environment $env, $date, $modifier) { $date = twig_date_converter($env, $date, false); - $date->modify($modifier); + $resultDate = $date->modify($modifier); - return $date; + // This is a hack to ensure PHP 5.2 support and support for DateTimeImmutable + // DateTime::modify does not return the modified DateTime object < 5.3.0 + // and DateTimeImmutable does not modify $date. + return null === $resultDate ? $date : $resultDate; } /** @@ -442,27 +498,32 @@ function twig_date_modify_filter(Twig_Environment $env, $date, $modifier) * {% endif %} * * - * @param Twig_Environment $env A Twig_Environment instance - * @param DateTime|string $date A date - * @param DateTimeZone|string $timezone A timezone + * @param Twig_Environment $env A Twig_Environment instance + * @param DateTime|DateTimeInterface|string|null $date A date + * @param DateTimeZone|string|null|false $timezone The target timezone, null to use the default, false to leave unchanged * * @return DateTime A DateTime instance */ function twig_date_converter(Twig_Environment $env, $date = null, $timezone = null) { // determine the timezone - if (!$timezone) { - $defaultTimezone = $env->getExtension('core')->getTimezone(); - } elseif (!$timezone instanceof DateTimeZone) { - $defaultTimezone = new DateTimeZone($timezone); - } else { - $defaultTimezone = $timezone; + if (false !== $timezone) { + if (null === $timezone) { + $timezone = $env->getExtension('core')->getTimezone(); + } elseif (!$timezone instanceof DateTimeZone) { + $timezone = new DateTimeZone($timezone); + } } - if ($date instanceof DateTime) { + // immutable dates + if ($date instanceof DateTimeImmutable) { + return false !== $timezone ? $date->setTimezone($timezone) : $date; + } + + if ($date instanceof DateTime || $date instanceof DateTimeInterface) { $date = clone $date; if (false !== $timezone) { - $date->setTimezone($defaultTimezone); + $date->setTimezone($timezone); } return $date; @@ -473,14 +534,36 @@ function twig_date_converter(Twig_Environment $env, $date = null, $timezone = nu $date = '@'.$date; } - $date = new DateTime($date, $defaultTimezone); + $date = new DateTime($date, $env->getExtension('core')->getTimezone()); if (false !== $timezone) { - $date->setTimezone($defaultTimezone); + $date->setTimezone($timezone); } return $date; } +/** + * Rounds a number. + * + * @param int|float $value The value to round + * @param int|float $precision The rounding precision + * @param string $method The method to use for rounding + * + * @return int|float The rounded number + */ +function twig_round($value, $precision = 0, $method = 'common') +{ + if ('common' == $method) { + return round($value, $precision); + } + + if ('ceil' != $method && 'floor' != $method) { + throw new Twig_Error_Runtime('The round filter only supports the "common", "ceil", and "floor" methods.'); + } + + return $method($value * pow(10, $precision)) / pow(10, $precision); +} + /** * Number format filter. * @@ -490,7 +573,7 @@ function twig_date_converter(Twig_Environment $env, $date = null, $timezone = nu * * @param Twig_Environment $env A Twig_Environment instance * @param mixed $number A float/int/string of the number to format - * @param integer $decimal The number of decimal points to display. + * @param int $decimal The number of decimal points to display. * @param string $decimalPoint The character(s) to use for the decimal point. * @param string $thousandSep The character(s) to use for the thousands separator. * @@ -515,32 +598,31 @@ function twig_number_format_filter(Twig_Environment $env, $number, $decimal = nu } /** - * URL encodes a string as a path segment or an array as a query string. + * URL encodes (RFC 3986) a string as a path segment or an array as a query string. * * @param string|array $url A URL or an array of query parameters - * @param bool $raw true to use rawurlencode() instead of urlencode * * @return string The URL encoded value */ -function twig_urlencode_filter($url, $raw = false) +function twig_urlencode_filter($url) { if (is_array($url)) { + if (defined('PHP_QUERY_RFC3986')) { + return http_build_query($url, '', '&', PHP_QUERY_RFC3986); + } + return http_build_query($url, '', '&'); } - if ($raw) { - return rawurlencode($url); - } - - return urlencode($url); + return rawurlencode($url); } -if (version_compare(PHP_VERSION, '5.3.0', '<')) { +if (PHP_VERSION_ID < 50300) { /** * JSON encodes a variable. * - * @param mixed $value The value to encode. - * @param integer $options Not used on PHP 5.2.x + * @param mixed $value The value to encode. + * @param int $options Not used on PHP 5.2.x * * @return mixed The JSON encoded value */ @@ -558,8 +640,8 @@ if (version_compare(PHP_VERSION, '5.3.0', '<')) { /** * JSON encodes a variable. * - * @param mixed $value The value to encode. - * @param integer $options Bitmask consisting of JSON_HEX_QUOT, JSON_HEX_TAG, JSON_HEX_AMP, JSON_HEX_APOS, JSON_NUMERIC_CHECK, JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, JSON_FORCE_OBJECT + * @param mixed $value The value to encode. + * @param int $options Bitmask consisting of JSON_HEX_QUOT, JSON_HEX_TAG, JSON_HEX_AMP, JSON_HEX_APOS, JSON_NUMERIC_CHECK, JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, JSON_FORCE_OBJECT * * @return mixed The JSON encoded value */ @@ -601,7 +683,7 @@ function _twig_markup2string(&$value) function twig_array_merge($arr1, $arr2) { if (!is_array($arr1) || !is_array($arr2)) { - throw new Twig_Error_Runtime('The merge filter only works with arrays or hashes.'); + throw new Twig_Error_Runtime(sprintf('The merge filter only works with arrays or hashes; %s and %s given.', gettype($arr1), gettype($arr2))); } return array_merge($arr1, $arr2); @@ -612,16 +694,28 @@ function twig_array_merge($arr1, $arr2) * * @param Twig_Environment $env A Twig_Environment instance * @param mixed $item A variable - * @param integer $start Start of the slice - * @param integer $length Size of the slice - * @param Boolean $preserveKeys Whether to preserve key or not (when the input is an array) + * @param int $start Start of the slice + * @param int $length Size of the slice + * @param bool $preserveKeys Whether to preserve key or not (when the input is an array) * * @return mixed The sliced variable */ function twig_slice(Twig_Environment $env, $item, $start, $length = null, $preserveKeys = false) { - if (is_object($item) && $item instanceof Traversable) { - $item = iterator_to_array($item, false); + if ($item instanceof Traversable) { + if ($item instanceof IteratorAggregate) { + $item = $item->getIterator(); + } + + if ($start >= 0 && $length >= 0 && $item instanceof Iterator) { + try { + return iterator_to_array(new LimitIterator($item, $start, $length === null ? -1 : $length), $preserveKeys); + } catch (OutOfBoundsException $exception) { + return array(); + } + } + + $item = iterator_to_array($item, $preserveKeys); } if (is_array($item)) { @@ -631,10 +725,10 @@ function twig_slice(Twig_Environment $env, $item, $start, $length = null, $prese $item = (string) $item; if (function_exists('mb_get_info') && null !== $charset = $env->getCharset()) { - return mb_substr($item, $start, null === $length ? mb_strlen($item, $charset) - $start : $length, $charset); + return (string) mb_substr($item, $start, null === $length ? mb_strlen($item, $charset) - $start : $length, $charset); } - return null === $length ? substr($item, $start) : substr($item, $start, $length); + return (string) (null === $length ? substr($item, $start) : substr($item, $start, $length)); } /** @@ -649,7 +743,7 @@ function twig_first(Twig_Environment $env, $item) { $elements = twig_slice($env, $item, 0, 1, false); - return is_string($elements) ? $elements[0] : current($elements); + return is_string($elements) ? $elements : current($elements); } /** @@ -664,7 +758,7 @@ function twig_last(Twig_Environment $env, $item) { $elements = twig_slice($env, $item, -1, 1, false); - return is_string($elements) ? $elements[0] : current($elements); + return is_string($elements) ? $elements : current($elements); } /** @@ -687,7 +781,7 @@ function twig_last(Twig_Environment $env, $item) */ function twig_join_filter($value, $glue = '') { - if (is_object($value) && $value instanceof Traversable) { + if ($value instanceof Traversable) { $value = iterator_to_array($value, false); } @@ -713,17 +807,35 @@ function twig_join_filter($value, $glue = '') * * @param string $value A string * @param string $delimiter The delimiter - * @param integer $limit The limit + * @param int $limit The limit * * @return array The split string as an array */ -function twig_split_filter($value, $delimiter, $limit = null) +function twig_split_filter(Twig_Environment $env, $value, $delimiter, $limit = null) { - if (empty($delimiter)) { + if (!empty($delimiter)) { + return null === $limit ? explode($delimiter, $value) : explode($delimiter, $value, $limit); + } + + if (!function_exists('mb_get_info') || null === $charset = $env->getCharset()) { return str_split($value, null === $limit ? 1 : $limit); } - return null === $limit ? explode($delimiter, $value) : explode($delimiter, $value, $limit); + if ($limit <= 1) { + return preg_split('/(? true, 'ISO8859-1' => true, - 'ISO-8859-15' => true, 'ISO8859-15' => true, - 'utf-8' => true, 'UTF-8' => true, - 'CP866' => true, 'IBM866' => true, '866' => true, - 'CP1251' => true, 'WINDOWS-1251' => true, 'WIN-1251' => true, - '1251' => true, - 'CP1252' => true, 'WINDOWS-1252' => true, '1252' => true, - 'KOI8-R' => true, 'KOI8-RU' => true, 'KOI8R' => true, - 'BIG5' => true, '950' => true, - 'GB2312' => true, '936' => true, - 'BIG5-HKSCS' => true, - 'SHIFT_JIS' => true, 'SJIS' => true, '932' => true, - 'EUC-JP' => true, 'EUCJP' => true, - 'ISO8859-5' => true, 'ISO-8859-5' => true, 'MACROMAN' => true, - ); + static $htmlspecialcharsCharsets; + + if (null === $htmlspecialcharsCharsets) { + if (defined('HHVM_VERSION')) { + $htmlspecialcharsCharsets = array('utf-8' => true, 'UTF-8' => true); + } else { + $htmlspecialcharsCharsets = array( + 'ISO-8859-1' => true, 'ISO8859-1' => true, + 'ISO-8859-15' => true, 'ISO8859-15' => true, + 'utf-8' => true, 'UTF-8' => true, + 'CP866' => true, 'IBM866' => true, '866' => true, + 'CP1251' => true, 'WINDOWS-1251' => true, 'WIN-1251' => true, + '1251' => true, + 'CP1252' => true, 'WINDOWS-1252' => true, '1252' => true, + 'KOI8-R' => true, 'KOI8-RU' => true, 'KOI8R' => true, + 'BIG5' => true, '950' => true, + 'GB2312' => true, '936' => true, + 'BIG5-HKSCS' => true, + 'SHIFT_JIS' => true, 'SJIS' => true, '932' => true, + 'EUC-JP' => true, 'EUCJP' => true, + 'ISO8859-5' => true, 'ISO-8859-5' => true, 'MACROMAN' => true, + ); + } + } if (isset($htmlspecialcharsCharsets[$charset])) { return htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE, $charset); @@ -957,16 +1073,26 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html', return $string; case 'url': - // hackish test to avoid version_compare that is much slower, this works unless PHP releases a 5.10.* - // at that point however PHP 5.2.* support can be removed - if (PHP_VERSION < '5.3.0') { + if (PHP_VERSION_ID < 50300) { return str_replace('%7E', '~', rawurlencode($string)); } return rawurlencode($string); default: - throw new Twig_Error_Runtime(sprintf('Invalid escaping strategy "%s" (valid ones: html, js, url, css, and html_attr).', $strategy)); + static $escapers; + + if (null === $escapers) { + $escapers = $env->getExtension('core')->getEscapers(); + } + + if (isset($escapers[$strategy])) { + return call_user_func($escapers[$strategy], $env, $string, $charset); + } + + $validStrategies = implode(', ', array_merge(array('html', 'js', 'url', 'css', 'html_attr'), array_keys($escapers))); + + throw new Twig_Error_Runtime(sprintf('Invalid escaping strategy "%s" (valid ones: %s).', $strategy, $validStrategies)); } } @@ -1088,7 +1214,6 @@ function _twig_escape_html_attr_callback($matches) * Per OWASP recommendations, we'll use hex entities for any other * characters where a named entity does not exist. */ - return sprintf('&#x%s;', $hex); } @@ -1100,7 +1225,7 @@ if (function_exists('mb_get_info')) { * @param Twig_Environment $env A Twig_Environment instance * @param mixed $thing A variable * - * @return integer The length of the value + * @return int The length of the value */ function twig_length_filter(Twig_Environment $env, $thing) { @@ -1184,7 +1309,7 @@ else { * @param Twig_Environment $env A Twig_Environment instance * @param mixed $thing A variable * - * @return integer The length of the value + * @return int The length of the value */ function twig_length_filter(Twig_Environment $env, $thing) { @@ -1240,7 +1365,7 @@ function twig_ensure_traversable($seq) * * @param mixed $value A variable * - * @return Boolean true if the value is empty, false otherwise + * @return bool true if the value is empty, false otherwise */ function twig_test_empty($value) { @@ -1263,7 +1388,7 @@ function twig_test_empty($value) * * @param mixed $value A variable * - * @return Boolean true if the value is traversable + * @return bool true if the value is traversable */ function twig_test_iterable($value) { @@ -1273,16 +1398,18 @@ function twig_test_iterable($value) /** * Renders a template. * - * @param string $template The template to render - * @param array $variables The variables to pass to the template - * @param Boolean $with_context Whether to pass the current context variables or not - * @param Boolean $ignore_missing Whether to ignore missing templates or not - * @param Boolean $sandboxed Whether to sandbox the template or not + * @param string|array $template The template to render or an array of templates to try consecutively + * @param array $variables The variables to pass to the template + * @param bool $with_context Whether to pass the current context variables or not + * @param bool $ignore_missing Whether to ignore missing templates or not + * @param bool $sandboxed Whether to sandbox the template or not * * @return string The rendered template */ function twig_include(Twig_Environment $env, $context, $template, $variables = array(), $withContext = true, $ignoreMissing = false, $sandboxed = false) { + $alreadySandboxed = false; + $sandbox = null; if ($withContext) { $variables = array_merge($context, $variables); } @@ -1307,6 +1434,18 @@ function twig_include(Twig_Environment $env, $context, $template, $variables = a } } +/** + * Returns a template content without rendering it. + * + * @param string $name The template name + * + * @return string The template source + */ +function twig_source(Twig_Environment $env, $name) +{ + return $env->getLoader()->getSource($name); +} + /** * Provides the ability to get constants from instances as well as class/global constants. * @@ -1328,14 +1467,14 @@ function twig_constant($constant, $object = null) * Batches item. * * @param array $items An array of items - * @param integer $size The size of the batch + * @param int $size The size of the batch * @param mixed $fill A value used to fill missing items * * @return array */ function twig_array_batch($items, $size, $fill = null) { - if (is_object($items) && $items instanceof Traversable) { + if ($items instanceof Traversable) { $items = iterator_to_array($items, false); } diff --git a/inc/lib/Twig/Extension/Escaper.php b/inc/lib/Twig/Extension/Escaper.php index c9a7f68e..0edf563a 100644 --- a/inc/lib/Twig/Extension/Escaper.php +++ b/inc/lib/Twig/Extension/Escaper.php @@ -30,7 +30,7 @@ class Twig_Extension_Escaper extends Twig_Extension /** * Returns the node visitor instances to add to the existing list. * - * @return array An array of Twig_NodeVisitorInterface instances + * @return Twig_NodeVisitorInterface[] An array of Twig_NodeVisitorInterface instances */ public function getNodeVisitors() { @@ -64,6 +64,10 @@ class Twig_Extension_Escaper extends Twig_Extension $defaultStrategy = 'html'; } + if ('filename' === $defaultStrategy) { + $defaultStrategy = array('Twig_FileExtensionEscapingStrategy', 'guess'); + } + $this->defaultStrategy = $defaultStrategy; } diff --git a/inc/lib/Twig/Extension/Profiler.php b/inc/lib/Twig/Extension/Profiler.php new file mode 100644 index 00000000..35e04a01 --- /dev/null +++ b/inc/lib/Twig/Extension/Profiler.php @@ -0,0 +1,52 @@ +actives = array($profile); + } + + public function enter(Twig_Profiler_Profile $profile) + { + $this->actives[0]->addProfile($profile); + array_unshift($this->actives, $profile); + } + + public function leave(Twig_Profiler_Profile $profile) + { + $profile->leave(); + array_shift($this->actives); + + if (1 === count($this->actives)) { + $this->actives[0]->leave(); + } + } + + /** + * {@inheritdoc} + */ + public function getNodeVisitors() + { + return array(new Twig_Profiler_NodeVisitor_Profiler($this->getName())); + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'profiler'; + } +} diff --git a/inc/lib/Twig/Extension/Sandbox.php b/inc/lib/Twig/Extension/Sandbox.php index bf76c11a..c58259c6 100644 --- a/inc/lib/Twig/Extension/Sandbox.php +++ b/inc/lib/Twig/Extension/Sandbox.php @@ -33,7 +33,7 @@ class Twig_Extension_Sandbox extends Twig_Extension /** * Returns the node visitor instances to add to the existing list. * - * @return array An array of Twig_NodeVisitorInterface instances + * @return Twig_NodeVisitorInterface[] An array of Twig_NodeVisitorInterface instances */ public function getNodeVisitors() { @@ -93,7 +93,7 @@ class Twig_Extension_Sandbox extends Twig_Extension public function ensureToStringAllowed($obj) { - if (is_object($obj)) { + if ($this->isSandboxed() && is_object($obj)) { $this->policy->checkMethodAllowed($obj, '__toString'); } diff --git a/inc/lib/Twig/Extension/StringLoader.php b/inc/lib/Twig/Extension/StringLoader.php index 5e1a60d0..4e1a546c 100644 --- a/inc/lib/Twig/Extension/StringLoader.php +++ b/inc/lib/Twig/Extension/StringLoader.php @@ -43,22 +43,5 @@ class Twig_Extension_StringLoader extends Twig_Extension */ function twig_template_from_string(Twig_Environment $env, $template) { - $name = sprintf('__string_template__%s', hash('sha256', uniqid(mt_rand(), true), false)); - - $loader = new Twig_Loader_Chain(array( - new Twig_Loader_Array(array($name => $template)), - $current = $env->getLoader(), - )); - - $env->setLoader($loader); - try { - $template = $env->loadTemplate($name); - } catch (Exception $e) { - $env->setLoader($current); - - throw $e; - } - $env->setLoader($current); - - return $template; + return $env->createTemplate($template); } diff --git a/inc/lib/Twig/ExtensionInterface.php b/inc/lib/Twig/ExtensionInterface.php index f189e9d9..49541b02 100644 --- a/inc/lib/Twig/ExtensionInterface.php +++ b/inc/lib/Twig/ExtensionInterface.php @@ -35,7 +35,7 @@ interface Twig_ExtensionInterface /** * Returns the node visitor instances to add to the existing list. * - * @return array An array of Twig_NodeVisitorInterface instances + * @return Twig_NodeVisitorInterface[] An array of Twig_NodeVisitorInterface instances */ public function getNodeVisitors(); diff --git a/inc/lib/Twig/FileExtensionEscapingStrategy.php b/inc/lib/Twig/FileExtensionEscapingStrategy.php new file mode 100644 index 00000000..b1ace7dc --- /dev/null +++ b/inc/lib/Twig/FileExtensionEscapingStrategy.php @@ -0,0 +1,49 @@ + + */ +class Twig_FileExtensionEscapingStrategy +{ + /** + * Guesses the best autoescaping strategy based on the file name. + * + * @param string $filename The template file name + * + * @return string The escaping strategy name to use + */ + public static function guess($filename) + { + if (!preg_match('{\.(js|css|txt)(?:\.[^/\\\\]+)?$}', $filename, $match)) { + return 'html'; + } + + switch ($match[1]) { + case 'js': + return 'js'; + + case 'css': + return 'css'; + + case 'txt': + return false; + } + } +} diff --git a/inc/lib/Twig/LICENSE b/inc/lib/Twig/LICENSE new file mode 100644 index 00000000..a470002b --- /dev/null +++ b/inc/lib/Twig/LICENSE @@ -0,0 +1,31 @@ +Copyright (c) 2009-2014 by the Twig Team. + +Some rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/inc/lib/Twig/Lexer.php b/inc/lib/Twig/Lexer.php index 000b038e..19380b58 100644 --- a/inc/lib/Twig/Lexer.php +++ b/inc/lib/Twig/Lexer.php @@ -73,18 +73,15 @@ class Twig_Lexer implements Twig_LexerInterface } /** - * Tokenizes a source code. - * - * @param string $code The source code - * @param string $filename A unique identifier for the source code - * - * @return Twig_TokenStream A token stream instance + * {@inheritdoc} */ public function tokenize($code, $filename = null) { if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) { $mbEncoding = mb_internal_encoding(); mb_internal_encoding('ASCII'); + } else { + $mbEncoding = null; } $this->code = str_replace(array("\r\n", "\r"), "\n", $code); @@ -135,7 +132,7 @@ class Twig_Lexer implements Twig_LexerInterface throw new Twig_Error_Syntax(sprintf('Unclosed "%s"', $expect), $lineno, $this->filename); } - if (isset($mbEncoding)) { + if ($mbEncoding) { mb_internal_encoding($mbEncoding); } @@ -233,7 +230,7 @@ class Twig_Lexer implements Twig_LexerInterface // operators if (preg_match($this->regexes['operator'], $this->code, $match, null, $this->cursor)) { - $this->pushToken(Twig_Token::OPERATOR_TYPE, $match[0]); + $this->pushToken(Twig_Token::OPERATOR_TYPE, preg_replace('/\s+/', ' ', $match[0])); $this->moveCursor($match[0]); } // names @@ -320,13 +317,10 @@ class Twig_Lexer implements Twig_LexerInterface $this->pushToken(Twig_Token::INTERPOLATION_START_TYPE); $this->moveCursor($match[0]); $this->pushState(self::STATE_INTERPOLATION); - } elseif (preg_match(self::REGEX_DQ_STRING_PART, $this->code, $match, null, $this->cursor) && strlen($match[0]) > 0) { $this->pushToken(Twig_Token::STRING_TYPE, stripcslashes($match[0])); $this->moveCursor($match[0]); - } elseif (preg_match(self::REGEX_DQ_STRING_DELIM, $this->code, $match, null, $this->cursor)) { - list($expect, $lineno) = array_pop($this->brackets); if ($this->code[$this->cursor] != '"') { throw new Twig_Error_Syntax(sprintf('Unclosed "%s"', $expect), $lineno, $this->filename); @@ -382,10 +376,15 @@ class Twig_Lexer implements Twig_LexerInterface // an operator that ends with a character must be followed by // a whitespace or a parenthesis if (ctype_alpha($operator[$length - 1])) { - $regex[] = preg_quote($operator, '/').'(?=[\s()])'; + $r = preg_quote($operator, '/').'(?=[\s()])'; } else { - $regex[] = preg_quote($operator, '/'); + $r = preg_quote($operator, '/'); } + + // an operator with a space can be any amount of whitespaces + $r = preg_replace('/\s+/', '\s+', $r); + + $regex[] = $r; } return '/'.implode('|', $regex).'/A'; diff --git a/inc/lib/Twig/LexerInterface.php b/inc/lib/Twig/LexerInterface.php index 4b83f81b..24a94787 100644 --- a/inc/lib/Twig/LexerInterface.php +++ b/inc/lib/Twig/LexerInterface.php @@ -13,7 +13,8 @@ * Interface implemented by lexer classes. * * @author Fabien Potencier - * @deprecated since 1.12 (to be removed in 2.0) + * + * @deprecated since 1.12 (to be removed in 3.0) */ interface Twig_LexerInterface { @@ -24,6 +25,8 @@ interface Twig_LexerInterface * @param string $filename A unique identifier for the source code * * @return Twig_TokenStream A token stream instance + * + * @throws Twig_Error_Syntax When the code is syntactically wrong */ public function tokenize($code, $filename = null); } diff --git a/inc/lib/Twig/Loader/Array.php b/inc/lib/Twig/Loader/Array.php index ac561048..436edd81 100644 --- a/inc/lib/Twig/Loader/Array.php +++ b/inc/lib/Twig/Loader/Array.php @@ -17,6 +17,8 @@ * source code of the template). If you don't want to see your cache grows out of * control, you need to take care of clearing the old cache file by yourself. * + * This loader should only be used for unit testing. + * * @author Fabien Potencier */ class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterface diff --git a/inc/lib/Twig/Loader/Filesystem.php b/inc/lib/Twig/Loader/Filesystem.php index 23bac47d..818a461c 100644 --- a/inc/lib/Twig/Loader/Filesystem.php +++ b/inc/lib/Twig/Loader/Filesystem.php @@ -143,7 +143,8 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI */ public function exists($name) { - $name = (string) $name; + $name = $this->normalizeName($name); + if (isset($this->cache[$name])) { return true; } @@ -167,10 +168,7 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI protected function findTemplate($name) { - $name = (string) $name; - - // normalize name - $name = preg_replace('#/{2,}#', '/', strtr($name, '\\', '/')); + $name = $this->normalizeName($name); if (isset($this->cache[$name])) { return $this->cache[$name]; @@ -178,16 +176,7 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI $this->validateName($name); - $namespace = self::MAIN_NAMESPACE; - $shortname = $name; - if (isset($name[0]) && '@' == $name[0]) { - if (false === $pos = strpos($name, '/')) { - throw new Twig_Error_Loader(sprintf('Malformed namespaced template name "%s" (expecting "@namespace/template_name").', $name)); - } - - $namespace = substr($name, 1, $pos - 1); - $shortname = substr($name, $pos + 1); - } + list($namespace, $shortname) = $this->parseName($name); if (!isset($this->paths[$namespace])) { throw new Twig_Error_Loader(sprintf('There are no registered paths for namespace "%s".', $namespace)); @@ -195,6 +184,10 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI foreach ($this->paths[$namespace] as $path) { if (is_file($path.'/'.$shortname)) { + if (false !== $realpath = realpath($path.'/'.$shortname)) { + return $this->cache[$name] = $realpath; + } + return $this->cache[$name] = $path.'/'.$shortname; } } @@ -202,6 +195,27 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI throw new Twig_Error_Loader(sprintf('Unable to find template "%s" (looked into: %s).', $name, implode(', ', $this->paths[$namespace]))); } + protected function parseName($name, $default = self::MAIN_NAMESPACE) + { + if (isset($name[0]) && '@' == $name[0]) { + if (false === $pos = strpos($name, '/')) { + throw new Twig_Error_Loader(sprintf('Malformed namespaced template name "%s" (expecting "@namespace/template_name").', $name)); + } + + $namespace = substr($name, 1, $pos - 1); + $shortname = substr($name, $pos + 1); + + return array($namespace, $shortname); + } + + return array($default, $name); + } + + protected function normalizeName($name) + { + return preg_replace('#/{2,}#', '/', strtr((string) $name, '\\', '/')); + } + protected function validateName($name) { if (false !== strpos($name, "\0")) { diff --git a/inc/lib/Twig/Loader/String.php b/inc/lib/Twig/Loader/String.php index 8ad9856c..63d6890a 100644 --- a/inc/lib/Twig/Loader/String.php +++ b/inc/lib/Twig/Loader/String.php @@ -12,15 +12,15 @@ /** * Loads a template from a string. * - * This loader should only be used for unit testing as it has many limitations - * (for instance, the include or extends tag does not make any sense for a string - * loader). + * This loader should NEVER be used. It only exists for Twig internal purposes. * * When using this loader with a cache mechanism, you should know that a new cache * key is generated each time a template content "changes" (the cache key being the * source code of the template). If you don't want to see your cache grows out of * control, you need to take care of clearing the old cache file by yourself. * + * @deprecated since 1.18.1 (to be removed in 2.0) + * * @author Fabien Potencier */ class Twig_Loader_String implements Twig_LoaderInterface, Twig_ExistsLoaderInterface diff --git a/inc/lib/Twig/LoaderInterface.php b/inc/lib/Twig/LoaderInterface.php index 927786d1..b87058e6 100644 --- a/inc/lib/Twig/LoaderInterface.php +++ b/inc/lib/Twig/LoaderInterface.php @@ -44,7 +44,7 @@ interface Twig_LoaderInterface * @param string $name The template name * @param timestamp $time The last modification time of the cached template * - * @return Boolean true if the template is fresh, false otherwise + * @return bool true if the template is fresh, false otherwise * * @throws Twig_Error_Loader When $name is not found */ diff --git a/inc/lib/Twig/Node.php b/inc/lib/Twig/Node.php index 931b4635..515d81bb 100644 --- a/inc/lib/Twig/Node.php +++ b/inc/lib/Twig/Node.php @@ -28,10 +28,10 @@ class Twig_Node implements Twig_NodeInterface * The nodes are automatically made available as properties ($this->node). * The attributes are automatically made available as array items ($this['name']). * - * @param array $nodes An array of named nodes - * @param array $attributes An array of attributes (should not be nodes) - * @param integer $lineno The line number - * @param string $tag The tag name associated with the Node + * @param array $nodes An array of named nodes + * @param array $attributes An array of attributes (should not be nodes) + * @param int $lineno The line number + * @param string $tag The tag name associated with the Node */ public function __construct(array $nodes = array(), array $attributes = array(), $lineno = 0, $tag = null) { @@ -69,6 +69,9 @@ class Twig_Node implements Twig_NodeInterface return implode("\n", $repr); } + /** + * @deprecated since 1.16.1 (to be removed in 2.0) + */ public function toXml($asDom = false) { $dom = new DOMDocument('1.0', 'UTF-8'); @@ -121,7 +124,7 @@ class Twig_Node implements Twig_NodeInterface * * @param string The attribute name * - * @return Boolean true if the attribute is defined, false otherwise + * @return bool true if the attribute is defined, false otherwise */ public function hasAttribute($name) { @@ -170,7 +173,7 @@ class Twig_Node implements Twig_NodeInterface * * @param string The node name * - * @return Boolean true if the node with the given name exists, false otherwise + * @return bool true if the node with the given name exists, false otherwise */ public function hasNode($name) { diff --git a/inc/lib/Twig/Node/AutoEscape.php b/inc/lib/Twig/Node/AutoEscape.php index 8f190e0b..fcabf903 100644 --- a/inc/lib/Twig/Node/AutoEscape.php +++ b/inc/lib/Twig/Node/AutoEscape.php @@ -30,7 +30,7 @@ class Twig_Node_AutoEscape extends Twig_Node /** * Compiles the node to PHP. * - * @param Twig_Compiler A Twig_Compiler instance + * @param Twig_Compiler $compiler A Twig_Compiler instance */ public function compile(Twig_Compiler $compiler) { diff --git a/inc/lib/Twig/Node/Block.php b/inc/lib/Twig/Node/Block.php index 50eb67ed..989e4a0c 100644 --- a/inc/lib/Twig/Node/Block.php +++ b/inc/lib/Twig/Node/Block.php @@ -25,7 +25,7 @@ class Twig_Node_Block extends Twig_Node /** * Compiles the node to PHP. * - * @param Twig_Compiler A Twig_Compiler instance + * @param Twig_Compiler $compiler A Twig_Compiler instance */ public function compile(Twig_Compiler $compiler) { diff --git a/inc/lib/Twig/Node/BlockReference.php b/inc/lib/Twig/Node/BlockReference.php index 013e369e..a05ea045 100644 --- a/inc/lib/Twig/Node/BlockReference.php +++ b/inc/lib/Twig/Node/BlockReference.php @@ -25,7 +25,7 @@ class Twig_Node_BlockReference extends Twig_Node implements Twig_NodeOutputInter /** * Compiles the node to PHP. * - * @param Twig_Compiler A Twig_Compiler instance + * @param Twig_Compiler $compiler A Twig_Compiler instance */ public function compile(Twig_Compiler $compiler) { diff --git a/inc/lib/Twig/Node/CheckSecurity.php b/inc/lib/Twig/Node/CheckSecurity.php new file mode 100644 index 00000000..3040b76c --- /dev/null +++ b/inc/lib/Twig/Node/CheckSecurity.php @@ -0,0 +1,78 @@ + + */ +class Twig_Node_CheckSecurity extends Twig_Node +{ + protected $usedFilters; + protected $usedTags; + protected $usedFunctions; + + public function __construct(array $usedFilters, array $usedTags, array $usedFunctions) + { + $this->usedFilters = $usedFilters; + $this->usedTags = $usedTags; + $this->usedFunctions = $usedFunctions; + + parent::__construct(); + } + + public function compile(Twig_Compiler $compiler) + { + $tags = $filters = $functions = array(); + foreach (array('tags', 'filters', 'functions') as $type) { + foreach ($this->{'used'.ucfirst($type)} as $name => $node) { + if ($node instanceof Twig_Node) { + ${$type}[$name] = $node->getLine(); + } else { + ${$type}[$node] = null; + } + } + } + + $compiler + ->write("\$tags = ")->repr(array_filter($tags))->raw(";\n") + ->write("\$filters = ")->repr(array_filter($filters))->raw(";\n") + ->write("\$functions = ")->repr(array_filter($functions))->raw(";\n\n") + ->write("try {\n") + ->indent() + ->write("\$this->env->getExtension('sandbox')->checkSecurity(\n") + ->indent() + ->write(!$tags ? "array(),\n" : "array('".implode("', '", array_keys($tags))."'),\n") + ->write(!$filters ? "array(),\n" : "array('".implode("', '", array_keys($filters))."'),\n") + ->write(!$functions ? "array()\n" : "array('".implode("', '", array_keys($functions))."')\n") + ->outdent() + ->write(");\n") + ->outdent() + ->write("} catch (Twig_Sandbox_SecurityError \$e) {\n") + ->indent() + ->write("\$e->setTemplateFile(\$this->getTemplateName());\n\n") + ->write("if (\$e instanceof Twig_Sandbox_SecurityNotAllowedTagError && isset(\$tags[\$e->getTagName()])) {\n") + ->indent() + ->write("\$e->setTemplateLine(\$tags[\$e->getTagName()]);\n") + ->outdent() + ->write("} elseif (\$e instanceof Twig_Sandbox_SecurityNotAllowedFilterError && isset(\$filters[\$e->getFilterName()])) {\n") + ->indent() + ->write("\$e->setTemplateLine(\$filters[\$e->getFilterName()]);\n") + ->outdent() + ->write("} elseif (\$e instanceof Twig_Sandbox_SecurityNotAllowedFunctionError && isset(\$functions[\$e->getFunctionName()])) {\n") + ->indent() + ->write("\$e->setTemplateLine(\$functions[\$e->getFunctionName()]);\n") + ->outdent() + ->write("}\n\n") + ->write("throw \$e;\n") + ->outdent() + ->write("}\n\n") + ; + } +} diff --git a/inc/lib/Twig/Node/Do.php b/inc/lib/Twig/Node/Do.php index c528066b..9981bc16 100644 --- a/inc/lib/Twig/Node/Do.php +++ b/inc/lib/Twig/Node/Do.php @@ -24,7 +24,7 @@ class Twig_Node_Do extends Twig_Node /** * Compiles the node to PHP. * - * @param Twig_Compiler A Twig_Compiler instance + * @param Twig_Compiler $compiler A Twig_Compiler instance */ public function compile(Twig_Compiler $compiler) { diff --git a/inc/lib/Twig/Node/Embed.php b/inc/lib/Twig/Node/Embed.php index 4c9456dc..c54d2cce 100644 --- a/inc/lib/Twig/Node/Embed.php +++ b/inc/lib/Twig/Node/Embed.php @@ -28,9 +28,13 @@ class Twig_Node_Embed extends Twig_Node_Include protected function addGetTemplate(Twig_Compiler $compiler) { $compiler - ->write("\$this->env->loadTemplate(") + ->write("\$this->loadTemplate(") ->string($this->getAttribute('filename')) ->raw(', ') + ->repr($compiler->getFilename()) + ->raw(', ') + ->repr($this->getLine()) + ->raw(', ') ->string($this->getAttribute('index')) ->raw(")") ; diff --git a/inc/lib/Twig/Node/Expression/Array.php b/inc/lib/Twig/Node/Expression/Array.php index 1da785fe..6cf7ca14 100644 --- a/inc/lib/Twig/Node/Expression/Array.php +++ b/inc/lib/Twig/Node/Expression/Array.php @@ -63,7 +63,7 @@ class Twig_Node_Expression_Array extends Twig_Node_Expression /** * Compiles the node to PHP. * - * @param Twig_Compiler A Twig_Compiler instance + * @param Twig_Compiler $compiler A Twig_Compiler instance */ public function compile(Twig_Compiler $compiler) { diff --git a/inc/lib/Twig/Node/Expression/AssignName.php b/inc/lib/Twig/Node/Expression/AssignName.php index 2ddea78c..4d5dbdb9 100644 --- a/inc/lib/Twig/Node/Expression/AssignName.php +++ b/inc/lib/Twig/Node/Expression/AssignName.php @@ -15,7 +15,7 @@ class Twig_Node_Expression_AssignName extends Twig_Node_Expression_Name /** * Compiles the node to PHP. * - * @param Twig_Compiler A Twig_Compiler instance + * @param Twig_Compiler $compiler A Twig_Compiler instance */ public function compile(Twig_Compiler $compiler) { diff --git a/inc/lib/Twig/Node/Expression/Binary.php b/inc/lib/Twig/Node/Expression/Binary.php index 9dd5de2c..5c383d15 100644 --- a/inc/lib/Twig/Node/Expression/Binary.php +++ b/inc/lib/Twig/Node/Expression/Binary.php @@ -19,7 +19,7 @@ abstract class Twig_Node_Expression_Binary extends Twig_Node_Expression /** * Compiles the node to PHP. * - * @param Twig_Compiler A Twig_Compiler instance + * @param Twig_Compiler $compiler A Twig_Compiler instance */ public function compile(Twig_Compiler $compiler) { diff --git a/inc/lib/Twig/Node/Expression/Binary/EndsWith.php b/inc/lib/Twig/Node/Expression/Binary/EndsWith.php new file mode 100644 index 00000000..93b3b96f --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Binary/EndsWith.php @@ -0,0 +1,30 @@ +getVarName(); + $right = $compiler->getVarName(); + $compiler + ->raw(sprintf('(is_string($%s = ', $left)) + ->subcompile($this->getNode('left')) + ->raw(sprintf(') && is_string($%s = ', $right)) + ->subcompile($this->getNode('right')) + ->raw(sprintf(') && (\'\' === $%2$s || $%2$s === substr($%1$s, -strlen($%2$s))))', $left, $right)) + ; + } + + public function operator(Twig_Compiler $compiler) + { + return $compiler->raw(''); + } +} diff --git a/inc/lib/Twig/Node/Expression/Binary/FloorDiv.php b/inc/lib/Twig/Node/Expression/Binary/FloorDiv.php index 7fbd0556..d3518b55 100644 --- a/inc/lib/Twig/Node/Expression/Binary/FloorDiv.php +++ b/inc/lib/Twig/Node/Expression/Binary/FloorDiv.php @@ -13,7 +13,7 @@ class Twig_Node_Expression_Binary_FloorDiv extends Twig_Node_Expression_Binary /** * Compiles the node to PHP. * - * @param Twig_Compiler A Twig_Compiler instance + * @param Twig_Compiler $compiler A Twig_Compiler instance */ public function compile(Twig_Compiler $compiler) { diff --git a/inc/lib/Twig/Node/Expression/Binary/In.php b/inc/lib/Twig/Node/Expression/Binary/In.php index 788f9377..1d485b61 100644 --- a/inc/lib/Twig/Node/Expression/Binary/In.php +++ b/inc/lib/Twig/Node/Expression/Binary/In.php @@ -13,7 +13,7 @@ class Twig_Node_Expression_Binary_In extends Twig_Node_Expression_Binary /** * Compiles the node to PHP. * - * @param Twig_Compiler A Twig_Compiler instance + * @param Twig_Compiler $compiler A Twig_Compiler instance */ public function compile(Twig_Compiler $compiler) { diff --git a/inc/lib/Twig/Node/Expression/Binary/Matches.php b/inc/lib/Twig/Node/Expression/Binary/Matches.php new file mode 100644 index 00000000..93bb2920 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Binary/Matches.php @@ -0,0 +1,28 @@ +raw('preg_match(') + ->subcompile($this->getNode('right')) + ->raw(', ') + ->subcompile($this->getNode('left')) + ->raw(')') + ; + } + + public function operator(Twig_Compiler $compiler) + { + return $compiler->raw(''); + } +} diff --git a/inc/lib/Twig/Node/Expression/Binary/NotIn.php b/inc/lib/Twig/Node/Expression/Binary/NotIn.php index f347b7b6..8f215f1c 100644 --- a/inc/lib/Twig/Node/Expression/Binary/NotIn.php +++ b/inc/lib/Twig/Node/Expression/Binary/NotIn.php @@ -13,7 +13,7 @@ class Twig_Node_Expression_Binary_NotIn extends Twig_Node_Expression_Binary /** * Compiles the node to PHP. * - * @param Twig_Compiler A Twig_Compiler instance + * @param Twig_Compiler $compiler A Twig_Compiler instance */ public function compile(Twig_Compiler $compiler) { diff --git a/inc/lib/Twig/Node/Expression/Binary/Power.php b/inc/lib/Twig/Node/Expression/Binary/Power.php index b2c59040..6cd3a217 100644 --- a/inc/lib/Twig/Node/Expression/Binary/Power.php +++ b/inc/lib/Twig/Node/Expression/Binary/Power.php @@ -13,7 +13,7 @@ class Twig_Node_Expression_Binary_Power extends Twig_Node_Expression_Binary /** * Compiles the node to PHP. * - * @param Twig_Compiler A Twig_Compiler instance + * @param Twig_Compiler $compiler A Twig_Compiler instance */ public function compile(Twig_Compiler $compiler) { diff --git a/inc/lib/Twig/Node/Expression/Binary/Range.php b/inc/lib/Twig/Node/Expression/Binary/Range.php index bea4f2a6..fc102fed 100644 --- a/inc/lib/Twig/Node/Expression/Binary/Range.php +++ b/inc/lib/Twig/Node/Expression/Binary/Range.php @@ -13,7 +13,7 @@ class Twig_Node_Expression_Binary_Range extends Twig_Node_Expression_Binary /** * Compiles the node to PHP. * - * @param Twig_Compiler A Twig_Compiler instance + * @param Twig_Compiler $compiler A Twig_Compiler instance */ public function compile(Twig_Compiler $compiler) { diff --git a/inc/lib/Twig/Node/Expression/Binary/StartsWith.php b/inc/lib/Twig/Node/Expression/Binary/StartsWith.php new file mode 100644 index 00000000..d2e30d66 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Binary/StartsWith.php @@ -0,0 +1,30 @@ +getVarName(); + $right = $compiler->getVarName(); + $compiler + ->raw(sprintf('(is_string($%s = ', $left)) + ->subcompile($this->getNode('left')) + ->raw(sprintf(') && is_string($%s = ', $right)) + ->subcompile($this->getNode('right')) + ->raw(sprintf(') && (\'\' === $%2$s || 0 === strpos($%1$s, $%2$s)))', $left, $right)) + ; + } + + public function operator(Twig_Compiler $compiler) + { + return $compiler->raw(''); + } +} diff --git a/inc/lib/Twig/Node/Expression/BlockReference.php b/inc/lib/Twig/Node/Expression/BlockReference.php index 647196eb..4ddb2cf4 100644 --- a/inc/lib/Twig/Node/Expression/BlockReference.php +++ b/inc/lib/Twig/Node/Expression/BlockReference.php @@ -25,7 +25,7 @@ class Twig_Node_Expression_BlockReference extends Twig_Node_Expression /** * Compiles the node to PHP. * - * @param Twig_Compiler A Twig_Compiler instance + * @param Twig_Compiler $compiler A Twig_Compiler instance */ public function compile(Twig_Compiler $compiler) { diff --git a/inc/lib/Twig/Node/Expression/Call.php b/inc/lib/Twig/Node/Expression/Call.php index dba9b0e6..998160b4 100644 --- a/inc/lib/Twig/Node/Expression/Call.php +++ b/inc/lib/Twig/Node/Expression/Call.php @@ -12,10 +12,8 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression { protected function compileCallable(Twig_Compiler $compiler) { - $callable = $this->getAttribute('callable'); - $closingParenthesis = false; - if ($callable) { + if ($this->hasAttribute('callable') && $callable = $this->getAttribute('callable')) { if (is_string($callable)) { $compiler->raw($callable); } elseif (is_array($callable) && $callable[0] instanceof Twig_ExtensionInterface) { @@ -92,6 +90,9 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression protected function getArguments($callable, $arguments) { + $callType = $this->getAttribute('type'); + $callName = $this->getAttribute('name'); + $parameters = array(); $named = false; foreach ($arguments as $name => $node) { @@ -99,7 +100,7 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression $named = true; $name = $this->normalizeName($name); } elseif ($named) { - throw new Twig_Error_Syntax(sprintf('Positional arguments cannot be used after named arguments for %s "%s".', $this->getAttribute('type'), $this->getAttribute('name'))); + throw new Twig_Error_Syntax(sprintf('Positional arguments cannot be used after named arguments for %s "%s".', $callType, $callName)); } $parameters[$name] = $node; @@ -110,7 +111,7 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression } if (!$callable) { - throw new LogicException(sprintf('Named arguments are not supported for %s "%s".', $this->getAttribute('type'), $this->getAttribute('name'))); + throw new LogicException(sprintf('Named arguments are not supported for %s "%s".', $callType, $callName)); } // manage named arguments @@ -119,6 +120,8 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression } elseif (is_object($callable) && !$callable instanceof Closure) { $r = new ReflectionObject($callable); $r = $r->getMethod('__invoke'); + } elseif (is_string($callable) && false !== strpos($callable, '::')) { + $r = new ReflectionMethod($callable); } else { $r = new ReflectionFunction($callable); } @@ -140,32 +143,61 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression } $arguments = array(); + $names = array(); + $missingArguments = array(); + $optionalArguments = array(); $pos = 0; foreach ($definition as $param) { - $name = $this->normalizeName($param->name); + $names[] = $name = $this->normalizeName($param->name); if (array_key_exists($name, $parameters)) { if (array_key_exists($pos, $parameters)) { - throw new Twig_Error_Syntax(sprintf('Argument "%s" is defined twice for %s "%s".', $name, $this->getAttribute('type'), $this->getAttribute('name'))); + throw new Twig_Error_Syntax(sprintf('Argument "%s" is defined twice for %s "%s".', $name, $callType, $callName)); } + if (!empty($missingArguments)) { + throw new Twig_Error_Syntax(sprintf( + 'Argument "%s" could not be assigned for %s "%s(%s)" because it is mapped to an internal PHP function which cannot determine default value for optional argument%s "%s".', + $name, $callType, $callName, implode(', ', $names), count($missingArguments) > 1 ? 's' : '', implode('", "', $missingArguments)) + ); + } + + $arguments = array_merge($arguments, $optionalArguments); $arguments[] = $parameters[$name]; unset($parameters[$name]); + $optionalArguments = array(); } elseif (array_key_exists($pos, $parameters)) { + $arguments = array_merge($arguments, $optionalArguments); $arguments[] = $parameters[$pos]; unset($parameters[$pos]); + $optionalArguments = array(); ++$pos; } elseif ($param->isDefaultValueAvailable()) { - $arguments[] = new Twig_Node_Expression_Constant($param->getDefaultValue(), -1); + $optionalArguments[] = new Twig_Node_Expression_Constant($param->getDefaultValue(), -1); } elseif ($param->isOptional()) { - break; + if (empty($parameters)) { + break; + } else { + $missingArguments[] = $name; + } } else { - throw new Twig_Error_Syntax(sprintf('Value for argument "%s" is required for %s "%s".', $name, $this->getAttribute('type'), $this->getAttribute('name'))); + throw new Twig_Error_Syntax(sprintf('Value for argument "%s" is required for %s "%s".', $name, $callType, $callName)); } } if (!empty($parameters)) { - throw new Twig_Error_Syntax(sprintf('Unknown argument%s "%s" for %s "%s".', count($parameters) > 1 ? 's' : '' , implode('", "', array_keys($parameters)), $this->getAttribute('type'), $this->getAttribute('name'))); + $unknownParameter = null; + foreach ($parameters as $parameter) { + if ($parameter instanceof Twig_Node) { + $unknownParameter = $parameter; + break; + } + } + + throw new Twig_Error_Syntax(sprintf( + 'Unknown argument%s "%s" for %s "%s(%s)".', + count($parameters) > 1 ? 's' : '', implode('", "', array_keys($parameters)), $callType, $callName, implode(', ', $names) + ), $unknownParameter ? $unknownParameter->getLine() : -1); } return $arguments; diff --git a/inc/lib/Twig/Node/Expression/ExtensionReference.php b/inc/lib/Twig/Node/Expression/ExtensionReference.php index 00ac6701..db06abb0 100644 --- a/inc/lib/Twig/Node/Expression/ExtensionReference.php +++ b/inc/lib/Twig/Node/Expression/ExtensionReference.php @@ -24,7 +24,7 @@ class Twig_Node_Expression_ExtensionReference extends Twig_Node_Expression /** * Compiles the node to PHP. * - * @param Twig_Compiler A Twig_Compiler instance + * @param Twig_Compiler $compiler A Twig_Compiler instance */ public function compile(Twig_Compiler $compiler) { diff --git a/inc/lib/Twig/Node/Expression/GetAttr.php b/inc/lib/Twig/Node/Expression/GetAttr.php index 55d9fcc3..6ce61111 100644 --- a/inc/lib/Twig/Node/Expression/GetAttr.php +++ b/inc/lib/Twig/Node/Expression/GetAttr.php @@ -11,7 +11,7 @@ */ class Twig_Node_Expression_GetAttr extends Twig_Node_Expression { - public function __construct(Twig_Node_Expression $node, Twig_Node_Expression $attribute, Twig_Node_Expression_Array $arguments, $type, $lineno) + public function __construct(Twig_Node_Expression $node, Twig_Node_Expression $attribute, Twig_Node_Expression $arguments = null, $type, $lineno) { parent::__construct(array('node' => $node, 'attribute' => $attribute, 'arguments' => $arguments), array('type' => $type, 'is_defined_test' => false, 'ignore_strict_check' => false, 'disable_c_ext' => false), $lineno); } @@ -32,20 +32,30 @@ class Twig_Node_Expression_GetAttr extends Twig_Node_Expression $compiler->raw(', ')->subcompile($this->getNode('attribute')); - if (count($this->getNode('arguments')) || Twig_Template::ANY_CALL !== $this->getAttribute('type') || $this->getAttribute('is_defined_test') || $this->getAttribute('ignore_strict_check')) { - $compiler->raw(', ')->subcompile($this->getNode('arguments')); + // only generate optional arguments when needed (to make generated code more readable) + $needFourth = $this->getAttribute('ignore_strict_check'); + $needThird = $needFourth || $this->getAttribute('is_defined_test'); + $needSecond = $needThird || Twig_Template::ANY_CALL !== $this->getAttribute('type'); + $needFirst = $needSecond || null !== $this->getNode('arguments'); - if (Twig_Template::ANY_CALL !== $this->getAttribute('type') || $this->getAttribute('is_defined_test') || $this->getAttribute('ignore_strict_check')) { - $compiler->raw(', ')->repr($this->getAttribute('type')); + if ($needFirst) { + if (null !== $this->getNode('arguments')) { + $compiler->raw(', ')->subcompile($this->getNode('arguments')); + } else { + $compiler->raw(', array()'); } + } - if ($this->getAttribute('is_defined_test') || $this->getAttribute('ignore_strict_check')) { - $compiler->raw(', '.($this->getAttribute('is_defined_test') ? 'true' : 'false')); - } + if ($needSecond) { + $compiler->raw(', ')->repr($this->getAttribute('type')); + } - if ($this->getAttribute('ignore_strict_check')) { - $compiler->raw(', '.($this->getAttribute('ignore_strict_check') ? 'true' : 'false')); - } + if ($needThird) { + $compiler->raw(', ')->repr($this->getAttribute('is_defined_test')); + } + + if ($needFourth) { + $compiler->raw(', ')->repr($this->getAttribute('ignore_strict_check')); } $compiler->raw(')'); diff --git a/inc/lib/Twig/Node/Expression/MacroCall.php b/inc/lib/Twig/Node/Expression/MacroCall.php deleted file mode 100644 index 3e6b8c12..00000000 --- a/inc/lib/Twig/Node/Expression/MacroCall.php +++ /dev/null @@ -1,60 +0,0 @@ - - */ -class Twig_Node_Expression_MacroCall extends Twig_Node_Expression -{ - public function __construct(Twig_Node_Expression $template, $name, Twig_Node_Expression_Array $arguments, $lineno) - { - parent::__construct(array('template' => $template, 'arguments' => $arguments), array('name' => $name), $lineno); - } - - public function compile(Twig_Compiler $compiler) - { - $namedNames = array(); - $namedCount = 0; - $positionalCount = 0; - foreach ($this->getNode('arguments')->getKeyValuePairs() as $pair) { - $name = $pair['key']->getAttribute('value'); - if (!is_int($name)) { - $namedCount++; - $namedNames[$name] = 1; - } elseif ($namedCount > 0) { - throw new Twig_Error_Syntax(sprintf('Positional arguments cannot be used after named arguments for macro "%s".', $this->getAttribute('name')), $this->lineno); - } else { - $positionalCount++; - } - } - - $compiler - ->raw('$this->callMacro(') - ->subcompile($this->getNode('template')) - ->raw(', ')->repr($this->getAttribute('name')) - ->raw(', ')->subcompile($this->getNode('arguments')) - ; - - if ($namedCount > 0) { - $compiler - ->raw(', ')->repr($namedNames) - ->raw(', ')->repr($namedCount) - ->raw(', ')->repr($positionalCount) - ; - } - - $compiler - ->raw(')') - ; - } -} diff --git a/inc/lib/Twig/Node/Expression/Name.php b/inc/lib/Twig/Node/Expression/Name.php index 3b8fae01..0bfcdbc4 100644 --- a/inc/lib/Twig/Node/Expression/Name.php +++ b/inc/lib/Twig/Node/Expression/Name.php @@ -26,6 +26,8 @@ class Twig_Node_Expression_Name extends Twig_Node_Expression { $name = $this->getAttribute('name'); + $compiler->addDebugInfo($this); + if ($this->getAttribute('is_defined_test')) { if ($this->isSpecial()) { $compiler->repr(true); @@ -44,7 +46,7 @@ class Twig_Node_Expression_Name extends Twig_Node_Expression // remove the non-PHP 5.4 version when PHP 5.3 support is dropped // as the non-optimized version is just a workaround for slow ternary operator // when the context has a lot of variables - if (version_compare(phpversion(), '5.4.0RC1', '>=')) { + if (PHP_VERSION_ID >= 50400) { // PHP 5.4 ternary operator performance was optimized $compiler ->raw('(isset($context[') diff --git a/inc/lib/Twig/Node/Expression/Parent.php b/inc/lib/Twig/Node/Expression/Parent.php index dcf618c0..a22ce038 100644 --- a/inc/lib/Twig/Node/Expression/Parent.php +++ b/inc/lib/Twig/Node/Expression/Parent.php @@ -25,7 +25,7 @@ class Twig_Node_Expression_Parent extends Twig_Node_Expression /** * Compiles the node to PHP. * - * @param Twig_Compiler A Twig_Compiler instance + * @param Twig_Compiler $compiler A Twig_Compiler instance */ public function compile(Twig_Compiler $compiler) { diff --git a/inc/lib/Twig/Node/Expression/Test/Divisibleby.php b/inc/lib/Twig/Node/Expression/Test/Divisibleby.php index 0aceb530..d5bed234 100644 --- a/inc/lib/Twig/Node/Expression/Test/Divisibleby.php +++ b/inc/lib/Twig/Node/Expression/Test/Divisibleby.php @@ -13,7 +13,7 @@ * Checks if a variable is divisible by a number. * *
    - *  {% if loop.index is divisibleby(3) %}
    + *  {% if loop.index is divisible by(3) %}
      * 
    * * @author Fabien Potencier diff --git a/inc/lib/Twig/Node/Expression/Unary.php b/inc/lib/Twig/Node/Expression/Unary.php index c514388e..1cf54c32 100644 --- a/inc/lib/Twig/Node/Expression/Unary.php +++ b/inc/lib/Twig/Node/Expression/Unary.php @@ -18,12 +18,9 @@ abstract class Twig_Node_Expression_Unary extends Twig_Node_Expression public function compile(Twig_Compiler $compiler) { - $compiler->raw('('); + $compiler->raw(' '); $this->operator($compiler); - $compiler - ->subcompile($this->getNode('node')) - ->raw(')') - ; + $compiler->subcompile($this->getNode('node')); } abstract public function operator(Twig_Compiler $compiler); diff --git a/inc/lib/Twig/Node/Flush.php b/inc/lib/Twig/Node/Flush.php index 0467ddce..20d6aab4 100644 --- a/inc/lib/Twig/Node/Flush.php +++ b/inc/lib/Twig/Node/Flush.php @@ -24,7 +24,7 @@ class Twig_Node_Flush extends Twig_Node /** * Compiles the node to PHP. * - * @param Twig_Compiler A Twig_Compiler instance + * @param Twig_Compiler $compiler A Twig_Compiler instance */ public function compile(Twig_Compiler $compiler) { diff --git a/inc/lib/Twig/Node/For.php b/inc/lib/Twig/Node/For.php index d1ff371d..c54a23cc 100644 --- a/inc/lib/Twig/Node/For.php +++ b/inc/lib/Twig/Node/For.php @@ -33,7 +33,7 @@ class Twig_Node_For extends Twig_Node /** * Compiles the node to PHP. * - * @param Twig_Compiler A Twig_Compiler instance + * @param Twig_Compiler $compiler A Twig_Compiler instance */ public function compile(Twig_Compiler $compiler) { diff --git a/inc/lib/Twig/Node/ForLoop.php b/inc/lib/Twig/Node/ForLoop.php index b8841583..d330283e 100644 --- a/inc/lib/Twig/Node/ForLoop.php +++ b/inc/lib/Twig/Node/ForLoop.php @@ -24,7 +24,7 @@ class Twig_Node_ForLoop extends Twig_Node /** * Compiles the node to PHP. * - * @param Twig_Compiler A Twig_Compiler instance + * @param Twig_Compiler $compiler A Twig_Compiler instance */ public function compile(Twig_Compiler $compiler) { diff --git a/inc/lib/Twig/Node/If.php b/inc/lib/Twig/Node/If.php index 4296a8d6..980274e5 100644 --- a/inc/lib/Twig/Node/If.php +++ b/inc/lib/Twig/Node/If.php @@ -25,12 +25,12 @@ class Twig_Node_If extends Twig_Node /** * Compiles the node to PHP. * - * @param Twig_Compiler A Twig_Compiler instance + * @param Twig_Compiler $compiler A Twig_Compiler instance */ public function compile(Twig_Compiler $compiler) { $compiler->addDebugInfo($this); - for ($i = 0; $i < count($this->getNode('tests')); $i += 2) { + for ($i = 0, $count = count($this->getNode('tests')); $i < $count; $i += 2) { if ($i > 0) { $compiler ->outdent() diff --git a/inc/lib/Twig/Node/Import.php b/inc/lib/Twig/Node/Import.php index 99efc091..5e4aa115 100644 --- a/inc/lib/Twig/Node/Import.php +++ b/inc/lib/Twig/Node/Import.php @@ -24,7 +24,7 @@ class Twig_Node_Import extends Twig_Node /** * Compiles the node to PHP. * - * @param Twig_Compiler A Twig_Compiler instance + * @param Twig_Compiler $compiler A Twig_Compiler instance */ public function compile(Twig_Compiler $compiler) { @@ -39,8 +39,12 @@ class Twig_Node_Import extends Twig_Node $compiler->raw("\$this"); } else { $compiler - ->raw('$this->env->loadTemplate(') + ->raw('$this->loadTemplate(') ->subcompile($this->getNode('expr')) + ->raw(', ') + ->repr($compiler->getFilename()) + ->raw(', ') + ->repr($this->getLine()) ->raw(")") ; } diff --git a/inc/lib/Twig/Node/Include.php b/inc/lib/Twig/Node/Include.php index ed4a3751..46b06852 100644 --- a/inc/lib/Twig/Node/Include.php +++ b/inc/lib/Twig/Node/Include.php @@ -19,13 +19,13 @@ class Twig_Node_Include extends Twig_Node implements Twig_NodeOutputInterface { public function __construct(Twig_Node_Expression $expr, Twig_Node_Expression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null) { - parent::__construct(array('expr' => $expr, 'variables' => $variables), array('only' => (Boolean) $only, 'ignore_missing' => (Boolean) $ignoreMissing), $lineno, $tag); + parent::__construct(array('expr' => $expr, 'variables' => $variables), array('only' => (bool) $only, 'ignore_missing' => (bool) $ignoreMissing), $lineno, $tag); } /** * Compiles the node to PHP. * - * @param Twig_Compiler A Twig_Compiler instance + * @param Twig_Compiler $compiler A Twig_Compiler instance */ public function compile(Twig_Compiler $compiler) { @@ -60,40 +60,29 @@ class Twig_Node_Include extends Twig_Node implements Twig_NodeOutputInterface protected function addGetTemplate(Twig_Compiler $compiler) { - if ($this->getNode('expr') instanceof Twig_Node_Expression_Constant) { - $compiler - ->write("\$this->env->loadTemplate(") - ->subcompile($this->getNode('expr')) - ->raw(")") - ; - } else { - $compiler - ->write("\$template = \$this->env->resolveTemplate(") - ->subcompile($this->getNode('expr')) - ->raw(");\n") - ->write('$template') - ; - } + $compiler + ->write("\$this->loadTemplate(") + ->subcompile($this->getNode('expr')) + ->raw(', ') + ->repr($compiler->getFilename()) + ->raw(', ') + ->repr($this->getLine()) + ->raw(")") + ; } protected function addTemplateArguments(Twig_Compiler $compiler) { - if (false === $this->getAttribute('only')) { - if (null === $this->getNode('variables')) { - $compiler->raw('$context'); - } else { - $compiler - ->raw('array_merge($context, ') - ->subcompile($this->getNode('variables')) - ->raw(')') - ; - } + if (null === $this->getNode('variables')) { + $compiler->raw(false === $this->getAttribute('only') ? '$context' : 'array()'); + } elseif (false === $this->getAttribute('only')) { + $compiler + ->raw('array_merge($context, ') + ->subcompile($this->getNode('variables')) + ->raw(')') + ; } else { - if (null === $this->getNode('variables')) { - $compiler->raw('array()'); - } else { - $compiler->subcompile($this->getNode('variables')); - } + $compiler->subcompile($this->getNode('variables')); } } } diff --git a/inc/lib/Twig/Node/Macro.php b/inc/lib/Twig/Node/Macro.php index 43c75e5c..ab7e8d25 100644 --- a/inc/lib/Twig/Node/Macro.php +++ b/inc/lib/Twig/Node/Macro.php @@ -18,26 +18,26 @@ class Twig_Node_Macro extends Twig_Node { public function __construct($name, Twig_NodeInterface $body, Twig_NodeInterface $arguments, $lineno, $tag = null) { - parent::__construct(array('body' => $body, 'arguments' => $arguments), array('name' => $name, 'method' => 'get'.ucfirst($name)), $lineno, $tag); + parent::__construct(array('body' => $body, 'arguments' => $arguments), array('name' => $name), $lineno, $tag); } /** * Compiles the node to PHP. * - * @param Twig_Compiler A Twig_Compiler instance + * @param Twig_Compiler $compiler A Twig_Compiler instance */ public function compile(Twig_Compiler $compiler) { $compiler ->addDebugInfo($this) - ->write(sprintf("public function %s(", $this->getAttribute('method'))) + ->write(sprintf("public function get%s(", $this->getAttribute('name'))) ; $count = count($this->getNode('arguments')); $pos = 0; foreach ($this->getNode('arguments') as $name => $default) { $compiler - ->raw('$_'.$name.' = ') + ->raw('$__'.$name.'__ = ') ->subcompile($default) ; @@ -64,7 +64,7 @@ class Twig_Node_Macro extends Twig_Node $compiler ->write('') ->string($name) - ->raw(' => $_'.$name) + ->raw(' => $__'.$name.'__') ->raw(",\n") ; } diff --git a/inc/lib/Twig/Node/Module.php b/inc/lib/Twig/Node/Module.php index 224410a2..78022632 100644 --- a/inc/lib/Twig/Node/Module.php +++ b/inc/lib/Twig/Node/Module.php @@ -13,6 +13,10 @@ /** * Represents a module node. * + * Consider this class as being final. If you need to customize the behavior of + * the generated class, consider adding nodes to the following nodes: display_start, + * display_end, constructor_start, constructor_end, and class_end. + * * @author Fabien Potencier */ class Twig_Node_Module extends Twig_Node @@ -20,7 +24,22 @@ class Twig_Node_Module extends Twig_Node public function __construct(Twig_NodeInterface $body, Twig_Node_Expression $parent = null, Twig_NodeInterface $blocks, Twig_NodeInterface $macros, Twig_NodeInterface $traits, $embeddedTemplates, $filename) { // embedded templates are set as attributes so that they are only visited once by the visitors - parent::__construct(array('parent' => $parent, 'body' => $body, 'blocks' => $blocks, 'macros' => $macros, 'traits' => $traits), array('filename' => $filename, 'index' => null, 'embedded_templates' => $embeddedTemplates), 1); + parent::__construct(array( + 'parent' => $parent, + 'body' => $body, + 'blocks' => $blocks, + 'macros' => $macros, + 'traits' => $traits, + 'display_start' => new Twig_Node(), + 'display_end' => new Twig_Node(), + 'constructor_start' => new Twig_Node(), + 'constructor_end' => new Twig_Node(), + 'class_end' => new Twig_Node(), + ), array( + 'filename' => $filename, + 'index' => null, + 'embedded_templates' => $embeddedTemplates, + ), 1); } public function setIndex($index) @@ -31,7 +50,7 @@ class Twig_Node_Module extends Twig_Node /** * Compiles the node to PHP. * - * @param Twig_Compiler A Twig_Compiler instance + * @param Twig_Compiler $compiler A Twig_Compiler instance */ public function compile(Twig_Compiler $compiler) { @@ -50,17 +69,20 @@ class Twig_Node_Module extends Twig_Node $this->compileClassHeader($compiler); - if (count($this->getNode('blocks')) || count($this->getNode('traits')) || null === $this->getNode('parent') || $this->getNode('parent') instanceof Twig_Node_Expression_Constant) { + if ( + count($this->getNode('blocks')) + || count($this->getNode('traits')) + || null === $this->getNode('parent') + || $this->getNode('parent') instanceof Twig_Node_Expression_Constant + || count($this->getNode('constructor_start')) + || count($this->getNode('constructor_end')) + ) { $this->compileConstructor($compiler); } $this->compileGetParent($compiler); - $this->compileDisplayHeader($compiler); - - $this->compileDisplayBody($compiler); - - $this->compileDisplayFooter($compiler); + $this->compileDisplay($compiler); $compiler->subcompile($this->getNode('blocks')); @@ -77,22 +99,27 @@ class Twig_Node_Module extends Twig_Node protected function compileGetParent(Twig_Compiler $compiler) { - if (null === $this->getNode('parent')) { + if (null === $parent = $this->getNode('parent')) { return; } $compiler ->write("protected function doGetParent(array \$context)\n", "{\n") ->indent() + ->addDebugInfo($parent) ->write("return ") ; - if ($this->getNode('parent') instanceof Twig_Node_Expression_Constant) { - $compiler->subcompile($this->getNode('parent')); + if ($parent instanceof Twig_Node_Expression_Constant) { + $compiler->subcompile($parent); } else { $compiler - ->raw("\$this->env->resolveTemplate(") - ->subcompile($this->getNode('parent')) + ->raw("\$this->loadTemplate(") + ->subcompile($parent) + ->raw(', ') + ->repr($compiler->getFilename()) + ->raw(', ') + ->repr($this->getNode('parent')->getLine()) ->raw(")") ; } @@ -104,20 +131,6 @@ class Twig_Node_Module extends Twig_Node ; } - protected function compileDisplayBody(Twig_Compiler $compiler) - { - $compiler->subcompile($this->getNode('body')); - - if (null !== $this->getNode('parent')) { - if ($this->getNode('parent') instanceof Twig_Node_Expression_Constant) { - $compiler->write("\$this->parent"); - } else { - $compiler->write("\$this->getParent(\$context)"); - } - $compiler->raw("->display(\$context, array_merge(\$this->blocks, \$blocks));\n"); - } - } - protected function compileClassHeader(Twig_Compiler $compiler) { $compiler @@ -136,17 +149,23 @@ class Twig_Node_Module extends Twig_Node $compiler ->write("public function __construct(Twig_Environment \$env)\n", "{\n") ->indent() + ->subcompile($this->getNode('constructor_start')) ->write("parent::__construct(\$env);\n\n") ; // parent - if (null === $this->getNode('parent')) { + if (null === $parent = $this->getNode('parent')) { $compiler->write("\$this->parent = false;\n\n"); - } elseif ($this->getNode('parent') instanceof Twig_Node_Expression_Constant) { + } elseif ($parent instanceof Twig_Node_Expression_Constant) { $compiler - ->write("\$this->parent = \$this->env->loadTemplate(") - ->subcompile($this->getNode('parent')) - ->raw(");\n\n") + ->addDebugInfo($parent) + ->write("\$this->parent = \$this->loadTemplate(") + ->subcompile($parent) + ->raw(', ') + ->repr($compiler->getFilename()) + ->raw(', ') + ->repr($this->getNode('parent')->getLine()) + ->raw(");\n") ; } @@ -170,6 +189,18 @@ class Twig_Node_Module extends Twig_Node foreach ($trait->getNode('targets') as $key => $value) { $compiler + ->write(sprintf("if (!isset(\$_trait_%s_blocks[", $i)) + ->string($key) + ->raw("])) {\n") + ->indent() + ->write("throw new Twig_Error_Runtime(sprintf('Block ") + ->string($key) + ->raw(" is not defined in trait ") + ->subcompile($trait->getNode('template')) + ->raw(".'));\n") + ->outdent() + ->write("}\n\n") + ->write(sprintf("\$_trait_%s_blocks[", $i)) ->subcompile($value) ->raw(sprintf("] = \$_trait_%s_blocks[", $i)) @@ -233,57 +264,36 @@ class Twig_Node_Module extends Twig_Node ; } - $compiler - ->outdent() - ->write(");\n\n") - ; - - // macro information - $compiler - ->write("\$this->macros = array(\n") - ->indent() - ; - - foreach ($this->getNode('macros') as $name => $node) { - $compiler - ->addIndentation()->repr($name)->raw(" => array(\n") - ->indent() - ->write("'method' => ")->repr($node->getAttribute('method'))->raw(",\n") - ->write("'arguments' => array(\n") - ->indent() - ; - foreach ($node->getNode('arguments') as $argument => $value) { - $compiler->addIndentation()->repr($argument)->raw (' => ')->subcompile($value)->raw(",\n"); - } - $compiler - ->outdent() - ->write("),\n") - ->outdent() - ->write("),\n") - ; - } $compiler ->outdent() ->write(");\n") - ; - - $compiler ->outdent() + ->subcompile($this->getNode('constructor_end')) ->write("}\n\n") ; } - protected function compileDisplayHeader(Twig_Compiler $compiler) + protected function compileDisplay(Twig_Compiler $compiler) { $compiler ->write("protected function doDisplay(array \$context, array \$blocks = array())\n", "{\n") ->indent() + ->subcompile($this->getNode('display_start')) + ->subcompile($this->getNode('body')) ; - } - protected function compileDisplayFooter(Twig_Compiler $compiler) - { + if (null !== $parent = $this->getNode('parent')) { + $compiler->addDebugInfo($parent); + if ($parent instanceof Twig_Node_Expression_Constant) { + $compiler->write("\$this->parent"); + } else { + $compiler->write("\$this->getParent(\$context)"); + } + $compiler->raw("->display(\$context, array_merge(\$this->blocks, \$blocks));\n"); + } + $compiler + ->subcompile($this->getNode('display_end')) ->outdent() ->write("}\n\n") ; @@ -292,6 +302,7 @@ class Twig_Node_Module extends Twig_Node protected function compileClassFooter(Twig_Compiler $compiler) { $compiler + ->subcompile($this->getNode('class_end')) ->outdent() ->write("}\n") ; @@ -382,8 +393,12 @@ class Twig_Node_Module extends Twig_Node { if ($node instanceof Twig_Node_Expression_Constant) { $compiler - ->write(sprintf("%s = \$this->env->loadTemplate(", $var)) + ->write(sprintf("%s = \$this->loadTemplate(", $var)) ->subcompile($node) + ->raw(', ') + ->repr($compiler->getFilename()) + ->raw(', ') + ->repr($node->getLine()) ->raw(");\n") ; } else { @@ -394,7 +409,12 @@ class Twig_Node_Module extends Twig_Node ->write(sprintf("if (!%s", $var)) ->raw(" instanceof Twig_Template) {\n") ->indent() - ->write(sprintf("%s = \$this->env->loadTemplate(%s);\n", $var, $var)) + ->write(sprintf("%s = \$this->loadTemplate(%s") + ->raw(', ') + ->repr($compiler->getFilename()) + ->raw(', ') + ->repr($node->getLine()) + ->raw(");\n", $var, $var)) ->outdent() ->write("}\n") ; diff --git a/inc/lib/Twig/Node/Print.php b/inc/lib/Twig/Node/Print.php index b0c41d1d..42635361 100644 --- a/inc/lib/Twig/Node/Print.php +++ b/inc/lib/Twig/Node/Print.php @@ -25,7 +25,7 @@ class Twig_Node_Print extends Twig_Node implements Twig_NodeOutputInterface /** * Compiles the node to PHP. * - * @param Twig_Compiler A Twig_Compiler instance + * @param Twig_Compiler $compiler A Twig_Compiler instance */ public function compile(Twig_Compiler $compiler) { diff --git a/inc/lib/Twig/Node/Sandbox.php b/inc/lib/Twig/Node/Sandbox.php index 8cf3ed44..8ca772bc 100644 --- a/inc/lib/Twig/Node/Sandbox.php +++ b/inc/lib/Twig/Node/Sandbox.php @@ -24,7 +24,7 @@ class Twig_Node_Sandbox extends Twig_Node /** * Compiles the node to PHP. * - * @param Twig_Compiler A Twig_Compiler instance + * @param Twig_Compiler $compiler A Twig_Compiler instance */ public function compile(Twig_Compiler $compiler) { diff --git a/inc/lib/Twig/Node/SandboxedModule.php b/inc/lib/Twig/Node/SandboxedModule.php deleted file mode 100644 index be1f5daa..00000000 --- a/inc/lib/Twig/Node/SandboxedModule.php +++ /dev/null @@ -1,60 +0,0 @@ - - */ -class Twig_Node_SandboxedModule extends Twig_Node_Module -{ - protected $usedFilters; - protected $usedTags; - protected $usedFunctions; - - public function __construct(Twig_Node_Module $node, array $usedFilters, array $usedTags, array $usedFunctions) - { - parent::__construct($node->getNode('body'), $node->getNode('parent'), $node->getNode('blocks'), $node->getNode('macros'), $node->getNode('traits'), $node->getAttribute('embedded_templates'), $node->getAttribute('filename'), $node->getLine(), $node->getNodeTag()); - - $this->setAttribute('index', $node->getAttribute('index')); - - $this->usedFilters = $usedFilters; - $this->usedTags = $usedTags; - $this->usedFunctions = $usedFunctions; - } - - protected function compileDisplayBody(Twig_Compiler $compiler) - { - $compiler->write("\$this->checkSecurity();\n"); - - parent::compileDisplayBody($compiler); - } - - protected function compileDisplayFooter(Twig_Compiler $compiler) - { - parent::compileDisplayFooter($compiler); - - $compiler - ->write("protected function checkSecurity()\n", "{\n") - ->indent() - ->write("\$this->env->getExtension('sandbox')->checkSecurity(\n") - ->indent() - ->write(!$this->usedTags ? "array(),\n" : "array('".implode('\', \'', $this->usedTags)."'),\n") - ->write(!$this->usedFilters ? "array(),\n" : "array('".implode('\', \'', $this->usedFilters)."'),\n") - ->write(!$this->usedFunctions ? "array()\n" : "array('".implode('\', \'', $this->usedFunctions)."')\n") - ->outdent() - ->write(");\n") - ->outdent() - ->write("}\n\n") - ; - } -} diff --git a/inc/lib/Twig/Node/SandboxedPrint.php b/inc/lib/Twig/Node/SandboxedPrint.php index 73dfaa96..91872ccc 100644 --- a/inc/lib/Twig/Node/SandboxedPrint.php +++ b/inc/lib/Twig/Node/SandboxedPrint.php @@ -29,7 +29,7 @@ class Twig_Node_SandboxedPrint extends Twig_Node_Print /** * Compiles the node to PHP. * - * @param Twig_Compiler A Twig_Compiler instance + * @param Twig_Compiler $compiler A Twig_Compiler instance */ public function compile(Twig_Compiler $compiler) { diff --git a/inc/lib/Twig/Node/Set.php b/inc/lib/Twig/Node/Set.php index 4c9c16ce..407d1473 100644 --- a/inc/lib/Twig/Node/Set.php +++ b/inc/lib/Twig/Node/Set.php @@ -39,7 +39,7 @@ class Twig_Node_Set extends Twig_Node /** * Compiles the node to PHP. * - * @param Twig_Compiler A Twig_Compiler instance + * @param Twig_Compiler $compiler A Twig_Compiler instance */ public function compile(Twig_Compiler $compiler) { diff --git a/inc/lib/Twig/Node/Spaceless.php b/inc/lib/Twig/Node/Spaceless.php index 7555fa0f..1478c59a 100644 --- a/inc/lib/Twig/Node/Spaceless.php +++ b/inc/lib/Twig/Node/Spaceless.php @@ -26,7 +26,7 @@ class Twig_Node_Spaceless extends Twig_Node /** * Compiles the node to PHP. * - * @param Twig_Compiler A Twig_Compiler instance + * @param Twig_Compiler $compiler A Twig_Compiler instance */ public function compile(Twig_Compiler $compiler) { diff --git a/inc/lib/Twig/Node/Text.php b/inc/lib/Twig/Node/Text.php index 21bdcea1..6863604e 100644 --- a/inc/lib/Twig/Node/Text.php +++ b/inc/lib/Twig/Node/Text.php @@ -25,7 +25,7 @@ class Twig_Node_Text extends Twig_Node implements Twig_NodeOutputInterface /** * Compiles the node to PHP. * - * @param Twig_Compiler A Twig_Compiler instance + * @param Twig_Compiler $compiler A Twig_Compiler instance */ public function compile(Twig_Compiler $compiler) { diff --git a/inc/lib/Twig/NodeInterface.php b/inc/lib/Twig/NodeInterface.php index f0ef7258..8077349b 100644 --- a/inc/lib/Twig/NodeInterface.php +++ b/inc/lib/Twig/NodeInterface.php @@ -13,14 +13,15 @@ * Represents a node in the AST. * * @author Fabien Potencier - * @deprecated since 1.12 (to be removed in 2.0) + * + * @deprecated since 1.12 (to be removed in 3.0) */ interface Twig_NodeInterface extends Countable, IteratorAggregate { /** * Compiles the node to PHP. * - * @param Twig_Compiler A Twig_Compiler instance + * @param Twig_Compiler $compiler A Twig_Compiler instance */ public function compile(Twig_Compiler $compiler); diff --git a/inc/lib/Twig/NodeTraverser.php b/inc/lib/Twig/NodeTraverser.php index 28cba1ad..8178a55c 100644 --- a/inc/lib/Twig/NodeTraverser.php +++ b/inc/lib/Twig/NodeTraverser.php @@ -12,7 +12,7 @@ /** * Twig_NodeTraverser is a node traverser. * - * It visits all nodes and their children and call the given visitor for each. + * It visits all nodes and their children and calls the given visitor for each. * * @author Fabien Potencier */ @@ -24,8 +24,8 @@ class Twig_NodeTraverser /** * Constructor. * - * @param Twig_Environment $env A Twig_Environment instance - * @param array $visitors An array of Twig_NodeVisitorInterface instances + * @param Twig_Environment $env A Twig_Environment instance + * @param Twig_NodeVisitorInterface[] $visitors An array of Twig_NodeVisitorInterface instances */ public function __construct(Twig_Environment $env, array $visitors = array()) { @@ -70,7 +70,7 @@ class Twig_NodeTraverser protected function traverseForVisitor(Twig_NodeVisitorInterface $visitor, Twig_NodeInterface $node = null) { if (null === $node) { - return null; + return; } $node = $visitor->enterNode($node, $this->env); diff --git a/inc/lib/Twig/NodeVisitor/Optimizer.php b/inc/lib/Twig/NodeVisitor/Optimizer.php index a254def7..b9f9a5bf 100644 --- a/inc/lib/Twig/NodeVisitor/Optimizer.php +++ b/inc/lib/Twig/NodeVisitor/Optimizer.php @@ -28,6 +28,7 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface const OPTIMIZE_VAR_ACCESS = 8; protected $loops = array(); + protected $loopsTargets = array(); protected $optimizers; protected $prependedNodes = array(); protected $inABody = false; @@ -35,11 +36,11 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface /** * Constructor. * - * @param integer $optimizers The optimizer mode + * @param int $optimizers The optimizer mode */ public function __construct($optimizers = -1) { - if (!is_int($optimizers) || $optimizers > 2) { + if (!is_int($optimizers) || $optimizers > (self::OPTIMIZE_FOR | self::OPTIMIZE_RAW_FILTER | self::OPTIMIZE_VAR_ACCESS)) { throw new InvalidArgumentException(sprintf('Optimizer mode "%s" is not valid.', $optimizers)); } @@ -55,7 +56,7 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface $this->enterOptimizeFor($node, $env); } - if (!version_compare(phpversion(), '5.4.0RC1', '>=') && self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('sandbox')) { + if (PHP_VERSION_ID < 50400 && self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('sandbox')) { if ($this->inABody) { if (!$node instanceof Twig_Node_Expression) { if (get_class($node) !== 'Twig_Node') { @@ -108,7 +109,7 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface return $node; } - protected function optimizeVariables($node, $env) + protected function optimizeVariables(Twig_NodeInterface $node, Twig_Environment $env) { if ('Twig_Node_Expression_Name' === get_class($node) && $node->isSimple()) { $this->prependedNodes[0][] = $node->getAttribute('name'); @@ -129,7 +130,7 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface * @param Twig_NodeInterface $node A Node * @param Twig_Environment $env The current Twig environment */ - protected function optimizePrintNode($node, $env) + protected function optimizePrintNode(Twig_NodeInterface $node, Twig_Environment $env) { if (!$node instanceof Twig_Node_Print) { return $node; @@ -153,7 +154,7 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface * @param Twig_NodeInterface $node A Node * @param Twig_Environment $env The current Twig environment */ - protected function optimizeRawFilter($node, $env) + protected function optimizeRawFilter(Twig_NodeInterface $node, Twig_Environment $env) { if ($node instanceof Twig_Node_Expression_Filter && 'raw' == $node->getNode('filter')->getAttribute('value')) { return $node->getNode('node'); @@ -168,12 +169,14 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface * @param Twig_NodeInterface $node A Node * @param Twig_Environment $env The current Twig environment */ - protected function enterOptimizeFor($node, $env) + protected function enterOptimizeFor(Twig_NodeInterface $node, Twig_Environment $env) { if ($node instanceof Twig_Node_For) { // disable the loop variable by default $node->setAttribute('with_loop', false); array_unshift($this->loops, $node); + array_unshift($this->loopsTargets, $node->getNode('value_target')->getAttribute('name')); + array_unshift($this->loopsTargets, $node->getNode('key_target')->getAttribute('name')); } elseif (!$this->loops) { // we are outside a loop return; @@ -183,9 +186,15 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface // the loop variable is referenced for the current loop elseif ($node instanceof Twig_Node_Expression_Name && 'loop' === $node->getAttribute('name')) { + $node->setAttribute('always_defined', true); $this->addLoopToCurrent(); } + // optimize access to loop targets + elseif ($node instanceof Twig_Node_Expression_Name && in_array($node->getAttribute('name'), $this->loopsTargets)) { + $node->setAttribute('always_defined', true); + } + // block reference elseif ($node instanceof Twig_Node_BlockReference || $node instanceof Twig_Node_Expression_BlockReference) { $this->addLoopToCurrent(); @@ -196,6 +205,16 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface $this->addLoopToAll(); } + // include function without the with_context=false parameter + elseif ($node instanceof Twig_Node_Expression_Function + && 'include' === $node->getAttribute('name') + && (!$node->getNode('arguments')->hasNode('with_context') + || false !== $node->getNode('arguments')->getNode('with_context')->getAttribute('value') + ) + ) { + $this->addLoopToAll(); + } + // the loop variable is referenced via an attribute elseif ($node instanceof Twig_Node_Expression_GetAttr && (!$node->getNode('attribute') instanceof Twig_Node_Expression_Constant @@ -217,10 +236,12 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface * @param Twig_NodeInterface $node A Node * @param Twig_Environment $env The current Twig environment */ - protected function leaveOptimizeFor($node, $env) + protected function leaveOptimizeFor(Twig_NodeInterface $node, Twig_Environment $env) { if ($node instanceof Twig_Node_For) { array_shift($this->loops); + array_shift($this->loopsTargets); + array_shift($this->loopsTargets); } } diff --git a/inc/lib/Twig/NodeVisitor/SafeAnalysis.php b/inc/lib/Twig/NodeVisitor/SafeAnalysis.php index b0c658cd..a5d06de2 100644 --- a/inc/lib/Twig/NodeVisitor/SafeAnalysis.php +++ b/inc/lib/Twig/NodeVisitor/SafeAnalysis.php @@ -13,12 +13,20 @@ class Twig_NodeVisitor_SafeAnalysis implements Twig_NodeVisitorInterface public function getSafe(Twig_NodeInterface $node) { $hash = spl_object_hash($node); - if (isset($this->data[$hash])) { - foreach ($this->data[$hash] as $bucket) { - if ($bucket['key'] === $node) { - return $bucket['value']; - } + if (!isset($this->data[$hash])) { + return; + } + + foreach ($this->data[$hash] as $bucket) { + if ($bucket['key'] !== $node) { + continue; } + + if (in_array('html_attr', $bucket['value'])) { + $bucket['value'][] = 'html'; + } + + return $bucket['value']; } } @@ -89,8 +97,6 @@ class Twig_NodeVisitor_SafeAnalysis implements Twig_NodeVisitorInterface } else { $this->setSafe($node, array()); } - } elseif ($node instanceof Twig_Node_Expression_MacroCall) { - $this->setSafe($node, array('all')); } elseif ($node instanceof Twig_Node_Expression_GetAttr && $node->getNode('node') instanceof Twig_Node_Expression_Name) { $name = $node->getNode('node')->getAttribute('name'); // attributes on template instances are safe diff --git a/inc/lib/Twig/NodeVisitor/Sandbox.php b/inc/lib/Twig/NodeVisitor/Sandbox.php index fb27045b..5467f813 100644 --- a/inc/lib/Twig/NodeVisitor/Sandbox.php +++ b/inc/lib/Twig/NodeVisitor/Sandbox.php @@ -40,18 +40,18 @@ class Twig_NodeVisitor_Sandbox implements Twig_NodeVisitorInterface return $node; } elseif ($this->inAModule) { // look for tags - if ($node->getNodeTag()) { - $this->tags[] = $node->getNodeTag(); + if ($node->getNodeTag() && !isset($this->tags[$node->getNodeTag()])) { + $this->tags[$node->getNodeTag()] = $node; } // look for filters - if ($node instanceof Twig_Node_Expression_Filter) { - $this->filters[] = $node->getNode('filter')->getAttribute('value'); + if ($node instanceof Twig_Node_Expression_Filter && !isset($this->filters[$node->getNode('filter')->getAttribute('value')])) { + $this->filters[$node->getNode('filter')->getAttribute('value')] = $node; } // look for functions - if ($node instanceof Twig_Node_Expression_Function) { - $this->functions[] = $node->getAttribute('name'); + if ($node instanceof Twig_Node_Expression_Function && !isset($this->functions[$node->getAttribute('name')])) { + $this->functions[$node->getAttribute('name')] = $node; } // wrap print to check __toString() calls @@ -76,7 +76,7 @@ class Twig_NodeVisitor_Sandbox implements Twig_NodeVisitorInterface if ($node instanceof Twig_Node_Module) { $this->inAModule = false; - return new Twig_Node_SandboxedModule($node, array_unique($this->filters), array_unique($this->tags), array_unique($this->functions)); + $node->setNode('display_start', new Twig_Node(array(new Twig_Node_CheckSecurity($this->filters, $this->tags, $this->functions), $node->getNode('display_start')))); } return $node; diff --git a/inc/lib/Twig/NodeVisitorInterface.php b/inc/lib/Twig/NodeVisitorInterface.php index f33c13fc..f2761630 100644 --- a/inc/lib/Twig/NodeVisitorInterface.php +++ b/inc/lib/Twig/NodeVisitorInterface.php @@ -41,7 +41,7 @@ interface Twig_NodeVisitorInterface * * Priority should be between -10 and 10 (0 is the default). * - * @return integer The priority level + * @return int The priority level */ public function getPriority(); } diff --git a/inc/lib/Twig/Parser.php b/inc/lib/Twig/Parser.php index bebdd9bb..549ce2bd 100644 --- a/inc/lib/Twig/Parser.php +++ b/inc/lib/Twig/Parser.php @@ -58,11 +58,7 @@ class Twig_Parser implements Twig_ParserInterface } /** - * Converts a token stream to a node tree. - * - * @param Twig_TokenStream $stream A token stream instance - * - * @return Twig_Node_Module A node tree + * {@inheritdoc} */ public function parse(Twig_TokenStream $stream, $test = null, $dropNeedle = false) { @@ -246,7 +242,7 @@ class Twig_Parser implements Twig_ParserInterface return $this->blocks[$name]; } - public function setBlock($name, $value) + public function setBlock($name, Twig_Node_Block $value) { $this->blocks[$name] = new Twig_Node_Body(array($value), array(), $value->getLine()); } @@ -384,7 +380,7 @@ class Twig_Parser implements Twig_ParserInterface } foreach ($node as $k => $n) { - if (null !== $n && null === $n = $this->filterBodyNodes($n)) { + if (null !== $n && null === $this->filterBodyNodes($n)) { $node->removeNode($k); } } diff --git a/inc/lib/Twig/ParserInterface.php b/inc/lib/Twig/ParserInterface.php index f0d79009..8e7cc0a8 100644 --- a/inc/lib/Twig/ParserInterface.php +++ b/inc/lib/Twig/ParserInterface.php @@ -13,7 +13,8 @@ * Interface implemented by parser classes. * * @author Fabien Potencier - * @deprecated since 1.12 (to be removed in 2.0) + * + * @deprecated since 1.12 (to be removed in 3.0) */ interface Twig_ParserInterface { @@ -23,6 +24,8 @@ interface Twig_ParserInterface * @param Twig_TokenStream $stream A token stream instance * * @return Twig_Node_Module A node tree + * + * @throws Twig_Error_Syntax When the token stream is syntactically or semantically wrong */ public function parse(Twig_TokenStream $stream); } diff --git a/inc/lib/Twig/Profiler/Dumper/Blackfire.php b/inc/lib/Twig/Profiler/Dumper/Blackfire.php new file mode 100644 index 00000000..b82747a9 --- /dev/null +++ b/inc/lib/Twig/Profiler/Dumper/Blackfire.php @@ -0,0 +1,68 @@ + + */ +class Twig_Profiler_Dumper_Blackfire +{ + public function dump(Twig_Profiler_Profile $profile) + { + $data = array(); + $this->dumpProfile('main()', $profile, $data); + $this->dumpChildren('main()', $profile, $data); + + $start = microtime(true); + $str = << $values) { + $str .= "{$name}//{$values['ct']} {$values['wt']} {$values['mu']} {$values['pmu']}\n"; + } + + return $str; + } + + private function dumpChildren($parent, Twig_Profiler_Profile $profile, &$data) + { + foreach ($profile as $p) { + if ($p->isTemplate()) { + $name = $p->getTemplate(); + } else { + $name = sprintf('%s::%s(%s)', $p->getTemplate(), $p->getType(), $p->getName()); + } + $this->dumpProfile(sprintf('%s==>%s', $parent, $name), $p, $data); + $this->dumpChildren($name, $p, $data); + } + } + + private function dumpProfile($edge, Twig_Profiler_Profile $profile, &$data) + { + if (isset($data[$edge])) { + $data[$edge]['ct'] += 1; + $data[$edge]['wt'] += floor($profile->getDuration() * 1000000); + $data[$edge]['mu'] += $profile->getMemoryUsage(); + $data[$edge]['pmu'] += $profile->getPeakMemoryUsage(); + } else { + $data[$edge] = array( + 'ct' => 1, + 'wt' => floor($profile->getDuration() * 1000000), + 'mu' => $profile->getMemoryUsage(), + 'pmu' => $profile->getPeakMemoryUsage(), + ); + } + } +} diff --git a/inc/lib/Twig/Profiler/Dumper/Html.php b/inc/lib/Twig/Profiler/Dumper/Html.php new file mode 100644 index 00000000..c8985206 --- /dev/null +++ b/inc/lib/Twig/Profiler/Dumper/Html.php @@ -0,0 +1,43 @@ + + */ +class Twig_Profiler_Dumper_Html extends Twig_Profiler_Dumper_Text +{ + static private $colors = array( + 'block' => '#dfd', + 'macro' => '#ddf', + 'template' => '#ffd', + 'big' => '#d44', + ); + + public function dump(Twig_Profiler_Profile $profile) + { + return '
    '.parent::dump($profile).'
    '; + } + + protected function formatTemplate(Twig_Profiler_Profile $profile, $prefix) + { + return sprintf('%s└ %s', $prefix, self::$colors['template'], $profile->getTemplate()); + } + + protected function formatNonTemplate(Twig_Profiler_Profile $profile, $prefix) + { + return sprintf('%s└ %s::%s(%s)', $prefix, $profile->getTemplate(), $profile->getType(), isset(self::$colors[$profile->getType()]) ? self::$colors[$profile->getType()] : 'auto', $profile->getName()); + } + + protected function formatTime(Twig_Profiler_Profile $profile, $percent) + { + return sprintf('%.2fms/%.0f%%', $percent > 20 ? self::$colors['big'] : 'auto', $profile->getDuration() * 1000, $percent); + } +} diff --git a/inc/lib/Twig/Profiler/Dumper/Text.php b/inc/lib/Twig/Profiler/Dumper/Text.php new file mode 100644 index 00000000..998e210d --- /dev/null +++ b/inc/lib/Twig/Profiler/Dumper/Text.php @@ -0,0 +1,68 @@ + + */ +class Twig_Profiler_Dumper_Text +{ + private $root; + + public function dump(Twig_Profiler_Profile $profile) + { + return $this->dumpProfile($profile); + } + + protected function formatTemplate(Twig_Profiler_Profile $profile, $prefix) + { + return sprintf('%s└ %s', $prefix, $profile->getTemplate()); + } + + protected function formatNonTemplate(Twig_Profiler_Profile $profile, $prefix) + { + return sprintf('%s└ %s::%s(%s)', $prefix, $profile->getTemplate(), $profile->getType(), $profile->getName()); + } + + protected function formatTime(Twig_Profiler_Profile $profile, $percent) + { + return sprintf('%.2fms/%.0f%%', $profile->getDuration() * 1000, $percent); + } + + private function dumpProfile(Twig_Profiler_Profile $profile, $prefix = '', $sibling = false) + { + if ($profile->isRoot()) { + $this->root = $profile->getDuration(); + $start = $profile->getName(); + } else { + if ($profile->isTemplate()) { + $start = $this->formatTemplate($profile, $prefix); + } else { + $start = $this->formatNonTemplate($profile, $prefix); + } + $prefix .= $sibling ? '│ ' : ' '; + } + + $percent = $this->root ? $profile->getDuration() / $this->root * 100 : 0; + + if ($profile->getDuration() * 1000 < 1) { + $str = $start."\n"; + } else { + $str = sprintf("%s %s\n", $start, $this->formatTime($profile, $percent)); + } + + $nCount = count($profile->getProfiles()); + foreach ($profile as $i => $p) { + $str .= $this->dumpProfile($p, $prefix, $i + 1 !== $nCount); + } + + return $str; + } +} diff --git a/inc/lib/Twig/Profiler/Node/EnterProfile.php b/inc/lib/Twig/Profiler/Node/EnterProfile.php new file mode 100644 index 00000000..11c1114a --- /dev/null +++ b/inc/lib/Twig/Profiler/Node/EnterProfile.php @@ -0,0 +1,40 @@ + + */ +class Twig_Profiler_Node_EnterProfile extends Twig_Node +{ + public function __construct($extensionName, $type, $name, $varName) + { + parent::__construct(array(), array('extension_name' => $extensionName, 'name' => $name, 'type' => $type, 'var_name' => $varName)); + } + + /** + * {@inheritdoc} + */ + public function compile(Twig_Compiler $compiler) + { + $compiler + ->write(sprintf("\$%s = \$this->env->getExtension(", $this->getAttribute('var_name'))) + ->repr($this->getAttribute('extension_name')) + ->raw(");\n") + ->write(sprintf("\$%s->enter(\$%s = new Twig_Profiler_Profile(\$this->getTemplateName(), ", $this->getAttribute('var_name'), $this->getAttribute('var_name').'_prof')) + ->repr($this->getAttribute('type')) + ->raw(", ") + ->repr($this->getAttribute('name')) + ->raw("));\n\n") + ; + } +} diff --git a/inc/lib/Twig/Profiler/Node/LeaveProfile.php b/inc/lib/Twig/Profiler/Node/LeaveProfile.php new file mode 100644 index 00000000..88074c2f --- /dev/null +++ b/inc/lib/Twig/Profiler/Node/LeaveProfile.php @@ -0,0 +1,34 @@ + + */ +class Twig_Profiler_Node_LeaveProfile extends Twig_Node +{ + public function __construct($varName) + { + parent::__construct(array(), array('var_name' => $varName)); + } + + /** + * {@inheritdoc} + */ + public function compile(Twig_Compiler $compiler) + { + $compiler + ->write("\n") + ->write(sprintf("\$%s->leave(\$%s);\n\n", $this->getAttribute('var_name'), $this->getAttribute('var_name').'_prof')) + ; + } +} diff --git a/inc/lib/Twig/Profiler/NodeVisitor/Profiler.php b/inc/lib/Twig/Profiler/NodeVisitor/Profiler.php new file mode 100644 index 00000000..58beb0a5 --- /dev/null +++ b/inc/lib/Twig/Profiler/NodeVisitor/Profiler.php @@ -0,0 +1,72 @@ + + */ +class Twig_Profiler_NodeVisitor_Profiler implements Twig_NodeVisitorInterface +{ + private $extensionName; + + public function __construct($extensionName) + { + $this->extensionName = $extensionName; + } + + /** + * {@inheritdoc} + */ + public function enterNode(Twig_NodeInterface $node, Twig_Environment $env) + { + return $node; + } + + /** + * {@inheritdoc} + */ + public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env) + { + if ($node instanceof Twig_Node_Module) { + $varName = $this->getVarName(); + $node->setNode('display_start', new Twig_Node(array(new Twig_Profiler_Node_EnterProfile($this->extensionName, Twig_Profiler_Profile::TEMPLATE, $node->getAttribute('filename'), $varName), $node->getNode('display_start')))); + $node->setNode('display_end', new Twig_Node(array(new Twig_Profiler_Node_LeaveProfile($varName), $node->getNode('display_end')))); + } elseif ($node instanceof Twig_Node_Block) { + $varName = $this->getVarName(); + $node->setNode('body', new Twig_Node_Body(array( + new Twig_Profiler_Node_EnterProfile($this->extensionName, Twig_Profiler_Profile::BLOCK, $node->getAttribute('name'), $varName), + $node->getNode('body'), + new Twig_Profiler_Node_LeaveProfile($varName), + ))); + } elseif ($node instanceof Twig_Node_Macro) { + $varName = $this->getVarName(); + $node->setNode('body', new Twig_Node_Body(array( + new Twig_Profiler_Node_EnterProfile($this->extensionName, Twig_Profiler_Profile::MACRO, $node->getAttribute('name'), $varName), + $node->getNode('body'), + new Twig_Profiler_Node_LeaveProfile($varName), + ))); + } + + return $node; + } + + private function getVarName() + { + return sprintf('__internal_%s', hash('sha256', uniqid(mt_rand(), true), false)); + } + + /** + * {@inheritdoc} + */ + public function getPriority() + { + return 0; + } +} diff --git a/inc/lib/Twig/Profiler/Profile.php b/inc/lib/Twig/Profiler/Profile.php new file mode 100644 index 00000000..fe48a4d2 --- /dev/null +++ b/inc/lib/Twig/Profiler/Profile.php @@ -0,0 +1,150 @@ + + */ +class Twig_Profiler_Profile implements IteratorAggregate, Serializable +{ + const ROOT = 'ROOT'; + const BLOCK = 'block'; + const TEMPLATE = 'template'; + const MACRO = 'macro'; + + private $template; + private $name; + private $type; + private $starts = array(); + private $ends = array(); + private $profiles = array(); + + public function __construct($template = 'main', $type = Twig_Profiler_Profile::ROOT, $name = 'main') + { + $this->template = $template; + $this->type = $type; + $this->name = 0 === strpos($name, '__internal_') ? 'INTERNAL' : $name; + $this->enter(); + } + + public function getTemplate() + { + return $this->template; + } + + public function getType() + { + return $this->type; + } + + public function getName() + { + return $this->name; + } + + public function isRoot() + { + return self::ROOT === $this->type; + } + + public function isTemplate() + { + return self::TEMPLATE === $this->type; + } + + public function isBlock() + { + return self::BLOCK === $this->type; + } + + public function isMacro() + { + return self::MACRO === $this->type; + } + + public function getProfiles() + { + return $this->profiles; + } + + public function addProfile(Twig_Profiler_Profile $profile) + { + $this->profiles[] = $profile; + } + + /** + * Returns the duration in microseconds. + * + * @return int + */ + public function getDuration() + { + return isset($this->ends['wt']) && isset($this->starts['wt']) ? $this->ends['wt'] - $this->starts['wt'] : 0; + } + + /** + * Returns the memory usage in bytes. + * + * @return int + */ + public function getMemoryUsage() + { + return isset($this->ends['mu']) && isset($this->starts['mu']) ? $this->ends['mu'] - $this->starts['mu'] : 0; + } + + /** + * Returns the peak memory usage in bytes. + * + * @return int + */ + public function getPeakMemoryUsage() + { + return isset($this->ends['pmu']) && isset($this->starts['pmu']) ? $this->ends['pmu'] - $this->starts['pmu'] : 0; + } + + /** + * Starts the profiling. + */ + public function enter() + { + $this->starts = array( + 'wt' => microtime(true), + 'mu' => memory_get_usage(), + 'pmu' => memory_get_peak_usage(), + ); + } + + /** + * Stops the profiling. + */ + public function leave() + { + $this->ends = array( + 'wt' => microtime(true), + 'mu' => memory_get_usage(), + 'pmu' => memory_get_peak_usage(), + ); + } + + public function getIterator() + { + return new ArrayIterator($this->profiles); + } + + public function serialize() + { + return serialize(array($this->template, $this->name, $this->type, $this->starts, $this->ends, $this->profiles)); + } + + public function unserialize($data) + { + list($this->template, $this->name, $this->type, $this->starts, $this->ends, $this->profiles) = unserialize($data); + } +} diff --git a/inc/lib/Twig/Sandbox/SecurityNotAllowedFilterError.php b/inc/lib/Twig/Sandbox/SecurityNotAllowedFilterError.php new file mode 100644 index 00000000..99faba9d --- /dev/null +++ b/inc/lib/Twig/Sandbox/SecurityNotAllowedFilterError.php @@ -0,0 +1,31 @@ + + */ +class Twig_Sandbox_SecurityNotAllowedFilterError extends Twig_Sandbox_SecurityError +{ + private $filterName; + + public function __construct($message, $functionName, $lineno = -1, $filename = null, Exception $previous = null) + { + parent::__construct($message, $lineno, $filename, $previous); + $this->filterName = $functionName; + } + + public function getFilterName() + { + return $this->filterName; + } +} diff --git a/inc/lib/Twig/Sandbox/SecurityNotAllowedFunctionError.php b/inc/lib/Twig/Sandbox/SecurityNotAllowedFunctionError.php new file mode 100644 index 00000000..05cf488a --- /dev/null +++ b/inc/lib/Twig/Sandbox/SecurityNotAllowedFunctionError.php @@ -0,0 +1,31 @@ + + */ +class Twig_Sandbox_SecurityNotAllowedFunctionError extends Twig_Sandbox_SecurityError +{ + private $functionName; + + public function __construct($message, $functionName, $lineno = -1, $filename = null, Exception $previous = null) + { + parent::__construct($message, $lineno, $filename, $previous); + $this->functionName = $functionName; + } + + public function getFunctionName() + { + return $this->functionName; + } +} diff --git a/inc/lib/Twig/Sandbox/SecurityNotAllowedTagError.php b/inc/lib/Twig/Sandbox/SecurityNotAllowedTagError.php new file mode 100644 index 00000000..b3bb5e8e --- /dev/null +++ b/inc/lib/Twig/Sandbox/SecurityNotAllowedTagError.php @@ -0,0 +1,31 @@ + + */ +class Twig_Sandbox_SecurityNotAllowedTagError extends Twig_Sandbox_SecurityError +{ + private $tagName; + + public function __construct($message, $tagName, $lineno = -1, $filename = null, Exception $previous = null) + { + parent::__construct($message, $lineno, $filename, $previous); + $this->tagName = $tagName; + } + + public function getTagName() + { + return $this->tagName; + } +} diff --git a/inc/lib/Twig/Sandbox/SecurityPolicy.php b/inc/lib/Twig/Sandbox/SecurityPolicy.php index 66ee2332..c4dd03df 100644 --- a/inc/lib/Twig/Sandbox/SecurityPolicy.php +++ b/inc/lib/Twig/Sandbox/SecurityPolicy.php @@ -63,19 +63,19 @@ class Twig_Sandbox_SecurityPolicy implements Twig_Sandbox_SecurityPolicyInterfac { foreach ($tags as $tag) { if (!in_array($tag, $this->allowedTags)) { - throw new Twig_Sandbox_SecurityError(sprintf('Tag "%s" is not allowed.', $tag)); + throw new Twig_Sandbox_SecurityNotAllowedTagError(sprintf('Tag "%s" is not allowed.', $tag), $tag); } } foreach ($filters as $filter) { if (!in_array($filter, $this->allowedFilters)) { - throw new Twig_Sandbox_SecurityError(sprintf('Filter "%s" is not allowed.', $filter)); + throw new Twig_Sandbox_SecurityNotAllowedFilterError(sprintf('Filter "%s" is not allowed.', $filter), $filter); } } foreach ($functions as $function) { if (!in_array($function, $this->allowedFunctions)) { - throw new Twig_Sandbox_SecurityError(sprintf('Function "%s" is not allowed.', $function)); + throw new Twig_Sandbox_SecurityNotAllowedFunctionError(sprintf('Function "%s" is not allowed.', $function), $function); } } } diff --git a/inc/lib/Twig/Template.php b/inc/lib/Twig/Template.php index a42fab28..caf96428 100644 --- a/inc/lib/Twig/Template.php +++ b/inc/lib/Twig/Template.php @@ -20,11 +20,10 @@ abstract class Twig_Template implements Twig_TemplateInterface protected static $cache = array(); protected $parent; - protected $parents; + protected $parents = array(); protected $env; protected $blocks; protected $traits; - protected $macros; /** * Constructor. @@ -36,7 +35,6 @@ abstract class Twig_Template implements Twig_TemplateInterface $this->env = $env; $this->blocks = array(); $this->traits = array(); - $this->macros = array(); } /** @@ -68,15 +66,25 @@ abstract class Twig_Template implements Twig_TemplateInterface return $this->parent; } - $parent = $this->doGetParent($context); - if (false === $parent) { - return false; - } elseif ($parent instanceof Twig_Template) { - $name = $parent->getTemplateName(); - $this->parents[$name] = $parent; - $parent = $name; - } elseif (!isset($this->parents[$parent])) { - $this->parents[$parent] = $this->env->loadTemplate($parent); + try { + $parent = $this->doGetParent($context); + + if (false === $parent) { + return false; + } + + if ($parent instanceof Twig_Template) { + return $this->parents[$parent->getTemplateName()] = $parent; + } + + if (!isset($this->parents[$parent])) { + $this->parents[$parent] = $this->loadTemplate($parent); + } + } catch (Twig_Error_Loader $e) { + $e->setTemplateFile(null); + $e->guess(); + + throw $e; } return $this->parents[$parent]; @@ -107,9 +115,9 @@ abstract class Twig_Template implements Twig_TemplateInterface $name = (string) $name; if (isset($this->traits[$name])) { - $this->traits[$name][0]->displayBlock($name, $context, $blocks); + $this->traits[$name][0]->displayBlock($name, $context, $blocks, false); } elseif (false !== $parent = $this->getParent($context)) { - $parent->displayBlock($name, $context, $blocks); + $parent->displayBlock($name, $context, $blocks, false); } else { throw new Twig_Error_Runtime(sprintf('The template has no parent and no traits defining the "%s" block', $name), -1, $this->getTemplateName()); } @@ -121,22 +129,36 @@ abstract class Twig_Template implements Twig_TemplateInterface * This method is for internal use only and should never be called * directly. * - * @param string $name The block name to display - * @param array $context The context - * @param array $blocks The current set of blocks + * @param string $name The block name to display + * @param array $context The context + * @param array $blocks The current set of blocks + * @param bool $useBlocks Whether to use the current set of blocks */ - public function displayBlock($name, array $context, array $blocks = array()) + public function displayBlock($name, array $context, array $blocks = array(), $useBlocks = true) { $name = (string) $name; - if (isset($blocks[$name])) { - $b = $blocks; - unset($b[$name]); - call_user_func($blocks[$name], $context, $b); + if ($useBlocks && isset($blocks[$name])) { + $template = $blocks[$name][0]; + $block = $blocks[$name][1]; } elseif (isset($this->blocks[$name])) { - call_user_func($this->blocks[$name], $context, $blocks); + $template = $this->blocks[$name][0]; + $block = $this->blocks[$name][1]; + } else { + $template = null; + $block = null; + } + + if (null !== $template) { + try { + $template->$block($context, $blocks); + } catch (Twig_Error $e) { + throw $e; + } catch (Exception $e) { + throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $template->getTemplateName(), $e); + } } elseif (false !== $parent = $this->getParent($context)) { - $parent->displayBlock($name, $context, array_merge($this->blocks, $blocks)); + $parent->displayBlock($name, $context, array_merge($this->blocks, $blocks), false); } } @@ -166,16 +188,17 @@ abstract class Twig_Template implements Twig_TemplateInterface * This method is for internal use only and should never be called * directly. * - * @param string $name The block name to render - * @param array $context The context - * @param array $blocks The current set of blocks + * @param string $name The block name to render + * @param array $context The context + * @param array $blocks The current set of blocks + * @param bool $useBlocks Whether to use the current set of blocks * * @return string The rendered block */ - public function renderBlock($name, array $context, array $blocks = array()) + public function renderBlock($name, array $context, array $blocks = array(), $useBlocks = true) { ob_start(); - $this->displayBlock($name, $context, $blocks); + $this->displayBlock($name, $context, $blocks, $useBlocks); return ob_get_clean(); } @@ -195,7 +218,7 @@ abstract class Twig_Template implements Twig_TemplateInterface * * @param string $name The block name * - * @return Boolean true if the block exists, false otherwise + * @return bool true if the block exists, false otherwise */ public function hasBlock($name) { @@ -217,6 +240,30 @@ abstract class Twig_Template implements Twig_TemplateInterface return array_keys($this->blocks); } + protected function loadTemplate($template, $templateName = null, $line = null, $index = null) + { + try { + if (is_array($template)) { + return $this->env->resolveTemplate($template); + } + + if ($template instanceof Twig_Template) { + return $template; + } + + return $this->env->loadTemplate($template, $index); + } catch (Twig_Error $e) { + $e->setTemplateFile($templateName ? $templateName : $this->getTemplateName()); + if (!$line) { + $e->guess(); + } else { + $e->setTemplateLine($line); + } + + throw $e; + } + } + /** * Returns all blocks. * @@ -237,7 +284,7 @@ abstract class Twig_Template implements Twig_TemplateInterface */ public function display(array $context, array $blocks = array()) { - $this->displayWithErrorHandling($this->env->mergeGlobals($context), $blocks); + $this->displayWithErrorHandling($this->env->mergeGlobals($context), array_merge($this->blocks, $blocks)); } /** @@ -278,7 +325,7 @@ abstract class Twig_Template implements Twig_TemplateInterface throw $e; } catch (Exception $e) { - throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, null, $e); + throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $this->getTemplateName(), $e); } } @@ -301,9 +348,9 @@ abstract class Twig_Template implements Twig_TemplateInterface * access for versions of PHP before 5.4. This is not a way to override * the way to get a variable value. * - * @param array $context The context - * @param string $item The variable to return from the context - * @param Boolean $ignoreStrictCheck Whether to ignore the strict variable check or not + * @param array $context The context + * @param string $item The variable to return from the context + * @param bool $ignoreStrictCheck Whether to ignore the strict variable check or not * * @return The content of the context variable * @@ -313,7 +360,7 @@ abstract class Twig_Template implements Twig_TemplateInterface { if (!array_key_exists($item, $context)) { if ($ignoreStrictCheck || !$this->env->isStrictVariables()) { - return null; + return; } throw new Twig_Error_Runtime(sprintf('Variable "%s" does not exist', $item), -1, $this->getTemplateName()); @@ -325,12 +372,12 @@ abstract class Twig_Template implements Twig_TemplateInterface /** * Returns the attribute value for a given array/object. * - * @param mixed $object The object or array from where to get the item - * @param mixed $item The item to get from the array or object - * @param array $arguments An array of arguments to pass if the item is an object method - * @param string $type The type of attribute (@see Twig_Template constants) - * @param Boolean $isDefinedTest Whether this is only a defined check - * @param Boolean $ignoreStrictCheck Whether to ignore the strict attribute check or not + * @param mixed $object The object or array from where to get the item + * @param mixed $item The item to get from the array or object + * @param array $arguments An array of arguments to pass if the item is an object method + * @param string $type The type of attribute (@see Twig_Template constants) + * @param bool $isDefinedTest Whether this is only a defined check + * @param bool $ignoreStrictCheck Whether to ignore the strict attribute check or not * * @return mixed The attribute value, or a Boolean when $isDefinedTest is true, or null when the attribute is not set and $ignoreStrictCheck is true * @@ -358,18 +405,26 @@ abstract class Twig_Template implements Twig_TemplateInterface } if ($ignoreStrictCheck || !$this->env->isStrictVariables()) { - return null; + return; } - if (is_object($object)) { - throw new Twig_Error_Runtime(sprintf('Key "%s" in object (with ArrayAccess) of type "%s" does not exist', $arrayItem, get_class($object)), -1, $this->getTemplateName()); + if ($object instanceof ArrayAccess) { + $message = sprintf('Key "%s" in object with ArrayAccess of class "%s" does not exist', $arrayItem, get_class($object)); + } elseif (is_object($object)) { + $message = sprintf('Impossible to access a key "%s" on an object of class "%s" that does not implement ArrayAccess interface', $item, get_class($object)); } elseif (is_array($object)) { - throw new Twig_Error_Runtime(sprintf('Key "%s" for array with keys "%s" does not exist', $arrayItem, implode(', ', array_keys($object))), -1, $this->getTemplateName()); + if (empty($object)) { + $message = sprintf('Key "%s" does not exist as the array is empty', $arrayItem); + } else { + $message = sprintf('Key "%s" for array with keys "%s" does not exist', $arrayItem, implode(', ', array_keys($object))); + } } elseif (Twig_Template::ARRAY_CALL === $type) { - throw new Twig_Error_Runtime(sprintf('Impossible to access a key ("%s") on a %s variable ("%s")', $item, gettype($object), $object), -1, $this->getTemplateName()); + $message = sprintf('Impossible to access a key ("%s") on a %s variable ("%s")', $item, gettype($object), $object); } else { - throw new Twig_Error_Runtime(sprintf('Impossible to access an attribute ("%s") on a %s variable ("%s")', $item, gettype($object), $object), -1, $this->getTemplateName()); + $message = sprintf('Impossible to access an attribute ("%s") on a %s variable ("%s")', $item, gettype($object), $object); } + + throw new Twig_Error_Runtime($message, -1, $this->getTemplateName()); } } @@ -379,14 +434,12 @@ abstract class Twig_Template implements Twig_TemplateInterface } if ($ignoreStrictCheck || !$this->env->isStrictVariables()) { - return null; + return; } throw new Twig_Error_Runtime(sprintf('Impossible to invoke a method ("%s") on a %s variable ("%s")', $item, gettype($object), $object), -1, $this->getTemplateName()); } - $class = get_class($object); - // object property if (Twig_Template::METHOD_CALL !== $type) { if (isset($object->$item) || array_key_exists((string) $item, $object)) { @@ -402,11 +455,14 @@ abstract class Twig_Template implements Twig_TemplateInterface } } + $class = get_class($object); + // object method if (!isset(self::$cache[$class]['methods'])) { self::$cache[$class]['methods'] = array_change_key_case(array_flip(get_class_methods($object))); } + $call = false; $lcItem = strtolower($item); if (isset(self::$cache[$class]['methods'][$lcItem])) { $method = (string) $item; @@ -416,13 +472,14 @@ abstract class Twig_Template implements Twig_TemplateInterface $method = 'is'.$item; } elseif (isset(self::$cache[$class]['methods']['__call'])) { $method = (string) $item; + $call = true; } else { if ($isDefinedTest) { return false; } if ($ignoreStrictCheck || !$this->env->isStrictVariables()) { - return null; + return; } throw new Twig_Error_Runtime(sprintf('Method "%s" for object "%s" does not exist', $item, get_class($object)), -1, $this->getTemplateName()); @@ -436,7 +493,16 @@ abstract class Twig_Template implements Twig_TemplateInterface $this->env->getExtension('sandbox')->checkMethodAllowed($object, $method); } - $ret = call_user_func_array(array($object, $method), $arguments); + // Some objects throw exceptions when they have __call, and the method we try + // to call is not supported. If ignoreStrictCheck is true, we should return null. + try { + $ret = call_user_func_array(array($object, $method), $arguments); + } catch (BadMethodCallException $e) { + if ($call && ($ignoreStrictCheck || !$this->env->isStrictVariables())) { + return; + } + throw $e; + } // useful when calling a template method from a template // this is not supported but unfortunately heavily used in the Symfony profiler @@ -446,72 +512,4 @@ abstract class Twig_Template implements Twig_TemplateInterface return $ret; } - - /** - * Calls macro in a template. - * - * @param Twig_Template $template The template - * @param string $macro The name of macro - * @param array $arguments The arguments of macro - * @param array $namedNames An array of names of arguments as keys - * @param integer $namedCount The count of named arguments - * @param integer $positionalCount The count of positional arguments - * - * @return string The content of a macro - * - * @throws Twig_Error_Runtime if the macro is not defined - * @throws Twig_Error_Runtime if the argument is defined twice - * @throws Twig_Error_Runtime if the argument is unknown - */ - protected function callMacro(Twig_Template $template, $macro, array $arguments, array $namedNames = array(), $namedCount = 0, $positionalCount = -1) - { - if (!isset($template->macros[$macro]['reflection'])) { - if (!isset($template->macros[$macro])) { - throw new Twig_Error_Runtime(sprintf('Macro "%s" is not defined in the template "%s".', $macro, $template->getTemplateName())); - } - - $template->macros[$macro]['reflection'] = new ReflectionMethod($template, $template->macros[$macro]['method']); - } - - if ($namedCount < 1) { - return $template->macros[$macro]['reflection']->invokeArgs($template, $arguments); - } - - $i = 0; - $args = array(); - foreach ($template->macros[$macro]['arguments'] as $name => $value) { - if (isset($namedNames[$name])) { - if ($i < $positionalCount) { - throw new Twig_Error_Runtime(sprintf('Argument "%s" is defined twice for macro "%s" defined in the template "%s".', $name, $macro, $template->getTemplateName())); - } - - $args[] = $arguments[$name]; - if (--$namedCount < 1) { - break; - } - } elseif ($i < $positionalCount) { - $args[] = $arguments[$i]; - } else { - $args[] = $value; - } - - $i++; - } - - if ($namedCount > 0) { - $parameters = array_keys(array_diff_key($namedNames, $template->macros[$macro]['arguments'])); - - throw new Twig_Error_Runtime(sprintf('Unknown argument%s "%s" for macro "%s" defined in the template "%s".', count($parameters) > 1 ? 's' : '' , implode('", "', $parameters), $macro, $template->getTemplateName())); - } - - return $template->macros[$macro]['reflection']->invokeArgs($template, $args); - } - - /** - * This method is only useful when testing Twig. Do not use it. - */ - public static function clearCache() - { - self::$cache = array(); - } } diff --git a/inc/lib/Twig/TemplateInterface.php b/inc/lib/Twig/TemplateInterface.php index 879f503e..d178832e 100644 --- a/inc/lib/Twig/TemplateInterface.php +++ b/inc/lib/Twig/TemplateInterface.php @@ -13,7 +13,8 @@ * Interface implemented by all compiled templates. * * @author Fabien Potencier - * @deprecated since 1.12 (to be removed in 2.0) + * + * @deprecated since 1.12 (to be removed in 3.0) */ interface Twig_TemplateInterface { diff --git a/inc/lib/Twig/Test/IntegrationTestCase.php b/inc/lib/Twig/Test/IntegrationTestCase.php index 724f0941..b8bceb81 100644 --- a/inc/lib/Twig/Test/IntegrationTestCase.php +++ b/inc/lib/Twig/Test/IntegrationTestCase.php @@ -123,7 +123,7 @@ abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase if (false !== $exception) { list($class, ) = explode(':', $exception); - $this->assertThat(NULL, new PHPUnit_Framework_Constraint_Exception($class)); + $this->assertThat(null, new PHPUnit_Framework_Constraint_Exception($class)); } $expected = trim($match[3], "\n "); diff --git a/inc/lib/Twig/Test/NodeTestCase.php b/inc/lib/Twig/Test/NodeTestCase.php index b15c85ff..bf865211 100644 --- a/inc/lib/Twig/Test/NodeTestCase.php +++ b/inc/lib/Twig/Test/NodeTestCase.php @@ -38,13 +38,15 @@ abstract class Twig_Test_NodeTestCase extends PHPUnit_Framework_TestCase return new Twig_Environment(); } - protected function getVariableGetter($name) + protected function getVariableGetter($name, $line = false) { - if (version_compare(phpversion(), '5.4.0RC1', '>=')) { - return sprintf('(isset($context["%s"]) ? $context["%s"] : null)', $name, $name); + $line = $line > 0 ? "// line {$line}\n" : ''; + + if (PHP_VERSION_ID >= 50400) { + return sprintf('%s(isset($context["%s"]) ? $context["%s"] : null)', $line, $name, $name); } - return sprintf('$this->getContext($context, "%s")', $name); + return sprintf('%s$this->getContext($context, "%s")', $line, $name); } protected function getAttributeGetter() diff --git a/inc/lib/Twig/Token.php b/inc/lib/Twig/Token.php index bbca90db..15dd4eb6 100644 --- a/inc/lib/Twig/Token.php +++ b/inc/lib/Twig/Token.php @@ -38,9 +38,9 @@ class Twig_Token /** * Constructor. * - * @param integer $type The type of the token - * @param string $value The token value - * @param integer $lineno The line position in the source + * @param int $type The type of the token + * @param string $value The token value + * @param int $lineno The line position in the source */ public function __construct($type, $value, $lineno) { @@ -56,7 +56,7 @@ class Twig_Token */ public function __toString() { - return sprintf('%s(%s)', self::typeToString($this->type, true, $this->lineno), $this->value); + return sprintf('%s(%s)', self::typeToString($this->type, true), $this->value); } /** @@ -67,10 +67,10 @@ class Twig_Token * * type and value (or array of possible values) * * just value (or array of possible values) (NAME_TYPE is used as type) * - * @param array|integer $type The type to test + * @param array|int $type The type to test * @param array|string|null $values The token value * - * @return Boolean + * @return bool */ public function test($type, $values = null) { @@ -89,7 +89,7 @@ class Twig_Token /** * Gets the line. * - * @return integer The source line + * @return int The source line */ public function getLine() { @@ -99,7 +99,7 @@ class Twig_Token /** * Gets the token type. * - * @return integer The token type + * @return int The token type */ public function getType() { @@ -119,13 +119,12 @@ class Twig_Token /** * Returns the constant representation (internal) of a given type. * - * @param integer $type The type as an integer - * @param Boolean $short Whether to return a short representation or not - * @param integer $line The code line + * @param int $type The type as an integer + * @param bool $short Whether to return a short representation or not * * @return string The string representation */ - public static function typeToString($type, $short = false, $line = -1) + public static function typeToString($type, $short = false) { switch ($type) { case self::EOF_TYPE: @@ -177,12 +176,11 @@ class Twig_Token /** * Returns the english representation of a given type. * - * @param integer $type The type as an integer - * @param integer $line The code line + * @param int $type The type as an integer * * @return string The string representation */ - public static function typeToEnglish($type, $line = -1) + public static function typeToEnglish($type) { switch ($type) { case self::EOF_TYPE: diff --git a/inc/lib/Twig/TokenParser/Block.php b/inc/lib/Twig/TokenParser/Block.php index a2e017f3..81e6b1cf 100644 --- a/inc/lib/Twig/TokenParser/Block.php +++ b/inc/lib/Twig/TokenParser/Block.php @@ -41,12 +41,10 @@ class Twig_TokenParser_Block extends Twig_TokenParser $this->parser->pushLocalScope(); $this->parser->pushBlockStack($name); - if ($stream->test(Twig_Token::BLOCK_END_TYPE)) { - $stream->next(); - + if ($stream->nextIf(Twig_Token::BLOCK_END_TYPE)) { $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true); - if ($stream->test(Twig_Token::NAME_TYPE)) { - $value = $stream->next()->getValue(); + if ($token = $stream->nextIf(Twig_Token::NAME_TYPE)) { + $value = $token->getValue(); if ($value != $name) { throw new Twig_Error_Syntax(sprintf("Expected endblock for block '$name' (but %s given)", $value), $stream->getCurrent()->getLine(), $stream->getFilename()); diff --git a/inc/lib/Twig/TokenParser/For.php b/inc/lib/Twig/TokenParser/For.php index 98a6d079..5c07d639 100644 --- a/inc/lib/Twig/TokenParser/For.php +++ b/inc/lib/Twig/TokenParser/For.php @@ -39,8 +39,7 @@ class Twig_TokenParser_For extends Twig_TokenParser $seq = $this->parser->getExpressionParser()->parseExpression(); $ifexpr = null; - if ($stream->test(Twig_Token::NAME_TYPE, 'if')) { - $stream->next(); + if ($stream->nextIf(Twig_Token::NAME_TYPE, 'if')) { $ifexpr = $this->parser->getExpressionParser()->parseExpression(); } diff --git a/inc/lib/Twig/TokenParser/From.php b/inc/lib/Twig/TokenParser/From.php index ff6e5756..dd73f990 100644 --- a/inc/lib/Twig/TokenParser/From.php +++ b/inc/lib/Twig/TokenParser/From.php @@ -36,19 +36,15 @@ class Twig_TokenParser_From extends Twig_TokenParser $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); $alias = $name; - if ($stream->test('as')) { - $stream->next(); - + if ($stream->nextIf('as')) { $alias = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); } $targets[$name] = $alias; - if (!$stream->test(Twig_Token::PUNCTUATION_TYPE, ',')) { + if (!$stream->nextIf(Twig_Token::PUNCTUATION_TYPE, ',')) { break; } - - $stream->next(); } while (true); $stream->expect(Twig_Token::BLOCK_END_TYPE); @@ -56,7 +52,7 @@ class Twig_TokenParser_From extends Twig_TokenParser $node = new Twig_Node_Import($macro, new Twig_Node_Expression_AssignName($this->parser->getVarName(), $token->getLine()), $token->getLine(), $this->getTag()); foreach ($targets as $name => $alias) { - $this->parser->addImportedSymbol('macro', $alias, $name, $node->getNode('var')); + $this->parser->addImportedSymbol('function', $alias, 'get'.$name, $node->getNode('var')); } return $node; diff --git a/inc/lib/Twig/TokenParser/Include.php b/inc/lib/Twig/TokenParser/Include.php index 4a317868..9c3099a6 100644 --- a/inc/lib/Twig/TokenParser/Include.php +++ b/inc/lib/Twig/TokenParser/Include.php @@ -42,24 +42,19 @@ class Twig_TokenParser_Include extends Twig_TokenParser $stream = $this->parser->getStream(); $ignoreMissing = false; - if ($stream->test(Twig_Token::NAME_TYPE, 'ignore')) { - $stream->next(); + if ($stream->nextIf(Twig_Token::NAME_TYPE, 'ignore')) { $stream->expect(Twig_Token::NAME_TYPE, 'missing'); $ignoreMissing = true; } $variables = null; - if ($stream->test(Twig_Token::NAME_TYPE, 'with')) { - $stream->next(); - + if ($stream->nextIf(Twig_Token::NAME_TYPE, 'with')) { $variables = $this->parser->getExpressionParser()->parseExpression(); } $only = false; - if ($stream->test(Twig_Token::NAME_TYPE, 'only')) { - $stream->next(); - + if ($stream->nextIf(Twig_Token::NAME_TYPE, 'only')) { $only = true; } diff --git a/inc/lib/Twig/TokenParser/Macro.php b/inc/lib/Twig/TokenParser/Macro.php index 82b4fa6d..87a299d8 100644 --- a/inc/lib/Twig/TokenParser/Macro.php +++ b/inc/lib/Twig/TokenParser/Macro.php @@ -38,8 +38,8 @@ class Twig_TokenParser_Macro extends Twig_TokenParser $stream->expect(Twig_Token::BLOCK_END_TYPE); $this->parser->pushLocalScope(); $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true); - if ($stream->test(Twig_Token::NAME_TYPE)) { - $value = $stream->next()->getValue(); + if ($token = $stream->nextIf(Twig_Token::NAME_TYPE)) { + $value = $token->getValue(); if ($value != $name) { throw new Twig_Error_Syntax(sprintf("Expected endmacro for macro '$name' (but %s given)", $value), $stream->getCurrent()->getLine(), $stream->getFilename()); diff --git a/inc/lib/Twig/TokenParser/Set.php b/inc/lib/Twig/TokenParser/Set.php index 70e0b41b..84f7e94c 100644 --- a/inc/lib/Twig/TokenParser/Set.php +++ b/inc/lib/Twig/TokenParser/Set.php @@ -42,8 +42,7 @@ class Twig_TokenParser_Set extends Twig_TokenParser $names = $this->parser->getExpressionParser()->parseAssignmentExpression(); $capture = false; - if ($stream->test(Twig_Token::OPERATOR_TYPE, '=')) { - $stream->next(); + if ($stream->nextIf(Twig_Token::OPERATOR_TYPE, '=')) { $values = $this->parser->getExpressionParser()->parseMultitargetExpression(); $stream->expect(Twig_Token::BLOCK_END_TYPE); diff --git a/inc/lib/Twig/TokenParser/Use.php b/inc/lib/Twig/TokenParser/Use.php index bc0e09ef..3ea68b1a 100644 --- a/inc/lib/Twig/TokenParser/Use.php +++ b/inc/lib/Twig/TokenParser/Use.php @@ -42,26 +42,20 @@ class Twig_TokenParser_Use extends Twig_TokenParser } $targets = array(); - if ($stream->test('with')) { - $stream->next(); - + if ($stream->nextIf('with')) { do { $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); $alias = $name; - if ($stream->test('as')) { - $stream->next(); - + if ($stream->nextIf('as')) { $alias = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); } $targets[$name] = new Twig_Node_Expression_Constant($alias, -1); - if (!$stream->test(Twig_Token::PUNCTUATION_TYPE, ',')) { + if (!$stream->nextIf(Twig_Token::PUNCTUATION_TYPE, ',')) { break; } - - $stream->next(); } while (true); } diff --git a/inc/lib/Twig/TokenParserInterface.php b/inc/lib/Twig/TokenParserInterface.php index bbde7714..31e8d5d5 100644 --- a/inc/lib/Twig/TokenParserInterface.php +++ b/inc/lib/Twig/TokenParserInterface.php @@ -29,6 +29,8 @@ interface Twig_TokenParserInterface * @param Twig_Token $token A Twig_Token instance * * @return Twig_NodeInterface A Twig_NodeInterface instance + * + * @throws Twig_Error_Syntax */ public function parse(Twig_Token $token); diff --git a/inc/lib/Twig/TokenStream.php b/inc/lib/Twig/TokenStream.php index a78189f6..7e95a4f0 100644 --- a/inc/lib/Twig/TokenStream.php +++ b/inc/lib/Twig/TokenStream.php @@ -63,6 +63,18 @@ class Twig_TokenStream return $this->tokens[$this->current - 1]; } + /** + * Tests a token, sets the pointer to the next one and returns it or throws a syntax error. + * + * @return Twig_Token|null The next token if the condition is true, null otherwise + */ + public function nextIf($primary, $secondary = null) + { + if ($this->tokens[$this->current]->test($primary, $secondary)) { + return $this->next(); + } + } + /** * Tests a token and returns it or throws a syntax error. * @@ -75,8 +87,8 @@ class Twig_TokenStream $line = $token->getLine(); throw new Twig_Error_Syntax(sprintf('%sUnexpected token "%s" of value "%s" ("%s" expected%s)', $message ? $message.'. ' : '', - Twig_Token::typeToEnglish($token->getType(), $line), $token->getValue(), - Twig_Token::typeToEnglish($type, $line), $value ? sprintf(' with value "%s"', $value) : ''), + Twig_Token::typeToEnglish($token->getType()), $token->getValue(), + Twig_Token::typeToEnglish($type), $value ? sprintf(' with value "%s"', $value) : ''), $line, $this->filename ); @@ -89,7 +101,7 @@ class Twig_TokenStream /** * Looks at the next token. * - * @param integer $number + * @param int $number * * @return Twig_Token */ diff --git a/index.php b/index.php index 1aa350c6..5031df82 100644 --- a/index.php +++ b/index.php @@ -1,4 +1,7 @@ fetchAll(PDO::FETCH_ASSOC); -echo Element("8chan/index.html", array("config" => $config)); +$index = Element("8chan/index.html", array("config" => $config, "newsplus" => $newsplus)); +file_write('index.html', $index); diff --git a/js/ajax.js b/js/ajax.js index 11fac152..794e6a48 100644 --- a/js/ajax.js +++ b/js/ajax.js @@ -103,7 +103,7 @@ $(window).ready(function() { $(form).find('input[type="submit"]').val(submit_txt); $(form).find('input[type="submit"]').removeAttr('disabled'); $(form).find('input[name="subject"],input[name="file_url"],\ - textarea[name="body"],input[type="file"]').val('').change(); + textarea[name="body"],input[type="file"],input[name="embed"]').val('').change(); }, cache: false, contentType: false, diff --git a/js/mathjax/config/8chanTeX.js b/js/mathjax/config/8chanTeX.js new file mode 100644 index 00000000..d6c37d81 --- /dev/null +++ b/js/mathjax/config/8chanTeX.js @@ -0,0 +1,113 @@ +/* + * /MathJax/config/TeX-AMS-MML_SVG.js + * + * Copyright (c) 2010-2015 The MathJax Consortium + * + * Part of the MathJax library. + * See http://www.mathjax.org for details. + * + * Licensed under the Apache License, Version 2.0; + * you may not use this file except in compliance with the License. + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ + +MathJax.Ajax.Preloading( + "[MathJax]/jax/input/TeX/config.js", + "[MathJax]/jax/input/MathML/config.js", + "[MathJax]/jax/output/SVG/config.js", + "[MathJax]/jax/output/CommonHTML/config.js", + "[MathJax]/extensions/tex2jax.js", + "[MathJax]/extensions/mml2jax.js", + "[MathJax]/extensions/MathEvents.js", + "[MathJax]/extensions/MathZoom.js", + "[MathJax]/extensions/MathMenu.js", + "[MathJax]/jax/element/mml/jax.js", + "[MathJax]/extensions/toMathML.js", + "[MathJax]/extensions/TeX/noErrors.js", + "[MathJax]/extensions/TeX/noUndefined.js", + "[MathJax]/jax/input/TeX/jax.js", + "[MathJax]/extensions/TeX/AMSmath.js", + "[MathJax]/extensions/TeX/AMSsymbols.js", + "[MathJax]/jax/input/MathML/jax.js", + "[MathJax]/jax/output/CommonHTML/jax.js", + "[MathJax]/extensions/CHTML-preview.js" +); + +MathJax.Hub.Config({"v1.0-compatible":false}); + +MathJax.InputJax.TeX=MathJax.InputJax({id:"TeX",version:"2.5.0",directory:MathJax.InputJax.directory+"/TeX",extensionDir:MathJax.InputJax.extensionDir+"/TeX",config:{TagSide:"right",TagIndent:"0.8em",MultLineWidth:"85%",equationNumbers:{autoNumber:"none",formatNumber:function(a){return a},formatTag:function(a){return"("+a+")"},formatID:function(a){return"mjx-eqn-"+String(a).replace(/[:"'<>&]/g,"")},formatURL:function(a){return"#"+escape(a)},useLabelIds:true}}});MathJax.InputJax.TeX.Register("math/tex");MathJax.InputJax.TeX.loadComplete("config.js"); +MathJax.InputJax.MathML=MathJax.InputJax({id:"MathML",version:"2.5.0",directory:MathJax.InputJax.directory+"/MathML",extensionDir:MathJax.InputJax.extensionDir+"/MathML",entityDir:MathJax.InputJax.directory+"/MathML/entities",config:{useMathMLspacing:false}});MathJax.InputJax.MathML.Register("math/mml");MathJax.InputJax.MathML.loadComplete("config.js"); +MathJax.OutputJax.SVG=MathJax.OutputJax({id:"SVG",version:"2.5.0",directory:MathJax.OutputJax.directory+"/SVG",extensionDir:MathJax.OutputJax.extensionDir+"/SVG",autoloadDir:MathJax.OutputJax.directory+"/SVG/autoload",fontDir:MathJax.OutputJax.directory+"/SVG/fonts",config:{scale:100,minScaleAdjust:50,font:"TeX",blacker:10,mtextFontInherit:false,undefinedFamily:"STIXGeneral,'Arial Unicode MS',serif",addMMLclasses:false,useFontCache:true,useGlobalCache:true,EqnChunk:(MathJax.Hub.Browser.isMobile?10:50),EqnChunkFactor:1.5,EqnChunkDelay:100,linebreaks:{automatic:false,width:"container"},merrorStyle:{fontSize:"90%",color:"#C00",background:"#FF8",border:"1px solid #C00",padding:"3px"},styles:{".MathJax_SVG_Display":{"text-align":"center",margin:"1em 0em"},".MathJax_SVG .MJX-monospace":{"font-family":"monospace"},".MathJax_SVG .MJX-sans-serif":{"font-family":"sans-serif"},"#MathJax_SVG_Tooltip":{"background-color":"InfoBackground",color:"InfoText",border:"1px solid black","box-shadow":"2px 2px 5px #AAAAAA","-webkit-box-shadow":"2px 2px 5px #AAAAAA","-moz-box-shadow":"2px 2px 5px #AAAAAA","-khtml-box-shadow":"2px 2px 5px #AAAAAA",padding:"3px 4px","z-index":401}}}});if(!MathJax.Hub.config.delayJaxRegistration){MathJax.OutputJax.SVG.Register("jax/mml")}MathJax.OutputJax.SVG.loadComplete("config.js"); +MathJax.OutputJax.CommonHTML=MathJax.OutputJax({id:"CommonHTML",version:"2.5.0",directory:MathJax.OutputJax.directory+"/CommonHTML",extensionDir:MathJax.OutputJax.extensionDir+"/CommonHTML",config:{scale:100,minScaleAdjust:50,mtextFontInherit:false,linebreaks:{automatic:false,width:"container"}}});if(!MathJax.Hub.config.delayJaxRegistration){MathJax.OutputJax.CommonHTML.Register("jax/mml")}MathJax.OutputJax.CommonHTML.loadComplete("config.js"); +MathJax.Extension.tex2jax={version:"2.5.0",config:{inlineMath:[["\\(","\\)"]],displayMath:[["$$","$$"],["\\[","\\]"]],balanceBraces:true,skipTags:["script","noscript","style","textarea","pre","code","annotation","annotation-xml"],ignoreClass:"tex2jax_ignore",processClass:"tex2jax_process",processEscapes:false,processEnvironments:true,processRefs:true,preview:"TeX"},PreProcess:function(a){if(!this.configured){this.config=MathJax.Hub.CombineConfig("tex2jax",this.config);if(this.config.Augment){MathJax.Hub.Insert(this,this.config.Augment)}if(typeof(this.config.previewTeX)!=="undefined"&&!this.config.previewTeX){this.config.preview="none"}this.configured=true}if(typeof(a)==="string"){a=document.getElementById(a)}if(!a){a=document.body}if(this.createPatterns()){this.scanElement(a,a.nextSibling)}},createPatterns:function(){var d=[],e=[],c,a,b=this.config;this.match={};for(c=0,a=b.inlineMath.length;c0)},patternQuote:function(a){return a.replace(/([\^$(){}+*?\-|\[\]\:\\])/g,"\\$1")},endPattern:function(a){return new RegExp(this.patternQuote(a)+"|\\\\.|[{}]","g")},sortLength:function(d,c){if(d.length!==c.length){return c.length-d.length}return(d==c?0:(d/i,"").replace(/<\?xml:namespace .*?\/>/i,"");b=b.replace(/ /g," ")}MathJax.HTML.setScript(a,b);d.removeChild(e)}else{var c=MathJax.HTML.Element("span");c.appendChild(e);MathJax.HTML.setScript(a,c.innerHTML)}if(this.config.preview!=="none"){this.createPreview(e,a)}},ProcessMathFlattened:function(f){var d=f.parentNode;if(!d||d.className===MathJax.Hub.config.preRemoveClass){return}var b=document.createElement("script");b.type="math/mml";d.insertBefore(b,f);var c="",e,a=f;while(f&&f.nodeName!=="/MATH"){e=f;f=f.nextSibling;c+=this.NodeHTML(e);e.parentNode.removeChild(e)}if(f&&f.nodeName==="/MATH"){f.parentNode.removeChild(f)}b.text=c+"";if(this.config.preview!=="none"){this.createPreview(a,b)}},NodeHTML:function(e){var c,b,a;if(e.nodeName==="#text"){c=this.quoteHTML(e.nodeValue)}else{if(e.nodeName==="#comment"){c=""}else{c="<"+e.nodeName.toLowerCase();for(b=0,a=e.attributes.length;b";if(e.outerHTML!=null&&e.outerHTML.match(/(.<\/[A-Z]+>|\/>)$/)){for(b=0,a=e.childNodes.length;b"}}}return c},OuterHTML:function(d){if(d.nodeName.charAt(0)==="#"){return this.NodeHTML(d)}if(!this.AttributeBug){return d.outerHTML}var c=this.NodeHTML(d);for(var b=0,a=d.childNodes.length;b";return c},quoteHTML:function(a){if(a==null){a=""}return a.replace(/&/g,"&").replace(//g,">").replace(/\"/g,""")},createPreview:function(f,b){var g=this.config.preview;if(g==="none"){return}var a=false;if(g==="mathml"){a=true;if(this.MathTagBug){g="alttext"}else{g=f.cloneNode(true)}}if(g==="alttext"||g==="altimg"){a=true;var c=this.filterPreview(f.getAttribute("alttext"));if(g==="alttext"){if(c!=null){g=MathJax.HTML.TextNode(c)}else{g=null}}else{var h=f.getAttribute("altimg");if(h!=null){var e={width:f.getAttribute("altimg-width"),height:f.getAttribute("altimg-height")};g=MathJax.HTML.Element("img",{src:h,alt:c,style:e})}else{g=null}}}if(g){var d;if(a){d=MathJax.HTML.Element("span",{className:MathJax.Hub.config.preRemoveClass});d.appendChild(g)}else{d=MathJax.HTML.Element("span",{className:MathJax.Hub.config.preRemoveClass},g)}b.parentNode.insertBefore(d,b)}},filterPreview:function(a){return a},InitBrowser:function(){var b=MathJax.HTML.Element("span",{id:"<",className:"mathjax",innerHTML:"x"});var a=b.outerHTML||"";this.AttributeBug=a!==""&&!(a.match(/id="<"/)&&a.match(/class="mathjax"/)&&a.match(/<\/math>/));this.MathTagBug=b.childNodes.length>1;this.CleanupHTML=MathJax.Hub.Browser.isMSIE}};MathJax.Hub.Register.PreProcessor(["PreProcess",MathJax.Extension.mml2jax],5);MathJax.Ajax.loadComplete("[MathJax]/extensions/mml2jax.js"); +(function(d,h,l,g,m,b,j){var q="2.5.0";var i=MathJax.Extension;var c=i.MathEvents={version:q};var k=d.config.menuSettings;var p={hover:500,frame:{x:3.5,y:5,bwidth:1,bcolor:"#A6D",hwidth:"15px",hcolor:"#83A"},button:{x:-4,y:-3,wx:-2,src:l.urlRev(b.imageDir+"/MenuArrow-15.png")},fadeinInc:0.2,fadeoutInc:0.05,fadeDelay:50,fadeoutStart:400,fadeoutDelay:15*1000,styles:{".MathJax_Hover_Frame":{"border-radius":".25em","-webkit-border-radius":".25em","-moz-border-radius":".25em","-khtml-border-radius":".25em","box-shadow":"0px 0px 15px #83A","-webkit-box-shadow":"0px 0px 15px #83A","-moz-box-shadow":"0px 0px 15px #83A","-khtml-box-shadow":"0px 0px 15px #83A",border:"1px solid #A6D ! important",display:"inline-block",position:"absolute"},".MathJax_Hover_Arrow":{position:"absolute",width:"15px",height:"11px",cursor:"pointer"}}};var n=c.Event={LEFTBUTTON:0,RIGHTBUTTON:2,MENUKEY:"altKey",Mousedown:function(r){return n.Handler(r,"Mousedown",this)},Mouseup:function(r){return n.Handler(r,"Mouseup",this)},Mousemove:function(r){return n.Handler(r,"Mousemove",this)},Mouseover:function(r){return n.Handler(r,"Mouseover",this)},Mouseout:function(r){return n.Handler(r,"Mouseout",this)},Click:function(r){return n.Handler(r,"Click",this)},DblClick:function(r){return n.Handler(r,"DblClick",this)},Menu:function(r){return n.Handler(r,"ContextMenu",this)},Handler:function(u,s,t){if(l.loadingMathMenu){return n.False(u)}var r=b[t.jaxID];if(!u){u=window.event}u.isContextMenu=(s==="ContextMenu");if(r[s]){return r[s](u,t)}if(i.MathZoom){return i.MathZoom.HandleEvent(u,s,t)}},False:function(r){if(!r){r=window.event}if(r){if(r.preventDefault){r.preventDefault()}else{r.returnValue=false}if(r.stopPropagation){r.stopPropagation()}r.cancelBubble=true}return false},ContextMenu:function(u,F,x){var C=b[F.jaxID],w=C.getJaxFromMath(F);var G=(C.config.showMathMenu!=null?C:d).config.showMathMenu;if(!G||(k.context!=="MathJax"&&!x)){return}if(c.msieEventBug){u=window.event||u}n.ClearSelection();f.ClearHoverTimer();if(w.hover){if(w.hover.remove){clearTimeout(w.hover.remove);delete w.hover.remove}w.hover.nofade=true}var v=MathJax.Menu;var H,E;if(v){if(v.loadingDomain){return n.False(u)}H=m.loadDomain("MathMenu");if(!H){v.jax=w;var s=v.menu.Find("Show Math As").menu;s.items[0].name=w.sourceMenuTitle;s.items[0].format=(w.sourceMenuFormat||"MathML");s.items[1].name=j[w.inputJax].sourceMenuTitle;s.items[5].disabled=!j[w.inputJax].annotationEncoding;var B=s.items[2];B.disabled=true;var r=B.menu.items;annotationList=MathJax.Hub.Config.semanticsAnnotations;for(var A=0,z=r.length;A0){this.HoverFadeTimer(r,r.hover.inc);return}t.parentNode.removeChild(t);if(s){s.parentNode.removeChild(s)}if(r.hover.remove){clearTimeout(r.hover.remove)}delete r.hover},HoverFadeTimer:function(r,t,s){r.hover.inc=t;if(!r.hover.timer){r.hover.timer=setTimeout(g(["HoverFade",this,r]),(s||p.fadeDelay))}},HoverMenu:function(r){if(!r){r=window.event}return b[this.jax].ContextMenu(r,this.math,true)},ClearHover:function(r){if(r.hover.remove){clearTimeout(r.hover.remove)}if(r.hover.timer){clearTimeout(r.hover.timer)}f.ClearHoverTimer();delete r.hover},Px:function(r){if(Math.abs(r)<0.006){return"0px"}return r.toFixed(2).replace(/\.?0+$/,"")+"px"},getImages:function(){if(k.discoverable){var r=new Image();r.src=p.button.src}}};var a=c.Touch={last:0,delay:500,start:function(s){var r=new Date().getTime();var t=(r-a.lastt){z.style.height=t+"px";z.style.width=(x.zW+this.scrollSize)+"px"}if(z.offsetWidth>l){z.style.width=l+"px";z.style.height=(x.zH+this.scrollSize)+"px"}}if(this.operaPositionBug){z.style.width=Math.min(l,x.zW)+"px"}if(z.offsetWidth>m&&z.offsetWidth-m=9);h.msiePositionBug=!m;h.msieSizeBug=l.versionAtLeast("7.0")&&(!document.documentMode||n===7||n===8);h.msieZIndexBug=(n<=7);h.msieInlineBlockAlignBug=(n<=7);h.msieTrapEventBug=!window.addEventListener;if(document.compatMode==="BackCompat"){h.scrollSize=52}if(m){delete i.styles["#MathJax_Zoom"].filter}},Opera:function(l){h.operaPositionBug=true;h.operaRefreshBug=true}});h.topImg=(h.msieInlineBlockAlignBug?d.Element("img",{style:{width:0,height:0,position:"relative"},src:"about:blank"}):d.Element("span",{style:{width:0,height:0,display:"inline-block"}}));if(h.operaPositionBug||h.msieTopBug){h.topImg.style.border="1px solid"}MathJax.Callback.Queue(["StartupHook",MathJax.Hub.Register,"Begin Styles",{}],["Styles",f,i.styles],["Post",a.Startup.signal,"MathZoom Ready"],["loadComplete",f,"[MathJax]/extensions/MathZoom.js"])})(MathJax.Hub,MathJax.HTML,MathJax.Ajax,MathJax.OutputJax["HTML-CSS"],MathJax.OutputJax.NativeMML); +(function(c,g,k,f,b){var q="2.5.0";var j=MathJax.Callback.Signal("menu");MathJax.Extension.MathMenu={version:q,signal:j};var o=function(r){return MathJax.Localization._.apply(MathJax.Localization,[["MathMenu",r]].concat([].slice.call(arguments,1)))};var n=c.Browser.isPC,l=c.Browser.isMSIE,e=((document.documentMode||0)>8);var i=(n?null:"5px");var p=c.CombineConfig("MathMenu",{delay:150,closeImg:k.urlRev(b.imageDir+"/CloseX-31.png"),showRenderer:true,showMathPlayer:true,showFontMenu:false,showContext:false,showDiscoverable:false,showLocale:true,showLocaleURL:false,semanticsAnnotations:{TeX:["TeX","LaTeX","application/x-tex"],StarMath:["StarMath 5.0"],Maple:["Maple"],ContentMathML:["MathML-Content","application/mathml-content+xml"],OpenMath:["OpenMath"]},windowSettings:{status:"no",toolbar:"no",locationbar:"no",menubar:"no",directories:"no",personalbar:"no",resizable:"yes",scrollbars:"yes",width:400,height:300,left:Math.round((screen.width-400)/2),top:Math.round((screen.height-300)/3)},styles:{"#MathJax_About":{position:"fixed",left:"50%",width:"auto","text-align":"center",border:"3px outset",padding:"1em 2em","background-color":"#DDDDDD",color:"black",cursor:"default","font-family":"message-box","font-size":"120%","font-style":"normal","text-indent":0,"text-transform":"none","line-height":"normal","letter-spacing":"normal","word-spacing":"normal","word-wrap":"normal","white-space":"nowrap","float":"none","z-index":201,"border-radius":"15px","-webkit-border-radius":"15px","-moz-border-radius":"15px","-khtml-border-radius":"15px","box-shadow":"0px 10px 20px #808080","-webkit-box-shadow":"0px 10px 20px #808080","-moz-box-shadow":"0px 10px 20px #808080","-khtml-box-shadow":"0px 10px 20px #808080",filter:"progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color='gray', Positive='true')"},".MathJax_Menu":{position:"absolute","background-color":"white",color:"black",width:"auto",padding:(n?"2px":"5px 0px"),border:"1px solid #CCCCCC",margin:0,cursor:"default",font:"menu","text-align":"left","text-indent":0,"text-transform":"none","line-height":"normal","letter-spacing":"normal","word-spacing":"normal","word-wrap":"normal","white-space":"nowrap","float":"none","z-index":201,"border-radius":i,"-webkit-border-radius":i,"-moz-border-radius":i,"-khtml-border-radius":i,"box-shadow":"0px 10px 20px #808080","-webkit-box-shadow":"0px 10px 20px #808080","-moz-box-shadow":"0px 10px 20px #808080","-khtml-box-shadow":"0px 10px 20px #808080",filter:"progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color='gray', Positive='true')"},".MathJax_MenuItem":{padding:(n?"2px 2em":"1px 2em"),background:"transparent"},".MathJax_MenuArrow":{position:"absolute",right:".5em",color:"#666666","font-family":(l?"'Arial unicode MS'":null)},".MathJax_MenuActive .MathJax_MenuArrow":{color:"white"},".MathJax_MenuArrow.RTL":{left:".5em",right:"auto"},".MathJax_MenuCheck":{position:"absolute",left:".7em","font-family":(l?"'Arial unicode MS'":null)},".MathJax_MenuCheck.RTL":{right:".7em",left:"auto"},".MathJax_MenuRadioCheck":{position:"absolute",left:(n?"1em":".7em")},".MathJax_MenuRadioCheck.RTL":{right:(n?"1em":".7em"),left:"auto"},".MathJax_MenuLabel":{padding:(n?"2px 2em 4px 1.33em":"1px 2em 3px 1.33em"),"font-style":"italic"},".MathJax_MenuRule":{"border-top":(n?"1px solid #CCCCCC":"1px solid #DDDDDD"),margin:(n?"4px 1px 0px":"4px 3px")},".MathJax_MenuDisabled":{color:"GrayText"},".MathJax_MenuActive":{"background-color":(n?"Highlight":"#606872"),color:(n?"HighlightText":"white")},".MathJax_Menu_Close":{position:"absolute",width:"31px",height:"31px",top:"-15px",left:"-15px"}}});var h,d;c.Register.StartupHook("MathEvents Ready",function(){h=MathJax.Extension.MathEvents.Event.False;d=MathJax.Extension.MathEvents.Hover});var a=MathJax.Menu=MathJax.Object.Subclass({version:q,items:[],posted:false,title:null,margin:5,Init:function(r){this.items=[].slice.call(arguments,0)},With:function(r){if(r){c.Insert(this,r)}return this},Post:function(s,C,A){if(!s){s=window.event}var r=document.getElementById("MathJax_MenuFrame");if(!r){r=a.Background(this);delete m.lastItem;delete m.lastMenu;delete a.skipUp;j.Post(["post",a.jax]);a.isRTL=(MathJax.Localization.fontDirection()==="rtl")}var t=g.Element("div",{onmouseup:a.Mouseup,ondblclick:h,ondragstart:h,onselectstart:h,oncontextmenu:h,menuItem:this,className:"MathJax_Menu"});if(!A){MathJax.Localization.setCSS(t)}for(var v=0,u=this.items.length;vdocument.body.offsetWidth-this.margin){B=document.body.offsetWidth-t.offsetWidth-this.margin}if(a.isMobile){B=Math.max(5,B-Math.floor(t.offsetWidth/2));z-=20}a.skipUp=s.isContextMenu}else{var w="left",D=C.offsetWidth;B=(a.isMobile?30:D-2);z=0;while(C&&C!==r){B+=C.offsetLeft;z+=C.offsetTop;C=C.parentNode}if(!a.isMobile){if((a.isRTL&&B-D-t.offsetWidth>this.margin)||(!a.isRTL&&B+t.offsetWidth>document.body.offsetWidth-this.margin)){w="right";B=Math.max(this.margin,B-D-t.offsetWidth+6)}}if(!n){t.style["borderRadiusTop"+w]=0;t.style["WebkitBorderRadiusTop"+w]=0;t.style["MozBorderRadiusTop"+w]=0;t.style["KhtmlBorderRadiusTop"+w]=0}}t.style.left=B+"px";t.style.top=z+"px";if(document.selection&&document.selection.empty){document.selection.empty()}return h(s)},Remove:function(r,s){j.Post(["unpost",a.jax]);var t=document.getElementById("MathJax_MenuFrame");if(t){t.parentNode.removeChild(t);if(this.msieFixedPositionBug){detachEvent("onresize",a.Resize)}}if(a.jax.hover){delete a.jax.hover.nofade;d.UnHover(a.jax)}return h(r)},Find:function(r){return this.FindN(1,r,[].slice.call(arguments,1))},FindId:function(r){return this.FindN(0,r,[].slice.call(arguments,1))},FindN:function(v,s,u){for(var t=0,r=this.items.length;t=0&&x.parentNode.menuItem!==w[r].menuItem){w[r].menuItem.posted=false;w[r].parentNode.removeChild(w[r]);r--}if(this.Timer&&!a.isMobile){this.Timer(v,x)}}},Mouseout:function(r,s){if(!this.menu||!this.menu.posted){this.Deactivate(s)}if(this.timer){clearTimeout(this.timer);delete this.timer}},Mouseup:function(r,s){return this.Remove(r,s)},Touchstart:function(r,s){return this.TouchEvent(r,s,"Mousedown")},Touchend:function(r,s){return this.TouchEvent(r,s,"Mouseup")},TouchEvent:function(s,t,r){if(this!==m.lastItem){if(m.lastMenu){a.Event(s,m.lastMenu,"Mouseout")}a.Event(s,t,"Mouseover",true);m.lastItem=this;m.lastMenu=t}if(this.nativeTouch){return null}a.Event(s,t,r);return false},Remove:function(r,s){s=s.parentNode.menuItem;return s.Remove(r,s)},Activate:function(r){this.Deactivate(r);r.className+=" MathJax_MenuActive"},Deactivate:function(r){r.className=r.className.replace(/ MathJax_MenuActive/,"")},With:function(r){if(r){c.Insert(this,r)}return this},isRTL:function(){return a.isRTL},rtlClass:function(){return(this.isRTL()?" RTL":"")}});a.ITEM.COMMAND=a.ITEM.Subclass({action:function(){},Init:function(r,t,s){if(!(r instanceof Array)){r=[r,r]}this.name=r;this.action=t;this.With(s)},Label:function(r,s){return[this.Name()]},Mouseup:function(r,s){if(!this.disabled){this.Remove(r,s);j.Post(["command",this]);this.action.call(this,r)}return h(r)}});a.ITEM.SUBMENU=a.ITEM.Subclass({menu:null,marker:(n&&!c.Browser.isSafari?"\u25B6":"\u25B8"),markerRTL:(n&&!c.Browser.isSafari?"\u25B0":"\u25C2"),Init:function(r,t){if(!(r instanceof Array)){r=[r,r]}this.name=r;var s=1;if(!(t instanceof a.ITEM)){this.With(t),s++}this.menu=a.apply(a,[].slice.call(arguments,s))},Label:function(r,s){this.menu.posted=false;return[this.Name()+" ",["span",{className:"MathJax_MenuArrow"+this.rtlClass()},[this.isRTL()?this.markerRTL:this.marker]]]},Timer:function(r,s){if(this.timer){clearTimeout(this.timer)}r={clientX:r.clientX,clientY:r.clientY};this.timer=setTimeout(f(["Mouseup",this,r,s]),p.delay)},Touchend:function(s,u){var t=this.menu.posted;var r=this.SUPER(arguments).Touchend.apply(this,arguments);if(t){this.Deactivate(u);delete m.lastItem;delete m.lastMenu}return r},Mouseup:function(s,u){if(!this.disabled){if(!this.menu.posted){if(this.timer){clearTimeout(this.timer);delete this.timer}this.menu.Post(s,u,this.ltr)}else{var t=document.getElementById("MathJax_MenuFrame").childNodes,r=t.length-1;while(r>=0){var v=t[r];v.menuItem.posted=false;v.parentNode.removeChild(v);if(v.menuItem===this.menu){break}r--}}}return h(s)}});a.ITEM.RADIO=a.ITEM.Subclass({variable:null,marker:(n?"\u25CF":"\u2713"),Init:function(s,r,t){if(!(s instanceof Array)){s=[s,s]}this.name=s;this.variable=r;this.With(t);if(this.value==null){this.value=this.name[0]}},Label:function(s,t){var r={className:"MathJax_MenuRadioCheck"+this.rtlClass()};if(p.settings[this.variable]!==this.value){r={style:{display:"none"}}}return[["span",r,[this.marker]]," "+this.Name()]},Mouseup:function(u,v){if(!this.disabled){var w=v.parentNode.childNodes;for(var s=0,r=w.length;s/g,">");var u=o("EqSource","MathJax Equation Source");if(a.isMobile){r.document.open();r.document.write(""+u+"");r.document.write("
    "+v+"
    ");r.document.write("
    ");r.document.write("");r.document.close()}else{r.document.open();r.document.write(""+u+"");r.document.write("
    "+v+"
    ");r.document.write("");r.document.close();var s=r.document.body.firstChild;setTimeout(function(){var A=(r.outerHeight-r.innerHeight)||30,z=(r.outerWidth-r.innerWidth)||30,w,D;z=Math.max(100,Math.min(Math.floor(0.5*screen.width),s.offsetWidth+z+25));A=Math.max(40,Math.min(Math.floor(0.5*screen.height),s.offsetHeight+A+25));if(a.prototype.msieHeightBug){A+=35}r.resizeTo(z,A);var C;try{C=t.screenX}catch(B){}if(t&&C!=null){w=Math.max(0,Math.min(t.screenX-Math.floor(z/2),screen.width-z-20));D=Math.max(0,Math.min(t.screenY-Math.floor(A/2),screen.height-A-20));r.moveTo(w,D)}},50)}};a.Scale=function(){var s=b["HTML-CSS"],r=b.NativeMML,v=b.SVG;var u=(s||r||v||{config:{scale:100}}).config.scale;var t=prompt(o("ScaleMath","Scale all mathematics (compared to surrounding text) by"),u+"%");if(t){if(t.match(/^\s*\d+(\.\d*)?\s*%?\s*$/)){t=parseFloat(t);if(t){if(t!==u){if(s){s.config.scale=t}if(r){r.config.scale=t}if(v){v.config.scale=t}a.cookie.scale=t;a.saveCookie();c.Rerender()}}else{alert(o("NonZeroScale","The scale should not be zero"))}}else{alert(o("PercentScale","The scale should be a percentage (e.g., 120%%)"))}}};a.Zoom=function(){if(!MathJax.Extension.MathZoom){k.Require("[MathJax]/extensions/MathZoom.js")}};a.Renderer=function(){var s=c.outputJax["jax/mml"];if(s[0]!==p.settings.renderer){var v=c.Browser,u,r=a.Renderer.Messages,t;switch(p.settings.renderer){case"NativeMML":if(!p.settings.warnedMML){if(v.isChrome&&v.version.substr(0,3)!=="24."){u=r.MML.WebKit}else{if(v.isSafari&&!v.versionAtLeast("5.0")){u=r.MML.WebKit}else{if(v.isMSIE){if(!v.hasMathPlayer){u=r.MML.MSIE}}else{u=r.MML[v]}}}t="warnedMML"}break;case"SVG":if(!p.settings.warnedSVG){if(v.isMSIE&&!e){u=r.SVG.MSIE}}break}if(u){u=o(u[0],u[1]);u+="\n\n";u+=o("SwitchAnyway","Switch the renderer anyway?\n\n(Press OK to switch, CANCEL to continue with the current renderer)");a.cookie.renderer=s[0].id;a.saveCookie();if(!confirm(u)){a.cookie.renderer=p.settings.renderer=g.Cookie.Get("menu").renderer;a.saveCookie();return}if(t){a.cookie.warned=p.settings.warned=true}a.cookie.renderer=p.settings.renderer;a.saveCookie()}c.Queue(["setRenderer",c,p.settings.renderer,"jax/mml"],["Rerender",c])}};a.Renderer.Messages={MML:{WebKit:["WebkitNativeMMLWarning","Your browser doesn't seem to support MathML natively, so switching to MathML output may cause the mathematics on the page to become unreadable."],MSIE:["MSIENativeMMLWarning","Internet Explorer requires the MathPlayer plugin in order to process MathML output."],Opera:["OperaNativeMMLWarning","Opera's support for MathML is limited, so switching to MathML output may cause some expressions to render poorly."],Safari:["SafariNativeMMLWarning","Your browser's native MathML does not implement all the features used by MathJax, so some expressions may not render properly."],Firefox:["FirefoxNativeMMLWarning","Your browser's native MathML does not implement all the features used by MathJax, so some expressions may not render properly."]},SVG:{MSIE:["MSIESVGWarning","SVG is not implemented in Internet Explorer prior to IE9 or when it is emulating IE8 or below. Switching to SVG output will cause the mathematics to not display properly."]}};a.Font=function(){var r=b["HTML-CSS"];if(!r){return}document.location.reload()};a.Locale=function(){MathJax.Localization.setLocale(p.settings.locale);MathJax.Hub.Queue(["Reprocess",MathJax.Hub])};a.LoadLocale=function(){var r=prompt(o("LoadURL","Load translation data from this URL:"));if(r){if(!r.match(/\.js$/)){alert(o("BadURL","The URL should be for a javascript file that defines MathJax translation data. Javascript file names should end with '.js'"))}k.Require(r,function(s){if(s!=k.STATUS.OK){alert(o("BadData","Failed to load translation data from %1",r))}})}};a.MPEvents=function(t){var s=p.settings.discoverable,r=a.MPEvents.Messages;if(!e){if(p.settings.mpMouse&&!confirm(o.apply(o,r.IE8warning))){delete a.cookie.mpContext;delete p.settings.mpContext;delete a.cookie.mpMouse;delete p.settings.mpMouse;a.saveCookie();return}p.settings.mpContext=p.settings.mpMouse;a.cookie.mpContext=a.cookie.mpMouse=p.settings.mpMouse;a.saveCookie();MathJax.Hub.Queue(["Rerender",MathJax.Hub])}else{if(!s&&t.name[1]==="Menu Events"&&p.settings.mpContext){alert(o.apply(o,r.IE9warning))}}};a.MPEvents.Messages={IE8warning:["IE8warning","This will disable the MathJax menu and zoom features, but you can Alt-Click on an expression to obtain the MathJax menu instead.\n\nReally change the MathPlayer settings?"],IE9warning:["IE9warning","The MathJax contextual menu will be disabled, but you can Alt-Click on an expression to obtain the MathJax menu instead."]};c.Browser.Select({MSIE:function(r){var s=(document.compatMode==="BackCompat");var t=r.versionAtLeast("8.0")&&document.documentMode>7;a.Augment({margin:20,msieBackgroundBug:((document.documentMode||0)<9),msieFixedPositionBug:(s||!t),msieAboutBug:s,msieHeightBug:((document.documentMode||0)<9)});if(e){delete p.styles["#MathJax_About"].filter;delete p.styles[".MathJax_Menu"].filter}},Firefox:function(r){a.skipMouseover=r.isMobile&&r.versionAtLeast("6.0");a.skipMousedown=r.isMobile}});a.isMobile=c.Browser.isMobile;a.noContextMenu=c.Browser.noContextMenu;a.CreateLocaleMenu=function(){if(!a.menu){return}var w=a.menu.Find("Language").menu,t=w.items;var s=[],y=MathJax.Localization.strings;for(var x in y){if(y.hasOwnProperty(x)){s.push(x)}}s=s.sort();w.items=[];for(var u=0,r=s.length;u0&&this.Get("scriptlevel")>0&&g>=0){return""}return this.TEXSPACELENGTH[Math.abs(g)]},TEXSPACELENGTH:["",a.LENGTH.THINMATHSPACE,a.LENGTH.MEDIUMMATHSPACE,a.LENGTH.THICKMATHSPACE],TEXSPACE:[[0,-1,2,3,0,0,0,1],[-1,-1,0,3,0,0,0,1],[2,2,0,0,2,0,0,2],[3,3,0,0,3,0,0,3],[0,0,0,0,0,0,0,0],[0,-1,2,3,0,0,0,1],[1,1,0,1,1,1,1,1],[1,-1,2,3,1,0,1,1]],autoDefault:function(e){return""},isSpacelike:function(){return false},isEmbellished:function(){return false},Core:function(){return this},CoreMO:function(){return this},hasNewline:function(){if(this.isEmbellished()){return this.CoreMO().hasNewline()}if(this.isToken||this.linebreakContainer){return false}for(var f=0,e=this.data.length;f=55296&&e.charCodeAt(0)<56320)?a.VARIANT.ITALIC:a.VARIANT.NORMAL)}return""},setTeXclass:function(f){this.getPrevClass(f);var e=this.data.join("");if(e.length>1&&e.match(/^[a-z][a-z0-9]*$/i)&&this.texClass===a.TEXCLASS.ORD){this.texClass=a.TEXCLASS.OP;this.autoOP=true}return this}});a.mn=a.mbase.Subclass({type:"mn",isToken:true,texClass:a.TEXCLASS.ORD,defaults:{mathvariant:a.INHERIT,mathsize:a.INHERIT,mathbackground:a.INHERIT,mathcolor:a.INHERIT,dir:a.INHERIT}});a.mo=a.mbase.Subclass({type:"mo",isToken:true,defaults:{mathvariant:a.INHERIT,mathsize:a.INHERIT,mathbackground:a.INHERIT,mathcolor:a.INHERIT,dir:a.INHERIT,form:a.AUTO,fence:a.AUTO,separator:a.AUTO,lspace:a.AUTO,rspace:a.AUTO,stretchy:a.AUTO,symmetric:a.AUTO,maxsize:a.AUTO,minsize:a.AUTO,largeop:a.AUTO,movablelimits:a.AUTO,accent:a.AUTO,linebreak:a.LINEBREAK.AUTO,lineleading:a.INHERIT,linebreakstyle:a.AUTO,linebreakmultchar:a.INHERIT,indentalign:a.INHERIT,indentshift:a.INHERIT,indenttarget:a.INHERIT,indentalignfirst:a.INHERIT,indentshiftfirst:a.INHERIT,indentalignlast:a.INHERIT,indentshiftlast:a.INHERIT,texClass:a.AUTO},defaultDef:{form:a.FORM.INFIX,fence:false,separator:false,lspace:a.LENGTH.THICKMATHSPACE,rspace:a.LENGTH.THICKMATHSPACE,stretchy:false,symmetric:false,maxsize:a.SIZE.INFINITY,minsize:"0em",largeop:false,movablelimits:false,accent:false,linebreak:a.LINEBREAK.AUTO,lineleading:"1ex",linebreakstyle:"before",indentalign:a.INDENTALIGN.AUTO,indentshift:"0",indenttarget:"",indentalignfirst:a.INDENTALIGN.INDENTALIGN,indentshiftfirst:a.INDENTSHIFT.INDENTSHIFT,indentalignlast:a.INDENTALIGN.INDENTALIGN,indentshiftlast:a.INDENTSHIFT.INDENTSHIFT,texClass:a.TEXCLASS.REL},SPACE_ATTR:{lspace:1,rspace:2,form:4},useMMLspacing:7,autoDefault:function(g,n){var l=this.def;if(!l){if(g==="form"){this.useMMLspacing&=~this.SPACE_ATTR.form;return this.getForm()}var k=this.data.join("");var f=[this.Get("form"),a.FORM.INFIX,a.FORM.POSTFIX,a.FORM.PREFIX];for(var h=0,e=f.length;h=55296&&k<56320){k=(((k-55296)<<10)+(j.charCodeAt(1)-56320))+65536}for(var g=0,e=this.RANGES.length;g=0;e--){if(this.data[0]&&!this.data[e].isSpacelike()){return this.data[e]}}return null},Core:function(){if(!(this.isEmbellished())||typeof(this.core)==="undefined"){return this}return this.data[this.core]},CoreMO:function(){if(!(this.isEmbellished())||typeof(this.core)==="undefined"){return this}return this.data[this.core].CoreMO()},toString:function(){if(this.inferred){return"["+this.data.join(",")+"]"}return this.SUPER(arguments).toString.call(this)},setTeXclass:function(g){var f,e=this.data.length;if((this.open||this.close)&&(!g||!g.fnOP)){this.getPrevClass(g);g=null;for(f=0;f0){e++}return e},adjustChild_texprimestyle:function(e){if(e==this.den){return true}return this.Get("texprimestyle")},setTeXclass:a.mbase.setSeparateTeXclasses});a.msqrt=a.mbase.Subclass({type:"msqrt",inferRow:true,linebreakContainer:true,texClass:a.TEXCLASS.ORD,setTeXclass:a.mbase.setSeparateTeXclasses,adjustChild_texprimestyle:function(e){return true}});a.mroot=a.mbase.Subclass({type:"mroot",linebreakContainer:true,texClass:a.TEXCLASS.ORD,adjustChild_displaystyle:function(e){if(e===1){return false}return this.Get("displaystyle")},adjustChild_scriptlevel:function(f){var e=this.Get("scriptlevel");if(f===1){e+=2}return e},adjustChild_texprimestyle:function(e){if(e===0){return true}return this.Get("texprimestyle")},setTeXclass:a.mbase.setSeparateTeXclasses});a.mstyle=a.mbase.Subclass({type:"mstyle",isSpacelike:a.mbase.childrenSpacelike,isEmbellished:a.mbase.childEmbellished,Core:a.mbase.childCore,CoreMO:a.mbase.childCoreMO,inferRow:true,defaults:{scriptlevel:a.INHERIT,displaystyle:a.INHERIT,scriptsizemultiplier:Math.sqrt(1/2),scriptminsize:"8pt",mathbackground:a.INHERIT,mathcolor:a.INHERIT,dir:a.INHERIT,infixlinebreakstyle:a.LINEBREAKSTYLE.BEFORE,decimalseparator:"."},adjustChild_scriptlevel:function(g){var f=this.scriptlevel;if(f==null){f=this.Get("scriptlevel")}else{if(String(f).match(/^ *[-+]/)){delete this.scriptlevel;var e=this.Get("scriptlevel");this.scriptlevel=f;f=e+parseInt(f)}}return f},inheritFromMe:true,noInherit:{mpadded:{width:true,height:true,depth:true,lspace:true,voffset:true},mtable:{width:true,height:true,depth:true,align:true}},setTeXclass:a.mbase.setChildTeXclass});a.merror=a.mbase.Subclass({type:"merror",inferRow:true,linebreakContainer:true,texClass:a.TEXCLASS.ORD});a.mpadded=a.mbase.Subclass({type:"mpadded",inferRow:true,isSpacelike:a.mbase.childrenSpacelike,isEmbellished:a.mbase.childEmbellished,Core:a.mbase.childCore,CoreMO:a.mbase.childCoreMO,defaults:{mathbackground:a.INHERIT,mathcolor:a.INHERIT,width:"",height:"",depth:"",lspace:0,voffset:0},setTeXclass:a.mbase.setChildTeXclass});a.mphantom=a.mbase.Subclass({type:"mphantom",texClass:a.TEXCLASS.ORD,inferRow:true,isSpacelike:a.mbase.childrenSpacelike,isEmbellished:a.mbase.childEmbellished,Core:a.mbase.childCore,CoreMO:a.mbase.childCoreMO,setTeXclass:a.mbase.setChildTeXclass});a.mfenced=a.mbase.Subclass({type:"mfenced",defaults:{mathbackground:a.INHERIT,mathcolor:a.INHERIT,open:"(",close:")",separators:","},addFakeNodes:function(){var f=this.getValues("open","close","separators");f.open=f.open.replace(/[ \t\n\r]/g,"");f.close=f.close.replace(/[ \t\n\r]/g,"");f.separators=f.separators.replace(/[ \t\n\r]/g,"");if(f.open!==""){this.SetData("open",a.mo(f.open).With({fence:true,form:a.FORM.PREFIX,texClass:a.TEXCLASS.OPEN}));this.data.open.useMMLspacing&=~this.data.open.SPACE_ATTR.form}if(f.separators!==""){while(f.separators.length0){return false}return this.Get("displaystyle")},adjustChild_scriptlevel:function(f){var e=this.Get("scriptlevel");if(f>0){e++}return e},adjustChild_texprimestyle:function(e){if(e===this.sub){return true}return this.Get("texprimestyle")},setTeXclass:a.mbase.setBaseTeXclasses});a.msub=a.msubsup.Subclass({type:"msub"});a.msup=a.msubsup.Subclass({type:"msup",sub:2,sup:1});a.mmultiscripts=a.msubsup.Subclass({type:"mmultiscripts",adjustChild_texprimestyle:function(e){if(e%2===1){return true}return this.Get("texprimestyle")}});a.mprescripts=a.mbase.Subclass({type:"mprescripts"});a.none=a.mbase.Subclass({type:"none"});a.munderover=a.mbase.Subclass({type:"munderover",base:0,under:1,over:2,sub:1,sup:2,ACCENTS:["","accentunder","accent"],linebreakContainer:true,isEmbellished:a.mbase.childEmbellished,Core:a.mbase.childCore,CoreMO:a.mbase.childCoreMO,defaults:{mathbackground:a.INHERIT,mathcolor:a.INHERIT,accent:a.AUTO,accentunder:a.AUTO,align:a.ALIGN.CENTER,texClass:a.AUTO,subscriptshift:"",superscriptshift:""},autoDefault:function(e){if(e==="texClass"){return(this.isEmbellished()?this.CoreMO().Get(e):a.TEXCLASS.ORD)}if(e==="accent"&&this.data[this.over]){return this.data[this.over].CoreMO().Get("accent")}if(e==="accentunder"&&this.data[this.under]){return this.data[this.under].CoreMO().Get("accent")}return false},adjustChild_displaystyle:function(e){if(e>0){return false}return this.Get("displaystyle")},adjustChild_scriptlevel:function(g){var f=this.Get("scriptlevel");var e=(this.data[this.base]&&!this.Get("displaystyle")&&this.data[this.base].CoreMO().Get("movablelimits"));if(g==this.under&&(e||!this.Get("accentunder"))){f++}if(g==this.over&&(e||!this.Get("accent"))){f++}return f},adjustChild_texprimestyle:function(e){if(e===this.base&&this.data[this.over]){return true}return this.Get("texprimestyle")},setTeXclass:a.mbase.setBaseTeXclasses});a.munder=a.munderover.Subclass({type:"munder"});a.mover=a.munderover.Subclass({type:"mover",over:1,under:2,sup:1,sub:2,ACCENTS:["","accent","accentunder"]});a.mtable=a.mbase.Subclass({type:"mtable",defaults:{mathbackground:a.INHERIT,mathcolor:a.INHERIT,align:a.ALIGN.AXIS,rowalign:a.ALIGN.BASELINE,columnalign:a.ALIGN.CENTER,groupalign:"{left}",alignmentscope:true,columnwidth:a.WIDTH.AUTO,width:a.WIDTH.AUTO,rowspacing:"1ex",columnspacing:".8em",rowlines:a.LINES.NONE,columnlines:a.LINES.NONE,frame:a.LINES.NONE,framespacing:"0.4em 0.5ex",equalrows:false,equalcolumns:false,displaystyle:false,side:a.SIDE.RIGHT,minlabelspacing:"0.8em",texClass:a.TEXCLASS.ORD,useHeight:1},adjustChild_displaystyle:function(){return(this.displaystyle!=null?this.displaystyle:this.defaults.displaystyle)},inheritFromMe:true,noInherit:{mover:{align:true},munder:{align:true},munderover:{align:true},mtable:{align:true,rowalign:true,columnalign:true,groupalign:true,alignmentscope:true,columnwidth:true,width:true,rowspacing:true,columnspacing:true,rowlines:true,columnlines:true,frame:true,framespacing:true,equalrows:true,equalcolumns:true,displaystyle:true,side:true,minlabelspacing:true,texClass:true,useHeight:1}},linebreakContainer:true,Append:function(){for(var f=0,e=arguments.length;f>10)+55296)+String.fromCharCode((e&1023)+56320)}});a.xml=a.mbase.Subclass({type:"xml",Init:function(){this.div=document.createElement("div");return this.SUPER(arguments).Init.apply(this,arguments)},Append:function(){for(var f=0,e=arguments.length;f":d.REL,"?":[1,1,b.CLOSE],"\\":d.ORD,"^":d.ORD11,_:d.ORD11,"|":[2,2,b.ORD,{fence:true,stretchy:true,symmetric:true}],"#":d.ORD,"$":d.ORD,"\u002E":[0,3,b.PUNCT,{separator:true}],"\u02B9":d.ORD,"\u0300":d.ACCENT,"\u0301":d.ACCENT,"\u0303":d.WIDEACCENT,"\u0304":d.ACCENT,"\u0306":d.ACCENT,"\u0307":d.ACCENT,"\u0308":d.ACCENT,"\u030C":d.ACCENT,"\u0332":d.WIDEACCENT,"\u0338":d.REL4,"\u2015":[0,0,b.ORD,{stretchy:true}],"\u2017":[0,0,b.ORD,{stretchy:true}],"\u2020":d.BIN3,"\u2021":d.BIN3,"\u20D7":d.ACCENT,"\u2111":d.ORD,"\u2113":d.ORD,"\u2118":d.ORD,"\u211C":d.ORD,"\u2205":d.ORD,"\u221E":d.ORD,"\u2305":d.BIN3,"\u2306":d.BIN3,"\u2322":d.REL4,"\u2323":d.REL4,"\u2329":d.OPEN,"\u232A":d.CLOSE,"\u23AA":d.ORD,"\u23AF":[0,0,b.ORD,{stretchy:true}],"\u23B0":d.OPEN,"\u23B1":d.CLOSE,"\u2500":d.ORD,"\u25EF":d.BIN3,"\u2660":d.ORD,"\u2661":d.ORD,"\u2662":d.ORD,"\u2663":d.ORD,"\u3008":d.OPEN,"\u3009":d.CLOSE,"\uFE37":d.WIDEACCENT,"\uFE38":d.WIDEACCENT}}},{OPTYPES:d});var c=a.mo.prototype.OPTABLE;c.infix["^"]=d.WIDEREL;c.infix._=d.WIDEREL;c.prefix["\u2223"]=d.OPEN;c.prefix["\u2225"]=d.OPEN;c.postfix["\u2223"]=d.CLOSE;c.postfix["\u2225"]=d.CLOSE})(MathJax.ElementJax.mml);MathJax.ElementJax.mml.loadComplete("jax.js"); +MathJax.Hub.Register.LoadHook("[MathJax]/jax/element/mml/jax.js",function(){var b="2.5.0";var a=MathJax.ElementJax.mml;SETTINGS=MathJax.Hub.config.menuSettings;a.mbase.Augment({toMathML:function(k){var g=(this.inferred&&this.parent.inferRow);if(k==null){k=""}var e=this.type,d=this.toMathMLattributes();if(e==="mspace"){return k+"<"+e+d+" />"}var j=[],h=(this.isToken?"":k+(g?"":" "));for(var f=0,c=this.data.length;f")}}}if(this.isToken||this.isChars){return k+"<"+e+d+">"+j.join("")+""}if(g){return j.join("\n")}if(j.length===0||(j.length===1&&j[0]==="")){return k+"<"+e+d+" />"}return k+"<"+e+d+">\n"+j.join("\n")+"\n"+k+""},toMathMLattributes:function(){var h=(this.type==="mstyle"?a.math.prototype.defaults:this.defaults);var g=(this.attrNames||a.copyAttributeNames),f=a.skipAttributes,k=a.copyAttributes;var d=[];if(this.type==="math"&&(!this.attr||!this.attr.xmlns)){d.push('xmlns="http://www.w3.org/1998/Math/MathML"')}if(!this.attrNames){for(var j in h){if(!f[j]&&!k[j]&&h.hasOwnProperty(j)){if(this[j]!=null&&this[j]!==h[j]){if(this.Get(j,null,1)!==this[j]){d.push(j+'="'+this.toMathMLattribute(this[j])+'"')}}}}}for(var e=0,c=g.length;e126||(k<32&&k!==10&&k!==13&&k!==9)){f[g]="&#x"+k.toString(16).toUpperCase()+";"}else{var j={"&":"&","<":"<",">":">",'"':"""}[f[g]];if(j){f[g]=j}}}else{if(g+11);var o=this.type,j=this.toMathMLattributes();var h=[],n=c+(f?" "+(l?" ":""):"")+" ";for(var g=0,e=this.data.length;g")}}if(h.length===0||(h.length===1&&h[0]==="")){if(!f){return"<"+o+j+" />"}h.push(n+"")}if(f){if(l){h.unshift(c+" ");h.push(c+" ")}h.unshift(c+" ");var k=d.originalText.replace(/[&<>]/g,function(i){return{">":">","<":"<","&":"&"}[i]});h.push(c+' '+k+"");h.push(c+" ")}return c+"<"+o+j+">\n"+h.join("\n")+"\n"+c+""}});a.msubsup.Augment({toMathML:function(h){var e=this.type;if(this.data[this.sup]==null){e="msub"}if(this.data[this.sub]==null){e="msup"}var d=this.toMathMLattributes();delete this.data[0].inferred;var g=[];for(var f=0,c=this.data.length;f\n"+g.join("\n")+"\n"+h+""}});a.munderover.Augment({toMathML:function(h){var e=this.type;if(this.data[this.under]==null){e="mover"}if(this.data[this.over]==null){e="munder"}var d=this.toMathMLattributes();delete this.data[0].inferred;var g=[];for(var f=0,c=this.data.length;f\n"+g.join("\n")+"\n"+h+""}});a.TeXAtom.Augment({toMathML:function(d){var c=this.toMathMLattributes();if(!c&&this.data[0].data.length===1){return d.substr(2)+this.data[0].toMathML(d)}return d+"\n"+this.data[0].toMathML(d+" ")+"\n"+d+""}});a.chars.Augment({toMathML:function(c){return(c||"")+this.toMathMLquote(this.toString())}});a.entity.Augment({toMathML:function(c){return(c||"")+"&"+this.data[0]+";"}});a.xml.Augment({toMathML:function(c){return(c||"")+this.toString()}});MathJax.Hub.Register.StartupHook("TeX mathchoice Ready",function(){a.TeXmathchoice.Augment({toMathML:function(c){return this.Core().toMathML(c)}})});MathJax.Hub.Startup.signal.Post("toMathML Ready")});MathJax.Ajax.loadComplete("[MathJax]/extensions/toMathML.js"); +(function(b,e){var d="2.5.0";var a=b.CombineConfig("TeX.noErrors",{disabled:false,multiLine:true,inlineDelimiters:["",""],style:{"font-size":"90%","text-align":"left",color:"black",padding:"1px 3px",border:"1px solid"}});var c="\u00A0";MathJax.Extension["TeX/noErrors"]={version:d,config:a};b.Register.StartupHook("TeX Jax Ready",function(){var f=MathJax.InputJax.TeX.formatError;MathJax.InputJax.TeX.Augment({formatError:function(j,i,k,g){if(a.disabled){return f.apply(this,arguments)}var h=j.message.replace(/\n.*/,"");b.signal.Post(["TeX Jax - parse error",h,i,k,g]);var m=a.inlineDelimiters;var l=(k||a.multiLine);if(!k){i=m[0]+i+m[1]}if(l){i=i.replace(/ /g,c)}else{i=i.replace(/\n/g," ")}return MathJax.ElementJax.mml.merror(i).With({isError:true,multiLine:l})}})});b.Register.StartupHook("HTML-CSS Jax Config",function(){b.Config({"HTML-CSS":{styles:{".MathJax .noError":b.Insert({"vertical-align":(b.Browser.isMSIE&&a.multiLine?"-2px":"")},a.style)}}})});b.Register.StartupHook("HTML-CSS Jax Ready",function(){var g=MathJax.ElementJax.mml;var h=MathJax.OutputJax["HTML-CSS"];var f=g.math.prototype.toHTML,i=g.merror.prototype.toHTML;g.math.Augment({toHTML:function(j,k){var l=this.data[0];if(l&&l.data[0]&&l.data[0].isError){j.style.fontSize="";j=this.HTMLcreateSpan(j);j.bbox=l.data[0].toHTML(j).bbox}else{j=f.call(this,j,k)}return j}});g.merror.Augment({toHTML:function(p){if(!this.isError){return i.call(this,p)}p=this.HTMLcreateSpan(p);p.className="noError";if(this.multiLine){p.style.display="inline-block"}var r=this.data[0].data[0].data.join("").split(/\n/);for(var o=0,l=r.length;o1){var n=(q.h+q.d)/2,j=h.TeX.x_height/2;p.parentNode.style.verticalAlign=h.Em(q.d+(j-n));q.h=j+n;q.d=n-j}p.bbox={h:q.h,d:q.d,w:k,lw:0,rw:k};return p}})});b.Register.StartupHook("SVG Jax Config",function(){b.Config({SVG:{styles:{".MathJax_SVG .noError":b.Insert({"vertical-align":(b.Browser.isMSIE&&a.multiLine?"-2px":"")},a.style)}}})});b.Register.StartupHook("SVG Jax Ready",function(){var g=MathJax.ElementJax.mml;var f=g.math.prototype.toSVG,h=g.merror.prototype.toSVG;g.math.Augment({toSVG:function(i,j){var k=this.data[0];if(k&&k.data[0]&&k.data[0].isError){i=k.data[0].toSVG(i)}else{i=f.call(this,i,j)}return i}});g.merror.Augment({toSVG:function(n){if(!this.isError||this.Parent().type!=="math"){return h.call(this,n)}n=e.addElement(n,"span",{className:"noError",isMathJax:true});if(this.multiLine){n.style.display="inline-block"}var o=this.data[0].data[0].data.join("").split(/\n/);for(var l=0,j=o.length;l1){var k=n.offsetHeight/2;n.style.verticalAlign=(-k+(k/j))+"px"}return n}})});b.Register.StartupHook("NativeMML Jax Ready",function(){var h=MathJax.ElementJax.mml;var g=MathJax.Extension["TeX/noErrors"].config;var f=h.math.prototype.toNativeMML,i=h.merror.prototype.toNativeMML;h.math.Augment({toNativeMML:function(j){var k=this.data[0];if(k&&k.data[0]&&k.data[0].isError){j=k.data[0].toNativeMML(j)}else{j=f.call(this,j)}return j}});h.merror.Augment({toNativeMML:function(n){if(!this.isError){return i.call(this,n)}n=n.appendChild(document.createElement("span"));var o=this.data[0].data[0].data.join("").split(/\n/);for(var l=0,k=o.length;l1){n.style.verticalAlign="middle"}}for(var p in g.style){if(g.style.hasOwnProperty(p)){var j=p.replace(/-./g,function(m){return m.charAt(1).toUpperCase()});n.style[j]=g.style[p]}}return n}})});b.Register.StartupHook("CommonHTML Jax Config",function(){b.Config({CommonHTML:{styles:{".MathJax_CHTML .noError":b.Insert({"vertical-align":(b.Browser.isMSIE&&a.multiLine?"-2px":"")},a.style)}}})});b.Register.StartupHook("CommonHTML Jax Ready",function(){var f=MathJax.ElementJax.mml;var h=MathJax.HTML;var g=f.merror.prototype.toCommonHTML;f.merror.Augment({toCommonHTML:function(l){if(!this.isError){return g.call(this,l)}l=this.CHTMLcreateSpan(l);l.className="noError";if(this.multiLine){l.style.display="inline-block"}var n=this.data[0].data[0].data.join("").split(/\n/);for(var k=0,j=n.length;k":"27E9","\\lt":"27E8","\\gt":"27E9","/":"/","|":["|",{texClass:h.TEXCLASS.ORD}],".":"","\\\\":"\\","\\lmoustache":"23B0","\\rmoustache":"23B1","\\lgroup":"27EE","\\rgroup":"27EF","\\arrowvert":"23D0","\\Arrowvert":"2016","\\bracevert":"23AA","\\Vert":["2225",{texClass:h.TEXCLASS.ORD}],"\\|":["2225",{texClass:h.TEXCLASS.ORD}],"\\vert":["|",{texClass:h.TEXCLASS.ORD}],"\\uparrow":"2191","\\downarrow":"2193","\\updownarrow":"2195","\\Uparrow":"21D1","\\Downarrow":"21D3","\\Updownarrow":"21D5","\\backslash":"\\","\\rangle":"27E9","\\langle":"27E8","\\rbrace":"}","\\lbrace":"{","\\}":"}","\\{":"{","\\rceil":"2309","\\lceil":"2308","\\rfloor":"230B","\\lfloor":"230A","\\lbrack":"[","\\rbrack":"]"},macros:{displaystyle:["SetStyle","D",true,0],textstyle:["SetStyle","T",false,0],scriptstyle:["SetStyle","S",false,1],scriptscriptstyle:["SetStyle","SS",false,2],rm:["SetFont",h.VARIANT.NORMAL],mit:["SetFont",h.VARIANT.ITALIC],oldstyle:["SetFont",h.VARIANT.OLDSTYLE],cal:["SetFont",h.VARIANT.CALIGRAPHIC],it:["SetFont","-tex-mathit"],bf:["SetFont",h.VARIANT.BOLD],bbFont:["SetFont",h.VARIANT.DOUBLESTRUCK],scr:["SetFont",h.VARIANT.SCRIPT],frak:["SetFont",h.VARIANT.FRAKTUR],sf:["SetFont",h.VARIANT.SANSSERIF],tt:["SetFont",h.VARIANT.MONOSPACE],tiny:["SetSize",0.5],Tiny:["SetSize",0.6],scriptsize:["SetSize",0.7],small:["SetSize",0.85],normalsize:["SetSize",1],large:["SetSize",1.2],Large:["SetSize",1.44],LARGE:["SetSize",1.73],huge:["SetSize",2.07],Huge:["SetSize",2.49],arcsin:["NamedFn"],arccos:["NamedFn"],arctan:["NamedFn"],arg:["NamedFn"],cos:["NamedFn"],cosh:["NamedFn"],cot:["NamedFn"],coth:["NamedFn"],csc:["NamedFn"],deg:["NamedFn"],det:"NamedOp",dim:["NamedFn"],exp:["NamedFn"],gcd:"NamedOp",hom:["NamedFn"],inf:"NamedOp",ker:["NamedFn"],lg:["NamedFn"],lim:"NamedOp",liminf:["NamedOp","lim inf"],limsup:["NamedOp","lim sup"],ln:["NamedFn"],log:["NamedFn"],max:"NamedOp",min:"NamedOp",Pr:"NamedOp",sec:["NamedFn"],sin:["NamedFn"],sinh:["NamedFn"],sup:"NamedOp",tan:["NamedFn"],tanh:["NamedFn"],limits:["Limits",1],nolimits:["Limits",0],overline:["UnderOver","00AF"],underline:["UnderOver","005F"],overbrace:["UnderOver","23DE",1],underbrace:["UnderOver","23DF",1],overrightarrow:["UnderOver","2192"],underrightarrow:["UnderOver","2192"],overleftarrow:["UnderOver","2190"],underleftarrow:["UnderOver","2190"],overleftrightarrow:["UnderOver","2194"],underleftrightarrow:["UnderOver","2194"],overset:"Overset",underset:"Underset",stackrel:["Macro","\\mathrel{\\mathop{#2}\\limits^{#1}}",2],over:"Over",overwithdelims:"Over",atop:"Over",atopwithdelims:"Over",above:"Over",abovewithdelims:"Over",brace:["Over","{","}"],brack:["Over","[","]"],choose:["Over","(",")"],frac:"Frac",sqrt:"Sqrt",root:"Root",uproot:["MoveRoot","upRoot"],leftroot:["MoveRoot","leftRoot"],left:"LeftRight",right:"LeftRight",middle:"Middle",llap:"Lap",rlap:"Lap",raise:"RaiseLower",lower:"RaiseLower",moveleft:"MoveLeftRight",moveright:"MoveLeftRight",",":["Spacer",h.LENGTH.THINMATHSPACE],":":["Spacer",h.LENGTH.MEDIUMMATHSPACE],">":["Spacer",h.LENGTH.MEDIUMMATHSPACE],";":["Spacer",h.LENGTH.THICKMATHSPACE],"!":["Spacer",h.LENGTH.NEGATIVETHINMATHSPACE],enspace:["Spacer",".5em"],quad:["Spacer","1em"],qquad:["Spacer","2em"],thinspace:["Spacer",h.LENGTH.THINMATHSPACE],negthinspace:["Spacer",h.LENGTH.NEGATIVETHINMATHSPACE],hskip:"Hskip",hspace:"Hskip",kern:"Hskip",mskip:"Hskip",mspace:"Hskip",mkern:"Hskip",Rule:["Rule"],Space:["Rule","blank"],big:["MakeBig",h.TEXCLASS.ORD,0.85],Big:["MakeBig",h.TEXCLASS.ORD,1.15],bigg:["MakeBig",h.TEXCLASS.ORD,1.45],Bigg:["MakeBig",h.TEXCLASS.ORD,1.75],bigl:["MakeBig",h.TEXCLASS.OPEN,0.85],Bigl:["MakeBig",h.TEXCLASS.OPEN,1.15],biggl:["MakeBig",h.TEXCLASS.OPEN,1.45],Biggl:["MakeBig",h.TEXCLASS.OPEN,1.75],bigr:["MakeBig",h.TEXCLASS.CLOSE,0.85],Bigr:["MakeBig",h.TEXCLASS.CLOSE,1.15],biggr:["MakeBig",h.TEXCLASS.CLOSE,1.45],Biggr:["MakeBig",h.TEXCLASS.CLOSE,1.75],bigm:["MakeBig",h.TEXCLASS.REL,0.85],Bigm:["MakeBig",h.TEXCLASS.REL,1.15],biggm:["MakeBig",h.TEXCLASS.REL,1.45],Biggm:["MakeBig",h.TEXCLASS.REL,1.75],mathord:["TeXAtom",h.TEXCLASS.ORD],mathop:["TeXAtom",h.TEXCLASS.OP],mathopen:["TeXAtom",h.TEXCLASS.OPEN],mathclose:["TeXAtom",h.TEXCLASS.CLOSE],mathbin:["TeXAtom",h.TEXCLASS.BIN],mathrel:["TeXAtom",h.TEXCLASS.REL],mathpunct:["TeXAtom",h.TEXCLASS.PUNCT],mathinner:["TeXAtom",h.TEXCLASS.INNER],vcenter:["TeXAtom",h.TEXCLASS.VCENTER],mathchoice:["Extension","mathchoice"],buildrel:"BuildRel",hbox:["HBox",0],text:"HBox",mbox:["HBox",0],fbox:"FBox",strut:"Strut",mathstrut:["Macro","\\vphantom{(}"],phantom:"Phantom",vphantom:["Phantom",1,0],hphantom:["Phantom",0,1],smash:"Smash",acute:["Accent","00B4"],grave:["Accent","0060"],ddot:["Accent","00A8"],tilde:["Accent","007E"],bar:["Accent","00AF"],breve:["Accent","02D8"],check:["Accent","02C7"],hat:["Accent","005E"],vec:["Accent","2192"],dot:["Accent","02D9"],widetilde:["Accent","007E",1],widehat:["Accent","005E",1],matrix:"Matrix",array:"Matrix",pmatrix:["Matrix","(",")"],cases:["Matrix","{","","left left",null,".1em",null,true],eqalign:["Matrix",null,null,"right left",h.LENGTH.THICKMATHSPACE,".5em","D"],displaylines:["Matrix",null,null,"center",null,".5em","D"],cr:"Cr","\\":"CrLaTeX",newline:"Cr",hline:["HLine","solid"],hdashline:["HLine","dashed"],eqalignno:["Matrix",null,null,"right left",h.LENGTH.THICKMATHSPACE,".5em","D",null,"right"],leqalignno:["Matrix",null,null,"right left",h.LENGTH.THICKMATHSPACE,".5em","D",null,"left"],hfill:"HFill",hfil:"HFill",hfilll:"HFill",bmod:["Macro",'\\mmlToken{mo}[lspace="thickmathspace" rspace="thickmathspace"]{mod}'],pmod:["Macro","\\pod{\\mmlToken{mi}{mod}\\kern 6mu #1}",1],mod:["Macro","\\mathchoice{\\kern18mu}{\\kern12mu}{\\kern12mu}{\\kern12mu}\\mmlToken{mi}{mod}\\,\\,#1",1],pod:["Macro","\\mathchoice{\\kern18mu}{\\kern8mu}{\\kern8mu}{\\kern8mu}(#1)",1],iff:["Macro","\\;\\Longleftrightarrow\\;"],skew:["Macro","{{#2{#3\\mkern#1mu}\\mkern-#1mu}{}}",3],mathcal:["Macro","{\\cal #1}",1],mathscr:["Macro","{\\scr #1}",1],mathrm:["Macro","{\\rm #1}",1],mathbf:["Macro","{\\bf #1}",1],mathbb:["Macro","{\\bbFont #1}",1],Bbb:["Macro","{\\bbFont #1}",1],mathit:["Macro","{\\it #1}",1],mathfrak:["Macro","{\\frak #1}",1],mathsf:["Macro","{\\sf #1}",1],mathtt:["Macro","{\\tt #1}",1],textrm:["Macro","\\mathord{\\rm\\text{#1}}",1],textit:["Macro","\\mathord{\\it\\text{#1}}",1],textbf:["Macro","\\mathord{\\bf\\text{#1}}",1],textsf:["Macro","\\mathord{\\sf\\text{#1}}",1],texttt:["Macro","\\mathord{\\tt\\text{#1}}",1],pmb:["Macro","\\rlap{#1}\\kern1px{#1}",1],TeX:["Macro","T\\kern-.14em\\lower.5ex{E}\\kern-.115em X"],LaTeX:["Macro","L\\kern-.325em\\raise.21em{\\scriptstyle{A}}\\kern-.17em\\TeX"]," ":["Macro","\\text{ }"],not:"Not",dots:"Dots",space:"Tilde","\u00A0":"Tilde",begin:"BeginEnd",end:"BeginEnd",newcommand:["Extension","newcommand"],renewcommand:["Extension","newcommand"],newenvironment:["Extension","newcommand"],renewenvironment:["Extension","newcommand"],def:["Extension","newcommand"],let:["Extension","newcommand"],verb:["Extension","verb"],boldsymbol:["Extension","boldsymbol"],tag:["Extension","AMSmath"],notag:["Extension","AMSmath"],label:["Extension","AMSmath"],ref:["Extension","AMSmath"],eqref:["Extension","AMSmath"],nonumber:["Macro","\\notag"],unicode:["Extension","unicode"],color:"Color",href:["Extension","HTML"],"class":["Extension","HTML"],style:["Extension","HTML"],cssId:["Extension","HTML"],bbox:["Extension","bbox"],mmlToken:"MmlToken",require:"Require"},environment:{array:["AlignedArray"],matrix:["Array",null,null,null,"c"],pmatrix:["Array",null,"(",")","c"],bmatrix:["Array",null,"[","]","c"],Bmatrix:["Array",null,"\\{","\\}","c"],vmatrix:["Array",null,"\\vert","\\vert","c"],Vmatrix:["Array",null,"\\Vert","\\Vert","c"],cases:["Array",null,"\\{",".","ll",null,".2em","T"],equation:[null,"Equation"],"equation*":[null,"Equation"],eqnarray:["ExtensionEnv",null,"AMSmath"],"eqnarray*":["ExtensionEnv",null,"AMSmath"],align:["ExtensionEnv",null,"AMSmath"],"align*":["ExtensionEnv",null,"AMSmath"],aligned:["ExtensionEnv",null,"AMSmath"],multline:["ExtensionEnv",null,"AMSmath"],"multline*":["ExtensionEnv",null,"AMSmath"],split:["ExtensionEnv",null,"AMSmath"],gather:["ExtensionEnv",null,"AMSmath"],"gather*":["ExtensionEnv",null,"AMSmath"],gathered:["ExtensionEnv",null,"AMSmath"],alignat:["ExtensionEnv",null,"AMSmath"],"alignat*":["ExtensionEnv",null,"AMSmath"],alignedat:["ExtensionEnv",null,"AMSmath"]},p_height:1.2/0.85});if(this.config.Macros){var l=this.config.Macros;for(var m in l){if(l.hasOwnProperty(m)){if(typeof(l[m])==="string"){f.macros[m]=["Macro",l[m]]}else{f.macros[m]=["Macro"].concat(l[m])}f.macros[m].isUser=true}}}};var a=MathJax.Object.Subclass({Init:function(m,n){this.string=m;this.i=0;this.macroCount=0;var l;if(n){l={};for(var o in n){if(n.hasOwnProperty(o)){l[o]=n[o]}}}this.stack=d.Stack(l,!!n);this.Parse();this.Push(b.stop())},Parse:function(){var m,l;while(this.i=55296&&l<56320){m+=this.string.charAt(this.i++)}if(f.special[m]){this[f.special[m]](m)}else{if(f.letter.test(m)){this.Variable(m)}else{if(f.digit.test(m)){this.Number(m)}else{this.Other(m)}}}}},Push:function(){this.stack.Push.apply(this.stack,arguments)},mml:function(){if(this.stack.Top().type!=="mml"){return null}return this.stack.Top().data[0]},mmlToken:function(l){return l},ControlSequence:function(o){var l=this.GetCS(),n=this.csFindMacro(l);if(n){if(!(n instanceof Array)){n=[n]}var m=n[0];if(!(m instanceof Function)){m=this[m]}m.apply(this,[o+l].concat(n.slice(1)))}else{if(f.mathchar0mi[l]){this.csMathchar0mi(l,f.mathchar0mi[l])}else{if(f.mathchar0mo[l]){this.csMathchar0mo(l,f.mathchar0mo[l])}else{if(f.mathchar7[l]){this.csMathchar7(l,f.mathchar7[l])}else{if(f.delimiter["\\"+l]!=null){this.csDelimiter(l,f.delimiter["\\"+l])}else{this.csUndefined(o+l)}}}}}},csFindMacro:function(l){return f.macros[l]},csMathchar0mi:function(l,n){var m={mathvariant:h.VARIANT.ITALIC};if(n instanceof Array){m=n[1];n=n[0]}this.Push(this.mmlToken(h.mi(h.entity("#x"+n)).With(m)))},csMathchar0mo:function(l,n){var m={stretchy:false};if(n instanceof Array){m=n[1];m.stretchy=false;n=n[0]}this.Push(this.mmlToken(h.mo(h.entity("#x"+n)).With(m)))},csMathchar7:function(l,n){var m={mathvariant:h.VARIANT.NORMAL};if(n instanceof Array){m=n[1];n=n[0]}if(this.stack.env.font){m.mathvariant=this.stack.env.font}this.Push(this.mmlToken(h.mi(h.entity("#x"+n)).With(m)))},csDelimiter:function(l,n){var m={};if(n instanceof Array){m=n[1];n=n[0]}if(n.length===4){n=h.entity("#x"+n)}else{n=h.chars(n)}this.Push(this.mmlToken(h.mo(n).With({fence:false,stretchy:false}).With(m)))},csUndefined:function(l){d.Error(["UndefinedControlSequence","Undefined control sequence %1",l])},Variable:function(m){var l={};if(this.stack.env.font){l.mathvariant=this.stack.env.font}this.Push(this.mmlToken(h.mi(h.chars(m)).With(l)))},Number:function(o){var l,m=this.string.slice(this.i-1).match(f.number);if(m){l=h.mn(m[0].replace(/[{}]/g,""));this.i+=m[0].length-1}else{l=h.mo(h.chars(o))}if(this.stack.env.font){l.mathvariant=this.stack.env.font}this.Push(this.mmlToken(l))},Open:function(l){this.Push(b.open())},Close:function(l){this.Push(b.close())},Tilde:function(l){this.Push(h.mtext(h.chars(g)))},Space:function(l){},Superscript:function(q){if(this.GetNext().match(/\d/)){this.string=this.string.substr(0,this.i+1)+" "+this.string.substr(this.i+1)}var p,n,o=this.stack.Top();if(o.type==="prime"){n=o.data[0];p=o.data[1];this.stack.Pop()}else{n=this.stack.Prev();if(!n){n=h.mi("")}}if(n.isEmbellishedWrapper){n=n.data[0].data[0]}var m=n.movesupsub,l=n.sup;if((n.type==="msubsup"&&n.data[n.sup])||(n.type==="munderover"&&n.data[n.over]&&!n.subsupOK)){d.Error(["DoubleExponent","Double exponent: use braces to clarify"])}if(n.type!=="msubsup"){if(m){if(n.type!=="munderover"||n.data[n.over]){if(n.movablelimits&&n.isa(h.mi)){n=this.mi2mo(n)}n=h.munderover(n,null,null).With({movesupsub:true})}l=n.over}else{n=h.msubsup(n,null,null);l=n.sup}}this.Push(b.subsup(n).With({position:l,primes:p,movesupsub:m}))},Subscript:function(q){if(this.GetNext().match(/\d/)){this.string=this.string.substr(0,this.i+1)+" "+this.string.substr(this.i+1)}var p,n,o=this.stack.Top();if(o.type==="prime"){n=o.data[0];p=o.data[1];this.stack.Pop()}else{n=this.stack.Prev();if(!n){n=h.mi("")}}if(n.isEmbellishedWrapper){n=n.data[0].data[0]}var m=n.movesupsub,l=n.sub;if((n.type==="msubsup"&&n.data[n.sub])||(n.type==="munderover"&&n.data[n.under]&&!n.subsupOK)){d.Error(["DoubleSubscripts","Double subscripts: use braces to clarify"])}if(n.type!=="msubsup"){if(m){if(n.type!=="munderover"||n.data[n.under]){if(n.movablelimits&&n.isa(h.mi)){n=this.mi2mo(n)}n=h.munderover(n,null,null).With({movesupsub:true})}l=n.under}else{n=h.msubsup(n,null,null);l=n.sub}}this.Push(b.subsup(n).With({position:l,primes:p,movesupsub:m}))},PRIME:"\u2032",SMARTQUOTE:"\u2019",Prime:function(n){var m=this.stack.Prev();if(!m){m=h.mi()}if(m.type==="msubsup"&&m.data[m.sup]){d.Error(["DoubleExponentPrime","Prime causes double exponent: use braces to clarify"])}var l="";this.i--;do{l+=this.PRIME;this.i++,n=this.GetNext()}while(n==="'"||n===this.SMARTQUOTE);l=["","\u2032","\u2033","\u2034","\u2057"][l.length]||l;this.Push(b.prime(m,this.mmlToken(h.mo(l))))},mi2mo:function(l){var m=h.mo();m.Append.apply(m,l.data);var n;for(n in m.defaults){if(m.defaults.hasOwnProperty(n)&&l[n]!=null){m[n]=l[n]}}for(n in h.copyAttributes){if(h.copyAttributes.hasOwnProperty(n)&&l[n]!=null){m[n]=l[n]}}return m},Comment:function(l){while(this.id.config.MAXMACROS){d.Error(["MaxMacroSub1","MathJax maximum macro substitution count exceeded; is there a recursive macro call?"])}},Matrix:function(m,o,u,q,t,n,l,v,s){var r=this.GetNext();if(r===""){d.Error(["MissingArgFor","Missing argument for %1",m])}if(r==="{"){this.i++}else{this.string=r+"}"+this.string.slice(this.i+1);this.i=0}var p=b.array().With({requireClose:true,arraydef:{rowspacing:(n||"4pt"),columnspacing:(t||"1em")}});if(v){p.isCases=true}if(s){p.isNumbered=true;p.arraydef.side=s}if(o||u){p.open=o;p.close=u}if(l==="D"){p.arraydef.displaystyle=true}if(q!=null){p.arraydef.columnalign=q}this.Push(p)},Entry:function(o){this.Push(b.cell().With({isEntry:true,name:o}));if(this.stack.Top().isCases){var n=this.string;var r=0,p=this.i,l=n.length;while(pd.config.MAXMACROS){d.Error(["MaxMacroSub2","MathJax maximum substitution count exceeded; is there a recursive latex environment?"])}if(p[0]&&this[p[0]]){m=this[p[0]].apply(this,[m].concat(p.slice(2)))}}this.Push(m)},envFindName:function(l){return f.environment[l]},Equation:function(l,m){return m},ExtensionEnv:function(m,l){this.Extension(m.name,l,"environment")},Array:function(m,o,t,r,s,n,l,p){if(!r){r=this.GetArgument("\\begin{"+m.name+"}")}var u=("c"+r).replace(/[^clr|:]/g,"").replace(/[^|:]([|:])+/g,"$1");r=r.replace(/[^clr]/g,"").split("").join(" ");r=r.replace(/l/g,"left").replace(/r/g,"right").replace(/c/g,"center");var q=b.array().With({arraydef:{columnalign:r,columnspacing:(s||"1em"),rowspacing:(n||"4pt")}});if(u.match(/[|:]/)){if(u.charAt(0).match(/[|:]/)){q.frame.push("left");q.frame.dashed=u.charAt(0)===":"}if(u.charAt(u.length-1).match(/[|:]/)){q.frame.push("right")}u=u.substr(1,u.length-2);q.arraydef.columnlines=u.split("").join(" ").replace(/[^|: ]/g,"none").replace(/\|/g,"solid").replace(/:/g,"dashed")}if(o){q.open=this.convertDelimiter(o)}if(t){q.close=this.convertDelimiter(t)}if(l==="D"){q.arraydef.displaystyle=true}else{if(l){q.arraydef.displaystyle=false}}if(l==="S"){q.arraydef.scriptlevel=1}if(p){q.arraydef.useHeight=false}this.Push(m);return q},AlignedArray:function(l){var m=this.GetBrackets("\\begin{"+l.name+"}");return this.setArrayAlign(this.Array.apply(this,arguments),m)},setArrayAlign:function(m,l){l=this.trimSpaces(l||"");if(l==="t"){m.arraydef.align="baseline 1"}else{if(l==="b"){m.arraydef.align="baseline -1"}else{if(l==="c"){m.arraydef.align="center"}else{if(l){m.arraydef.align=l}}}}return m},convertDelimiter:function(l){if(l){l=f.delimiter[l]}if(l==null){return null}if(l instanceof Array){l=l[0]}if(l.length===4){l=String.fromCharCode(parseInt(l,16))}return l},trimSpaces:function(l){if(typeof(l)!="string"){return l}return l.replace(/^\s+|\s+$/g,"")},nextIsSpace:function(){return this.string.charAt(this.i).match(/\s/)},GetNext:function(){while(this.nextIsSpace()){this.i++}return this.string.charAt(this.i)},GetCS:function(){var l=this.string.slice(this.i).match(/^([a-z]+|.) ?/i);if(l){this.i+=l[1].length;return l[1]}else{this.i++;return" "}},GetArgument:function(m,n){switch(this.GetNext()){case"":if(!n){d.Error(["MissingArgFor","Missing argument for %1",m])}return null;case"}":if(!n){d.Error(["ExtraCloseMissingOpen","Extra close brace or missing open brace"])}return null;case"\\":this.i++;return"\\"+this.GetCS();case"{":var l=++this.i,o=1;while(this.im.length){d.Error(["IllegalMacroParam","Illegal macro parameter reference"])}o=this.AddArgs(this.AddArgs(o,p),m[q-1]);p=""}}else{p+=q}}}return this.AddArgs(o,p)},AddArgs:function(m,l){if(l.match(/^[a-z]/i)&&m.match(/(^|[^\\])(\\\\)*\\[a-z]+$/i)){m+=" "}if(m.length+l.length>d.config.MAXBUFFER){d.Error(["MaxBufferSize","MathJax internal buffer size exceeded; is there a recursive macro call?"])}return m+l}});d.Augment({Stack:e,Parse:a,Definitions:f,Startup:k,config:{MAXMACROS:10000,MAXBUFFER:5*1024},sourceMenuTitle:["TeXCommands","TeX Commands"],annotationEncoding:"application/x-tex",prefilterHooks:MathJax.Callback.Hooks(true),postfilterHooks:MathJax.Callback.Hooks(true),Config:function(){this.SUPER(arguments).Config.apply(this,arguments);if(this.config.equationNumbers.autoNumber!=="none"){if(!this.config.extensions){this.config.extensions=[]}this.config.extensions.push("AMSmath.js")}},Translate:function(l){var m,n=false,p=MathJax.HTML.getScript(l);var r=(l.type.replace(/\n/g," ").match(/(;|\s|\n)mode\s*=\s*display(;|\s|\n|$)/)!=null);var q={math:p,display:r,script:l};var s=this.prefilterHooks.Execute(q);if(s){return s}p=q.math;try{m=d.Parse(p).mml()}catch(o){if(!o.texError){throw o}m=this.formatError(o,p,r,l);n=true}if(m.isa(h.mtable)&&m.displaystyle==="inherit"){m.displaystyle=r}if(m.inferred){m=h.apply(MathJax.ElementJax,m.data)}else{m=h(m)}if(r){m.root.display="block"}if(n){m.texError=true}q.math=m;return this.postfilterHooks.Execute(q)||q.math},prefilterMath:function(m,n,l){return m},postfilterMath:function(m,n,l){this.combineRelations(m.root);return m},formatError:function(o,n,p,l){var m=o.message.replace(/\n.*/,"");c.signal.Post(["TeX Jax - parse error",m,n,p,l]);return h.Error(m)},Error:function(l){if(l instanceof Array){l=j.apply(j,l)}throw c.Insert(Error(l),{texError:true})},Macro:function(l,m,n){f.macros[l]=["Macro"].concat([].slice.call(arguments,1));f.macros[l].isUser=true},fenced:function(n,m,o){var l=h.mrow().With({open:n,close:o,texClass:h.TEXCLASS.INNER});l.Append(h.mo(n).With({fence:true,stretchy:true,texClass:h.TEXCLASS.OPEN}));if(m.type==="mrow"){l.Append.apply(l,m.data)}else{l.Append(m)}l.Append(h.mo(o).With({fence:true,stretchy:true,texClass:h.TEXCLASS.CLOSE}));return l},fixedFence:function(n,m,o){var l=h.mrow().With({open:n,close:o,texClass:h.TEXCLASS.ORD});if(n){l.Append(this.mathPalette(n,"l"))}if(m.type==="mrow"){l.Append.apply(l,m.data)}else{l.Append(m)}if(o){l.Append(this.mathPalette(o,"r"))}return l},mathPalette:function(o,m){if(o==="{"||o==="}"){o="\\"+o}var n="{\\bigg"+m+" "+o+"}",l="{\\big"+m+" "+o+"}";return d.Parse("\\mathchoice"+n+l+l+l).mml()},combineRelations:function(p){var q,l,o,n;for(q=0,l=p.data.length;q0){o+="rl";m.push("0em 0em");p--}m=m.join(" ");if(h){return this.AMSarray(k,i,h,o,m)}var l=this.Array.call(this,k,null,null,o,m,".5em","D");return this.setArrayAlign(l,j)},EquationBegin:function(h,i){this.checkEqnEnv();this.stack.global.forcetag=(i&&a.autoNumber!=="none");return h},EquationStar:function(h,i){this.stack.global.tagged=true;return i},checkEqnEnv:function(){if(this.stack.global.eqnenv){g.Error(["ErroneousNestingEq","Erroneous nesting of equation structures"])}this.stack.global.eqnenv=true},MultiIntegral:function(h,l){var k=this.GetNext();if(k==="\\"){var j=this.i;k=this.GetArgument(h);this.i=j;if(k==="\\limits"){if(h==="\\idotsint"){l="\\!\\!\\mathop{\\,\\,"+l+"}"}else{l="\\!\\!\\!\\mathop{\\,\\,\\,"+l+"}"}}}this.string=l+" "+this.string.slice(this.i);this.i=0},xArrow:function(j,n,m,h){var k={width:"+"+(m+h)+"mu",lspace:m+"mu"};var o=this.GetBrackets(j),p=this.ParseArg(j);var q=b.mo(b.chars(String.fromCharCode(n))).With({stretchy:true,texClass:b.TEXCLASS.REL});var i=b.munderover(q);i.SetData(i.over,b.mpadded(p).With(k).With({voffset:".15em"}));if(o){o=g.Parse(o,this.stack.env).mml();i.SetData(i.under,b.mpadded(o).With(k).With({voffset:"-.24em"}))}this.Push(i.With({subsupOK:true}))},GetDelimiterArg:function(h){var i=this.trimSpaces(this.GetArgument(h));if(i==""){return null}if(d.delimiter[i]==null){g.Error(["MissingOrUnrecognizedDelim","Missing or unrecognized delimiter for %1",h])}return this.convertDelimiter(i)},GetStar:function(){var h=(this.GetNext()==="*");if(h){this.i++}return h}});e.Augment({autoTag:function(){var i=this.global;if(!i.notag){f.number++;i.tagID=a.formatNumber(f.number.toString());var h=g.Parse("\\text{"+a.formatTag(i.tagID)+"}",{}).mml();i.tag=b.mtd(h).With({id:a.formatID(i.tagID)})}},getTag:function(){var l=this.global,j=l.tag;l.tagged=true;if(l.label){if(a.useLabelIds){j.id=a.formatID(l.label)}f.eqlabels[l.label]={tag:l.tagID,id:j.id}}if(document.getElementById(j.id)||f.IDs[j.id]||f.eqIDs[j.id]){var k=0,h;do{k++;h=j.id+"_"+k}while(document.getElementById(h)||f.IDs[h]||f.eqIDs[h]);j.id=h;if(l.label){f.eqlabels[l.label].id=h}}f.eqIDs[j.id]=1;this.clearTag();return j},clearTag:function(){var h=this.global;delete h.tag;delete h.tagID;delete h.label},fixInitialMO:function(k){for(var j=0,h=k.length;j element, not %1","<"+j.firstChild.nodeName+">"])}var i={math:j.firstChild,script:e};c.DOMfilterHooks.Execute(i);this.mml=this.MakeMML(i.math)},MakeMML:function(h){var i=String(h.getAttribute("class")||"");var f,g=h.nodeName.toLowerCase().replace(/^[a-z]+:/,"");var e=(i.match(/(^| )MJX-TeXAtom-([^ ]*)/));if(e){f=this.TeXAtom(e[2])}else{if(!(a[g]&&a[g].isa&&a[g].isa(a.mbase))){MathJax.Hub.signal.Post(["MathML Jax - unknown node type",g]);return a.Error(b("UnknownNodeType","Unknown node type: %1",g))}else{f=a[g]()}}this.AddAttributes(f,h);this.CheckClass(f,f["class"]);this.AddChildren(f,h);if(c.config.useMathMLspacing){f.useMMLspacing=8}return f},TeXAtom:function(f){var e=a.TeXAtom().With({texClass:a.TEXCLASS[f]});if(e.texClass===a.TEXCLASS.OP){e.movesupsub=e.movablelimits=true}return e},CheckClass:function(f,h){h=(h||"").split(/ /);var j=[];for(var g=0,e=h.length;g=2){var l=e.data[0],n=e.data[e.data.length-1];if(l.type==="mo"&&l.Get("fence")&&n.type==="mo"&&n.Get("fence")){if(l.data[0]){e.open=l.data.join("")}if(n.data[0]){e.close=n.data.join("")}}}},preProcessMath:function(f){if(f.match(/^<[a-z]+:/i)&&!f.match(/^<[^<>]* xmlns:/)){f=f.replace(/^<([a-z]+)(:math)/i,'<$1$2 xmlns:$1="http://www.w3.org/1998/Math/MathML"')}var e=f.match(/^(])+)>)/i);if(e&&e[2].match(/ (?!xmlns=)[a-z]+=\"http:/i)){f=e[1].replace(/ (?!xmlns=)([a-z]+=(['"])http:.*?\2)/ig," xmlns:$1 $1")+f.substr(e[0].length)}if(f.match(/^]* xmlns=/)){f=f.replace(/^<(math)/i,'\s*$/,"$2");return f.replace(/&([a-z][a-z0-9]*);/ig,this.replaceEntity)},trimSpace:function(e){return e.replace(/[\t\n\r]/g," ").replace(/^ +/,"").replace(/ +$/,"").replace(/ +/g," ")},replaceEntity:function(g,f){if(f.match(/^(lt|amp|quot)$/)){return g}if(c.Parse.Entity[f]){return c.Parse.Entity[f]}var h=f.charAt(0).toLowerCase();var e=f.match(/^[a-zA-Z](fr|scr|opf)$/);if(e){h=e[1]}if(!c.Parse.loaded[h]){c.Parse.loaded[h]=true;MathJax.Hub.RestartAfter(MathJax.Ajax.Require(c.entityDir+"/"+h+".js"))}return g}},{loaded:[]});c.Augment({sourceMenuTitle:["OriginalMathML","Original MathML"],prefilterHooks:MathJax.Callback.Hooks(true),DOMfilterHooks:MathJax.Callback.Hooks(true),postfilterHooks:MathJax.Callback.Hooks(true),Translate:function(e){if(!this.ParseXML){this.ParseXML=this.createParser()}var f,h,i={script:e};if(e.firstChild&&e.firstChild.nodeName.toLowerCase().replace(/^[a-z]+:/,"")==="math"){i.math=e.firstChild}else{h=MathJax.HTML.getScript(e);if(d.isMSIE){h=h.replace(/( )+$/,"")}i.math=h}var j=this.prefilterHooks.Execute(i);if(j){return j}h=i.math;try{f=c.Parse(h,e).mml}catch(g){if(!g.mathmlError){throw g}f=this.formatError(g,h,e)}i.math=a(f);return this.postfilterHooks.Execute(i)||i.math},prefilterMath:function(f,e){return f},prefilterMathML:function(f,e){return f},formatError:function(h,g,e){var f=h.message.replace(/\n.*/,"");MathJax.Hub.signal.Post(["MathML Jax - parse error",f,g,e]);return a.Error(f)},Error:function(e){if(e instanceof Array){e=b.apply(b,e)}throw MathJax.Hub.Insert(Error(e),{mathmlError:true})},parseDOM:function(e){return this.parser.parseFromString(e,"text/xml")},parseMS:function(e){return(this.parser.loadXML(e)?this.parser:null)},parseDIV:function(e){this.div.innerHTML="
    "+e.replace(/<([a-z]+)([^>]*)\/>/g,"<$1$2>")+"
    ";var f=this.div.firstChild;this.div.innerHTML="";return f},parseError:function(e){return null},createMSParser:function(){var j=null;var f=["MSXML2.DOMDocument.6.0","MSXML2.DOMDocument.5.0","MSXML2.DOMDocument.4.0","MSXML2.DOMDocument.3.0","MSXML2.DOMDocument.2.0","Microsoft.XMLDOM"];for(var g=0,e=f.length;g *":{display:"table-row!important"},".MJXc-surd":{"vertical-align":"top"},".MJXc-surd > *":{display:"block!important"},".MJXc-script-box > * ":{display:"table!important",height:"50%"},".MJXc-script-box > * > *":{display:"table-cell!important","vertical-align":"top"},".MJXc-script-box > *:last-child > *":{"vertical-align":"bottom"},".MJXc-script-box > * > * > *":{display:"block!important"},".MJXc-mphantom":{visibility:"hidden"},".MJXc-munderover":{display:"inline-table!important"},".MJXc-over":{display:"inline-block!important","text-align":"center"},".MJXc-over > *":{display:"block!important"},".MJXc-munderover > *":{display:"table-row!important"},".MJXc-mtable":{"vertical-align":".25em",margin:"0 .125em"},".MJXc-mtable > *":{display:"inline-table!important","vertical-align":"middle"},".MJXc-mtr":{display:"table-row!important"},".MJXc-mtd":{display:"table-cell!important","text-align":"center",padding:".5em 0 0 .5em"},".MJXc-mtr > .MJXc-mtd:first-child":{"padding-left":0},".MJXc-mtr:first-child > .MJXc-mtd":{"padding-top":0},".MJXc-mlabeledtr":{display:"table-row!important"},".MJXc-mlabeledtr > .MJXc-mtd:first-child":{"padding-left":0},".MJXc-mlabeledtr:first-child > .MJXc-mtd":{"padding-top":0},".MJXc-merror":{"background-color":"#FFFF88",color:"#CC0000",border:"1px solid #CC0000",padding:"1px 3px","font-style":"normal","font-size":"90%"}};(function(){for(var n=0;n<10;n++){var o="scaleX(."+n+")";m[".MJXc-scale"+n]={"-webkit-transform":o,"-moz-transform":o,"-ms-transform":o,"-o-transform":o,transform:o}}})();var k=1000000;var c="V",l="H";g.Augment({settings:b.config.menuSettings,config:{styles:m},hideProcessedMath:false,maxStretchyParts:1000,Config:function(){if(!this.require){this.require=[]}this.SUPER(arguments).Config.call(this);var n=this.settings;if(n.scale){this.config.scale=n.scale}this.require.push(MathJax.OutputJax.extensionDir+"/MathEvents.js")},Startup:function(){j=MathJax.Extension.MathEvents.Event;a=MathJax.Extension.MathEvents.Touch;d=MathJax.Extension.MathEvents.Hover;this.ContextMenu=j.ContextMenu;this.Mousedown=j.AltContextMenu;this.Mouseover=d.Mouseover;this.Mouseout=d.Mouseout;this.Mousemove=d.Mousemove;var n=e.addElement(document.body,"div",{style:{width:"5in"}});this.pxPerInch=n.offsetWidth/5;n.parentNode.removeChild(n);return i.Styles(this.config.styles,["InitializeCHTML",this])},InitializeCHTML:function(){},preTranslate:function(p){var s=p.jax[this.id],t,q=s.length,u,r,v,o,n;for(t=0;tthis.CHTML.h){this.CHTML.h=q.CHTML.h}if(q.CHTML.d>this.CHTML.d){this.CHTML.d=q.CHTML.d}if(q.CHTML.t>this.CHTML.t){this.CHTML.t=q.CHTML.t}if(q.CHTML.b>this.CHTML.b){this.CHTML.b=q.CHTML.b}}}else{if(n.forceChild){e.addElement(p,"span")}}},CHTMLstretchChild:function(q,p,s){var r=this.data[q];if(r&&r.CHTMLcanStretch("Vertical",p,s)){var t=this.CHTML,o=r.CHTML,n=o.w;r.CHTMLstretchV(p,s);t.w+=o.w-n;if(o.h>t.h){t.h=o.h}if(o.d>t.d){t.d=o.d}}},CHTMLcreateSpan:function(n){if(!this.CHTML){this.CHTML={}}this.CHTML={w:0,h:0,d:0,l:0,r:0,t:0,b:0};if(this.inferred){return n}if(this.type==="mo"&&this.data.join("")==="\u222B"){g.lastIsInt=true}else{if(this.type!=="mspace"||this.width!=="negativethinmathspace"){g.lastIsInt=false}}if(!this.CHTMLspanID){this.CHTMLspanID=g.GetID()}var o=(this.id||"MJXc-Span-"+this.CHTMLspanID);return e.addElement(n,"span",{className:"MJXc-"+this.type,id:o})},CHTMLspanElement:function(){if(!this.CHTMLspanID){return null}return document.getElementById(this.id||"MJXc-Span-"+this.CHTMLspanID)},CHTMLhandleToken:function(o){var n=this.getValues("mathvariant");if(n.mathvariant!==h.VARIANT.NORMAL){o.className+=" "+g.VARIANT[n.mathvariant]}},CHTMLhandleStyle:function(n){if(this.style){n.style.cssText=this.style}},CHTMLhandleColor:function(n){if(this.mathcolor){n.style.color=this.mathcolor}if(this.mathbackground){n.style.backgroundColor=this.mathbackground}},CHTMLhandleScriptlevel:function(n){var o=this.Get("scriptlevel");if(o){n.className+=" MJXc-script"}},CHTMLhandleText:function(y,A){var v,p;var z=0,o=0,q=0;for(var s=0,r=A.length;s=55296&&p<56319){s++;p=(((p-55296)<<10)+(A.charCodeAt(s)-56320))+65536}var t=0.7,u=0.22,x=0.5;if(p<127){if(v.match(/[A-Za-ehik-or-xz0-9]/)){u=0}if(v.match(/[A-HK-Z]/)){x=0.67}else{if(v.match(/[IJ]/)){x=0.36}}if(v.match(/[acegm-su-z]/)){t=0.45}else{if(v.match(/[ij]/)){t=0.75}}if(v.match(/[ijlt]/)){x=0.28}}if(g.DELIMITERS[v]){x=g.DELIMITERS[v].w||0.4}if(t>z){z=t}if(u>o){o=u}q+=x}if(!this.CHML){this.CHTML={}}this.CHTML={h:0.9,d:0.3,w:q,l:0,r:0,t:z,b:o};e.addText(y,A)},CHTMLbboxFor:function(o){if(this.data[o]&&this.data[o].CHTML){return this.data[o].CHTML}return{w:0,h:0,d:0,l:0,r:0,t:0,b:0}},CHTMLcanStretch:function(q,o,p){if(this.isEmbellished()){var n=this.Core();if(n&&n!==this){return n.CHTMLcanStretch(q,o,p)}}return false},CHTMLstretchV:function(n,o){},CHTMLstretchH:function(n){},CoreParent:function(){var n=this;while(n&&n.isEmbellished()&&n.CoreMO()===this&&!n.isa(h.math)){n=n.Parent()}return n},CoreText:function(n){if(!n){return""}if(n.isEmbellished()){return n.CoreMO().data.join("")}while((n.isa(h.mrow)||n.isa(h.TeXAtom)||n.isa(h.mstyle)||n.isa(h.mphantom))&&n.data.length===1&&n.data[0]){n=n.data[0]}if(!n.isToken){return""}else{return n.data.join("")}}});h.chars.Augment({toCommonHTML:function(n){var o=this.toString().replace(/[\u2061-\u2064]/g,"");this.CHTMLhandleText(n,o)}});h.entity.Augment({toCommonHTML:function(n){var o=this.toString().replace(/[\u2061-\u2064]/g,"");this.CHTMLhandleText(n,o)}});h.math.Augment({toCommonHTML:function(n){n=this.CHTMLdefaultSpan(n);if(this.Get("display")==="block"){n.className+=" MJXc-display"}return n}});h.mo.Augment({toCommonHTML:function(o){o=this.CHTMLdefaultSpan(o);this.CHTMLadjustAccent(o);var n=this.getValues("lspace","rspace","scriptlevel","displaystyle","largeop");if(n.scriptlevel===0){this.CHTML.l=g.length2em(n.lspace);this.CHTML.r=g.length2em(n.rspace);o.style.marginLeft=g.Em(this.CHTML.l);o.style.marginRight=g.Em(this.CHTML.r)}else{this.CHTML.l=0.15;this.CHTML.r=0.1}if(n.displaystyle&&n.largeop){var p=e.Element("span",{className:"MJXc-largeop"});p.appendChild(o.firstChild);o.appendChild(p);this.CHTML.h*=1.2;this.CHTML.d*=1.2;if(this.data.join("")==="\u222B"){p.className+=" MJXc-int"}}return o},CHTMLadjustAccent:function(p){var o=this.CoreParent();if(o&&o.isa(h.munderover)&&this.CoreText(o.data[o.base]).length===1){var q=o.data[o.over],n=o.data[o.under];var s=this.data.join(""),r;if(q&&this===q.CoreMO()&&o.Get("accent")){r=g.REMAPACCENT[s]}else{if(n&&this===n.CoreMO()&&o.Get("accentunder")){r=g.REMAPACCENTUNDER[s]}}if(r){s=p.innerHTML=r}if(s.match(/[\u02C6-\u02DC\u00A8]/)){this.CHTML.acc=-0.52}else{if(s==="\u2192"){this.CHTML.acc=-0.15;this.CHTML.vec=true}}}},CHTMLcanStretch:function(q,o,p){if(!this.Get("stretchy")){return false}var r=this.data.join("");if(r.length>1){return false}r=g.DELIMITERS[r];var n=(r&&r.dir===q.substr(0,1));if(n){n=(this.CHTML.h!==o||this.CHTML.d!==p||(this.Get("minsize",true)||this.Get("maxsize",true)))}return n},CHTMLstretchV:function(p,u){var o=this.CHTMLspanElement(),t=this.CHTML;var n=this.getValues("symmetric","maxsize","minsize");if(n.symmetric){l=2*Math.max(p-0.25,u+0.25)}else{l=p+u}n.maxsize=g.length2em(n.maxsize,t.h+t.d);n.minsize=g.length2em(n.minsize,t.h+t.d);l=Math.max(n.minsize,Math.min(n.maxsize,l));var s=l/(t.h+t.d-0.3);var q=e.Element("span",{style:{"font-size":g.Em(s)}});if(s>1.25){var r=Math.ceil(1.25/s*10);q.className="MJXc-right MJXc-scale"+r;q.style.marginLeft=g.Em(t.w*(r/10-1)+0.07);t.w*=s*r/10}q.appendChild(o.firstChild);o.appendChild(q);if(n.symmetric){o.style.verticalAlign=g.Em(0.25*(1-s))}}});h.mspace.Augment({toCommonHTML:function(q){q=this.CHTMLdefaultSpan(q);var o=this.getValues("height","depth","width");var n=g.length2em(o.width),p=g.length2em(o.height),s=g.length2em(o.depth);var r=this.CHTML;r.w=n;r.h=p;r.d=s;if(n<0){if(!g.lastIsInt){q.style.marginLeft=g.Em(n)}n=0}q.style.width=g.Em(n);q.style.height=g.Em(p+s);if(s){q.style.verticalAlign=g.Em(-s)}return q}});h.mpadded.Augment({toCommonHTML:function(u){u=this.CHTMLdefaultSpan(u,{childSpans:true,className:"MJXc-box",forceChild:true});var o=u.firstChild;var v=this.getValues("width","height","depth","lspace","voffset");var s=this.CHTMLdimen(v.lspace);var q=0,n=0,t=s.len,r=-s.len,p=0;if(v.width!==""){s=this.CHTMLdimen(v.width,"w",0);if(s.pm){r+=s.len}else{u.style.width=g.Em(s.len)}}if(v.height!==""){s=this.CHTMLdimen(v.height,"h",0);if(!s.pm){q+=-this.CHTMLbboxFor(0).h}q+=s.len}if(v.depth!==""){s=this.CHTMLdimen(v.depth,"d",0);if(!s.pm){n+=-this.CHTMLbboxFor(0).d;p+=-s.len}n+=s.len}if(v.voffset!==""){s=this.CHTMLdimen(v.voffset);q-=s.len;n+=s.len;p+=s.len}if(q){o.style.marginTop=g.Em(q)}if(n){o.style.marginBottom=g.Em(n)}if(t){o.style.marginLeft=g.Em(t)}if(r){o.style.marginRight=g.Em(r)}if(p){u.style.verticalAlign=g.Em(p)}return u},CHTMLdimen:function(q,r,n){if(n==null){n=-k}q=String(q);var o=q.match(/width|height|depth/);var p=(o?this.CHTML[o[0].charAt(0)]:(r?this.CHTML[r]:0));return{len:g.length2em(q,p)||0,pm:!!q.match(/^[-+]/)}}});h.munderover.Augment({toCommonHTML:function(q){var n=this.getValues("displaystyle","accent","accentunder","align");if(!n.displaystyle&&this.data[this.base]!=null&&this.data[this.base].CoreMO().Get("movablelimits")){q=h.msubsup.prototype.toCommonHTML.call(this,q);q.className=q.className.replace(/munderover/,"msubsup");return q}q=this.CHTMLdefaultSpan(q,{childSpans:true,className:"",noBBox:true});var p=this.CHTMLbboxFor(this.over),s=this.CHTMLbboxFor(this.under),u=this.CHTMLbboxFor(this.base),o=this.CHTML,r=p.acc;if(this.data[this.over]){q.lastChild.firstChild.style.marginLeft=p.l=q.lastChild.firstChild.style.marginRight=p.r=0;var t=e.Element("span",{},[["span",{className:"MJXc-over"}]]);t.firstChild.appendChild(q.lastChild);if(q.childNodes.length>(this.data[this.under]?1:0)){t.firstChild.appendChild(q.firstChild)}this.data[this.over].CHTMLhandleScriptlevel(t.firstChild.firstChild);if(r!=null){if(p.vec){t.firstChild.firstChild.firstChild.style.fontSize="60%";p.h*=0.6;p.d*=0.6;p.w*=0.6}r=r-p.d+0.1;if(u.t!=null){r+=u.t-u.h}t.firstChild.firstChild.style.marginBottom=g.Em(r)}if(q.firstChild){q.insertBefore(t,q.firstChild)}else{q.appendChild(t)}}if(this.data[this.under]){q.lastChild.firstChild.style.marginLeft=s.l=q.lastChild.firstChild.marginRight=s.r=0;this.data[this.under].CHTMLhandleScriptlevel(q.lastChild)}o.w=Math.max(0.8*p.w,0.8*s.w,u.w);o.h=0.8*(p.h+p.d+(r||0))+u.h;o.d=u.d+0.8*(s.h+s.d);return q}});h.msubsup.Augment({toCommonHTML:function(q){q=this.CHTMLdefaultSpan(q,{noBBox:true});if(!this.data[this.base]){if(q.firstChild){q.insertBefore(e.Element("span"),q.firstChild)}else{q.appendChild(e.Element("span"))}}var s=this.data[this.base],p=this.data[this.sub],n=this.data[this.sup];if(!s){s={bbox:{h:0.8,d:0.2}}}q.firstChild.style.marginRight=".05em";var o=Math.max(0.4,s.CHTML.h-0.4),u=Math.max(0.2,s.CHTML.d+0.1);var t=this.CHTML;if(n&&p){var r=e.Element("span",{className:"MJXc-script-box",style:{height:g.Em(o+n.CHTML.h*0.8+u+p.CHTML.d*0.8),"vertical-align":g.Em(-u-p.CHTML.d*0.8)}},[["span",{},[["span",{},[["span",{style:{"margin-bottom":g.Em(-(n.CHTML.d-0.05))}}]]]]],["span",{},[["span",{},[["span",{style:{"margin-top":g.Em(-(n.CHTML.h-0.05))}}]]]]]]);p.CHTMLhandleScriptlevel(r.firstChild);n.CHTMLhandleScriptlevel(r.lastChild);r.firstChild.firstChild.firstChild.appendChild(q.lastChild);r.lastChild.firstChild.firstChild.appendChild(q.lastChild);q.appendChild(r);t.h=Math.max(s.CHTML.h,n.CHTML.h*0.8+o);t.d=Math.max(s.CHTML.d,p.CHTML.d*0.8+u);t.w=s.CHTML.w+Math.max(n.CHTML.w,p.CHTML.w)+0.07}else{if(n){q.lastChild.style.verticalAlign=g.Em(o);n.CHTMLhandleScriptlevel(q.lastChild);t.h=Math.max(s.CHTML.h,n.CHTML.h*0.8+o);t.d=Math.max(s.CHTML.d,n.CHTML.d*0.8-o);t.w=s.CHTML.w+n.CHTML.w+0.07}else{if(p){q.lastChild.style.verticalAlign=g.Em(-u);p.CHTMLhandleScriptlevel(q.lastChild);t.h=Math.max(s.CHTML.h,p.CHTML.h*0.8-u);t.d=Math.max(s.CHTML.d,p.CHTML.d*0.8+u);t.w=s.CHTML.w+p.CHTML.w+0.07}}}return q}});h.mfrac.Augment({toCommonHTML:function(r){r=this.CHTMLdefaultSpan(r,{childSpans:true,className:"MJXc-box",forceChild:true,noBBox:true});var o=this.getValues("linethickness","displaystyle");if(!o.displaystyle){if(this.data[0]){this.data[0].CHTMLhandleScriptlevel(r.firstChild)}if(this.data[1]){this.data[1].CHTMLhandleScriptlevel(r.lastChild)}}var n=e.Element("span",{className:"MJXc-box",style:{"margin-top":"-.8em"}},[["span",{className:"MJXc-denom"},[["span",{},[["span",{className:"MJXc-rule"}]]],["span"]]]]);n.firstChild.lastChild.appendChild(r.lastChild);r.appendChild(n);var s=this.CHTMLbboxFor(0),p=this.CHTMLbboxFor(1),v=this.CHTML;v.w=Math.max(s.w,p.w)*0.8;v.h=s.h+s.d+0.1+0.25;v.d=p.h+p.d-0.25;v.l=v.r=0.125;o.linethickness=Math.max(0,g.length2em(o.linethickness||"0",0));if(o.linethickness){var u=n.firstChild.firstChild.firstChild;var q=g.Em(o.linethickness);u.style.borderTop=(o.linethickness<0.15?"1px":q)+" solid";u.style.margin=q+" 0";q=o.linethickness;n.style.marginTop=g.Em(3*q-0.9);r.style.verticalAlign=g.Em(1.5*q+0.1);v.h+=1.5*q-0.1;v.d+=1.5*q}return r}});h.msqrt.Augment({toCommonHTML:function(n){n=this.CHTMLdefaultSpan(n,{childSpans:true,className:"MJXc-box",forceChild:true,noBBox:true});this.CHTMLlayoutRoot(n,n.firstChild);return n},CHTMLlayoutRoot:function(u,n){var v=this.CHTMLbboxFor(0);var q=Math.ceil((v.h+v.d+0.14)*100),w=g.Em(14/q);var r=e.Element("span",{className:"MJXc-surd"},[["span",{style:{"font-size":q+"%","margin-top":w}},["\u221A"]]]);var s=e.Element("span",{className:"MJXc-root"},[["span",{className:"MJXc-rule",style:{"border-top":".08em solid"}}]]);var p=(1.2/2.2)*q/100;if(q>150){var o=Math.ceil(150/q*10);r.firstChild.className="MJXc-right MJXc-scale"+o;r.firstChild.style.marginLeft=g.Em(p*(o/10-1)/q*100);p=p*o/10;s.firstChild.style.borderTopWidth=g.Em(0.08/Math.sqrt(o/10))}s.appendChild(n);u.appendChild(r);u.appendChild(s);this.CHTML.h=v.h+0.18;this.CHTML.d=v.d;this.CHTML.w=v.w+p;return u}});h.mroot.Augment({toCommonHTML:function(q){q=this.CHTMLdefaultSpan(q,{childSpans:true,className:"MJXc-box",forceChild:true,noBBox:true});var p=this.CHTMLbboxFor(1),n=q.removeChild(q.lastChild);var t=this.CHTMLlayoutRoot(e.Element("span"),q.firstChild);n.className="MJXc-script";var u=parseInt(t.firstChild.firstChild.style.fontSize);var o=0.55*(u/120)+p.d*0.8,s=-0.6*(u/120);if(u>150){s*=0.95*Math.ceil(150/u*10)/10}n.style.marginRight=g.Em(s);n.style.verticalAlign=g.Em(o);if(-s>p.w*0.8){n.style.marginLeft=g.Em(-s-p.w*0.8)}q.appendChild(n);q.appendChild(t);this.CHTML.w+=Math.max(0,p.w*0.8+s);this.CHTML.h=Math.max(this.CHTML.h,p.h*0.8+o);return q},CHTMLlayoutRoot:h.msqrt.prototype.CHTMLlayoutRoot});h.mfenced.Augment({toCommonHTML:function(q){q=this.CHTMLcreateSpan(q);this.CHTMLhandleStyle(q);this.CHTMLhandleColor(q);this.addFakeNodes();this.CHTMLaddChild(q,"open",{});for(var p=0,n=this.data.length;ps){s=x.w}}}var o=this.CHTML;o.w=s;o.h=y/2+0.25;o.d=y/2-0.25;o.l=o.r=0.125;return E}});h.mlabeledtr.Augment({CHTMLdefaultSpan:function(q,o){if(!o){o={}}q=this.CHTMLcreateSpan(q);this.CHTMLhandleStyle(q);this.CHTMLhandleColor(q);if(this.isToken){this.CHTMLhandleToken(q)}for(var p=1,n=this.data.length;psvg" : { + "max-height": "800px", + "max-width": "500px", + }} +}); + +$(document).on('new_post', function() { + MathJax.Hub.Queue(["Typeset",MathJax.Hub]); +}); + +MathJax.Ajax.loadComplete("[MathJax]/config/8chanTeX.js"); + diff --git a/js/quick-reply.js b/js/quick-reply.js index c5738eec..399e759b 100644 --- a/js/quick-reply.js +++ b/js/quick-reply.js @@ -98,9 +98,6 @@ #quick-reply .nonsense {\ display: none;\ }\ - #quick-reply td.submit {\ - width: 1%;\ - }\ #quick-reply td.recaptcha {\ text-align: center;\ padding: 0 0 1px 0;\ @@ -257,7 +254,7 @@ } // Remove mod controls, because it looks shit. - if ($td.find('input[type="checkbox"]').length) { + /*if ($td.find('input[type="checkbox"]').length) { var tr = this; $td.find('input[type="checkbox"]').each(function() { if ($(this).attr('name') == 'spoiler') { @@ -272,7 +269,7 @@ $(tr).remove(); } }); - } + }*/ $td.find('small').hide(); } diff --git a/js/settings.js b/js/settings.js index 81e88f7a..267a85aa 100644 --- a/js/settings.js +++ b/js/settings.js @@ -35,7 +35,7 @@ tb_settings['quick-reply'] = { // Show remote in quick reply show_remote: false, // Show embedding in quick reply - show_embed: false + show_embed: true }; // ajax.js diff --git a/js/twemoji/twemoji.js b/js/twemoji/twemoji.js index c3bffbe8..bd0eb4d6 100644 --- a/js/twemoji/twemoji.js +++ b/js/twemoji/twemoji.js @@ -513,13 +513,14 @@ var twemoji = (function ( }()); -onready(function(){ +$(document).ready(function () { var twemoji_opts = { callback: function(icon, options, variant) { switch ( icon ) { case 'a9': // copyright case 'ae': // (R) case '2122': // TM + case '25b6': // post filter return false; } return ''.concat(options.base, options.size, '/', icon, options.ext); diff --git a/post.php b/post.php index 86b7de61..7e22612a 100644 --- a/post.php +++ b/post.php @@ -394,6 +394,15 @@ elseif (isset($_POST['post'])) { $post['name'] = $_POST['name'] != '' ? $_POST['name'] : $config['anonymous']; $post['subject'] = $_POST['subject']; $post['email'] = str_replace(' ', '%20', htmlspecialchars($_POST['email'])); + + if (isset($_POST['no-bump'])) { + if (!empty($post['email'])) { + $post['email'] .= '+sage'; + } else { + $post['email'] = 'sage'; + } + } + $post['body'] = $_POST['body']; $post['password'] = $_POST['password']; $post['has_file'] = (!isset($post['embed']) && (($post['op'] && !isset($post['no_longer_require_an_image_for_op']) && $config['force_image_op']) || !empty($_FILES['file']['name']))); @@ -887,7 +896,7 @@ elseif (isset($_POST['post'])) { query('INSERT INTO ``cites`` VALUES ' . implode(', ', $insert_rows)) or error(db_error()); } - if (!$post['op'] && strtolower($post['email']) != 'sage' && !$thread['sage'] && ($config['reply_limit'] == 0 || $numposts['replies']+1 < $config['reply_limit'])) { + if (!$post['op'] && !isset($_POST['no-bump']) && strtolower($post['email']) != 'sage' && !$thread['sage'] && ($config['reply_limit'] == 0 || $numposts['replies']+1 < $config['reply_limit'])) { bumpThread($post['thread']); } diff --git a/settings.php b/settings.php index 2d29a122..8ed599df 100644 --- a/settings.php +++ b/settings.php @@ -11,6 +11,9 @@ if (!openBoard($_GET['board'])) { } header('Content-Type: text/json'); +$safe_config['title'] = $board['title']; +$safe_config['subtitle'] = $board['subtitle']; +$safe_config['indexed'] = ($board['indexed'] == "1"); $safe_config['country_flags'] = $config['country_flags']; $safe_config['field_disable_name'] = $config['field_disable_name']; $safe_config['enable_embedding'] = $config['enable_embedding']; diff --git a/stylesheets/font-awesome/css/font-awesome.css b/stylesheets/font-awesome/css/font-awesome.css index eb4127b7..2dcdc220 100644 --- a/stylesheets/font-awesome/css/font-awesome.css +++ b/stylesheets/font-awesome/css/font-awesome.css @@ -1,24 +1,24 @@ /*! - * Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome + * Font Awesome 4.3.0 by @davegandy - http://fontawesome.io - @fontawesome * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) */ /* FONT PATH * -------------------------- */ @font-face { font-family: 'FontAwesome'; - src: url('../fonts/fontawesome-webfont.eot?v=4.1.0'); - src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.1.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff?v=4.1.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.1.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.1.0#fontawesomeregular') format('svg'); + src: url('../fonts/fontawesome-webfont.eot?v=4.3.0'); + src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.3.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.3.0') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.3.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.3.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.3.0#fontawesomeregular') format('svg'); font-weight: normal; font-style: normal; } .fa { display: inline-block; - font-family: FontAwesome; - font-style: normal; - font-weight: normal; - line-height: 1; + font: normal normal normal 14px/1 FontAwesome; + font-size: inherit; + text-rendering: auto; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; + transform: translate(0, 0); } /* makes the font 33% larger relative to the icon container */ .fa-lg { @@ -78,36 +78,24 @@ margin-left: .3em; } .fa-spin { - -webkit-animation: spin 2s infinite linear; - -moz-animation: spin 2s infinite linear; - -o-animation: spin 2s infinite linear; - animation: spin 2s infinite linear; + -webkit-animation: fa-spin 2s infinite linear; + animation: fa-spin 2s infinite linear; } -@-moz-keyframes spin { - 0% { - -moz-transform: rotate(0deg); - } - 100% { - -moz-transform: rotate(359deg); - } +.fa-pulse { + -webkit-animation: fa-spin 1s infinite steps(8); + animation: fa-spin 1s infinite steps(8); } -@-webkit-keyframes spin { +@-webkit-keyframes fa-spin { 0% { -webkit-transform: rotate(0deg); + transform: rotate(0deg); } 100% { -webkit-transform: rotate(359deg); + transform: rotate(359deg); } } -@-o-keyframes spin { - 0% { - -o-transform: rotate(0deg); - } - 100% { - -o-transform: rotate(359deg); - } -} -@keyframes spin { +@keyframes fa-spin { 0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); @@ -120,43 +108,40 @@ .fa-rotate-90 { filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); -webkit-transform: rotate(90deg); - -moz-transform: rotate(90deg); -ms-transform: rotate(90deg); - -o-transform: rotate(90deg); transform: rotate(90deg); } .fa-rotate-180 { filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2); -webkit-transform: rotate(180deg); - -moz-transform: rotate(180deg); -ms-transform: rotate(180deg); - -o-transform: rotate(180deg); transform: rotate(180deg); } .fa-rotate-270 { filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3); -webkit-transform: rotate(270deg); - -moz-transform: rotate(270deg); -ms-transform: rotate(270deg); - -o-transform: rotate(270deg); transform: rotate(270deg); } .fa-flip-horizontal { filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1); -webkit-transform: scale(-1, 1); - -moz-transform: scale(-1, 1); -ms-transform: scale(-1, 1); - -o-transform: scale(-1, 1); transform: scale(-1, 1); } .fa-flip-vertical { filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1); -webkit-transform: scale(1, -1); - -moz-transform: scale(1, -1); -ms-transform: scale(1, -1); - -o-transform: scale(1, -1); transform: scale(1, -1); } +:root .fa-rotate-90, +:root .fa-rotate-180, +:root .fa-rotate-270, +:root .fa-flip-horizontal, +:root .fa-flip-vertical { + filter: none; +} .fa-stack { position: relative; display: inline-block; @@ -222,6 +207,8 @@ .fa-check:before { content: "\f00c"; } +.fa-remove:before, +.fa-close:before, .fa-times:before { content: "\f00d"; } @@ -551,7 +538,8 @@ .fa-arrows-h:before { content: "\f07e"; } -.fa-bar-chart-o:before { +.fa-bar-chart-o:before, +.fa-bar-chart:before { content: "\f080"; } .fa-twitter-square:before { @@ -627,6 +615,7 @@ .fa-twitter:before { content: "\f099"; } +.fa-facebook-f:before, .fa-facebook:before { content: "\f09a"; } @@ -1276,7 +1265,8 @@ .fa-male:before { content: "\f183"; } -.fa-gittip:before { +.fa-gittip:before, +.fa-gratipay:before { content: "\f184"; } .fa-sun-o:before { @@ -1380,7 +1370,6 @@ .fa-digg:before { content: "\f1a6"; } -.fa-pied-piper-square:before, .fa-pied-piper:before { content: "\f1a7"; } @@ -1497,6 +1486,7 @@ content: "\f1cc"; } .fa-life-bouy:before, +.fa-life-buoy:before, .fa-life-saver:before, .fa-support:before, .fa-life-ring:before { @@ -1543,6 +1533,7 @@ .fa-history:before { content: "\f1da"; } +.fa-genderless:before, .fa-circle-thin:before { content: "\f1db"; } @@ -1564,3 +1555,247 @@ .fa-bomb:before { content: "\f1e2"; } +.fa-soccer-ball-o:before, +.fa-futbol-o:before { + content: "\f1e3"; +} +.fa-tty:before { + content: "\f1e4"; +} +.fa-binoculars:before { + content: "\f1e5"; +} +.fa-plug:before { + content: "\f1e6"; +} +.fa-slideshare:before { + content: "\f1e7"; +} +.fa-twitch:before { + content: "\f1e8"; +} +.fa-yelp:before { + content: "\f1e9"; +} +.fa-newspaper-o:before { + content: "\f1ea"; +} +.fa-wifi:before { + content: "\f1eb"; +} +.fa-calculator:before { + content: "\f1ec"; +} +.fa-paypal:before { + content: "\f1ed"; +} +.fa-google-wallet:before { + content: "\f1ee"; +} +.fa-cc-visa:before { + content: "\f1f0"; +} +.fa-cc-mastercard:before { + content: "\f1f1"; +} +.fa-cc-discover:before { + content: "\f1f2"; +} +.fa-cc-amex:before { + content: "\f1f3"; +} +.fa-cc-paypal:before { + content: "\f1f4"; +} +.fa-cc-stripe:before { + content: "\f1f5"; +} +.fa-bell-slash:before { + content: "\f1f6"; +} +.fa-bell-slash-o:before { + content: "\f1f7"; +} +.fa-trash:before { + content: "\f1f8"; +} +.fa-copyright:before { + content: "\f1f9"; +} +.fa-at:before { + content: "\f1fa"; +} +.fa-eyedropper:before { + content: "\f1fb"; +} +.fa-paint-brush:before { + content: "\f1fc"; +} +.fa-birthday-cake:before { + content: "\f1fd"; +} +.fa-area-chart:before { + content: "\f1fe"; +} +.fa-pie-chart:before { + content: "\f200"; +} +.fa-line-chart:before { + content: "\f201"; +} +.fa-lastfm:before { + content: "\f202"; +} +.fa-lastfm-square:before { + content: "\f203"; +} +.fa-toggle-off:before { + content: "\f204"; +} +.fa-toggle-on:before { + content: "\f205"; +} +.fa-bicycle:before { + content: "\f206"; +} +.fa-bus:before { + content: "\f207"; +} +.fa-ioxhost:before { + content: "\f208"; +} +.fa-angellist:before { + content: "\f209"; +} +.fa-cc:before { + content: "\f20a"; +} +.fa-shekel:before, +.fa-sheqel:before, +.fa-ils:before { + content: "\f20b"; +} +.fa-meanpath:before { + content: "\f20c"; +} +.fa-buysellads:before { + content: "\f20d"; +} +.fa-connectdevelop:before { + content: "\f20e"; +} +.fa-dashcube:before { + content: "\f210"; +} +.fa-forumbee:before { + content: "\f211"; +} +.fa-leanpub:before { + content: "\f212"; +} +.fa-sellsy:before { + content: "\f213"; +} +.fa-shirtsinbulk:before { + content: "\f214"; +} +.fa-simplybuilt:before { + content: "\f215"; +} +.fa-skyatlas:before { + content: "\f216"; +} +.fa-cart-plus:before { + content: "\f217"; +} +.fa-cart-arrow-down:before { + content: "\f218"; +} +.fa-diamond:before { + content: "\f219"; +} +.fa-ship:before { + content: "\f21a"; +} +.fa-user-secret:before { + content: "\f21b"; +} +.fa-motorcycle:before { + content: "\f21c"; +} +.fa-street-view:before { + content: "\f21d"; +} +.fa-heartbeat:before { + content: "\f21e"; +} +.fa-venus:before { + content: "\f221"; +} +.fa-mars:before { + content: "\f222"; +} +.fa-mercury:before { + content: "\f223"; +} +.fa-transgender:before { + content: "\f224"; +} +.fa-transgender-alt:before { + content: "\f225"; +} +.fa-venus-double:before { + content: "\f226"; +} +.fa-mars-double:before { + content: "\f227"; +} +.fa-venus-mars:before { + content: "\f228"; +} +.fa-mars-stroke:before { + content: "\f229"; +} +.fa-mars-stroke-v:before { + content: "\f22a"; +} +.fa-mars-stroke-h:before { + content: "\f22b"; +} +.fa-neuter:before { + content: "\f22c"; +} +.fa-facebook-official:before { + content: "\f230"; +} +.fa-pinterest-p:before { + content: "\f231"; +} +.fa-whatsapp:before { + content: "\f232"; +} +.fa-server:before { + content: "\f233"; +} +.fa-user-plus:before { + content: "\f234"; +} +.fa-user-times:before { + content: "\f235"; +} +.fa-hotel:before, +.fa-bed:before { + content: "\f236"; +} +.fa-viacoin:before { + content: "\f237"; +} +.fa-train:before { + content: "\f238"; +} +.fa-subway:before { + content: "\f239"; +} +.fa-medium:before { + content: "\f23a"; +} diff --git a/stylesheets/font-awesome/css/font-awesome.min.css b/stylesheets/font-awesome/css/font-awesome.min.css index 3d920fc8..24fcc04c 100644 --- a/stylesheets/font-awesome/css/font-awesome.min.css +++ b/stylesheets/font-awesome/css/font-awesome.min.css @@ -1,4 +1,4 @@ /*! - * Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome + * Font Awesome 4.3.0 by @davegandy - http://fontawesome.io - @fontawesome * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.1.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.1.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff?v=4.1.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.1.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.1.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:spin 2s infinite linear;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;animation:spin 2s infinite linear}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)}100%{-o-transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-moz-transform:scale(-1, 1);-ms-transform:scale(-1, 1);-o-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-moz-transform:scale(1, -1);-ms-transform:scale(1, -1);-o-transform:scale(1, -1);transform:scale(1, -1)}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-square:before,.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"} \ No newline at end of file + */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.3.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.3.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.3.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.3.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.3.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.3.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;transform:translate(0, 0)}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-genderless:before,.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"} \ No newline at end of file diff --git a/stylesheets/font-awesome/fonts/FontAwesome.otf b/stylesheets/font-awesome/fonts/FontAwesome.otf index 3461e3fc..f7936cc1 100644 Binary files a/stylesheets/font-awesome/fonts/FontAwesome.otf and b/stylesheets/font-awesome/fonts/FontAwesome.otf differ diff --git a/stylesheets/font-awesome/fonts/fontawesome-webfont.eot b/stylesheets/font-awesome/fonts/fontawesome-webfont.eot index 6cfd5660..33b2bb80 100644 Binary files a/stylesheets/font-awesome/fonts/fontawesome-webfont.eot and b/stylesheets/font-awesome/fonts/fontawesome-webfont.eot differ diff --git a/stylesheets/font-awesome/fonts/fontawesome-webfont.svg b/stylesheets/font-awesome/fonts/fontawesome-webfont.svg index a9f84695..1ee89d43 100644 --- a/stylesheets/font-awesome/fonts/fontawesome-webfont.svg +++ b/stylesheets/font-awesome/fonts/fontawesome-webfont.svg @@ -1,6 +1,6 @@ - + @@ -32,473 +32,534 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - \ No newline at end of file diff --git a/stylesheets/font-awesome/fonts/fontawesome-webfont.ttf b/stylesheets/font-awesome/fonts/fontawesome-webfont.ttf index 5cd6cff6..ed9372f8 100644 Binary files a/stylesheets/font-awesome/fonts/fontawesome-webfont.ttf and b/stylesheets/font-awesome/fonts/fontawesome-webfont.ttf differ diff --git a/stylesheets/font-awesome/fonts/fontawesome-webfont.woff b/stylesheets/font-awesome/fonts/fontawesome-webfont.woff index 9eaecb37..8b280b98 100644 Binary files a/stylesheets/font-awesome/fonts/fontawesome-webfont.woff and b/stylesheets/font-awesome/fonts/fontawesome-webfont.woff differ diff --git a/stylesheets/font-awesome/fonts/fontawesome-webfont.woff2 b/stylesheets/font-awesome/fonts/fontawesome-webfont.woff2 new file mode 100644 index 00000000..3311d585 Binary files /dev/null and b/stylesheets/font-awesome/fonts/fontawesome-webfont.woff2 differ diff --git a/stylesheets/font-awesome/less/animated.less b/stylesheets/font-awesome/less/animated.less new file mode 100644 index 00000000..66ad52a5 --- /dev/null +++ b/stylesheets/font-awesome/less/animated.less @@ -0,0 +1,34 @@ +// Animated Icons +// -------------------------- + +.@{fa-css-prefix}-spin { + -webkit-animation: fa-spin 2s infinite linear; + animation: fa-spin 2s infinite linear; +} + +.@{fa-css-prefix}-pulse { + -webkit-animation: fa-spin 1s infinite steps(8); + animation: fa-spin 1s infinite steps(8); +} + +@-webkit-keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} + +@keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} diff --git a/stylesheets/font-awesome/less/core.less b/stylesheets/font-awesome/less/core.less index 6d223bc2..f814f1e1 100644 --- a/stylesheets/font-awesome/less/core.less +++ b/stylesheets/font-awesome/less/core.less @@ -3,10 +3,11 @@ .@{fa-css-prefix} { display: inline-block; - font-family: FontAwesome; - font-style: normal; - font-weight: normal; - line-height: 1; + font: normal normal normal @fa-font-size-base/1 FontAwesome; // shortening font declaration + font-size: inherit; // can't have font-size inherit on line above, so need to override + text-rendering: auto; // optimizelegibility throws things off #1094 -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; + transform: translate(0, 0); // ensures no half-pixel rendering in firefox + } diff --git a/stylesheets/font-awesome/less/font-awesome.less b/stylesheets/font-awesome/less/font-awesome.less index 50cbcac4..1f45c63d 100644 --- a/stylesheets/font-awesome/less/font-awesome.less +++ b/stylesheets/font-awesome/less/font-awesome.less @@ -1,5 +1,5 @@ /*! - * Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome + * Font Awesome 4.3.0 by @davegandy - http://fontawesome.io - @fontawesome * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) */ @@ -11,7 +11,7 @@ @import "fixed-width.less"; @import "list.less"; @import "bordered-pulled.less"; -@import "spinning.less"; +@import "animated.less"; @import "rotated-flipped.less"; @import "stacked.less"; @import "icons.less"; diff --git a/stylesheets/font-awesome/less/icons.less b/stylesheets/font-awesome/less/icons.less index 13d8c685..c265de5a 100644 --- a/stylesheets/font-awesome/less/icons.less +++ b/stylesheets/font-awesome/less/icons.less @@ -14,6 +14,8 @@ .@{fa-css-prefix}-th:before { content: @fa-var-th; } .@{fa-css-prefix}-th-list:before { content: @fa-var-th-list; } .@{fa-css-prefix}-check:before { content: @fa-var-check; } +.@{fa-css-prefix}-remove:before, +.@{fa-css-prefix}-close:before, .@{fa-css-prefix}-times:before { content: @fa-var-times; } .@{fa-css-prefix}-search-plus:before { content: @fa-var-search-plus; } .@{fa-css-prefix}-search-minus:before { content: @fa-var-search-minus; } @@ -129,7 +131,8 @@ .@{fa-css-prefix}-folder-open:before { content: @fa-var-folder-open; } .@{fa-css-prefix}-arrows-v:before { content: @fa-var-arrows-v; } .@{fa-css-prefix}-arrows-h:before { content: @fa-var-arrows-h; } -.@{fa-css-prefix}-bar-chart-o:before { content: @fa-var-bar-chart-o; } +.@{fa-css-prefix}-bar-chart-o:before, +.@{fa-css-prefix}-bar-chart:before { content: @fa-var-bar-chart; } .@{fa-css-prefix}-twitter-square:before { content: @fa-var-twitter-square; } .@{fa-css-prefix}-facebook-square:before { content: @fa-var-facebook-square; } .@{fa-css-prefix}-camera-retro:before { content: @fa-var-camera-retro; } @@ -155,6 +158,7 @@ .@{fa-css-prefix}-bookmark-o:before { content: @fa-var-bookmark-o; } .@{fa-css-prefix}-phone-square:before { content: @fa-var-phone-square; } .@{fa-css-prefix}-twitter:before { content: @fa-var-twitter; } +.@{fa-css-prefix}-facebook-f:before, .@{fa-css-prefix}-facebook:before { content: @fa-var-facebook; } .@{fa-css-prefix}-github:before { content: @fa-var-github; } .@{fa-css-prefix}-unlock:before { content: @fa-var-unlock; } @@ -394,7 +398,8 @@ .@{fa-css-prefix}-trello:before { content: @fa-var-trello; } .@{fa-css-prefix}-female:before { content: @fa-var-female; } .@{fa-css-prefix}-male:before { content: @fa-var-male; } -.@{fa-css-prefix}-gittip:before { content: @fa-var-gittip; } +.@{fa-css-prefix}-gittip:before, +.@{fa-css-prefix}-gratipay:before { content: @fa-var-gratipay; } .@{fa-css-prefix}-sun-o:before { content: @fa-var-sun-o; } .@{fa-css-prefix}-moon-o:before { content: @fa-var-moon-o; } .@{fa-css-prefix}-archive:before { content: @fa-var-archive; } @@ -432,7 +437,6 @@ .@{fa-css-prefix}-stumbleupon:before { content: @fa-var-stumbleupon; } .@{fa-css-prefix}-delicious:before { content: @fa-var-delicious; } .@{fa-css-prefix}-digg:before { content: @fa-var-digg; } -.@{fa-css-prefix}-pied-piper-square:before, .@{fa-css-prefix}-pied-piper:before { content: @fa-var-pied-piper; } .@{fa-css-prefix}-pied-piper-alt:before { content: @fa-var-pied-piper-alt; } .@{fa-css-prefix}-drupal:before { content: @fa-var-drupal; } @@ -477,6 +481,7 @@ .@{fa-css-prefix}-codepen:before { content: @fa-var-codepen; } .@{fa-css-prefix}-jsfiddle:before { content: @fa-var-jsfiddle; } .@{fa-css-prefix}-life-bouy:before, +.@{fa-css-prefix}-life-buoy:before, .@{fa-css-prefix}-life-saver:before, .@{fa-css-prefix}-support:before, .@{fa-css-prefix}-life-ring:before { content: @fa-var-life-ring; } @@ -497,6 +502,7 @@ .@{fa-css-prefix}-send-o:before, .@{fa-css-prefix}-paper-plane-o:before { content: @fa-var-paper-plane-o; } .@{fa-css-prefix}-history:before { content: @fa-var-history; } +.@{fa-css-prefix}-genderless:before, .@{fa-css-prefix}-circle-thin:before { content: @fa-var-circle-thin; } .@{fa-css-prefix}-header:before { content: @fa-var-header; } .@{fa-css-prefix}-paragraph:before { content: @fa-var-paragraph; } @@ -504,3 +510,87 @@ .@{fa-css-prefix}-share-alt:before { content: @fa-var-share-alt; } .@{fa-css-prefix}-share-alt-square:before { content: @fa-var-share-alt-square; } .@{fa-css-prefix}-bomb:before { content: @fa-var-bomb; } +.@{fa-css-prefix}-soccer-ball-o:before, +.@{fa-css-prefix}-futbol-o:before { content: @fa-var-futbol-o; } +.@{fa-css-prefix}-tty:before { content: @fa-var-tty; } +.@{fa-css-prefix}-binoculars:before { content: @fa-var-binoculars; } +.@{fa-css-prefix}-plug:before { content: @fa-var-plug; } +.@{fa-css-prefix}-slideshare:before { content: @fa-var-slideshare; } +.@{fa-css-prefix}-twitch:before { content: @fa-var-twitch; } +.@{fa-css-prefix}-yelp:before { content: @fa-var-yelp; } +.@{fa-css-prefix}-newspaper-o:before { content: @fa-var-newspaper-o; } +.@{fa-css-prefix}-wifi:before { content: @fa-var-wifi; } +.@{fa-css-prefix}-calculator:before { content: @fa-var-calculator; } +.@{fa-css-prefix}-paypal:before { content: @fa-var-paypal; } +.@{fa-css-prefix}-google-wallet:before { content: @fa-var-google-wallet; } +.@{fa-css-prefix}-cc-visa:before { content: @fa-var-cc-visa; } +.@{fa-css-prefix}-cc-mastercard:before { content: @fa-var-cc-mastercard; } +.@{fa-css-prefix}-cc-discover:before { content: @fa-var-cc-discover; } +.@{fa-css-prefix}-cc-amex:before { content: @fa-var-cc-amex; } +.@{fa-css-prefix}-cc-paypal:before { content: @fa-var-cc-paypal; } +.@{fa-css-prefix}-cc-stripe:before { content: @fa-var-cc-stripe; } +.@{fa-css-prefix}-bell-slash:before { content: @fa-var-bell-slash; } +.@{fa-css-prefix}-bell-slash-o:before { content: @fa-var-bell-slash-o; } +.@{fa-css-prefix}-trash:before { content: @fa-var-trash; } +.@{fa-css-prefix}-copyright:before { content: @fa-var-copyright; } +.@{fa-css-prefix}-at:before { content: @fa-var-at; } +.@{fa-css-prefix}-eyedropper:before { content: @fa-var-eyedropper; } +.@{fa-css-prefix}-paint-brush:before { content: @fa-var-paint-brush; } +.@{fa-css-prefix}-birthday-cake:before { content: @fa-var-birthday-cake; } +.@{fa-css-prefix}-area-chart:before { content: @fa-var-area-chart; } +.@{fa-css-prefix}-pie-chart:before { content: @fa-var-pie-chart; } +.@{fa-css-prefix}-line-chart:before { content: @fa-var-line-chart; } +.@{fa-css-prefix}-lastfm:before { content: @fa-var-lastfm; } +.@{fa-css-prefix}-lastfm-square:before { content: @fa-var-lastfm-square; } +.@{fa-css-prefix}-toggle-off:before { content: @fa-var-toggle-off; } +.@{fa-css-prefix}-toggle-on:before { content: @fa-var-toggle-on; } +.@{fa-css-prefix}-bicycle:before { content: @fa-var-bicycle; } +.@{fa-css-prefix}-bus:before { content: @fa-var-bus; } +.@{fa-css-prefix}-ioxhost:before { content: @fa-var-ioxhost; } +.@{fa-css-prefix}-angellist:before { content: @fa-var-angellist; } +.@{fa-css-prefix}-cc:before { content: @fa-var-cc; } +.@{fa-css-prefix}-shekel:before, +.@{fa-css-prefix}-sheqel:before, +.@{fa-css-prefix}-ils:before { content: @fa-var-ils; } +.@{fa-css-prefix}-meanpath:before { content: @fa-var-meanpath; } +.@{fa-css-prefix}-buysellads:before { content: @fa-var-buysellads; } +.@{fa-css-prefix}-connectdevelop:before { content: @fa-var-connectdevelop; } +.@{fa-css-prefix}-dashcube:before { content: @fa-var-dashcube; } +.@{fa-css-prefix}-forumbee:before { content: @fa-var-forumbee; } +.@{fa-css-prefix}-leanpub:before { content: @fa-var-leanpub; } +.@{fa-css-prefix}-sellsy:before { content: @fa-var-sellsy; } +.@{fa-css-prefix}-shirtsinbulk:before { content: @fa-var-shirtsinbulk; } +.@{fa-css-prefix}-simplybuilt:before { content: @fa-var-simplybuilt; } +.@{fa-css-prefix}-skyatlas:before { content: @fa-var-skyatlas; } +.@{fa-css-prefix}-cart-plus:before { content: @fa-var-cart-plus; } +.@{fa-css-prefix}-cart-arrow-down:before { content: @fa-var-cart-arrow-down; } +.@{fa-css-prefix}-diamond:before { content: @fa-var-diamond; } +.@{fa-css-prefix}-ship:before { content: @fa-var-ship; } +.@{fa-css-prefix}-user-secret:before { content: @fa-var-user-secret; } +.@{fa-css-prefix}-motorcycle:before { content: @fa-var-motorcycle; } +.@{fa-css-prefix}-street-view:before { content: @fa-var-street-view; } +.@{fa-css-prefix}-heartbeat:before { content: @fa-var-heartbeat; } +.@{fa-css-prefix}-venus:before { content: @fa-var-venus; } +.@{fa-css-prefix}-mars:before { content: @fa-var-mars; } +.@{fa-css-prefix}-mercury:before { content: @fa-var-mercury; } +.@{fa-css-prefix}-transgender:before { content: @fa-var-transgender; } +.@{fa-css-prefix}-transgender-alt:before { content: @fa-var-transgender-alt; } +.@{fa-css-prefix}-venus-double:before { content: @fa-var-venus-double; } +.@{fa-css-prefix}-mars-double:before { content: @fa-var-mars-double; } +.@{fa-css-prefix}-venus-mars:before { content: @fa-var-venus-mars; } +.@{fa-css-prefix}-mars-stroke:before { content: @fa-var-mars-stroke; } +.@{fa-css-prefix}-mars-stroke-v:before { content: @fa-var-mars-stroke-v; } +.@{fa-css-prefix}-mars-stroke-h:before { content: @fa-var-mars-stroke-h; } +.@{fa-css-prefix}-neuter:before { content: @fa-var-neuter; } +.@{fa-css-prefix}-facebook-official:before { content: @fa-var-facebook-official; } +.@{fa-css-prefix}-pinterest-p:before { content: @fa-var-pinterest-p; } +.@{fa-css-prefix}-whatsapp:before { content: @fa-var-whatsapp; } +.@{fa-css-prefix}-server:before { content: @fa-var-server; } +.@{fa-css-prefix}-user-plus:before { content: @fa-var-user-plus; } +.@{fa-css-prefix}-user-times:before { content: @fa-var-user-times; } +.@{fa-css-prefix}-hotel:before, +.@{fa-css-prefix}-bed:before { content: @fa-var-bed; } +.@{fa-css-prefix}-viacoin:before { content: @fa-var-viacoin; } +.@{fa-css-prefix}-train:before { content: @fa-var-train; } +.@{fa-css-prefix}-subway:before { content: @fa-var-subway; } +.@{fa-css-prefix}-medium:before { content: @fa-var-medium; } diff --git a/stylesheets/font-awesome/less/list.less b/stylesheets/font-awesome/less/list.less index eed93405..0b440382 100644 --- a/stylesheets/font-awesome/less/list.less +++ b/stylesheets/font-awesome/less/list.less @@ -14,6 +14,6 @@ top: (2em / 14); text-align: center; &.@{fa-css-prefix}-lg { - left: -@fa-li-width + (4em / 14); + left: (-@fa-li-width + (4em / 14)); } } diff --git a/stylesheets/font-awesome/less/mixins.less b/stylesheets/font-awesome/less/mixins.less index 19e5a645..c97f4604 100644 --- a/stylesheets/font-awesome/less/mixins.less +++ b/stylesheets/font-awesome/less/mixins.less @@ -1,20 +1,27 @@ // Mixins // -------------------------- +.fa-icon() { + display: inline-block; + font: normal normal normal @fa-font-size-base/1 FontAwesome; // shortening font declaration + font-size: inherit; // can't have font-size inherit on line above, so need to override + text-rendering: auto; // optimizelegibility throws things off #1094 + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + transform: translate(0, 0); // ensures no half-pixel rendering in firefox + +} + .fa-icon-rotate(@degrees, @rotation) { filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=@rotation); -webkit-transform: rotate(@degrees); - -moz-transform: rotate(@degrees); -ms-transform: rotate(@degrees); - -o-transform: rotate(@degrees); transform: rotate(@degrees); } .fa-icon-flip(@horiz, @vert, @rotation) { filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=@rotation, mirror=1); -webkit-transform: scale(@horiz, @vert); - -moz-transform: scale(@horiz, @vert); -ms-transform: scale(@horiz, @vert); - -o-transform: scale(@horiz, @vert); transform: scale(@horiz, @vert); } diff --git a/stylesheets/font-awesome/less/path.less b/stylesheets/font-awesome/less/path.less index d73bff8b..9211e665 100644 --- a/stylesheets/font-awesome/less/path.less +++ b/stylesheets/font-awesome/less/path.less @@ -3,11 +3,12 @@ @font-face { font-family: 'FontAwesome'; - src: ~"url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}')"; - src: ~"url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype')", - ~"url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff')", - ~"url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype')", - ~"url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg')"; + src: url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}'); + src: url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype'), + url('@{fa-font-path}/fontawesome-webfont.woff2?v=@{fa-version}') format('woff2'), + url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff'), + url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype'), + url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg'); // src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts font-weight: normal; font-style: normal; diff --git a/stylesheets/font-awesome/less/rotated-flipped.less b/stylesheets/font-awesome/less/rotated-flipped.less index 8fff3a6c..f6ba8147 100644 --- a/stylesheets/font-awesome/less/rotated-flipped.less +++ b/stylesheets/font-awesome/less/rotated-flipped.less @@ -7,3 +7,14 @@ .@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); } .@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); } + +// Hook for IE8-9 +// ------------------------- + +:root .@{fa-css-prefix}-rotate-90, +:root .@{fa-css-prefix}-rotate-180, +:root .@{fa-css-prefix}-rotate-270, +:root .@{fa-css-prefix}-flip-horizontal, +:root .@{fa-css-prefix}-flip-vertical { + filter: none; +} diff --git a/stylesheets/font-awesome/less/spinning.less b/stylesheets/font-awesome/less/spinning.less deleted file mode 100644 index 06b71ecb..00000000 --- a/stylesheets/font-awesome/less/spinning.less +++ /dev/null @@ -1,32 +0,0 @@ -// Spinning Icons -// -------------------------- - -.@{fa-css-prefix}-spin { - -webkit-animation: spin 2s infinite linear; - -moz-animation: spin 2s infinite linear; - -o-animation: spin 2s infinite linear; - animation: spin 2s infinite linear; -} - -@-moz-keyframes spin { - 0% { -moz-transform: rotate(0deg); } - 100% { -moz-transform: rotate(359deg); } -} -@-webkit-keyframes spin { - 0% { -webkit-transform: rotate(0deg); } - 100% { -webkit-transform: rotate(359deg); } -} -@-o-keyframes spin { - 0% { -o-transform: rotate(0deg); } - 100% { -o-transform: rotate(359deg); } -} -@keyframes spin { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - 100% { - -webkit-transform: rotate(359deg); - transform: rotate(359deg); - } -} diff --git a/stylesheets/font-awesome/less/variables.less b/stylesheets/font-awesome/less/variables.less index d7e8bd72..d526064c 100644 --- a/stylesheets/font-awesome/less/variables.less +++ b/stylesheets/font-awesome/less/variables.less @@ -2,9 +2,10 @@ // -------------------------- @fa-font-path: "../fonts"; -//@fa-font-path: "//netdna.bootstrapcdn.com/font-awesome/4.1.0/fonts"; // for referencing Bootstrap CDN font files directly +@fa-font-size-base: 14px; +//@fa-font-path: "//netdna.bootstrapcdn.com/font-awesome/4.3.0/fonts"; // for referencing Bootstrap CDN font files directly @fa-css-prefix: fa; -@fa-version: "4.1.0"; +@fa-version: "4.3.0"; @fa-border-color: #eee; @fa-inverse: #fff; @fa-li-width: (30em / 14); @@ -18,6 +19,7 @@ @fa-var-ambulance: "\f0f9"; @fa-var-anchor: "\f13d"; @fa-var-android: "\f17b"; +@fa-var-angellist: "\f209"; @fa-var-angle-double-down: "\f103"; @fa-var-angle-double-left: "\f100"; @fa-var-angle-double-right: "\f101"; @@ -28,6 +30,7 @@ @fa-var-angle-up: "\f106"; @fa-var-apple: "\f179"; @fa-var-archive: "\f187"; +@fa-var-area-chart: "\f1fe"; @fa-var-arrow-circle-down: "\f0ab"; @fa-var-arrow-circle-left: "\f0a8"; @fa-var-arrow-circle-o-down: "\f01a"; @@ -45,18 +48,26 @@ @fa-var-arrows-h: "\f07e"; @fa-var-arrows-v: "\f07d"; @fa-var-asterisk: "\f069"; +@fa-var-at: "\f1fa"; @fa-var-automobile: "\f1b9"; @fa-var-backward: "\f04a"; @fa-var-ban: "\f05e"; @fa-var-bank: "\f19c"; +@fa-var-bar-chart: "\f080"; @fa-var-bar-chart-o: "\f080"; @fa-var-barcode: "\f02a"; @fa-var-bars: "\f0c9"; +@fa-var-bed: "\f236"; @fa-var-beer: "\f0fc"; @fa-var-behance: "\f1b4"; @fa-var-behance-square: "\f1b5"; @fa-var-bell: "\f0f3"; @fa-var-bell-o: "\f0a2"; +@fa-var-bell-slash: "\f1f6"; +@fa-var-bell-slash-o: "\f1f7"; +@fa-var-bicycle: "\f206"; +@fa-var-binoculars: "\f1e5"; +@fa-var-birthday-cake: "\f1fd"; @fa-var-bitbucket: "\f171"; @fa-var-bitbucket-square: "\f172"; @fa-var-bitcoin: "\f15a"; @@ -73,7 +84,10 @@ @fa-var-building-o: "\f0f7"; @fa-var-bullhorn: "\f0a1"; @fa-var-bullseye: "\f140"; +@fa-var-bus: "\f207"; +@fa-var-buysellads: "\f20d"; @fa-var-cab: "\f1ba"; +@fa-var-calculator: "\f1ec"; @fa-var-calendar: "\f073"; @fa-var-calendar-o: "\f133"; @fa-var-camera: "\f030"; @@ -87,6 +101,15 @@ @fa-var-caret-square-o-right: "\f152"; @fa-var-caret-square-o-up: "\f151"; @fa-var-caret-up: "\f0d8"; +@fa-var-cart-arrow-down: "\f218"; +@fa-var-cart-plus: "\f217"; +@fa-var-cc: "\f20a"; +@fa-var-cc-amex: "\f1f3"; +@fa-var-cc-discover: "\f1f2"; +@fa-var-cc-mastercard: "\f1f1"; +@fa-var-cc-paypal: "\f1f4"; +@fa-var-cc-stripe: "\f1f5"; +@fa-var-cc-visa: "\f1f0"; @fa-var-certificate: "\f0a3"; @fa-var-chain: "\f0c1"; @fa-var-chain-broken: "\f127"; @@ -110,6 +133,7 @@ @fa-var-circle-thin: "\f1db"; @fa-var-clipboard: "\f0ea"; @fa-var-clock-o: "\f017"; +@fa-var-close: "\f00d"; @fa-var-cloud: "\f0c2"; @fa-var-cloud-download: "\f0ed"; @fa-var-cloud-upload: "\f0ee"; @@ -127,7 +151,9 @@ @fa-var-comments-o: "\f0e6"; @fa-var-compass: "\f14e"; @fa-var-compress: "\f066"; +@fa-var-connectdevelop: "\f20e"; @fa-var-copy: "\f0c5"; +@fa-var-copyright: "\f1f9"; @fa-var-credit-card: "\f09d"; @fa-var-crop: "\f125"; @fa-var-crosshairs: "\f05b"; @@ -137,11 +163,13 @@ @fa-var-cut: "\f0c4"; @fa-var-cutlery: "\f0f5"; @fa-var-dashboard: "\f0e4"; +@fa-var-dashcube: "\f210"; @fa-var-database: "\f1c0"; @fa-var-dedent: "\f03b"; @fa-var-delicious: "\f1a5"; @fa-var-desktop: "\f108"; @fa-var-deviantart: "\f1bd"; +@fa-var-diamond: "\f219"; @fa-var-digg: "\f1a6"; @fa-var-dollar: "\f155"; @fa-var-dot-circle-o: "\f192"; @@ -169,7 +197,10 @@ @fa-var-external-link-square: "\f14c"; @fa-var-eye: "\f06e"; @fa-var-eye-slash: "\f070"; +@fa-var-eyedropper: "\f1fb"; @fa-var-facebook: "\f09a"; +@fa-var-facebook-f: "\f09a"; +@fa-var-facebook-official: "\f230"; @fa-var-facebook-square: "\f082"; @fa-var-fast-backward: "\f049"; @fa-var-fast-forward: "\f050"; @@ -211,15 +242,18 @@ @fa-var-folder-open: "\f07c"; @fa-var-folder-open-o: "\f115"; @fa-var-font: "\f031"; +@fa-var-forumbee: "\f211"; @fa-var-forward: "\f04e"; @fa-var-foursquare: "\f180"; @fa-var-frown-o: "\f119"; +@fa-var-futbol-o: "\f1e3"; @fa-var-gamepad: "\f11b"; @fa-var-gavel: "\f0e3"; @fa-var-gbp: "\f154"; @fa-var-ge: "\f1d1"; @fa-var-gear: "\f013"; @fa-var-gears: "\f085"; +@fa-var-genderless: "\f1db"; @fa-var-gift: "\f06b"; @fa-var-git: "\f1d3"; @fa-var-git-square: "\f1d2"; @@ -232,7 +266,9 @@ @fa-var-google: "\f1a0"; @fa-var-google-plus: "\f0d5"; @fa-var-google-plus-square: "\f0d4"; +@fa-var-google-wallet: "\f1ee"; @fa-var-graduation-cap: "\f19d"; +@fa-var-gratipay: "\f184"; @fa-var-group: "\f0c0"; @fa-var-h-square: "\f0fd"; @fa-var-hacker-news: "\f1d4"; @@ -245,10 +281,13 @@ @fa-var-headphones: "\f025"; @fa-var-heart: "\f004"; @fa-var-heart-o: "\f08a"; +@fa-var-heartbeat: "\f21e"; @fa-var-history: "\f1da"; @fa-var-home: "\f015"; @fa-var-hospital-o: "\f0f8"; +@fa-var-hotel: "\f236"; @fa-var-html5: "\f13b"; +@fa-var-ils: "\f20b"; @fa-var-image: "\f03e"; @fa-var-inbox: "\f01c"; @fa-var-indent: "\f03c"; @@ -257,6 +296,7 @@ @fa-var-inr: "\f156"; @fa-var-instagram: "\f16d"; @fa-var-institution: "\f19c"; +@fa-var-ioxhost: "\f208"; @fa-var-italic: "\f033"; @fa-var-joomla: "\f1aa"; @fa-var-jpy: "\f157"; @@ -266,15 +306,20 @@ @fa-var-krw: "\f159"; @fa-var-language: "\f1ab"; @fa-var-laptop: "\f109"; +@fa-var-lastfm: "\f202"; +@fa-var-lastfm-square: "\f203"; @fa-var-leaf: "\f06c"; +@fa-var-leanpub: "\f212"; @fa-var-legal: "\f0e3"; @fa-var-lemon-o: "\f094"; @fa-var-level-down: "\f149"; @fa-var-level-up: "\f148"; @fa-var-life-bouy: "\f1cd"; +@fa-var-life-buoy: "\f1cd"; @fa-var-life-ring: "\f1cd"; @fa-var-life-saver: "\f1cd"; @fa-var-lightbulb-o: "\f0eb"; +@fa-var-line-chart: "\f201"; @fa-var-link: "\f0c1"; @fa-var-linkedin: "\f0e1"; @fa-var-linkedin-square: "\f08c"; @@ -296,9 +341,17 @@ @fa-var-mail-reply-all: "\f122"; @fa-var-male: "\f183"; @fa-var-map-marker: "\f041"; +@fa-var-mars: "\f222"; +@fa-var-mars-double: "\f227"; +@fa-var-mars-stroke: "\f229"; +@fa-var-mars-stroke-h: "\f22b"; +@fa-var-mars-stroke-v: "\f22a"; @fa-var-maxcdn: "\f136"; +@fa-var-meanpath: "\f20c"; +@fa-var-medium: "\f23a"; @fa-var-medkit: "\f0fa"; @fa-var-meh-o: "\f11a"; +@fa-var-mercury: "\f223"; @fa-var-microphone: "\f130"; @fa-var-microphone-slash: "\f131"; @fa-var-minus: "\f068"; @@ -310,11 +363,15 @@ @fa-var-money: "\f0d6"; @fa-var-moon-o: "\f186"; @fa-var-mortar-board: "\f19d"; +@fa-var-motorcycle: "\f21c"; @fa-var-music: "\f001"; @fa-var-navicon: "\f0c9"; +@fa-var-neuter: "\f22c"; +@fa-var-newspaper-o: "\f1ea"; @fa-var-openid: "\f19b"; @fa-var-outdent: "\f03b"; @fa-var-pagelines: "\f18c"; +@fa-var-paint-brush: "\f1fc"; @fa-var-paper-plane: "\f1d8"; @fa-var-paper-plane-o: "\f1d9"; @fa-var-paperclip: "\f0c6"; @@ -322,6 +379,7 @@ @fa-var-paste: "\f0ea"; @fa-var-pause: "\f04c"; @fa-var-paw: "\f1b0"; +@fa-var-paypal: "\f1ed"; @fa-var-pencil: "\f040"; @fa-var-pencil-square: "\f14b"; @fa-var-pencil-square-o: "\f044"; @@ -329,15 +387,17 @@ @fa-var-phone-square: "\f098"; @fa-var-photo: "\f03e"; @fa-var-picture-o: "\f03e"; +@fa-var-pie-chart: "\f200"; @fa-var-pied-piper: "\f1a7"; @fa-var-pied-piper-alt: "\f1a8"; -@fa-var-pied-piper-square: "\f1a7"; @fa-var-pinterest: "\f0d2"; +@fa-var-pinterest-p: "\f231"; @fa-var-pinterest-square: "\f0d3"; @fa-var-plane: "\f072"; @fa-var-play: "\f04b"; @fa-var-play-circle: "\f144"; @fa-var-play-circle-o: "\f01d"; +@fa-var-plug: "\f1e6"; @fa-var-plus: "\f067"; @fa-var-plus-circle: "\f055"; @fa-var-plus-square: "\f0fe"; @@ -358,6 +418,7 @@ @fa-var-reddit: "\f1a1"; @fa-var-reddit-square: "\f1a2"; @fa-var-refresh: "\f021"; +@fa-var-remove: "\f00d"; @fa-var-renren: "\f18b"; @fa-var-reorder: "\f0c9"; @fa-var-repeat: "\f01e"; @@ -380,23 +441,33 @@ @fa-var-search: "\f002"; @fa-var-search-minus: "\f010"; @fa-var-search-plus: "\f00e"; +@fa-var-sellsy: "\f213"; @fa-var-send: "\f1d8"; @fa-var-send-o: "\f1d9"; +@fa-var-server: "\f233"; @fa-var-share: "\f064"; @fa-var-share-alt: "\f1e0"; @fa-var-share-alt-square: "\f1e1"; @fa-var-share-square: "\f14d"; @fa-var-share-square-o: "\f045"; +@fa-var-shekel: "\f20b"; +@fa-var-sheqel: "\f20b"; @fa-var-shield: "\f132"; +@fa-var-ship: "\f21a"; +@fa-var-shirtsinbulk: "\f214"; @fa-var-shopping-cart: "\f07a"; @fa-var-sign-in: "\f090"; @fa-var-sign-out: "\f08b"; @fa-var-signal: "\f012"; +@fa-var-simplybuilt: "\f215"; @fa-var-sitemap: "\f0e8"; +@fa-var-skyatlas: "\f216"; @fa-var-skype: "\f17e"; @fa-var-slack: "\f198"; @fa-var-sliders: "\f1de"; +@fa-var-slideshare: "\f1e7"; @fa-var-smile-o: "\f118"; +@fa-var-soccer-ball-o: "\f1e3"; @fa-var-sort: "\f0dc"; @fa-var-sort-alpha-asc: "\f15d"; @fa-var-sort-alpha-desc: "\f15e"; @@ -429,10 +500,12 @@ @fa-var-step-forward: "\f051"; @fa-var-stethoscope: "\f0f1"; @fa-var-stop: "\f04d"; +@fa-var-street-view: "\f21d"; @fa-var-strikethrough: "\f0cc"; @fa-var-stumbleupon: "\f1a4"; @fa-var-stumbleupon-circle: "\f1a3"; @fa-var-subscript: "\f12c"; +@fa-var-subway: "\f239"; @fa-var-suitcase: "\f0f2"; @fa-var-sun-o: "\f185"; @fa-var-superscript: "\f12b"; @@ -463,17 +536,25 @@ @fa-var-tint: "\f043"; @fa-var-toggle-down: "\f150"; @fa-var-toggle-left: "\f191"; +@fa-var-toggle-off: "\f204"; +@fa-var-toggle-on: "\f205"; @fa-var-toggle-right: "\f152"; @fa-var-toggle-up: "\f151"; +@fa-var-train: "\f238"; +@fa-var-transgender: "\f224"; +@fa-var-transgender-alt: "\f225"; +@fa-var-trash: "\f1f8"; @fa-var-trash-o: "\f014"; @fa-var-tree: "\f1bb"; @fa-var-trello: "\f181"; @fa-var-trophy: "\f091"; @fa-var-truck: "\f0d1"; @fa-var-try: "\f195"; +@fa-var-tty: "\f1e4"; @fa-var-tumblr: "\f173"; @fa-var-tumblr-square: "\f174"; @fa-var-turkish-lira: "\f195"; +@fa-var-twitch: "\f1e8"; @fa-var-twitter: "\f099"; @fa-var-twitter-square: "\f081"; @fa-var-umbrella: "\f0e9"; @@ -488,7 +569,14 @@ @fa-var-usd: "\f155"; @fa-var-user: "\f007"; @fa-var-user-md: "\f0f0"; +@fa-var-user-plus: "\f234"; +@fa-var-user-secret: "\f21b"; +@fa-var-user-times: "\f235"; @fa-var-users: "\f0c0"; +@fa-var-venus: "\f221"; +@fa-var-venus-double: "\f226"; +@fa-var-venus-mars: "\f228"; +@fa-var-viacoin: "\f237"; @fa-var-video-camera: "\f03d"; @fa-var-vimeo-square: "\f194"; @fa-var-vine: "\f1ca"; @@ -500,7 +588,9 @@ @fa-var-wechat: "\f1d7"; @fa-var-weibo: "\f18a"; @fa-var-weixin: "\f1d7"; +@fa-var-whatsapp: "\f232"; @fa-var-wheelchair: "\f193"; +@fa-var-wifi: "\f1eb"; @fa-var-windows: "\f17a"; @fa-var-won: "\f159"; @fa-var-wordpress: "\f19a"; @@ -508,6 +598,7 @@ @fa-var-xing: "\f168"; @fa-var-xing-square: "\f169"; @fa-var-yahoo: "\f19e"; +@fa-var-yelp: "\f1e9"; @fa-var-yen: "\f157"; @fa-var-youtube: "\f167"; @fa-var-youtube-play: "\f16a"; diff --git a/stylesheets/font-awesome/scss/_animated.scss b/stylesheets/font-awesome/scss/_animated.scss new file mode 100644 index 00000000..8a020dbf --- /dev/null +++ b/stylesheets/font-awesome/scss/_animated.scss @@ -0,0 +1,34 @@ +// Spinning Icons +// -------------------------- + +.#{$fa-css-prefix}-spin { + -webkit-animation: fa-spin 2s infinite linear; + animation: fa-spin 2s infinite linear; +} + +.#{$fa-css-prefix}-pulse { + -webkit-animation: fa-spin 1s infinite steps(8); + animation: fa-spin 1s infinite steps(8); +} + +@-webkit-keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} + +@keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} diff --git a/stylesheets/font-awesome/scss/_core.scss b/stylesheets/font-awesome/scss/_core.scss index 861ccd9d..5a2db9d5 100644 --- a/stylesheets/font-awesome/scss/_core.scss +++ b/stylesheets/font-awesome/scss/_core.scss @@ -3,10 +3,11 @@ .#{$fa-css-prefix} { display: inline-block; - font-family: FontAwesome; - font-style: normal; - font-weight: normal; - line-height: 1; + font: normal normal normal #{$fa-font-size-base}/1 FontAwesome; // shortening font declaration + font-size: inherit; // can't have font-size inherit on line above, so need to override + text-rendering: auto; // optimizelegibility throws things off #1094 -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; + transform: translate(0, 0); // ensures no half-pixel rendering in firefox + } diff --git a/stylesheets/font-awesome/scss/_icons.scss b/stylesheets/font-awesome/scss/_icons.scss index efb44359..fbcfe812 100644 --- a/stylesheets/font-awesome/scss/_icons.scss +++ b/stylesheets/font-awesome/scss/_icons.scss @@ -14,6 +14,8 @@ .#{$fa-css-prefix}-th:before { content: $fa-var-th; } .#{$fa-css-prefix}-th-list:before { content: $fa-var-th-list; } .#{$fa-css-prefix}-check:before { content: $fa-var-check; } +.#{$fa-css-prefix}-remove:before, +.#{$fa-css-prefix}-close:before, .#{$fa-css-prefix}-times:before { content: $fa-var-times; } .#{$fa-css-prefix}-search-plus:before { content: $fa-var-search-plus; } .#{$fa-css-prefix}-search-minus:before { content: $fa-var-search-minus; } @@ -129,7 +131,8 @@ .#{$fa-css-prefix}-folder-open:before { content: $fa-var-folder-open; } .#{$fa-css-prefix}-arrows-v:before { content: $fa-var-arrows-v; } .#{$fa-css-prefix}-arrows-h:before { content: $fa-var-arrows-h; } -.#{$fa-css-prefix}-bar-chart-o:before { content: $fa-var-bar-chart-o; } +.#{$fa-css-prefix}-bar-chart-o:before, +.#{$fa-css-prefix}-bar-chart:before { content: $fa-var-bar-chart; } .#{$fa-css-prefix}-twitter-square:before { content: $fa-var-twitter-square; } .#{$fa-css-prefix}-facebook-square:before { content: $fa-var-facebook-square; } .#{$fa-css-prefix}-camera-retro:before { content: $fa-var-camera-retro; } @@ -155,6 +158,7 @@ .#{$fa-css-prefix}-bookmark-o:before { content: $fa-var-bookmark-o; } .#{$fa-css-prefix}-phone-square:before { content: $fa-var-phone-square; } .#{$fa-css-prefix}-twitter:before { content: $fa-var-twitter; } +.#{$fa-css-prefix}-facebook-f:before, .#{$fa-css-prefix}-facebook:before { content: $fa-var-facebook; } .#{$fa-css-prefix}-github:before { content: $fa-var-github; } .#{$fa-css-prefix}-unlock:before { content: $fa-var-unlock; } @@ -394,7 +398,8 @@ .#{$fa-css-prefix}-trello:before { content: $fa-var-trello; } .#{$fa-css-prefix}-female:before { content: $fa-var-female; } .#{$fa-css-prefix}-male:before { content: $fa-var-male; } -.#{$fa-css-prefix}-gittip:before { content: $fa-var-gittip; } +.#{$fa-css-prefix}-gittip:before, +.#{$fa-css-prefix}-gratipay:before { content: $fa-var-gratipay; } .#{$fa-css-prefix}-sun-o:before { content: $fa-var-sun-o; } .#{$fa-css-prefix}-moon-o:before { content: $fa-var-moon-o; } .#{$fa-css-prefix}-archive:before { content: $fa-var-archive; } @@ -432,7 +437,6 @@ .#{$fa-css-prefix}-stumbleupon:before { content: $fa-var-stumbleupon; } .#{$fa-css-prefix}-delicious:before { content: $fa-var-delicious; } .#{$fa-css-prefix}-digg:before { content: $fa-var-digg; } -.#{$fa-css-prefix}-pied-piper-square:before, .#{$fa-css-prefix}-pied-piper:before { content: $fa-var-pied-piper; } .#{$fa-css-prefix}-pied-piper-alt:before { content: $fa-var-pied-piper-alt; } .#{$fa-css-prefix}-drupal:before { content: $fa-var-drupal; } @@ -477,6 +481,7 @@ .#{$fa-css-prefix}-codepen:before { content: $fa-var-codepen; } .#{$fa-css-prefix}-jsfiddle:before { content: $fa-var-jsfiddle; } .#{$fa-css-prefix}-life-bouy:before, +.#{$fa-css-prefix}-life-buoy:before, .#{$fa-css-prefix}-life-saver:before, .#{$fa-css-prefix}-support:before, .#{$fa-css-prefix}-life-ring:before { content: $fa-var-life-ring; } @@ -497,6 +502,7 @@ .#{$fa-css-prefix}-send-o:before, .#{$fa-css-prefix}-paper-plane-o:before { content: $fa-var-paper-plane-o; } .#{$fa-css-prefix}-history:before { content: $fa-var-history; } +.#{$fa-css-prefix}-genderless:before, .#{$fa-css-prefix}-circle-thin:before { content: $fa-var-circle-thin; } .#{$fa-css-prefix}-header:before { content: $fa-var-header; } .#{$fa-css-prefix}-paragraph:before { content: $fa-var-paragraph; } @@ -504,3 +510,87 @@ .#{$fa-css-prefix}-share-alt:before { content: $fa-var-share-alt; } .#{$fa-css-prefix}-share-alt-square:before { content: $fa-var-share-alt-square; } .#{$fa-css-prefix}-bomb:before { content: $fa-var-bomb; } +.#{$fa-css-prefix}-soccer-ball-o:before, +.#{$fa-css-prefix}-futbol-o:before { content: $fa-var-futbol-o; } +.#{$fa-css-prefix}-tty:before { content: $fa-var-tty; } +.#{$fa-css-prefix}-binoculars:before { content: $fa-var-binoculars; } +.#{$fa-css-prefix}-plug:before { content: $fa-var-plug; } +.#{$fa-css-prefix}-slideshare:before { content: $fa-var-slideshare; } +.#{$fa-css-prefix}-twitch:before { content: $fa-var-twitch; } +.#{$fa-css-prefix}-yelp:before { content: $fa-var-yelp; } +.#{$fa-css-prefix}-newspaper-o:before { content: $fa-var-newspaper-o; } +.#{$fa-css-prefix}-wifi:before { content: $fa-var-wifi; } +.#{$fa-css-prefix}-calculator:before { content: $fa-var-calculator; } +.#{$fa-css-prefix}-paypal:before { content: $fa-var-paypal; } +.#{$fa-css-prefix}-google-wallet:before { content: $fa-var-google-wallet; } +.#{$fa-css-prefix}-cc-visa:before { content: $fa-var-cc-visa; } +.#{$fa-css-prefix}-cc-mastercard:before { content: $fa-var-cc-mastercard; } +.#{$fa-css-prefix}-cc-discover:before { content: $fa-var-cc-discover; } +.#{$fa-css-prefix}-cc-amex:before { content: $fa-var-cc-amex; } +.#{$fa-css-prefix}-cc-paypal:before { content: $fa-var-cc-paypal; } +.#{$fa-css-prefix}-cc-stripe:before { content: $fa-var-cc-stripe; } +.#{$fa-css-prefix}-bell-slash:before { content: $fa-var-bell-slash; } +.#{$fa-css-prefix}-bell-slash-o:before { content: $fa-var-bell-slash-o; } +.#{$fa-css-prefix}-trash:before { content: $fa-var-trash; } +.#{$fa-css-prefix}-copyright:before { content: $fa-var-copyright; } +.#{$fa-css-prefix}-at:before { content: $fa-var-at; } +.#{$fa-css-prefix}-eyedropper:before { content: $fa-var-eyedropper; } +.#{$fa-css-prefix}-paint-brush:before { content: $fa-var-paint-brush; } +.#{$fa-css-prefix}-birthday-cake:before { content: $fa-var-birthday-cake; } +.#{$fa-css-prefix}-area-chart:before { content: $fa-var-area-chart; } +.#{$fa-css-prefix}-pie-chart:before { content: $fa-var-pie-chart; } +.#{$fa-css-prefix}-line-chart:before { content: $fa-var-line-chart; } +.#{$fa-css-prefix}-lastfm:before { content: $fa-var-lastfm; } +.#{$fa-css-prefix}-lastfm-square:before { content: $fa-var-lastfm-square; } +.#{$fa-css-prefix}-toggle-off:before { content: $fa-var-toggle-off; } +.#{$fa-css-prefix}-toggle-on:before { content: $fa-var-toggle-on; } +.#{$fa-css-prefix}-bicycle:before { content: $fa-var-bicycle; } +.#{$fa-css-prefix}-bus:before { content: $fa-var-bus; } +.#{$fa-css-prefix}-ioxhost:before { content: $fa-var-ioxhost; } +.#{$fa-css-prefix}-angellist:before { content: $fa-var-angellist; } +.#{$fa-css-prefix}-cc:before { content: $fa-var-cc; } +.#{$fa-css-prefix}-shekel:before, +.#{$fa-css-prefix}-sheqel:before, +.#{$fa-css-prefix}-ils:before { content: $fa-var-ils; } +.#{$fa-css-prefix}-meanpath:before { content: $fa-var-meanpath; } +.#{$fa-css-prefix}-buysellads:before { content: $fa-var-buysellads; } +.#{$fa-css-prefix}-connectdevelop:before { content: $fa-var-connectdevelop; } +.#{$fa-css-prefix}-dashcube:before { content: $fa-var-dashcube; } +.#{$fa-css-prefix}-forumbee:before { content: $fa-var-forumbee; } +.#{$fa-css-prefix}-leanpub:before { content: $fa-var-leanpub; } +.#{$fa-css-prefix}-sellsy:before { content: $fa-var-sellsy; } +.#{$fa-css-prefix}-shirtsinbulk:before { content: $fa-var-shirtsinbulk; } +.#{$fa-css-prefix}-simplybuilt:before { content: $fa-var-simplybuilt; } +.#{$fa-css-prefix}-skyatlas:before { content: $fa-var-skyatlas; } +.#{$fa-css-prefix}-cart-plus:before { content: $fa-var-cart-plus; } +.#{$fa-css-prefix}-cart-arrow-down:before { content: $fa-var-cart-arrow-down; } +.#{$fa-css-prefix}-diamond:before { content: $fa-var-diamond; } +.#{$fa-css-prefix}-ship:before { content: $fa-var-ship; } +.#{$fa-css-prefix}-user-secret:before { content: $fa-var-user-secret; } +.#{$fa-css-prefix}-motorcycle:before { content: $fa-var-motorcycle; } +.#{$fa-css-prefix}-street-view:before { content: $fa-var-street-view; } +.#{$fa-css-prefix}-heartbeat:before { content: $fa-var-heartbeat; } +.#{$fa-css-prefix}-venus:before { content: $fa-var-venus; } +.#{$fa-css-prefix}-mars:before { content: $fa-var-mars; } +.#{$fa-css-prefix}-mercury:before { content: $fa-var-mercury; } +.#{$fa-css-prefix}-transgender:before { content: $fa-var-transgender; } +.#{$fa-css-prefix}-transgender-alt:before { content: $fa-var-transgender-alt; } +.#{$fa-css-prefix}-venus-double:before { content: $fa-var-venus-double; } +.#{$fa-css-prefix}-mars-double:before { content: $fa-var-mars-double; } +.#{$fa-css-prefix}-venus-mars:before { content: $fa-var-venus-mars; } +.#{$fa-css-prefix}-mars-stroke:before { content: $fa-var-mars-stroke; } +.#{$fa-css-prefix}-mars-stroke-v:before { content: $fa-var-mars-stroke-v; } +.#{$fa-css-prefix}-mars-stroke-h:before { content: $fa-var-mars-stroke-h; } +.#{$fa-css-prefix}-neuter:before { content: $fa-var-neuter; } +.#{$fa-css-prefix}-facebook-official:before { content: $fa-var-facebook-official; } +.#{$fa-css-prefix}-pinterest-p:before { content: $fa-var-pinterest-p; } +.#{$fa-css-prefix}-whatsapp:before { content: $fa-var-whatsapp; } +.#{$fa-css-prefix}-server:before { content: $fa-var-server; } +.#{$fa-css-prefix}-user-plus:before { content: $fa-var-user-plus; } +.#{$fa-css-prefix}-user-times:before { content: $fa-var-user-times; } +.#{$fa-css-prefix}-hotel:before, +.#{$fa-css-prefix}-bed:before { content: $fa-var-bed; } +.#{$fa-css-prefix}-viacoin:before { content: $fa-var-viacoin; } +.#{$fa-css-prefix}-train:before { content: $fa-var-train; } +.#{$fa-css-prefix}-subway:before { content: $fa-var-subway; } +.#{$fa-css-prefix}-medium:before { content: $fa-var-medium; } diff --git a/stylesheets/font-awesome/scss/_mixins.scss b/stylesheets/font-awesome/scss/_mixins.scss index 3354e695..6b7f1609 100644 --- a/stylesheets/font-awesome/scss/_mixins.scss +++ b/stylesheets/font-awesome/scss/_mixins.scss @@ -1,20 +1,27 @@ // Mixins // -------------------------- +@mixin fa-icon() { + display: inline-block; + font: normal normal normal #{$fa-font-size-base}/1 FontAwesome; // shortening font declaration + font-size: inherit; // can't have font-size inherit on line above, so need to override + text-rendering: auto; // optimizelegibility throws things off #1094 + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + transform: translate(0, 0); // ensures no half-pixel rendering in firefox + +} + @mixin fa-icon-rotate($degrees, $rotation) { filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}); -webkit-transform: rotate($degrees); - -moz-transform: rotate($degrees); -ms-transform: rotate($degrees); - -o-transform: rotate($degrees); transform: rotate($degrees); } @mixin fa-icon-flip($horiz, $vert, $rotation) { filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}); -webkit-transform: scale($horiz, $vert); - -moz-transform: scale($horiz, $vert); -ms-transform: scale($horiz, $vert); - -o-transform: scale($horiz, $vert); transform: scale($horiz, $vert); } diff --git a/stylesheets/font-awesome/scss/_path.scss b/stylesheets/font-awesome/scss/_path.scss index fd21c351..bb457c23 100644 --- a/stylesheets/font-awesome/scss/_path.scss +++ b/stylesheets/font-awesome/scss/_path.scss @@ -5,10 +5,11 @@ font-family: 'FontAwesome'; src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}'); src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'), + url('#{$fa-font-path}/fontawesome-webfont.woff2?v=#{$fa-version}') format('woff2'), url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'), url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'), url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg'); - //src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts +// src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts font-weight: normal; font-style: normal; } diff --git a/stylesheets/font-awesome/scss/_rotated-flipped.scss b/stylesheets/font-awesome/scss/_rotated-flipped.scss index 343fa550..a3558fd0 100644 --- a/stylesheets/font-awesome/scss/_rotated-flipped.scss +++ b/stylesheets/font-awesome/scss/_rotated-flipped.scss @@ -7,3 +7,14 @@ .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); } .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); } + +// Hook for IE8-9 +// ------------------------- + +:root .#{$fa-css-prefix}-rotate-90, +:root .#{$fa-css-prefix}-rotate-180, +:root .#{$fa-css-prefix}-rotate-270, +:root .#{$fa-css-prefix}-flip-horizontal, +:root .#{$fa-css-prefix}-flip-vertical { + filter: none; +} diff --git a/stylesheets/font-awesome/scss/_spinning.scss b/stylesheets/font-awesome/scss/_spinning.scss deleted file mode 100644 index c3787446..00000000 --- a/stylesheets/font-awesome/scss/_spinning.scss +++ /dev/null @@ -1,32 +0,0 @@ -// Spinning Icons -// -------------------------- - -.#{$fa-css-prefix}-spin { - -webkit-animation: spin 2s infinite linear; - -moz-animation: spin 2s infinite linear; - -o-animation: spin 2s infinite linear; - animation: spin 2s infinite linear; -} - -@-moz-keyframes spin { - 0% { -moz-transform: rotate(0deg); } - 100% { -moz-transform: rotate(359deg); } -} -@-webkit-keyframes spin { - 0% { -webkit-transform: rotate(0deg); } - 100% { -webkit-transform: rotate(359deg); } -} -@-o-keyframes spin { - 0% { -o-transform: rotate(0deg); } - 100% { -o-transform: rotate(359deg); } -} -@keyframes spin { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - 100% { - -webkit-transform: rotate(359deg); - transform: rotate(359deg); - } -} diff --git a/stylesheets/font-awesome/scss/_variables.scss b/stylesheets/font-awesome/scss/_variables.scss index ac2b5051..9b7210e2 100644 --- a/stylesheets/font-awesome/scss/_variables.scss +++ b/stylesheets/font-awesome/scss/_variables.scss @@ -2,9 +2,10 @@ // -------------------------- $fa-font-path: "../fonts" !default; -//$fa-font-path: "//netdna.bootstrapcdn.com/font-awesome/4.1.0/fonts" !default; // for referencing Bootstrap CDN font files directly +$fa-font-size-base: 14px !default; +//$fa-font-path: "//netdna.bootstrapcdn.com/font-awesome/4.3.0/fonts" !default; // for referencing Bootstrap CDN font files directly $fa-css-prefix: fa !default; -$fa-version: "4.1.0" !default; +$fa-version: "4.3.0" !default; $fa-border-color: #eee !default; $fa-inverse: #fff !default; $fa-li-width: (30em / 14) !default; @@ -18,6 +19,7 @@ $fa-var-align-right: "\f038"; $fa-var-ambulance: "\f0f9"; $fa-var-anchor: "\f13d"; $fa-var-android: "\f17b"; +$fa-var-angellist: "\f209"; $fa-var-angle-double-down: "\f103"; $fa-var-angle-double-left: "\f100"; $fa-var-angle-double-right: "\f101"; @@ -28,6 +30,7 @@ $fa-var-angle-right: "\f105"; $fa-var-angle-up: "\f106"; $fa-var-apple: "\f179"; $fa-var-archive: "\f187"; +$fa-var-area-chart: "\f1fe"; $fa-var-arrow-circle-down: "\f0ab"; $fa-var-arrow-circle-left: "\f0a8"; $fa-var-arrow-circle-o-down: "\f01a"; @@ -45,18 +48,26 @@ $fa-var-arrows-alt: "\f0b2"; $fa-var-arrows-h: "\f07e"; $fa-var-arrows-v: "\f07d"; $fa-var-asterisk: "\f069"; +$fa-var-at: "\f1fa"; $fa-var-automobile: "\f1b9"; $fa-var-backward: "\f04a"; $fa-var-ban: "\f05e"; $fa-var-bank: "\f19c"; +$fa-var-bar-chart: "\f080"; $fa-var-bar-chart-o: "\f080"; $fa-var-barcode: "\f02a"; $fa-var-bars: "\f0c9"; +$fa-var-bed: "\f236"; $fa-var-beer: "\f0fc"; $fa-var-behance: "\f1b4"; $fa-var-behance-square: "\f1b5"; $fa-var-bell: "\f0f3"; $fa-var-bell-o: "\f0a2"; +$fa-var-bell-slash: "\f1f6"; +$fa-var-bell-slash-o: "\f1f7"; +$fa-var-bicycle: "\f206"; +$fa-var-binoculars: "\f1e5"; +$fa-var-birthday-cake: "\f1fd"; $fa-var-bitbucket: "\f171"; $fa-var-bitbucket-square: "\f172"; $fa-var-bitcoin: "\f15a"; @@ -73,7 +84,10 @@ $fa-var-building: "\f1ad"; $fa-var-building-o: "\f0f7"; $fa-var-bullhorn: "\f0a1"; $fa-var-bullseye: "\f140"; +$fa-var-bus: "\f207"; +$fa-var-buysellads: "\f20d"; $fa-var-cab: "\f1ba"; +$fa-var-calculator: "\f1ec"; $fa-var-calendar: "\f073"; $fa-var-calendar-o: "\f133"; $fa-var-camera: "\f030"; @@ -87,6 +101,15 @@ $fa-var-caret-square-o-left: "\f191"; $fa-var-caret-square-o-right: "\f152"; $fa-var-caret-square-o-up: "\f151"; $fa-var-caret-up: "\f0d8"; +$fa-var-cart-arrow-down: "\f218"; +$fa-var-cart-plus: "\f217"; +$fa-var-cc: "\f20a"; +$fa-var-cc-amex: "\f1f3"; +$fa-var-cc-discover: "\f1f2"; +$fa-var-cc-mastercard: "\f1f1"; +$fa-var-cc-paypal: "\f1f4"; +$fa-var-cc-stripe: "\f1f5"; +$fa-var-cc-visa: "\f1f0"; $fa-var-certificate: "\f0a3"; $fa-var-chain: "\f0c1"; $fa-var-chain-broken: "\f127"; @@ -110,6 +133,7 @@ $fa-var-circle-o-notch: "\f1ce"; $fa-var-circle-thin: "\f1db"; $fa-var-clipboard: "\f0ea"; $fa-var-clock-o: "\f017"; +$fa-var-close: "\f00d"; $fa-var-cloud: "\f0c2"; $fa-var-cloud-download: "\f0ed"; $fa-var-cloud-upload: "\f0ee"; @@ -127,7 +151,9 @@ $fa-var-comments: "\f086"; $fa-var-comments-o: "\f0e6"; $fa-var-compass: "\f14e"; $fa-var-compress: "\f066"; +$fa-var-connectdevelop: "\f20e"; $fa-var-copy: "\f0c5"; +$fa-var-copyright: "\f1f9"; $fa-var-credit-card: "\f09d"; $fa-var-crop: "\f125"; $fa-var-crosshairs: "\f05b"; @@ -137,11 +163,13 @@ $fa-var-cubes: "\f1b3"; $fa-var-cut: "\f0c4"; $fa-var-cutlery: "\f0f5"; $fa-var-dashboard: "\f0e4"; +$fa-var-dashcube: "\f210"; $fa-var-database: "\f1c0"; $fa-var-dedent: "\f03b"; $fa-var-delicious: "\f1a5"; $fa-var-desktop: "\f108"; $fa-var-deviantart: "\f1bd"; +$fa-var-diamond: "\f219"; $fa-var-digg: "\f1a6"; $fa-var-dollar: "\f155"; $fa-var-dot-circle-o: "\f192"; @@ -169,7 +197,10 @@ $fa-var-external-link: "\f08e"; $fa-var-external-link-square: "\f14c"; $fa-var-eye: "\f06e"; $fa-var-eye-slash: "\f070"; +$fa-var-eyedropper: "\f1fb"; $fa-var-facebook: "\f09a"; +$fa-var-facebook-f: "\f09a"; +$fa-var-facebook-official: "\f230"; $fa-var-facebook-square: "\f082"; $fa-var-fast-backward: "\f049"; $fa-var-fast-forward: "\f050"; @@ -211,15 +242,18 @@ $fa-var-folder-o: "\f114"; $fa-var-folder-open: "\f07c"; $fa-var-folder-open-o: "\f115"; $fa-var-font: "\f031"; +$fa-var-forumbee: "\f211"; $fa-var-forward: "\f04e"; $fa-var-foursquare: "\f180"; $fa-var-frown-o: "\f119"; +$fa-var-futbol-o: "\f1e3"; $fa-var-gamepad: "\f11b"; $fa-var-gavel: "\f0e3"; $fa-var-gbp: "\f154"; $fa-var-ge: "\f1d1"; $fa-var-gear: "\f013"; $fa-var-gears: "\f085"; +$fa-var-genderless: "\f1db"; $fa-var-gift: "\f06b"; $fa-var-git: "\f1d3"; $fa-var-git-square: "\f1d2"; @@ -232,7 +266,9 @@ $fa-var-globe: "\f0ac"; $fa-var-google: "\f1a0"; $fa-var-google-plus: "\f0d5"; $fa-var-google-plus-square: "\f0d4"; +$fa-var-google-wallet: "\f1ee"; $fa-var-graduation-cap: "\f19d"; +$fa-var-gratipay: "\f184"; $fa-var-group: "\f0c0"; $fa-var-h-square: "\f0fd"; $fa-var-hacker-news: "\f1d4"; @@ -245,10 +281,13 @@ $fa-var-header: "\f1dc"; $fa-var-headphones: "\f025"; $fa-var-heart: "\f004"; $fa-var-heart-o: "\f08a"; +$fa-var-heartbeat: "\f21e"; $fa-var-history: "\f1da"; $fa-var-home: "\f015"; $fa-var-hospital-o: "\f0f8"; +$fa-var-hotel: "\f236"; $fa-var-html5: "\f13b"; +$fa-var-ils: "\f20b"; $fa-var-image: "\f03e"; $fa-var-inbox: "\f01c"; $fa-var-indent: "\f03c"; @@ -257,6 +296,7 @@ $fa-var-info-circle: "\f05a"; $fa-var-inr: "\f156"; $fa-var-instagram: "\f16d"; $fa-var-institution: "\f19c"; +$fa-var-ioxhost: "\f208"; $fa-var-italic: "\f033"; $fa-var-joomla: "\f1aa"; $fa-var-jpy: "\f157"; @@ -266,15 +306,20 @@ $fa-var-keyboard-o: "\f11c"; $fa-var-krw: "\f159"; $fa-var-language: "\f1ab"; $fa-var-laptop: "\f109"; +$fa-var-lastfm: "\f202"; +$fa-var-lastfm-square: "\f203"; $fa-var-leaf: "\f06c"; +$fa-var-leanpub: "\f212"; $fa-var-legal: "\f0e3"; $fa-var-lemon-o: "\f094"; $fa-var-level-down: "\f149"; $fa-var-level-up: "\f148"; $fa-var-life-bouy: "\f1cd"; +$fa-var-life-buoy: "\f1cd"; $fa-var-life-ring: "\f1cd"; $fa-var-life-saver: "\f1cd"; $fa-var-lightbulb-o: "\f0eb"; +$fa-var-line-chart: "\f201"; $fa-var-link: "\f0c1"; $fa-var-linkedin: "\f0e1"; $fa-var-linkedin-square: "\f08c"; @@ -296,9 +341,17 @@ $fa-var-mail-reply: "\f112"; $fa-var-mail-reply-all: "\f122"; $fa-var-male: "\f183"; $fa-var-map-marker: "\f041"; +$fa-var-mars: "\f222"; +$fa-var-mars-double: "\f227"; +$fa-var-mars-stroke: "\f229"; +$fa-var-mars-stroke-h: "\f22b"; +$fa-var-mars-stroke-v: "\f22a"; $fa-var-maxcdn: "\f136"; +$fa-var-meanpath: "\f20c"; +$fa-var-medium: "\f23a"; $fa-var-medkit: "\f0fa"; $fa-var-meh-o: "\f11a"; +$fa-var-mercury: "\f223"; $fa-var-microphone: "\f130"; $fa-var-microphone-slash: "\f131"; $fa-var-minus: "\f068"; @@ -310,11 +363,15 @@ $fa-var-mobile-phone: "\f10b"; $fa-var-money: "\f0d6"; $fa-var-moon-o: "\f186"; $fa-var-mortar-board: "\f19d"; +$fa-var-motorcycle: "\f21c"; $fa-var-music: "\f001"; $fa-var-navicon: "\f0c9"; +$fa-var-neuter: "\f22c"; +$fa-var-newspaper-o: "\f1ea"; $fa-var-openid: "\f19b"; $fa-var-outdent: "\f03b"; $fa-var-pagelines: "\f18c"; +$fa-var-paint-brush: "\f1fc"; $fa-var-paper-plane: "\f1d8"; $fa-var-paper-plane-o: "\f1d9"; $fa-var-paperclip: "\f0c6"; @@ -322,6 +379,7 @@ $fa-var-paragraph: "\f1dd"; $fa-var-paste: "\f0ea"; $fa-var-pause: "\f04c"; $fa-var-paw: "\f1b0"; +$fa-var-paypal: "\f1ed"; $fa-var-pencil: "\f040"; $fa-var-pencil-square: "\f14b"; $fa-var-pencil-square-o: "\f044"; @@ -329,15 +387,17 @@ $fa-var-phone: "\f095"; $fa-var-phone-square: "\f098"; $fa-var-photo: "\f03e"; $fa-var-picture-o: "\f03e"; +$fa-var-pie-chart: "\f200"; $fa-var-pied-piper: "\f1a7"; $fa-var-pied-piper-alt: "\f1a8"; -$fa-var-pied-piper-square: "\f1a7"; $fa-var-pinterest: "\f0d2"; +$fa-var-pinterest-p: "\f231"; $fa-var-pinterest-square: "\f0d3"; $fa-var-plane: "\f072"; $fa-var-play: "\f04b"; $fa-var-play-circle: "\f144"; $fa-var-play-circle-o: "\f01d"; +$fa-var-plug: "\f1e6"; $fa-var-plus: "\f067"; $fa-var-plus-circle: "\f055"; $fa-var-plus-square: "\f0fe"; @@ -358,6 +418,7 @@ $fa-var-recycle: "\f1b8"; $fa-var-reddit: "\f1a1"; $fa-var-reddit-square: "\f1a2"; $fa-var-refresh: "\f021"; +$fa-var-remove: "\f00d"; $fa-var-renren: "\f18b"; $fa-var-reorder: "\f0c9"; $fa-var-repeat: "\f01e"; @@ -380,23 +441,33 @@ $fa-var-scissors: "\f0c4"; $fa-var-search: "\f002"; $fa-var-search-minus: "\f010"; $fa-var-search-plus: "\f00e"; +$fa-var-sellsy: "\f213"; $fa-var-send: "\f1d8"; $fa-var-send-o: "\f1d9"; +$fa-var-server: "\f233"; $fa-var-share: "\f064"; $fa-var-share-alt: "\f1e0"; $fa-var-share-alt-square: "\f1e1"; $fa-var-share-square: "\f14d"; $fa-var-share-square-o: "\f045"; +$fa-var-shekel: "\f20b"; +$fa-var-sheqel: "\f20b"; $fa-var-shield: "\f132"; +$fa-var-ship: "\f21a"; +$fa-var-shirtsinbulk: "\f214"; $fa-var-shopping-cart: "\f07a"; $fa-var-sign-in: "\f090"; $fa-var-sign-out: "\f08b"; $fa-var-signal: "\f012"; +$fa-var-simplybuilt: "\f215"; $fa-var-sitemap: "\f0e8"; +$fa-var-skyatlas: "\f216"; $fa-var-skype: "\f17e"; $fa-var-slack: "\f198"; $fa-var-sliders: "\f1de"; +$fa-var-slideshare: "\f1e7"; $fa-var-smile-o: "\f118"; +$fa-var-soccer-ball-o: "\f1e3"; $fa-var-sort: "\f0dc"; $fa-var-sort-alpha-asc: "\f15d"; $fa-var-sort-alpha-desc: "\f15e"; @@ -429,10 +500,12 @@ $fa-var-step-backward: "\f048"; $fa-var-step-forward: "\f051"; $fa-var-stethoscope: "\f0f1"; $fa-var-stop: "\f04d"; +$fa-var-street-view: "\f21d"; $fa-var-strikethrough: "\f0cc"; $fa-var-stumbleupon: "\f1a4"; $fa-var-stumbleupon-circle: "\f1a3"; $fa-var-subscript: "\f12c"; +$fa-var-subway: "\f239"; $fa-var-suitcase: "\f0f2"; $fa-var-sun-o: "\f185"; $fa-var-superscript: "\f12b"; @@ -463,17 +536,25 @@ $fa-var-times-circle-o: "\f05c"; $fa-var-tint: "\f043"; $fa-var-toggle-down: "\f150"; $fa-var-toggle-left: "\f191"; +$fa-var-toggle-off: "\f204"; +$fa-var-toggle-on: "\f205"; $fa-var-toggle-right: "\f152"; $fa-var-toggle-up: "\f151"; +$fa-var-train: "\f238"; +$fa-var-transgender: "\f224"; +$fa-var-transgender-alt: "\f225"; +$fa-var-trash: "\f1f8"; $fa-var-trash-o: "\f014"; $fa-var-tree: "\f1bb"; $fa-var-trello: "\f181"; $fa-var-trophy: "\f091"; $fa-var-truck: "\f0d1"; $fa-var-try: "\f195"; +$fa-var-tty: "\f1e4"; $fa-var-tumblr: "\f173"; $fa-var-tumblr-square: "\f174"; $fa-var-turkish-lira: "\f195"; +$fa-var-twitch: "\f1e8"; $fa-var-twitter: "\f099"; $fa-var-twitter-square: "\f081"; $fa-var-umbrella: "\f0e9"; @@ -488,7 +569,14 @@ $fa-var-upload: "\f093"; $fa-var-usd: "\f155"; $fa-var-user: "\f007"; $fa-var-user-md: "\f0f0"; +$fa-var-user-plus: "\f234"; +$fa-var-user-secret: "\f21b"; +$fa-var-user-times: "\f235"; $fa-var-users: "\f0c0"; +$fa-var-venus: "\f221"; +$fa-var-venus-double: "\f226"; +$fa-var-venus-mars: "\f228"; +$fa-var-viacoin: "\f237"; $fa-var-video-camera: "\f03d"; $fa-var-vimeo-square: "\f194"; $fa-var-vine: "\f1ca"; @@ -500,7 +588,9 @@ $fa-var-warning: "\f071"; $fa-var-wechat: "\f1d7"; $fa-var-weibo: "\f18a"; $fa-var-weixin: "\f1d7"; +$fa-var-whatsapp: "\f232"; $fa-var-wheelchair: "\f193"; +$fa-var-wifi: "\f1eb"; $fa-var-windows: "\f17a"; $fa-var-won: "\f159"; $fa-var-wordpress: "\f19a"; @@ -508,6 +598,7 @@ $fa-var-wrench: "\f0ad"; $fa-var-xing: "\f168"; $fa-var-xing-square: "\f169"; $fa-var-yahoo: "\f19e"; +$fa-var-yelp: "\f1e9"; $fa-var-yen: "\f157"; $fa-var-youtube: "\f167"; $fa-var-youtube-play: "\f16a"; diff --git a/stylesheets/font-awesome/scss/font-awesome.scss b/stylesheets/font-awesome/scss/font-awesome.scss index 2307dbda..388ac6b0 100644 --- a/stylesheets/font-awesome/scss/font-awesome.scss +++ b/stylesheets/font-awesome/scss/font-awesome.scss @@ -1,5 +1,5 @@ /*! - * Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome + * Font Awesome 4.3.0 by @davegandy - http://fontawesome.io - @fontawesome * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) */ @@ -11,7 +11,7 @@ @import "fixed-width"; @import "list"; @import "bordered-pulled"; -@import "spinning"; +@import "animated"; @import "rotated-flipped"; @import "stacked"; @import "icons"; diff --git a/stylesheets/style.css b/stylesheets/style.css index ef26f40c..45d57e19 100644 --- a/stylesheets/style.css +++ b/stylesheets/style.css @@ -79,10 +79,6 @@ header div.subtitle { font-size: 8pt; } -form { - margin-bottom: 4em; -} - form table { margin: auto; } @@ -131,7 +127,10 @@ form table tr th { form table tr td div.center { text-align: center; float: left; - padding-left: 3px; + padding: 3px; + padding-top: 0px; + border: 1px dashed black; + margin: 2px } form table tr td div input { @@ -261,6 +260,11 @@ p.intro a { margin-left: 5px; } +.sage { + color: red; + font-weight: bold; +} + div.delete { float: right; } @@ -1035,3 +1039,9 @@ div.mix { display: block!important; font-size: 12pt; } + +.dx,.dy,.dz { + width: 30px; + text-align: right; + display: inline-block; +} diff --git a/templates/8chan/index.html b/templates/8chan/index.html index 9dc6cb3b..5c37cebf 100644 --- a/templates/8chan/index.html +++ b/templates/8chan/index.html @@ -298,11 +298,18 @@

    {% trans %}On 8chan, you can create your own imageboard for free with no experience or programming knowledge needed.{% endtrans %}

    {% trans %}Warning: Some boards on this site might contain content of an adult or offensive nature. Please cease use of this site if it is illegal for you to view such content. The boards on this site are made entirely by the users and do not represent the opinions of the administration of 8chan. In the interest of free speech, only content that directly violates the DMCA or other US laws is deleted.{% endtrans %}

    -
    “Give me your tired, your poor,
    Your huddled masses yearning to breathe free,
    The wretched refuse of your teeming shore.
    Send these, the homeless, tempest-tost to me,
    I lift my lamp beside the golden door!” ~ Emma Lazarus
    +

    +
    Latest headlines
    +
      + {% for n in newsplus[:15] %} +
    1. {{ n.subject|e }} (link)
    2. + {% endfor %} +
    +


    diff --git a/templates/header.html b/templates/header.html index 75f885c7..05ff089b 100644 --- a/templates/header.html +++ b/templates/header.html @@ -8,7 +8,6 @@ {% if config.default_stylesheet.1 != '' and not mod %}{% endif %} {% if config.font_awesome %}{% endif %} {% if config.country_flags_condensed %}{% endif %} - {% if config.katex %}{% endif %} {% endif %} diff --git a/templates/mod/settings.html b/templates/mod/settings.html index 22eafea6..f023cbb6 100644 --- a/templates/mod/settings.html +++ b/templates/mod/settings.html @@ -39,7 +39,7 @@ {% trans %}Archive my board on 8archive.moe{% endtrans %}
    {% trans %}This archives your board on 8archive.moe if you opt in{% endtrans %} {% trans %}[code] tags{% endtrans %} {% trans %}Oekaki{% endtrans %} - {% trans %}Format math between [tex]{% endtrans %} + {% trans %}Format math between $${% endtrans %} {% trans %}Allow SWF uploading{% endtrans %} {% trans %}Allow PDF uploading{% endtrans %} {% trans %}Enable dice rolling{% endtrans %} diff --git a/templates/post_form.html b/templates/post_form.html index 5f0d43ef..403af40c 100644 --- a/templates/post_form.html +++ b/templates/post_form.html @@ -11,7 +11,7 @@ {% if not config.field_disable_name or (mod and post.mod|hasPermission(config.mod.bypass_field_disable, board.uri)) %}{% endif %} {% if not config.field_disable_email or (mod and post.mod|hasPermission(config.mod.bypass_field_disable, board.uri)) %}{% endif %} {% if not (config.field_disable_subject or (id and config.field_disable_reply_subject)) or (mod and post.mod|hasPermission(config.mod.bypass_field_disable, board.uri)) %} {% endif %} @@ -98,7 +98,7 @@ {% if config.user_flag %} - + {% endif %} - {% if (mod and ((not id and post.mod|hasPermission(config.mod.sticky, board.uri)) or (not id and post.mod|hasPermission(config.mod.lock, board.uri)) or post.mod|hasPermission(config.mod.rawhtml, board.uri))) or (config.allow_no_country and config.country_flags) %} - + - {% endif %} {% if not config.field_disable_password or (mod and post.mod|hasPermission(config.mod.bypass_field_disable, board.uri)) %}
    - {% trans %}Name{% endtrans %} + {% trans %}Name{% endtrans %} {% trans %}(optional){% endtrans %} {{ antibot.html() }} @@ -21,7 +21,7 @@
    - {% trans %}Email{% endtrans %} + {% trans %}Email{% endtrans %} {% trans %}(optional){% endtrans %} {{ antibot.html() }} @@ -36,19 +36,19 @@ {% endif %} {{ antibot.html() }} {% if not (not (config.field_disable_subject or (id and config.field_disable_reply_subject)) or (mod and post.mod|hasPermission(config.mod.bypass_field_disable, board.uri))) %} - {% if config.spoiler_images %} {% endif %} + {% endif %} {{ antibot.html() }}
    - {% trans %}Subject{% endtrans %} + {% trans %}Subject{% endtrans %} {% if not config.force_subject_op or id %}{% trans %}(optional){% endtrans %}{% endif %} {{ antibot.html() }} - {% if config.spoiler_images %} {% endif %} +
    {% trans %}Flag{% endtrans %}{% trans %}Flag{% endtrans %} {% trans %}(optional){% endtrans %}
    - {% trans %}File{% endtrans %} + {% trans %}File{% endtrans %} {% if not config.force_image_op or id %}{% trans %}(optional){% endtrans %}{% endif %} @@ -130,7 +130,7 @@ {% if config.enable_embedding %}
    - {% trans %}Embed{% endtrans %} + {% trans %}Embed{% endtrans %} {% if not config.force_image_op or id %}{% trans %}(optional){% endtrans %}{% else %}{% trans %}(or file){% endtrans %}{% endif %} {{ antibot.html() }} @@ -138,34 +138,47 @@
    - {% trans %}Flags{% endtrans %} + {% trans %}Options{% endtrans %} - {% if config.allow_no_country and config.country_flags %}
    +
    + + +
    + + {% if config.spoiler_images %}
    + + +
    {% endif %} + + {% if config.allow_no_country and config.country_flags %}
    {% endif %} - {% if mod %} - {% if not id and post.mod|hasPermission(config.mod.sticky, board.uri) %}
    - -
    + {% if config.allow_roll %}
    + +
    d±
    {% endif %} - {% if not id and post.mod|hasPermission(config.mod.lock, board.uri) %}
    + + {% if mod %} + {% if not id and post.mod|hasPermission(config.mod.sticky, board.uri) %}
    + + +
    {% endif %} + {% if not id and post.mod|hasPermission(config.mod.lock, board.uri) %}

    {% endif %} - {% if post.mod|hasPermission(config.mod.rawhtml, board.uri) %}
    + {% if post.mod|hasPermission(config.mod.rawhtml, board.uri) %}

    {% endif %} {% endif %}
    {% trans %}Password{% endtrans %} @@ -198,7 +211,5 @@ Max filesize is {{ config.max_filesize|filesize }}.
    Max image dimensions are {{ config.max_height }} x {{ config.max_width }}.
    You may upload {{ config.max_images }} per post.
    {% endif %} -{% if config.allow_roll %} -You may roll dice on this board, type "dice XdY+Z" in the email field where X is number of dice, Y is max roll and Z is modifier.
    -{% endif %} +
    Confused? See the FAQ.