diff --git a/system/config/autoload.php b/system/config/autoload.php
index ef32444..81c30ee 100644
--- a/system/config/autoload.php
+++ b/system/config/autoload.php
@@ -86,8 +86,7 @@ final class Config {
$this->data = array_merge($this->data, $cfg);
} else {
- trigger_error('Error: Could not load config ' . $filename . '!');
- exit();
+ throw new \Phacil\Framework\Exception('Could not load config ' . $filename. '!');
}
}
}
diff --git a/system/database/databases/mssql.php b/system/database/databases/mssql.php
index f0c8083..aafe7b6 100644
--- a/system/database/databases/mssql.php
+++ b/system/database/databases/mssql.php
@@ -62,8 +62,7 @@ final class MSSQL implements \Phacil\Framework\Interfaces\Databases
return true;
}
} else {
- trigger_error('Error: ' . mssql_get_last_message($this->connection) . ' ' . $sql);
- exit();
+ throw new \Phacil\Framework\Exception('Error: ' . mssql_get_last_message($this->connection) . ' ' . $sql);
}
}
diff --git a/system/database/databases/mysql_legacy.php b/system/database/databases/mysql_legacy.php
index 12504f6..70c4d67 100644
--- a/system/database/databases/mysql_legacy.php
+++ b/system/database/databases/mysql_legacy.php
@@ -63,8 +63,7 @@ final class MySQL_legacy implements \Phacil\Framework\Interfaces\Databases {
return true;
}
} else {
- trigger_error('Error: ' . mysql_error($this->connection) . ' Error No: ' . mysql_errno($this->connection) . ' ' . $sql);
- exit();
+ throw new \Phacil\Framework\Exception('Error: ' . mysql_error($this->connection) . ' Error No: ' . mysql_errno($this->connection) . ' ' . $sql);
}
}
diff --git a/system/database/databases/mysql_pdo.php b/system/database/databases/mysql_pdo.php
index 0b3e2d4..da970e1 100644
--- a/system/database/databases/mysql_pdo.php
+++ b/system/database/databases/mysql_pdo.php
@@ -80,7 +80,7 @@ final class MYSQL_PDO implements Databases
$this->dbh->exec($this->options['PDO::MYSQL_ATTR_INIT_COMMAND']);
}
} catch (\PDOException $exception) {
- trigger_error($exception->getMessage());
+ throw new \Phacil\Framework\Exception($exception->getMessage());
}
}
/**
diff --git a/system/database/databases/oracle.php b/system/database/databases/oracle.php
index ac657bf..2f725b0 100644
--- a/system/database/databases/oracle.php
+++ b/system/database/databases/oracle.php
@@ -38,7 +38,7 @@ final class Oracle implements Databases {
if (!$this->connection) {
$e = oci_error();
$this->error = $e;
- throw new \Exception(trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR));
+ throw new \Phacil\Framework\Exception((htmlentities($e['message'], ENT_QUOTES)));
}
oci_set_client_info($this->connection, "Administrator");
//oci_set_module_name($this->connection, $module);
@@ -66,7 +66,7 @@ final class Oracle implements Databases {
} else {
- throw new \Exception('Error: ' . oci_error() . ' ' . $sql);
+ throw new \Phacil\Framework\Exception('Error: ' . oci_error() . ' ' . $sql);
}
}
diff --git a/system/database/databases/sqlsrv.php b/system/database/databases/sqlsrv.php
index 09141ee..bfeecfb 100644
--- a/system/database/databases/sqlsrv.php
+++ b/system/database/databases/sqlsrv.php
@@ -88,8 +88,7 @@ final class SQLSRV implements Databases {
return true;
}
} else {
- trigger_error('Error: ' . $sql);
- exit();
+ throw new \Phacil\Framework\Exception('Error: ' . $sql);
}
}
diff --git a/system/engine/exception.php b/system/engine/exception.php
index a1cdf3e..fd969c5 100644
--- a/system/engine/exception.php
+++ b/system/engine/exception.php
@@ -20,6 +20,21 @@ class Exception extends \Exception
{
public $errorFormat = 'text';
+ protected $heritageTrace = false;
+
+ /**
+ *
+ * @param \Exception $object
+ * @return $this
+ */
+ public function setObject(\Exception $object){
+ $this->message = $object->getMessage();
+ $this->line = $object->getLine();
+ $this->heritageTrace = $object->getTrace();
+ $this->file = $object->getFile();
+ return $this;
+ }
+
/**
* Save the exceptions in the exceptions log file
* @return void
@@ -35,7 +50,7 @@ class Exception extends \Exception
'error' => $this->getMessage(),
'line' => $this->getLine(),
'file' => $this->getFile(),
- 'trace' => ($debugging) ? (($this->errorFormat == 'json') ? $this->getTrace() : Debug::trace($this->getTrace())) : null
+ 'trace' => ($debugging) ? (($this->errorFormat == 'json') ? ($this->heritageTrace ?: $this->getTrace()) : Debug::trace(($this->heritageTrace ?: $this->getTrace()))) : null
];
$log->write(($this->errorFormat == 'json') ? json_encode($errorStamp) : implode(PHP_EOL, array_map(
['self','convertArray'],
diff --git a/system/engine/loader.php b/system/engine/loader.php
index e710453..920a5fd 100644
--- a/system/engine/loader.php
+++ b/system/engine/loader.php
@@ -40,8 +40,7 @@ final class Loader implements \Phacil\Framework\Interfaces\Loader {
if (file_exists($file)) {
return include_once($file);
} else {
- return trigger_error('Error: Could not load library ' . $library . '!');
- exit();
+ throw new \Phacil\Framework\Exception('Error: Could not load library ' . $library . '!');
}
}
@@ -74,8 +73,7 @@ final class Loader implements \Phacil\Framework\Interfaces\Loader {
$this->registry->set('model_' . str_replace('/', '_', $model), new $class($this->registry));
} else {
- trigger_error('Error: Could not load model ' . $model . '!');
- exit();
+ throw new \Phacil\Framework\Exception('Error: Could not load model ' . $model . '!');
}
}
@@ -101,8 +99,7 @@ final class Loader implements \Phacil\Framework\Interfaces\Loader {
$this->registry->set('model_' . str_replace('/', '_', $model), new $class($this->registry)); */
} else {
- trigger_error('Error: Could not load Helper ' . $helper . '!');
- exit();
+ throw new \Phacil\Framework\Exception('Error: Could not load Helper ' . $helper . '!');
}
}
@@ -132,8 +129,7 @@ final class Loader implements \Phacil\Framework\Interfaces\Loader {
$this->registry->set('controller_' . str_replace('/', '_', $control), new $class($this->registry));
} else {
- trigger_error('Error: Could not load model ' . $control . '!');
- exit();
+ throw new \Phacil\Framework\Exception('Error: Could not load model ' . $control . '!');
}
}
@@ -166,8 +162,7 @@ final class Loader implements \Phacil\Framework\Interfaces\Loader {
return $database_name;
} else {
- trigger_error('Error: Could not load database ' . $driver . '!');
- exit();
+ throw new \Phacil\Framework\Exception('Error: Could not load database ' . $driver . '!');
}
}
diff --git a/system/language/autoload.php b/system/language/autoload.php
index f6e2ddc..b33c74a 100644
--- a/system/language/autoload.php
+++ b/system/language/autoload.php
@@ -35,8 +35,7 @@ final class Language
return $this->data;
} else {
- trigger_error('Error: Could not load language ' . $filename . '!');
- exit();
+ throw new \Phacil\Framework\Exception('Error: Could not load language ' . $filename . '!');
}
}
}
diff --git a/system/mail/mail.php b/system/mail/mail.php
index 8f7a646..688a7f0 100644
--- a/system/mail/mail.php
+++ b/system/mail/mail.php
@@ -182,28 +182,23 @@ final class Mail {
/** @return void */
public function send() {
if (!$this->to) {
- trigger_error('Error: E-Mail to required!');
- exit();
+ throw new \Phacil\Framework\Exception('Error: E-Mail to required!');
}
if (!$this->from) {
- trigger_error('Error: E-Mail from required!');
- exit();
+ throw new \Phacil\Framework\Exception('Error: E-Mail from required!');
}
if (!$this->sender) {
- trigger_error('Error: E-Mail sender required!');
- exit();
+ throw new \Phacil\Framework\Exception('Error: E-Mail sender required!');
}
if (!$this->subject) {
- trigger_error('Error: E-Mail subject required!');
- exit();
+ throw new \Phacil\Framework\Exception('Error: E-Mail subject required!');
}
if ((!$this->text) && (!$this->html)) {
- trigger_error('Error: E-Mail message required!');
- exit();
+ throw new \Phacil\Framework\Exception('Error: E-Mail message required!');
}
if (is_array($this->to)) {
@@ -288,8 +283,7 @@ final class Mail {
$handle = fsockopen($this->hostname, $this->port, $errno, $errstr, $this->timeout);
if (!$handle) {
- trigger_error('Error: ' . $errstr . ' (' . $errno . ')');
- exit();
+ throw new \Phacil\Framework\Exception('Error: ' . $errstr . ' (' . $errno . ')');
} else {
if (substr(PHP_OS, 0, 3) != 'WIN') {
socket_set_timeout($handle, $this->timeout, 0);
@@ -313,8 +307,7 @@ final class Mail {
}
if (substr($reply, 0, 3) != 220) {
- trigger_error('Error: STARTTLS not accepted from server!');
- exit();
+ throw new \Phacil\Framework\Exception('Error: STARTTLS not accepted from server!');
}
}
@@ -332,8 +325,7 @@ final class Mail {
}
if (substr($reply, 0, 3) != 250) {
- trigger_error('Error: EHLO not accepted from server!');
- exit();
+ throw new \Phacil\Framework\Exception('Error: EHLO not accepted from server!');
}
fputs($handle, 'AUTH LOGIN' . $this->crlf);
@@ -349,8 +341,7 @@ final class Mail {
}
if (substr($reply, 0, 3) != 334) {
- trigger_error('Error: AUTH LOGIN not accepted from server!');
- exit();
+ throw new \Phacil\Framework\Exception('Error: AUTH LOGIN not accepted from server!');
}
fputs($handle, base64_encode($this->username) . $this->crlf);
@@ -366,8 +357,7 @@ final class Mail {
}
if (substr($reply, 0, 3) != 334) {
- trigger_error('Error: Username not accepted from server!');
- exit();
+ throw new \Phacil\Framework\Exception('Error: Username not accepted from server!');
}
fputs($handle, base64_encode($this->password) . $this->crlf);
@@ -383,8 +373,7 @@ final class Mail {
}
if (substr($reply, 0, 3) != 235) {
- trigger_error('Error: Password not accepted from server!');
- exit();
+ throw new \Phacil\Framework\Exception('Error: Password not accepted from server!');
}
} else {
fputs($handle, 'HELO ' . getenv('SERVER_NAME') . $this->crlf);
@@ -400,8 +389,7 @@ final class Mail {
}
if (substr($reply, 0, 3) != 250) {
- trigger_error('Error: HELO not accepted from server!');
- exit();
+ throw new \Phacil\Framework\Exception('Error: HELO not accepted from server!');
}
}
@@ -422,8 +410,7 @@ final class Mail {
}
if (substr($reply, 0, 3) != 250) {
- trigger_error('Error: MAIL FROM not accepted from server!');
- exit();
+ throw new \Phacil\Framework\Exception('Error: MAIL FROM not accepted from server!');
}
if (!is_array($this->to)) {
@@ -440,8 +427,7 @@ final class Mail {
}
if ((substr($reply, 0, 3) != 250) && (substr($reply, 0, 3) != 251)) {
- trigger_error('Error: RCPT TO not accepted from server!');
- exit();
+ throw new \Phacil\Framework\Exception('Error: RCPT TO not accepted from server!');
}
} else {
foreach ($this->to as $recipient) {
@@ -458,8 +444,7 @@ final class Mail {
}
if ((substr($reply, 0, 3) != 250) && (substr($reply, 0, 3) != 251)) {
- trigger_error('Error: RCPT TO not accepted from server!');
- exit();
+ throw new \Phacil\Framework\Exception('Error: RCPT TO not accepted from server!');
}
}
}
@@ -477,8 +462,7 @@ final class Mail {
}
if (substr($reply, 0, 3) != 354) {
- trigger_error('Error: DATA not accepted from server!');
- exit();
+ throw new \Phacil\Framework\Exception('Error: DATA not accepted from server!');
}
// According to rfc 821 we should not send more than 1000 including the CRLF
@@ -512,8 +496,7 @@ final class Mail {
}
if (substr($reply, 0, 3) != 250) {
- trigger_error('Error: DATA not accepted from server!');
- exit();
+ throw new \Phacil\Framework\Exception('Error: DATA not accepted from server!');
}
fputs($handle, 'QUIT' . $this->crlf);
@@ -529,8 +512,7 @@ final class Mail {
}
if (substr($reply, 0, 3) != 221) {
- trigger_error('Error: QUIT not accepted from server!');
- exit();
+ throw new \Phacil\Framework\Exception('Error: QUIT not accepted from server!');
}
fclose($handle);
diff --git a/system/system.php b/system/system.php
index ca79ea1..7fc2e44 100644
--- a/system/system.php
+++ b/system/system.php
@@ -437,6 +437,9 @@ set_exception_handler(function($e) use ($engine) {
echo '' . get_class($e) . ': ' . $e->getMessage() . ' in ' . $e->getFile() . ' on line ' . $e->getLine() . '';
}
+ $exception = new \Phacil\Framework\Exception();
+ $exception->setObject($e);
+
if ($engine->config->get('config_error_log')) {
$engine->log->write(get_class($e) . ': ' . $e->getMessage() . ' in ' . $e->getFile() . ' on line ' . $e->getLine());
}
diff --git a/system/templateEngines/Twig/Twig1x/autoload.php b/system/templateEngines/Twig/Twig1x/autoload.php
deleted file mode 100644
index 3f98022..0000000
--- a/system/templateEngines/Twig/Twig1x/autoload.php
+++ /dev/null
@@ -1,7 +0,0 @@
-=5.3.3"
+ },
+ "suggest": {
+ "ext-ctype": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.19-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Ctype\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Gert de Pagter",
+ "email": "BackEndTea@gmail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for ctype functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "ctype",
+ "polyfill",
+ "portable"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-ctype/tree/v1.19.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2020-10-23T09:01:57+00:00"
+ },
+ {
+ "name": "twig/twig",
+ "version": "v1.41.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/twigphp/Twig.git",
+ "reference": "575cd5028362da591facde1ef5d7b94553c375c9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/twigphp/Twig/zipball/575cd5028362da591facde1ef5d7b94553c375c9",
+ "reference": "575cd5028362da591facde1ef5d7b94553c375c9",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.4.0",
+ "symfony/polyfill-ctype": "^1.8"
+ },
+ "require-dev": {
+ "psr/container": "^1.0",
+ "symfony/debug": "^2.7",
+ "symfony/phpunit-bridge": "^3.4.19|^4.1.8"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.41-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Twig_": "lib/"
+ },
+ "psr-4": {
+ "Twig\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
+ },
+ {
+ "name": "Armin Ronacher",
+ "email": "armin.ronacher@active-4.com",
+ "role": "Project Founder"
+ },
+ {
+ "name": "Twig Team",
+ "homepage": "https://twig.symfony.com/contributors",
+ "role": "Contributors"
+ }
+ ],
+ "description": "Twig, the flexible, fast, and secure template language for PHP",
+ "homepage": "https://twig.symfony.com",
+ "keywords": [
+ "templating"
+ ],
+ "support": {
+ "issues": "https://github.com/twigphp/Twig/issues",
+ "source": "https://github.com/twigphp/Twig/tree/1.x"
+ },
+ "time": "2019-05-14T11:59:08+00:00"
+ }
+ ],
+ "packages-dev": [],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": [],
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": [],
+ "platform-dev": [],
+ "plugin-api-version": "2.2.0"
+}
diff --git a/system/templateEngines/Twig/Twig1x/composer/ClassLoader.php b/system/templateEngines/Twig/Twig1x/composer/ClassLoader.php
deleted file mode 100644
index fce8549..0000000
--- a/system/templateEngines/Twig/Twig1x/composer/ClassLoader.php
+++ /dev/null
@@ -1,445 +0,0 @@
-
- * Jordi Boggiano
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Composer\Autoload;
-
-/**
- * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
- *
- * $loader = new \Composer\Autoload\ClassLoader();
- *
- * // register classes with namespaces
- * $loader->add('Symfony\Component', __DIR__.'/component');
- * $loader->add('Symfony', __DIR__.'/framework');
- *
- * // activate the autoloader
- * $loader->register();
- *
- * // to enable searching the include path (eg. for PEAR packages)
- * $loader->setUseIncludePath(true);
- *
- * In this example, if you try to use a class in the Symfony\Component
- * namespace or one of its children (Symfony\Component\Console for instance),
- * the autoloader will first look for the class under the component/
- * directory, and it will then fallback to the framework/ directory if not
- * found before giving up.
- *
- * This class is loosely based on the Symfony UniversalClassLoader.
- *
- * @author Fabien Potencier
- * @author Jordi Boggiano
- * @see http://www.php-fig.org/psr/psr-0/
- * @see http://www.php-fig.org/psr/psr-4/
- */
-class ClassLoader
-{
- // PSR-4
- private $prefixLengthsPsr4 = array();
- private $prefixDirsPsr4 = array();
- private $fallbackDirsPsr4 = array();
-
- // PSR-0
- private $prefixesPsr0 = array();
- private $fallbackDirsPsr0 = array();
-
- private $useIncludePath = false;
- private $classMap = array();
- private $classMapAuthoritative = false;
- private $missingClasses = array();
- private $apcuPrefix;
-
- public function getPrefixes()
- {
- if (!empty($this->prefixesPsr0)) {
- return call_user_func_array('array_merge', $this->prefixesPsr0);
- }
-
- return array();
- }
-
- public function getPrefixesPsr4()
- {
- return $this->prefixDirsPsr4;
- }
-
- public function getFallbackDirs()
- {
- return $this->fallbackDirsPsr0;
- }
-
- public function getFallbackDirsPsr4()
- {
- return $this->fallbackDirsPsr4;
- }
-
- public function getClassMap()
- {
- return $this->classMap;
- }
-
- /**
- * @param array $classMap Class to filename map
- */
- public function addClassMap(array $classMap)
- {
- if ($this->classMap) {
- $this->classMap = array_merge($this->classMap, $classMap);
- } else {
- $this->classMap = $classMap;
- }
- }
-
- /**
- * Registers a set of PSR-0 directories for a given prefix, either
- * appending or prepending to the ones previously set for this prefix.
- *
- * @param string $prefix The prefix
- * @param array|string $paths The PSR-0 root directories
- * @param bool $prepend Whether to prepend the directories
- */
- public function add($prefix, $paths, $prepend = false)
- {
- if (!$prefix) {
- if ($prepend) {
- $this->fallbackDirsPsr0 = array_merge(
- (array) $paths,
- $this->fallbackDirsPsr0
- );
- } else {
- $this->fallbackDirsPsr0 = array_merge(
- $this->fallbackDirsPsr0,
- (array) $paths
- );
- }
-
- return;
- }
-
- $first = $prefix[0];
- if (!isset($this->prefixesPsr0[$first][$prefix])) {
- $this->prefixesPsr0[$first][$prefix] = (array) $paths;
-
- return;
- }
- if ($prepend) {
- $this->prefixesPsr0[$first][$prefix] = array_merge(
- (array) $paths,
- $this->prefixesPsr0[$first][$prefix]
- );
- } else {
- $this->prefixesPsr0[$first][$prefix] = array_merge(
- $this->prefixesPsr0[$first][$prefix],
- (array) $paths
- );
- }
- }
-
- /**
- * Registers a set of PSR-4 directories for a given namespace, either
- * appending or prepending to the ones previously set for this namespace.
- *
- * @param string $prefix The prefix/namespace, with trailing '\\'
- * @param array|string $paths The PSR-4 base directories
- * @param bool $prepend Whether to prepend the directories
- *
- * @throws \InvalidArgumentException
- */
- public function addPsr4($prefix, $paths, $prepend = false)
- {
- if (!$prefix) {
- // Register directories for the root namespace.
- if ($prepend) {
- $this->fallbackDirsPsr4 = array_merge(
- (array) $paths,
- $this->fallbackDirsPsr4
- );
- } else {
- $this->fallbackDirsPsr4 = array_merge(
- $this->fallbackDirsPsr4,
- (array) $paths
- );
- }
- } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
- // Register directories for a new namespace.
- $length = strlen($prefix);
- if ('\\' !== $prefix[$length - 1]) {
- throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
- }
- $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
- $this->prefixDirsPsr4[$prefix] = (array) $paths;
- } elseif ($prepend) {
- // Prepend directories for an already registered namespace.
- $this->prefixDirsPsr4[$prefix] = array_merge(
- (array) $paths,
- $this->prefixDirsPsr4[$prefix]
- );
- } else {
- // Append directories for an already registered namespace.
- $this->prefixDirsPsr4[$prefix] = array_merge(
- $this->prefixDirsPsr4[$prefix],
- (array) $paths
- );
- }
- }
-
- /**
- * Registers a set of PSR-0 directories for a given prefix,
- * replacing any others previously set for this prefix.
- *
- * @param string $prefix The prefix
- * @param array|string $paths The PSR-0 base directories
- */
- public function set($prefix, $paths)
- {
- if (!$prefix) {
- $this->fallbackDirsPsr0 = (array) $paths;
- } else {
- $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
- }
- }
-
- /**
- * Registers a set of PSR-4 directories for a given namespace,
- * replacing any others previously set for this namespace.
- *
- * @param string $prefix The prefix/namespace, with trailing '\\'
- * @param array|string $paths The PSR-4 base directories
- *
- * @throws \InvalidArgumentException
- */
- public function setPsr4($prefix, $paths)
- {
- if (!$prefix) {
- $this->fallbackDirsPsr4 = (array) $paths;
- } else {
- $length = strlen($prefix);
- if ('\\' !== $prefix[$length - 1]) {
- throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
- }
- $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
- $this->prefixDirsPsr4[$prefix] = (array) $paths;
- }
- }
-
- /**
- * Turns on searching the include path for class files.
- *
- * @param bool $useIncludePath
- */
- public function setUseIncludePath($useIncludePath)
- {
- $this->useIncludePath = $useIncludePath;
- }
-
- /**
- * Can be used to check if the autoloader uses the include path to check
- * for classes.
- *
- * @return bool
- */
- public function getUseIncludePath()
- {
- return $this->useIncludePath;
- }
-
- /**
- * Turns off searching the prefix and fallback directories for classes
- * that have not been registered with the class map.
- *
- * @param bool $classMapAuthoritative
- */
- public function setClassMapAuthoritative($classMapAuthoritative)
- {
- $this->classMapAuthoritative = $classMapAuthoritative;
- }
-
- /**
- * Should class lookup fail if not found in the current class map?
- *
- * @return bool
- */
- public function isClassMapAuthoritative()
- {
- return $this->classMapAuthoritative;
- }
-
- /**
- * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
- *
- * @param string|null $apcuPrefix
- */
- public function setApcuPrefix($apcuPrefix)
- {
- $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
- }
-
- /**
- * The APCu prefix in use, or null if APCu caching is not enabled.
- *
- * @return string|null
- */
- public function getApcuPrefix()
- {
- return $this->apcuPrefix;
- }
-
- /**
- * Registers this instance as an autoloader.
- *
- * @param bool $prepend Whether to prepend the autoloader or not
- */
- public function register($prepend = false)
- {
- spl_autoload_register(array($this, 'loadClass'), true, $prepend);
- }
-
- /**
- * Unregisters this instance as an autoloader.
- */
- public function unregister()
- {
- spl_autoload_unregister(array($this, 'loadClass'));
- }
-
- /**
- * Loads the given class or interface.
- *
- * @param string $class The name of the class
- * @return bool|null True if loaded, null otherwise
- */
- public function loadClass($class)
- {
- if ($file = $this->findFile($class)) {
- includeFile($file);
-
- return true;
- }
- }
-
- /**
- * Finds the path to the file where the class is defined.
- *
- * @param string $class The name of the class
- *
- * @return string|false The path if found, false otherwise
- */
- public function findFile($class)
- {
- // class map lookup
- if (isset($this->classMap[$class])) {
- return $this->classMap[$class];
- }
- if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
- return false;
- }
- if (null !== $this->apcuPrefix) {
- $file = apcu_fetch($this->apcuPrefix.$class, $hit);
- if ($hit) {
- return $file;
- }
- }
-
- $file = $this->findFileWithExtension($class, '.php');
-
- // Search for Hack files if we are running on HHVM
- if (false === $file && defined('HHVM_VERSION')) {
- $file = $this->findFileWithExtension($class, '.hh');
- }
-
- if (null !== $this->apcuPrefix) {
- apcu_add($this->apcuPrefix.$class, $file);
- }
-
- if (false === $file) {
- // Remember that this class does not exist.
- $this->missingClasses[$class] = true;
- }
-
- return $file;
- }
-
- private function findFileWithExtension($class, $ext)
- {
- // PSR-4 lookup
- $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
-
- $first = $class[0];
- if (isset($this->prefixLengthsPsr4[$first])) {
- $subPath = $class;
- while (false !== $lastPos = strrpos($subPath, '\\')) {
- $subPath = substr($subPath, 0, $lastPos);
- $search = $subPath . '\\';
- if (isset($this->prefixDirsPsr4[$search])) {
- $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
- foreach ($this->prefixDirsPsr4[$search] as $dir) {
- if (file_exists($file = $dir . $pathEnd)) {
- return $file;
- }
- }
- }
- }
- }
-
- // PSR-4 fallback dirs
- foreach ($this->fallbackDirsPsr4 as $dir) {
- if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
- return $file;
- }
- }
-
- // PSR-0 lookup
- if (false !== $pos = strrpos($class, '\\')) {
- // namespaced class name
- $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
- . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
- } else {
- // PEAR-like class name
- $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
- }
-
- if (isset($this->prefixesPsr0[$first])) {
- foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
- if (0 === strpos($class, $prefix)) {
- foreach ($dirs as $dir) {
- if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
- return $file;
- }
- }
- }
- }
- }
-
- // PSR-0 fallback dirs
- foreach ($this->fallbackDirsPsr0 as $dir) {
- if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
- return $file;
- }
- }
-
- // PSR-0 include paths.
- if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
- return $file;
- }
-
- return false;
- }
-}
-
-/**
- * Scope isolated include.
- *
- * Prevents access to $this/self from included files.
- */
-function includeFile($file)
-{
- include $file;
-}
diff --git a/system/templateEngines/Twig/Twig1x/composer/autoload_classmap.php b/system/templateEngines/Twig/Twig1x/composer/autoload_classmap.php
deleted file mode 100644
index 7a91153..0000000
--- a/system/templateEngines/Twig/Twig1x/composer/autoload_classmap.php
+++ /dev/null
@@ -1,9 +0,0 @@
-= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
- if ($useStaticLoader) {
- require_once __DIR__ . '/autoload_static.php';
-
- call_user_func(\Composer\Autoload\ComposerStaticInit09a276ab747dde32eaeb090fed801b7d::getInitializer($loader));
- } else {
- $map = require __DIR__ . '/autoload_namespaces.php';
- foreach ($map as $namespace => $path) {
- $loader->set($namespace, $path);
- }
-
- $map = require __DIR__ . '/autoload_psr4.php';
- foreach ($map as $namespace => $path) {
- $loader->setPsr4($namespace, $path);
- }
-
- $classMap = require __DIR__ . '/autoload_classmap.php';
- if ($classMap) {
- $loader->addClassMap($classMap);
- }
- }
-
- $loader->register(true);
-
- if ($useStaticLoader) {
- $includeFiles = Composer\Autoload\ComposerStaticInit09a276ab747dde32eaeb090fed801b7d::$files;
- } else {
- $includeFiles = require __DIR__ . '/autoload_files.php';
- }
- foreach ($includeFiles as $fileIdentifier => $file) {
- composerRequire09a276ab747dde32eaeb090fed801b7d($fileIdentifier, $file);
- }
-
- return $loader;
- }
-}
-
-function composerRequire09a276ab747dde32eaeb090fed801b7d($fileIdentifier, $file)
-{
- if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
- require $file;
-
- $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
- }
-}
diff --git a/system/templateEngines/Twig/Twig1x/composer/autoload_static.php b/system/templateEngines/Twig/Twig1x/composer/autoload_static.php
deleted file mode 100644
index e84611e..0000000
--- a/system/templateEngines/Twig/Twig1x/composer/autoload_static.php
+++ /dev/null
@@ -1,54 +0,0 @@
- __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
- );
-
- public static $prefixLengthsPsr4 = array (
- 'T' =>
- array (
- 'Twig\\' => 5,
- ),
- 'S' =>
- array (
- 'Symfony\\Polyfill\\Ctype\\' => 23,
- ),
- );
-
- public static $prefixDirsPsr4 = array (
- 'Twig\\' =>
- array (
- 0 => __DIR__ . '/..' . '/twig/twig/src',
- ),
- 'Symfony\\Polyfill\\Ctype\\' =>
- array (
- 0 => __DIR__ . '/..' . '/symfony/polyfill-ctype',
- ),
- );
-
- public static $prefixesPsr0 = array (
- 'T' =>
- array (
- 'Twig_' =>
- array (
- 0 => __DIR__ . '/..' . '/twig/twig/lib',
- ),
- ),
- );
-
- public static function getInitializer(ClassLoader $loader)
- {
- return \Closure::bind(function () use ($loader) {
- $loader->prefixLengthsPsr4 = ComposerStaticInit09a276ab747dde32eaeb090fed801b7d::$prefixLengthsPsr4;
- $loader->prefixDirsPsr4 = ComposerStaticInit09a276ab747dde32eaeb090fed801b7d::$prefixDirsPsr4;
- $loader->prefixesPsr0 = ComposerStaticInit09a276ab747dde32eaeb090fed801b7d::$prefixesPsr0;
-
- }, null, ClassLoader::class);
- }
-}
diff --git a/system/templateEngines/Twig/Twig1x/composer/installed.json b/system/templateEngines/Twig/Twig1x/composer/installed.json
deleted file mode 100644
index cadff09..0000000
--- a/system/templateEngines/Twig/Twig1x/composer/installed.json
+++ /dev/null
@@ -1,128 +0,0 @@
-[
- {
- "name": "symfony/polyfill-ctype",
- "version": "v1.14.0",
- "version_normalized": "1.14.0.0",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/polyfill-ctype.git",
- "reference": "fbdeaec0df06cf3d51c93de80c7eb76e271f5a38"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/fbdeaec0df06cf3d51c93de80c7eb76e271f5a38",
- "reference": "fbdeaec0df06cf3d51c93de80c7eb76e271f5a38",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.3"
- },
- "suggest": {
- "ext-ctype": "For best performance"
- },
- "time": "2020-01-13T11:15:53+00:00",
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.14-dev"
- }
- },
- "installation-source": "dist",
- "autoload": {
- "psr-4": {
- "Symfony\\Polyfill\\Ctype\\": ""
- },
- "files": [
- "bootstrap.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Gert de Pagter",
- "email": "BackEndTea@gmail.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony polyfill for ctype functions",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "ctype",
- "polyfill",
- "portable"
- ]
- },
- {
- "name": "twig/twig",
- "version": "v1.42.5",
- "version_normalized": "1.42.5.0",
- "source": {
- "type": "git",
- "url": "https://github.com/twigphp/Twig.git",
- "reference": "87b2ea9d8f6fd014d0621ca089bb1b3769ea3f8e"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/twigphp/Twig/zipball/87b2ea9d8f6fd014d0621ca089bb1b3769ea3f8e",
- "reference": "87b2ea9d8f6fd014d0621ca089bb1b3769ea3f8e",
- "shasum": ""
- },
- "require": {
- "php": ">=5.5.0",
- "symfony/polyfill-ctype": "^1.8"
- },
- "require-dev": {
- "psr/container": "^1.0",
- "symfony/phpunit-bridge": "^4.4|^5.0"
- },
- "time": "2020-02-11T05:59:23+00:00",
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.42-dev"
- }
- },
- "installation-source": "dist",
- "autoload": {
- "psr-0": {
- "Twig_": "lib/"
- },
- "psr-4": {
- "Twig\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com",
- "homepage": "http://fabien.potencier.org",
- "role": "Lead Developer"
- },
- {
- "name": "Twig Team",
- "role": "Contributors"
- },
- {
- "name": "Armin Ronacher",
- "email": "armin.ronacher@active-4.com",
- "role": "Project Founder"
- }
- ],
- "description": "Twig, the flexible, fast, and secure template language for PHP",
- "homepage": "https://twig.symfony.com",
- "keywords": [
- "templating"
- ]
- }
-]
diff --git a/system/templateEngines/Twig/Twig1x/symfony/polyfill-ctype/bootstrap.php b/system/templateEngines/Twig/Twig1x/symfony/polyfill-ctype/bootstrap.php
deleted file mode 100644
index 14d1d0f..0000000
--- a/system/templateEngines/Twig/Twig1x/symfony/polyfill-ctype/bootstrap.php
+++ /dev/null
@@ -1,26 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-use Symfony\Polyfill\Ctype as p;
-
-if (!function_exists('ctype_alnum')) {
- function ctype_alnum($text) { return p\Ctype::ctype_alnum($text); }
- function ctype_alpha($text) { return p\Ctype::ctype_alpha($text); }
- function ctype_cntrl($text) { return p\Ctype::ctype_cntrl($text); }
- function ctype_digit($text) { return p\Ctype::ctype_digit($text); }
- function ctype_graph($text) { return p\Ctype::ctype_graph($text); }
- function ctype_lower($text) { return p\Ctype::ctype_lower($text); }
- function ctype_print($text) { return p\Ctype::ctype_print($text); }
- function ctype_punct($text) { return p\Ctype::ctype_punct($text); }
- function ctype_space($text) { return p\Ctype::ctype_space($text); }
- function ctype_upper($text) { return p\Ctype::ctype_upper($text); }
- function ctype_xdigit($text) { return p\Ctype::ctype_xdigit($text); }
-}
diff --git a/system/templateEngines/Twig/Twig1x/symfony/polyfill-ctype/composer.json b/system/templateEngines/Twig/Twig1x/symfony/polyfill-ctype/composer.json
deleted file mode 100644
index 2596c74..0000000
--- a/system/templateEngines/Twig/Twig1x/symfony/polyfill-ctype/composer.json
+++ /dev/null
@@ -1,34 +0,0 @@
-{
- "name": "symfony/polyfill-ctype",
- "type": "library",
- "description": "Symfony polyfill for ctype functions",
- "keywords": ["polyfill", "compatibility", "portable", "ctype"],
- "homepage": "https://symfony.com",
- "license": "MIT",
- "authors": [
- {
- "name": "Gert de Pagter",
- "email": "BackEndTea@gmail.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "require": {
- "php": ">=5.3.3"
- },
- "autoload": {
- "psr-4": { "Symfony\\Polyfill\\Ctype\\": "" },
- "files": [ "bootstrap.php" ]
- },
- "suggest": {
- "ext-ctype": "For best performance"
- },
- "minimum-stability": "dev",
- "extra": {
- "branch-alias": {
- "dev-master": "1.14-dev"
- }
- }
-}
diff --git a/system/templateEngines/Twig/Twig1x/twig/twig/.gitattributes b/system/templateEngines/Twig/Twig1x/twig/twig/.gitattributes
deleted file mode 100644
index 3a3ce6e..0000000
--- a/system/templateEngines/Twig/Twig1x/twig/twig/.gitattributes
+++ /dev/null
@@ -1,2 +0,0 @@
-/tests export-ignore
-/phpunit.xml.dist export-ignore
diff --git a/system/templateEngines/Twig/Twig1x/twig/twig/.gitignore b/system/templateEngines/Twig/Twig1x/twig/twig/.gitignore
deleted file mode 100644
index 8a29959..0000000
--- a/system/templateEngines/Twig/Twig1x/twig/twig/.gitignore
+++ /dev/null
@@ -1,6 +0,0 @@
-/build
-/composer.lock
-/ext/twig/autom4te.cache/
-/phpunit.xml
-/vendor
-.phpunit.result.cache
diff --git a/system/templateEngines/Twig/Twig1x/twig/twig/.php_cs.dist b/system/templateEngines/Twig/Twig1x/twig/twig/.php_cs.dist
deleted file mode 100644
index b81882f..0000000
--- a/system/templateEngines/Twig/Twig1x/twig/twig/.php_cs.dist
+++ /dev/null
@@ -1,20 +0,0 @@
-setRules([
- '@Symfony' => true,
- '@Symfony:risky' => true,
- '@PHPUnit75Migration:risky' => true,
- 'php_unit_dedicate_assert' => ['target' => '5.6'],
- 'array_syntax' => ['syntax' => 'short'],
- 'php_unit_fqcn_annotation' => true,
- 'no_unreachable_default_argument_value' => false,
- 'braces' => ['allow_single_line_closure' => true],
- 'heredoc_to_nowdoc' => false,
- 'ordered_imports' => true,
- 'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'],
- 'native_function_invocation' => ['include' => ['@compiler_optimized'], 'scope' => 'all'],
- ])
- ->setRiskyAllowed(true)
- ->setFinder(PhpCsFixer\Finder::create()->in(__DIR__))
-;
diff --git a/system/templateEngines/Twig/Twig1x/twig/twig/.travis.yml b/system/templateEngines/Twig/Twig1x/twig/twig/.travis.yml
deleted file mode 100644
index ff6132b..0000000
--- a/system/templateEngines/Twig/Twig1x/twig/twig/.travis.yml
+++ /dev/null
@@ -1,46 +0,0 @@
-language: php
-
-dist: trusty
-
-sudo: false
-
-cache:
- directories:
- - vendor
- - $HOME/.composer/cache/files
-
-
-env:
- global:
- - TWIG_EXT=no
- - SYMFONY_PHPUNIT_REMOVE_RETURN_TYPEHINT=1
-
-before_install:
- - phpenv config-rm xdebug.ini || return 0
-
-install:
- - travis_retry composer install
-
-before_script:
- - if [ "$TWIG_EXT" == "yes" ]; then sh -c "cd ext/twig && phpize && ./configure --enable-twig && make && make install"; fi
- - if [ "$TWIG_EXT" == "yes" ]; then echo "extension=twig.so" >> `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"`; fi
-
-script: ./vendor/bin/simple-phpunit
-
-jobs:
- fast_finish: true
- include:
- - php: 5.5
- - php: 5.5
- env: TWIG_EXT=yes
- - php: 5.6
- - php: 5.6
- env: TWIG_EXT=yes
- - php: 7.0
- - php: 7.1
- - php: 7.2
- - php: 7.3
- - php: 7.4snapshot
- - stage: integration tests
- php: 7.3
- script: ./drupal_test.sh
diff --git a/system/templateEngines/Twig/Twig1x/twig/twig/LICENSE b/system/templateEngines/Twig/Twig1x/twig/twig/LICENSE
deleted file mode 100644
index 5e8a0b8..0000000
--- a/system/templateEngines/Twig/Twig1x/twig/twig/LICENSE
+++ /dev/null
@@ -1,29 +0,0 @@
-Copyright (c) 2009-2020 by the Twig Team.
-
-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/system/templateEngines/Twig/Twig1x/twig/twig/README.rst b/system/templateEngines/Twig/Twig1x/twig/twig/README.rst
deleted file mode 100644
index d896ff5..0000000
--- a/system/templateEngines/Twig/Twig1x/twig/twig/README.rst
+++ /dev/null
@@ -1,24 +0,0 @@
-Twig, the flexible, fast, and secure template language for PHP
-==============================================================
-
-Twig is a template language for PHP, released under the new BSD license (code
-and documentation).
-
-Twig uses a syntax similar to the Django and Jinja template languages which
-inspired the Twig runtime environment.
-
-Sponsors
---------
-
-.. raw:: html
-
-
-
-
-
-More Information
-----------------
-
-Read the `documentation`_ for more information.
-
-.. _documentation: https://twig.symfony.com/documentation
diff --git a/system/templateEngines/Twig/Twig1x/twig/twig/src/Cache/FilesystemCache.php b/system/templateEngines/Twig/Twig1x/twig/twig/src/Cache/FilesystemCache.php
deleted file mode 100644
index b7c1e43..0000000
--- a/system/templateEngines/Twig/Twig1x/twig/twig/src/Cache/FilesystemCache.php
+++ /dev/null
@@ -1,93 +0,0 @@
-
- */
-class FilesystemCache implements CacheInterface
-{
- const FORCE_BYTECODE_INVALIDATION = 1;
-
- private $directory;
- private $options;
-
- /**
- * @param string $directory The root cache directory
- * @param int $options A set of options
- */
- public function __construct($directory, $options = 0)
- {
- $this->directory = rtrim($directory, '\/').'/';
- $this->options = $options;
- }
-
- public function generateKey($name, $className)
- {
- $hash = hash('sha256', $className);
-
- return $this->directory.$hash[0].$hash[1].'/'.$hash.'.php';
- }
-
- public function load($key)
- {
- if (file_exists($key)) {
- @include_once $key;
- }
- }
-
- public function write($key, $content)
- {
- $dir = \dirname($key);
- if (!is_dir($dir)) {
- if (false === @mkdir($dir, 0777, true)) {
- clearstatcache(true, $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($dir, basename($key));
- if (false !== @file_put_contents($tmpFile, $content) && @rename($tmpFile, $key)) {
- @chmod($key, 0666 & ~umask());
-
- if (self::FORCE_BYTECODE_INVALIDATION == ($this->options & self::FORCE_BYTECODE_INVALIDATION)) {
- // Compile cached file into bytecode cache
- if (\function_exists('opcache_invalidate') && filter_var(ini_get('opcache.enable'), FILTER_VALIDATE_BOOLEAN)) {
- @opcache_invalidate($key, true);
- } elseif (\function_exists('apc_compile_file')) {
- apc_compile_file($key);
- }
- }
-
- return;
- }
-
- throw new \RuntimeException(sprintf('Failed to write cache file "%s".', $key));
- }
-
- public function getTimestamp($key)
- {
- if (!file_exists($key)) {
- return 0;
- }
-
- return (int) @filemtime($key);
- }
-}
-
-class_alias('Twig\Cache\FilesystemCache', 'Twig_Cache_Filesystem');
diff --git a/system/templateEngines/Twig/Twig1x/twig/twig/src/Environment.php b/system/templateEngines/Twig/Twig1x/twig/twig/src/Environment.php
deleted file mode 100644
index 97fa4c4..0000000
--- a/system/templateEngines/Twig/Twig1x/twig/twig/src/Environment.php
+++ /dev/null
@@ -1,1638 +0,0 @@
-
- */
-class Environment
-{
- const VERSION = '1.42.5';
- const VERSION_ID = 14205;
- const MAJOR_VERSION = 1;
- const MINOR_VERSION = 42;
- const RELEASE_VERSION = 5;
- const EXTRA_VERSION = '';
-
- protected $charset;
- protected $loader;
- protected $debug;
- protected $autoReload;
- protected $cache;
- protected $lexer;
- protected $parser;
- protected $compiler;
- protected $baseTemplateClass;
- protected $extensions;
- protected $parsers;
- protected $visitors;
- protected $filters;
- protected $tests;
- protected $functions;
- protected $globals;
- protected $runtimeInitialized = false;
- protected $extensionInitialized = false;
- protected $loadedTemplates;
- protected $strictVariables;
- protected $unaryOperators;
- protected $binaryOperators;
- protected $templateClassPrefix = '__TwigTemplate_';
- protected $functionCallbacks = [];
- protected $filterCallbacks = [];
- protected $staging;
-
- private $originalCache;
- private $bcWriteCacheFile = false;
- private $bcGetCacheFilename = false;
- private $lastModifiedExtension = 0;
- private $extensionsByClass = [];
- private $runtimeLoaders = [];
- private $runtimes = [];
- private $optionsHash;
-
- /**
- * Constructor.
- *
- * Available options:
- *
- * * debug: When set to true, it automatically set "auto_reload" to true as
- * well (default to false).
- *
- * * charset: The charset used by the templates (default to UTF-8).
- *
- * * base_template_class: The base template class to use for generated
- * templates (default to \Twig\Template).
- *
- * * cache: An absolute path where to store the compiled templates,
- * a \Twig\Cache\CacheInterface implementation,
- * or false to disable compilation cache (default).
- *
- * * 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 based on the debug value.
- *
- * * strict_variables: Whether to ignore invalid variables in templates
- * (default to false).
- *
- * * autoescape: Whether to enable auto-escaping (default to html):
- * * false: disable auto-escaping
- * * true: equivalent to html
- * * html, js: set the autoescaping to one of the supported strategies
- * * name: set the autoescaping strategy based on the template name extension
- * * PHP callback: a PHP callback that returns an escaping strategy based on the template "name"
- *
- * * optimizations: A flag that indicates which optimizations to apply
- * (default to -1 which means that all optimizations are enabled;
- * set it to 0 to disable).
- */
- public function __construct(LoaderInterface $loader = null, $options = [])
- {
- if (null !== $loader) {
- $this->setLoader($loader);
- } else {
- @trigger_error('Not passing a "Twig\Lodaer\LoaderInterface" as the first constructor argument of "Twig\Environment" is deprecated since version 1.21.', E_USER_DEPRECATED);
- }
-
- $options = array_merge([
- 'debug' => false,
- 'charset' => 'UTF-8',
- 'base_template_class' => '\Twig\Template',
- 'strict_variables' => false,
- 'autoescape' => 'html',
- 'cache' => false,
- 'auto_reload' => null,
- 'optimizations' => -1,
- ], $options);
-
- $this->debug = (bool) $options['debug'];
- $this->charset = strtoupper($options['charset']);
- $this->baseTemplateClass = $options['base_template_class'];
- $this->autoReload = null === $options['auto_reload'] ? $this->debug : (bool) $options['auto_reload'];
- $this->strictVariables = (bool) $options['strict_variables'];
- $this->setCache($options['cache']);
-
- $this->addExtension(new CoreExtension());
- $this->addExtension(new EscaperExtension($options['autoescape']));
- $this->addExtension(new OptimizerExtension($options['optimizations']));
- $this->staging = new StagingExtension();
-
- // For BC
- if (\is_string($this->originalCache)) {
- $r = new \ReflectionMethod($this, 'writeCacheFile');
- if (__CLASS__ !== $r->getDeclaringClass()->getName()) {
- @trigger_error('The Twig\Environment::writeCacheFile method is deprecated since version 1.22 and will be removed in Twig 2.0.', E_USER_DEPRECATED);
-
- $this->bcWriteCacheFile = true;
- }
-
- $r = new \ReflectionMethod($this, 'getCacheFilename');
- if (__CLASS__ !== $r->getDeclaringClass()->getName()) {
- @trigger_error('The Twig\Environment::getCacheFilename method is deprecated since version 1.22 and will be removed in Twig 2.0.', E_USER_DEPRECATED);
-
- $this->bcGetCacheFilename = true;
- }
- }
- }
-
- /**
- * Gets the base template class for compiled templates.
- *
- * @return string The base template class name
- */
- public function getBaseTemplateClass()
- {
- return $this->baseTemplateClass;
- }
-
- /**
- * Sets the base template class for compiled templates.
- *
- * @param string $class The base template class name
- */
- public function setBaseTemplateClass($class)
- {
- $this->baseTemplateClass = $class;
- $this->updateOptionsHash();
- }
-
- /**
- * Enables debugging mode.
- */
- public function enableDebug()
- {
- $this->debug = true;
- $this->updateOptionsHash();
- }
-
- /**
- * Disables debugging mode.
- */
- public function disableDebug()
- {
- $this->debug = false;
- $this->updateOptionsHash();
- }
-
- /**
- * Checks if debug mode is enabled.
- *
- * @return bool true if debug mode is enabled, false otherwise
- */
- public function isDebug()
- {
- return $this->debug;
- }
-
- /**
- * Enables the auto_reload option.
- */
- public function enableAutoReload()
- {
- $this->autoReload = true;
- }
-
- /**
- * Disables the auto_reload option.
- */
- public function disableAutoReload()
- {
- $this->autoReload = false;
- }
-
- /**
- * Checks if the auto_reload option is enabled.
- *
- * @return bool true if auto_reload is enabled, false otherwise
- */
- public function isAutoReload()
- {
- return $this->autoReload;
- }
-
- /**
- * Enables the strict_variables option.
- */
- public function enableStrictVariables()
- {
- $this->strictVariables = true;
- $this->updateOptionsHash();
- }
-
- /**
- * Disables the strict_variables option.
- */
- public function disableStrictVariables()
- {
- $this->strictVariables = false;
- $this->updateOptionsHash();
- }
-
- /**
- * Checks if the strict_variables option is enabled.
- *
- * @return bool true if strict_variables is enabled, false otherwise
- */
- public function isStrictVariables()
- {
- return $this->strictVariables;
- }
-
- /**
- * Gets the current cache implementation.
- *
- * @param bool $original Whether to return the original cache option or the real cache instance
- *
- * @return CacheInterface|string|false A Twig\Cache\CacheInterface implementation,
- * an absolute path to the compiled templates,
- * or false to disable cache
- */
- public function getCache($original = true)
- {
- return $original ? $this->originalCache : $this->cache;
- }
-
- /**
- * Sets the current cache implementation.
- *
- * @param CacheInterface|string|false $cache A Twig\Cache\CacheInterface implementation,
- * an absolute path to the compiled templates,
- * or false to disable cache
- */
- public function setCache($cache)
- {
- if (\is_string($cache)) {
- $this->originalCache = $cache;
- $this->cache = new FilesystemCache($cache);
- } elseif (false === $cache) {
- $this->originalCache = $cache;
- $this->cache = new NullCache();
- } elseif (null === $cache) {
- @trigger_error('Using "null" as the cache strategy is deprecated since version 1.23 and will be removed in Twig 2.0.', E_USER_DEPRECATED);
- $this->originalCache = false;
- $this->cache = new NullCache();
- } elseif ($cache instanceof CacheInterface) {
- $this->originalCache = $this->cache = $cache;
- } else {
- throw new \LogicException(sprintf('Cache can only be a string, false, or a \Twig\Cache\CacheInterface implementation.'));
- }
- }
-
- /**
- * Gets the cache filename for a given template.
- *
- * @param string $name The template name
- *
- * @return string|false The cache file name or false when caching is disabled
- *
- * @deprecated since 1.22 (to be removed in 2.0)
- */
- public function getCacheFilename($name)
- {
- @trigger_error(sprintf('The %s method is deprecated since version 1.22 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED);
-
- $key = $this->cache->generateKey($name, $this->getTemplateClass($name));
-
- return !$key ? false : $key;
- }
-
- /**
- * Gets the template class associated with the given string.
- *
- * The generated template class is based on the following parameters:
- *
- * * The cache key for the given template;
- * * The currently enabled extensions;
- * * Whether the Twig C extension is available or not;
- * * PHP version;
- * * Twig version;
- * * Options with what environment was created.
- *
- * @param string $name The name for which to calculate the template class name
- * @param int|null $index The index if it is an embedded template
- *
- * @return string The template class name
- */
- public function getTemplateClass($name, $index = null)
- {
- $key = $this->getLoader()->getCacheKey($name).$this->optionsHash;
-
- return $this->templateClassPrefix.hash('sha256', $key).(null === $index ? '' : '___'.$index);
- }
-
- /**
- * Gets the template class prefix.
- *
- * @return string The template class prefix
- *
- * @deprecated since 1.22 (to be removed in 2.0)
- */
- public function getTemplateClassPrefix()
- {
- @trigger_error(sprintf('The %s method is deprecated since version 1.22 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED);
-
- return $this->templateClassPrefix;
- }
-
- /**
- * Renders a template.
- *
- * @param string|TemplateWrapper $name The template name
- * @param array $context An array of parameters to pass to the template
- *
- * @return string The rendered template
- *
- * @throws LoaderError When the template cannot be found
- * @throws SyntaxError When an error occurred during compilation
- * @throws RuntimeError When an error occurred during rendering
- */
- public function render($name, array $context = [])
- {
- return $this->load($name)->render($context);
- }
-
- /**
- * Displays a template.
- *
- * @param string|TemplateWrapper $name The template name
- * @param array $context An array of parameters to pass to the template
- *
- * @throws LoaderError When the template cannot be found
- * @throws SyntaxError When an error occurred during compilation
- * @throws RuntimeError When an error occurred during rendering
- */
- public function display($name, array $context = [])
- {
- $this->load($name)->display($context);
- }
-
- /**
- * Loads a template.
- *
- * @param string|TemplateWrapper|\Twig\Template $name The template name
- *
- * @throws LoaderError When the template cannot be found
- * @throws RuntimeError When a previously generated cache is corrupted
- * @throws SyntaxError When an error occurred during compilation
- *
- * @return TemplateWrapper
- */
- public function load($name)
- {
- if ($name instanceof TemplateWrapper) {
- return $name;
- }
-
- if ($name instanceof Template) {
- return new TemplateWrapper($this, $name);
- }
-
- return new TemplateWrapper($this, $this->loadTemplate($name));
- }
-
- /**
- * Loads a template internal representation.
- *
- * This method is for internal use only and should never be called
- * directly.
- *
- * @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 LoaderError When the template cannot be found
- * @throws RuntimeError When a previously generated cache is corrupted
- * @throws SyntaxError When an error occurred during compilation
- *
- * @internal
- */
- public function loadTemplate($name, $index = null)
- {
- return $this->loadClass($this->getTemplateClass($name), $name, $index);
- }
-
- /**
- * @internal
- */
- public function loadClass($cls, $name, $index = null)
- {
- $mainCls = $cls;
- if (null !== $index) {
- $cls .= '___'.$index;
- }
-
- if (isset($this->loadedTemplates[$cls])) {
- return $this->loadedTemplates[$cls];
- }
-
- if (!class_exists($cls, false)) {
- if ($this->bcGetCacheFilename) {
- $key = $this->getCacheFilename($name);
- } else {
- $key = $this->cache->generateKey($name, $mainCls);
- }
-
- if (!$this->isAutoReload() || $this->isTemplateFresh($name, $this->cache->getTimestamp($key))) {
- $this->cache->load($key);
- }
-
- $source = null;
- if (!class_exists($cls, false)) {
- $loader = $this->getLoader();
- if (!$loader instanceof SourceContextLoaderInterface) {
- $source = new Source($loader->getSource($name), $name);
- } else {
- $source = $loader->getSourceContext($name);
- }
-
- $content = $this->compileSource($source);
-
- if ($this->bcWriteCacheFile) {
- $this->writeCacheFile($key, $content);
- } else {
- $this->cache->write($key, $content);
- $this->cache->load($key);
- }
-
- if (!class_exists($mainCls, false)) {
- /* Last line of defense if either $this->bcWriteCacheFile was used,
- * $this->cache is implemented as a no-op or we have a race condition
- * where the cache was cleared between the above calls to write to and load from
- * the cache.
- */
- eval('?>'.$content);
- }
- }
-
- if (!class_exists($cls, false)) {
- throw new RuntimeError(sprintf('Failed to load Twig template "%s", index "%s": cache might be corrupted.', $name, $index), -1, $source);
- }
- }
-
- if (!$this->runtimeInitialized) {
- $this->initRuntime();
- }
-
- 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 $template The template source
- * @param string $name An optional name of the template to be used in error messages
- *
- * @return TemplateWrapper A template instance representing the given template name
- *
- * @throws LoaderError When the template cannot be found
- * @throws SyntaxError When an error occurred during compilation
- */
- public function createTemplate($template, $name = null)
- {
- $hash = hash('sha256', $template, false);
- if (null !== $name) {
- $name = sprintf('%s (string template %s)', $name, $hash);
- } else {
- $name = sprintf('__string_template__%s', $hash);
- }
-
- $loader = new ChainLoader([
- new ArrayLoader([$name => $template]),
- $current = $this->getLoader(),
- ]);
-
- $this->setLoader($loader);
- try {
- $template = new TemplateWrapper($this, $this->loadTemplate($name));
- } catch (\Exception $e) {
- $this->setLoader($current);
-
- throw $e;
- } catch (\Throwable $e) {
- $this->setLoader($current);
-
- throw $e;
- }
- $this->setLoader($current);
-
- return $template;
- }
-
- /**
- * Returns true if the template is still fresh.
- *
- * Besides checking the loader for freshness information,
- * this method also checks if the enabled extensions have
- * not changed.
- *
- * @param string $name The template name
- * @param int $time The last modification time of the cached template
- *
- * @return bool true if the template is fresh, false otherwise
- */
- public function isTemplateFresh($name, $time)
- {
- if (0 === $this->lastModifiedExtension) {
- foreach ($this->extensions as $extension) {
- $r = new \ReflectionObject($extension);
- if (file_exists($r->getFileName()) && ($extensionTime = filemtime($r->getFileName())) > $this->lastModifiedExtension) {
- $this->lastModifiedExtension = $extensionTime;
- }
- }
- }
-
- return $this->lastModifiedExtension <= $time && $this->getLoader()->isFresh($name, $time);
- }
-
- /**
- * Tries to load a template consecutively from an array.
- *
- * Similar to load() but it also accepts instances of \Twig\Template and
- * \Twig\TemplateWrapper, and an array of templates where each is tried to be loaded.
- *
- * @param string|Template|\Twig\TemplateWrapper|array $names A template or an array of templates to try consecutively
- *
- * @return TemplateWrapper|Template
- *
- * @throws LoaderError When none of the templates can be found
- * @throws SyntaxError When an error occurred during compilation
- */
- public function resolveTemplate($names)
- {
- if (!\is_array($names)) {
- $names = [$names];
- }
-
- foreach ($names as $name) {
- if ($name instanceof Template) {
- return $name;
- }
- if ($name instanceof TemplateWrapper) {
- return $name;
- }
-
- try {
- return $this->loadTemplate($name);
- } catch (LoaderError $e) {
- if (1 === \count($names)) {
- throw $e;
- }
- }
- }
-
- throw new LoaderError(sprintf('Unable to find one of the following templates: "%s".', implode('", "', $names)));
- }
-
- /**
- * Clears the internal template cache.
- *
- * @deprecated since 1.18.3 (to be removed in 2.0)
- */
- public function clearTemplateCache()
- {
- @trigger_error(sprintf('The %s method is deprecated since version 1.18.3 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED);
-
- $this->loadedTemplates = [];
- }
-
- /**
- * Clears the template cache files on the filesystem.
- *
- * @deprecated since 1.22 (to be removed in 2.0)
- */
- public function clearCacheFiles()
- {
- @trigger_error(sprintf('The %s method is deprecated since version 1.22 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED);
-
- if (\is_string($this->originalCache)) {
- foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->originalCache), \RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
- if ($file->isFile()) {
- @unlink($file->getPathname());
- }
- }
- }
- }
-
- /**
- * Gets the Lexer instance.
- *
- * @return \Twig_LexerInterface
- *
- * @deprecated since 1.25 (to be removed in 2.0)
- */
- public function getLexer()
- {
- @trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), E_USER_DEPRECATED);
-
- if (null === $this->lexer) {
- $this->lexer = new Lexer($this);
- }
-
- return $this->lexer;
- }
-
- public function setLexer(\Twig_LexerInterface $lexer)
- {
- $this->lexer = $lexer;
- }
-
- /**
- * Tokenizes a source code.
- *
- * @param string|Source $source The template source code
- * @param string $name The template name (deprecated)
- *
- * @return TokenStream
- *
- * @throws SyntaxError When the code is syntactically wrong
- */
- public function tokenize($source, $name = null)
- {
- if (!$source instanceof Source) {
- @trigger_error(sprintf('Passing a string as the $source argument of %s() is deprecated since version 1.27. Pass a Twig\Source instance instead.', __METHOD__), E_USER_DEPRECATED);
- $source = new Source($source, $name);
- }
-
- if (null === $this->lexer) {
- $this->lexer = new Lexer($this);
- }
-
- return $this->lexer->tokenize($source);
- }
-
- /**
- * Gets the Parser instance.
- *
- * @return \Twig_ParserInterface
- *
- * @deprecated since 1.25 (to be removed in 2.0)
- */
- public function getParser()
- {
- @trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), E_USER_DEPRECATED);
-
- if (null === $this->parser) {
- $this->parser = new Parser($this);
- }
-
- return $this->parser;
- }
-
- public function setParser(\Twig_ParserInterface $parser)
- {
- $this->parser = $parser;
- }
-
- /**
- * Converts a token stream to a node tree.
- *
- * @return ModuleNode
- *
- * @throws SyntaxError When the token stream is syntactically or semantically wrong
- */
- public function parse(TokenStream $stream)
- {
- if (null === $this->parser) {
- $this->parser = new Parser($this);
- }
-
- return $this->parser->parse($stream);
- }
-
- /**
- * Gets the Compiler instance.
- *
- * @return \Twig_CompilerInterface
- *
- * @deprecated since 1.25 (to be removed in 2.0)
- */
- public function getCompiler()
- {
- @trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), E_USER_DEPRECATED);
-
- if (null === $this->compiler) {
- $this->compiler = new Compiler($this);
- }
-
- return $this->compiler;
- }
-
- public function setCompiler(\Twig_CompilerInterface $compiler)
- {
- $this->compiler = $compiler;
- }
-
- /**
- * Compiles a node and returns the PHP code.
- *
- * @return string The compiled PHP source code
- */
- public function compile(\Twig_NodeInterface $node)
- {
- if (null === $this->compiler) {
- $this->compiler = new Compiler($this);
- }
-
- return $this->compiler->compile($node)->getSource();
- }
-
- /**
- * Compiles a template source code.
- *
- * @param string|Source $source The template source code
- * @param string $name The template name (deprecated)
- *
- * @return string The compiled PHP source code
- *
- * @throws SyntaxError When there was an error during tokenizing, parsing or compiling
- */
- public function compileSource($source, $name = null)
- {
- if (!$source instanceof Source) {
- @trigger_error(sprintf('Passing a string as the $source argument of %s() is deprecated since version 1.27. Pass a Twig\Source instance instead.', __METHOD__), E_USER_DEPRECATED);
- $source = new Source($source, $name);
- }
-
- try {
- return $this->compile($this->parse($this->tokenize($source)));
- } catch (Error $e) {
- $e->setSourceContext($source);
- throw $e;
- } catch (\Exception $e) {
- throw new SyntaxError(sprintf('An exception has been thrown during the compilation of a template ("%s").', $e->getMessage()), -1, $source, $e);
- }
- }
-
- public function setLoader(LoaderInterface $loader)
- {
- if (!$loader instanceof SourceContextLoaderInterface && 0 !== strpos(\get_class($loader), 'Mock_')) {
- @trigger_error(sprintf('Twig loader "%s" should implement Twig\Loader\SourceContextLoaderInterface since version 1.27.', \get_class($loader)), E_USER_DEPRECATED);
- }
-
- $this->loader = $loader;
- }
-
- /**
- * Gets the Loader instance.
- *
- * @return LoaderInterface
- */
- public function getLoader()
- {
- if (null === $this->loader) {
- throw new \LogicException('You must set a loader first.');
- }
-
- return $this->loader;
- }
-
- /**
- * Sets the default template charset.
- *
- * @param string $charset The default charset
- */
- public function setCharset($charset)
- {
- $this->charset = strtoupper($charset);
- }
-
- /**
- * Gets the default template charset.
- *
- * @return string The default charset
- */
- public function getCharset()
- {
- return $this->charset;
- }
-
- /**
- * Initializes the runtime environment.
- *
- * @deprecated since 1.23 (to be removed in 2.0)
- */
- public function initRuntime()
- {
- $this->runtimeInitialized = true;
-
- foreach ($this->getExtensions() as $name => $extension) {
- if (!$extension instanceof InitRuntimeInterface) {
- $m = new \ReflectionMethod($extension, 'initRuntime');
-
- $parentClass = $m->getDeclaringClass()->getName();
- if ('Twig_Extension' !== $parentClass && 'Twig\Extension\AbstractExtension' !== $parentClass) {
- @trigger_error(sprintf('Defining the initRuntime() method in the "%s" extension is deprecated since version 1.23. Use the `needs_environment` option to get the \Twig_Environment instance in filters, functions, or tests; or explicitly implement Twig\Extension\InitRuntimeInterface if needed (not recommended).', $name), E_USER_DEPRECATED);
- }
- }
-
- $extension->initRuntime($this);
- }
- }
-
- /**
- * Returns true if the given extension is registered.
- *
- * @param string $class The extension class name
- *
- * @return bool Whether the extension is registered or not
- */
- public function hasExtension($class)
- {
- $class = ltrim($class, '\\');
- if (!isset($this->extensionsByClass[$class]) && class_exists($class, false)) {
- // For BC/FC with namespaced aliases
- $class = new \ReflectionClass($class);
- $class = $class->name;
- }
-
- if (isset($this->extensions[$class])) {
- if ($class !== \get_class($this->extensions[$class])) {
- @trigger_error(sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), E_USER_DEPRECATED);
- }
-
- return true;
- }
-
- return isset($this->extensionsByClass[$class]);
- }
-
- /**
- * Adds a runtime loader.
- */
- public function addRuntimeLoader(RuntimeLoaderInterface $loader)
- {
- $this->runtimeLoaders[] = $loader;
- }
-
- /**
- * Gets an extension by class name.
- *
- * @param string $class The extension class name
- *
- * @return ExtensionInterface
- */
- public function getExtension($class)
- {
- $class = ltrim($class, '\\');
- if (!isset($this->extensionsByClass[$class]) && class_exists($class, false)) {
- // For BC/FC with namespaced aliases
- $class = new \ReflectionClass($class);
- $class = $class->name;
- }
-
- if (isset($this->extensions[$class])) {
- if ($class !== \get_class($this->extensions[$class])) {
- @trigger_error(sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), E_USER_DEPRECATED);
- }
-
- return $this->extensions[$class];
- }
-
- if (!isset($this->extensionsByClass[$class])) {
- throw new RuntimeError(sprintf('The "%s" extension is not enabled.', $class));
- }
-
- return $this->extensionsByClass[$class];
- }
-
- /**
- * Returns the runtime implementation of a Twig element (filter/function/test).
- *
- * @param string $class A runtime class name
- *
- * @return object The runtime implementation
- *
- * @throws RuntimeError When the template cannot be found
- */
- public function getRuntime($class)
- {
- if (isset($this->runtimes[$class])) {
- return $this->runtimes[$class];
- }
-
- foreach ($this->runtimeLoaders as $loader) {
- if (null !== $runtime = $loader->load($class)) {
- return $this->runtimes[$class] = $runtime;
- }
- }
-
- throw new RuntimeError(sprintf('Unable to load the "%s" runtime.', $class));
- }
-
- public function addExtension(ExtensionInterface $extension)
- {
- if ($this->extensionInitialized) {
- throw new \LogicException(sprintf('Unable to register extension "%s" as extensions have already been initialized.', $extension->getName()));
- }
-
- $class = \get_class($extension);
- if ($class !== $extension->getName()) {
- if (isset($this->extensions[$extension->getName()])) {
- unset($this->extensions[$extension->getName()], $this->extensionsByClass[$class]);
- @trigger_error(sprintf('The possibility to register the same extension twice ("%s") is deprecated since version 1.23 and will be removed in Twig 2.0. Use proper PHP inheritance instead.', $extension->getName()), E_USER_DEPRECATED);
- }
- }
-
- $this->lastModifiedExtension = 0;
- $this->extensionsByClass[$class] = $extension;
- $this->extensions[$extension->getName()] = $extension;
- $this->updateOptionsHash();
- }
-
- /**
- * Removes an extension by name.
- *
- * This method is deprecated and you should not use it.
- *
- * @param string $name The extension name
- *
- * @deprecated since 1.12 (to be removed in 2.0)
- */
- public function removeExtension($name)
- {
- @trigger_error(sprintf('The %s method is deprecated since version 1.12 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED);
-
- if ($this->extensionInitialized) {
- throw new \LogicException(sprintf('Unable to remove extension "%s" as extensions have already been initialized.', $name));
- }
-
- $class = ltrim($name, '\\');
- if (!isset($this->extensionsByClass[$class]) && class_exists($class, false)) {
- // For BC/FC with namespaced aliases
- $class = new \ReflectionClass($class);
- $class = $class->name;
- }
-
- if (isset($this->extensions[$class])) {
- if ($class !== \get_class($this->extensions[$class])) {
- @trigger_error(sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), E_USER_DEPRECATED);
- }
-
- unset($this->extensions[$class]);
- }
-
- unset($this->extensions[$class]);
- $this->updateOptionsHash();
- }
-
- /**
- * Registers an array of extensions.
- *
- * @param array $extensions An array of extensions
- */
- public function setExtensions(array $extensions)
- {
- foreach ($extensions as $extension) {
- $this->addExtension($extension);
- }
- }
-
- /**
- * Returns all registered extensions.
- *
- * @return ExtensionInterface[] An array of extensions (keys are for internal usage only and should not be relied on)
- */
- public function getExtensions()
- {
- return $this->extensions;
- }
-
- public function addTokenParser(TokenParserInterface $parser)
- {
- if ($this->extensionInitialized) {
- throw new \LogicException('Unable to add a token parser as extensions have already been initialized.');
- }
-
- $this->staging->addTokenParser($parser);
- }
-
- /**
- * Gets the registered Token Parsers.
- *
- * @return \Twig_TokenParserBrokerInterface
- *
- * @internal
- */
- public function getTokenParsers()
- {
- if (!$this->extensionInitialized) {
- $this->initExtensions();
- }
-
- return $this->parsers;
- }
-
- /**
- * Gets registered tags.
- *
- * Be warned that this method cannot return tags defined by \Twig_TokenParserBrokerInterface classes.
- *
- * @return TokenParserInterface[]
- *
- * @internal
- */
- public function getTags()
- {
- $tags = [];
- foreach ($this->getTokenParsers()->getParsers() as $parser) {
- if ($parser instanceof TokenParserInterface) {
- $tags[$parser->getTag()] = $parser;
- }
- }
-
- return $tags;
- }
-
- public function addNodeVisitor(NodeVisitorInterface $visitor)
- {
- if ($this->extensionInitialized) {
- throw new \LogicException('Unable to add a node visitor as extensions have already been initialized.');
- }
-
- $this->staging->addNodeVisitor($visitor);
- }
-
- /**
- * Gets the registered Node Visitors.
- *
- * @return NodeVisitorInterface[]
- *
- * @internal
- */
- public function getNodeVisitors()
- {
- if (!$this->extensionInitialized) {
- $this->initExtensions();
- }
-
- return $this->visitors;
- }
-
- /**
- * Registers a Filter.
- *
- * @param string|TwigFilter $name The filter name or a \Twig_SimpleFilter instance
- * @param \Twig_FilterInterface|TwigFilter $filter
- */
- public function addFilter($name, $filter = null)
- {
- if (!$name instanceof TwigFilter && !($filter instanceof TwigFilter || $filter instanceof \Twig_FilterInterface)) {
- throw new \LogicException('A filter must be an instance of \Twig_FilterInterface or \Twig_SimpleFilter.');
- }
-
- if ($name instanceof TwigFilter) {
- $filter = $name;
- $name = $filter->getName();
- } else {
- @trigger_error(sprintf('Passing a name as a first argument to the %s method is deprecated since version 1.21. Pass an instance of "Twig_SimpleFilter" instead when defining filter "%s".', __METHOD__, $name), E_USER_DEPRECATED);
- }
-
- if ($this->extensionInitialized) {
- throw new \LogicException(sprintf('Unable to add filter "%s" as extensions have already been initialized.', $name));
- }
-
- $this->staging->addFilter($name, $filter);
- }
-
- /**
- * Get a filter by name.
- *
- * Subclasses may override this method and load filters differently;
- * so no list of filters is available.
- *
- * @param string $name The filter name
- *
- * @return \Twig_Filter|false
- *
- * @internal
- */
- public function getFilter($name)
- {
- if (!$this->extensionInitialized) {
- $this->initExtensions();
- }
-
- if (isset($this->filters[$name])) {
- return $this->filters[$name];
- }
-
- foreach ($this->filters as $pattern => $filter) {
- $pattern = str_replace('\\*', '(.*?)', preg_quote($pattern, '#'), $count);
-
- if ($count) {
- if (preg_match('#^'.$pattern.'$#', $name, $matches)) {
- array_shift($matches);
- $filter->setArguments($matches);
-
- return $filter;
- }
- }
- }
-
- foreach ($this->filterCallbacks as $callback) {
- if (false !== $filter = \call_user_func($callback, $name)) {
- return $filter;
- }
- }
-
- return false;
- }
-
- public function registerUndefinedFilterCallback($callable)
- {
- $this->filterCallbacks[] = $callable;
- }
-
- /**
- * Gets the registered Filters.
- *
- * Be warned that this method cannot return filters defined with registerUndefinedFilterCallback.
- *
- * @return \Twig_FilterInterface[]
- *
- * @see registerUndefinedFilterCallback
- *
- * @internal
- */
- public function getFilters()
- {
- if (!$this->extensionInitialized) {
- $this->initExtensions();
- }
-
- return $this->filters;
- }
-
- /**
- * Registers a Test.
- *
- * @param string|TwigTest $name The test name or a \Twig_SimpleTest instance
- * @param \Twig_TestInterface|TwigTest $test A \Twig_TestInterface instance or a \Twig_SimpleTest instance
- */
- public function addTest($name, $test = null)
- {
- if (!$name instanceof TwigTest && !($test instanceof TwigTest || $test instanceof \Twig_TestInterface)) {
- throw new \LogicException('A test must be an instance of \Twig_TestInterface or \Twig_SimpleTest.');
- }
-
- if ($name instanceof TwigTest) {
- $test = $name;
- $name = $test->getName();
- } else {
- @trigger_error(sprintf('Passing a name as a first argument to the %s method is deprecated since version 1.21. Pass an instance of "Twig_SimpleTest" instead when defining test "%s".', __METHOD__, $name), E_USER_DEPRECATED);
- }
-
- if ($this->extensionInitialized) {
- throw new \LogicException(sprintf('Unable to add test "%s" as extensions have already been initialized.', $name));
- }
-
- $this->staging->addTest($name, $test);
- }
-
- /**
- * Gets the registered Tests.
- *
- * @return \Twig_TestInterface[]
- *
- * @internal
- */
- public function getTests()
- {
- if (!$this->extensionInitialized) {
- $this->initExtensions();
- }
-
- return $this->tests;
- }
-
- /**
- * Gets a test by name.
- *
- * @param string $name The test name
- *
- * @return \Twig_Test|false
- *
- * @internal
- */
- public function getTest($name)
- {
- if (!$this->extensionInitialized) {
- $this->initExtensions();
- }
-
- if (isset($this->tests[$name])) {
- return $this->tests[$name];
- }
-
- foreach ($this->tests as $pattern => $test) {
- $pattern = str_replace('\\*', '(.*?)', preg_quote($pattern, '#'), $count);
-
- if ($count) {
- if (preg_match('#^'.$pattern.'$#', $name, $matches)) {
- array_shift($matches);
- $test->setArguments($matches);
-
- return $test;
- }
- }
- }
-
- return false;
- }
-
- /**
- * Registers a Function.
- *
- * @param string|TwigFunction $name The function name or a \Twig_SimpleFunction instance
- * @param \Twig_FunctionInterface|TwigFunction $function
- */
- public function addFunction($name, $function = null)
- {
- if (!$name instanceof TwigFunction && !($function instanceof TwigFunction || $function instanceof \Twig_FunctionInterface)) {
- throw new \LogicException('A function must be an instance of \Twig_FunctionInterface or \Twig_SimpleFunction.');
- }
-
- if ($name instanceof TwigFunction) {
- $function = $name;
- $name = $function->getName();
- } else {
- @trigger_error(sprintf('Passing a name as a first argument to the %s method is deprecated since version 1.21. Pass an instance of "Twig_SimpleFunction" instead when defining function "%s".', __METHOD__, $name), E_USER_DEPRECATED);
- }
-
- if ($this->extensionInitialized) {
- throw new \LogicException(sprintf('Unable to add function "%s" as extensions have already been initialized.', $name));
- }
-
- $this->staging->addFunction($name, $function);
- }
-
- /**
- * Get a function by name.
- *
- * Subclasses may override this method and load functions differently;
- * so no list of functions is available.
- *
- * @param string $name function name
- *
- * @return \Twig_Function|false
- *
- * @internal
- */
- public function getFunction($name)
- {
- if (!$this->extensionInitialized) {
- $this->initExtensions();
- }
-
- if (isset($this->functions[$name])) {
- return $this->functions[$name];
- }
-
- foreach ($this->functions as $pattern => $function) {
- $pattern = str_replace('\\*', '(.*?)', preg_quote($pattern, '#'), $count);
-
- if ($count) {
- if (preg_match('#^'.$pattern.'$#', $name, $matches)) {
- array_shift($matches);
- $function->setArguments($matches);
-
- return $function;
- }
- }
- }
-
- foreach ($this->functionCallbacks as $callback) {
- if (false !== $function = \call_user_func($callback, $name)) {
- return $function;
- }
- }
-
- return false;
- }
-
- public function registerUndefinedFunctionCallback($callable)
- {
- $this->functionCallbacks[] = $callable;
- }
-
- /**
- * Gets registered functions.
- *
- * Be warned that this method cannot return functions defined with registerUndefinedFunctionCallback.
- *
- * @return \Twig_FunctionInterface[]
- *
- * @see registerUndefinedFunctionCallback
- *
- * @internal
- */
- public function getFunctions()
- {
- if (!$this->extensionInitialized) {
- $this->initExtensions();
- }
-
- return $this->functions;
- }
-
- /**
- * Registers a Global.
- *
- * New globals can be added before compiling or rendering a template;
- * but after, you can only update existing globals.
- *
- * @param string $name The global name
- * @param mixed $value The global value
- */
- public function addGlobal($name, $value)
- {
- if ($this->extensionInitialized || $this->runtimeInitialized) {
- if (null === $this->globals) {
- $this->globals = $this->initGlobals();
- }
-
- if (!\array_key_exists($name, $this->globals)) {
- // The deprecation notice must be turned into the following exception in Twig 2.0
- @trigger_error(sprintf('Registering global variable "%s" at runtime or when the extensions have already been initialized is deprecated since version 1.21.', $name), E_USER_DEPRECATED);
- //throw new \LogicException(sprintf('Unable to add global "%s" as the runtime or the extensions have already been initialized.', $name));
- }
- }
-
- if ($this->extensionInitialized || $this->runtimeInitialized) {
- // update the value
- $this->globals[$name] = $value;
- } else {
- $this->staging->addGlobal($name, $value);
- }
- }
-
- /**
- * Gets the registered Globals.
- *
- * @return array An array of globals
- *
- * @internal
- */
- public function getGlobals()
- {
- if (!$this->runtimeInitialized && !$this->extensionInitialized) {
- return $this->initGlobals();
- }
-
- if (null === $this->globals) {
- $this->globals = $this->initGlobals();
- }
-
- return $this->globals;
- }
-
- /**
- * Merges a context with the defined globals.
- *
- * @param array $context An array representing the context
- *
- * @return array The context merged with the globals
- */
- public function mergeGlobals(array $context)
- {
- // we don't use array_merge as the context being generally
- // bigger than globals, this code is faster.
- foreach ($this->getGlobals() as $key => $value) {
- if (!\array_key_exists($key, $context)) {
- $context[$key] = $value;
- }
- }
-
- return $context;
- }
-
- /**
- * Gets the registered unary Operators.
- *
- * @return array An array of unary operators
- *
- * @internal
- */
- public function getUnaryOperators()
- {
- if (!$this->extensionInitialized) {
- $this->initExtensions();
- }
-
- return $this->unaryOperators;
- }
-
- /**
- * Gets the registered binary Operators.
- *
- * @return array An array of binary operators
- *
- * @internal
- */
- public function getBinaryOperators()
- {
- if (!$this->extensionInitialized) {
- $this->initExtensions();
- }
-
- return $this->binaryOperators;
- }
-
- /**
- * @deprecated since 1.23 (to be removed in 2.0)
- */
- public function computeAlternatives($name, $items)
- {
- @trigger_error(sprintf('The %s method is deprecated since version 1.23 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED);
-
- return SyntaxError::computeAlternatives($name, $items);
- }
-
- /**
- * @internal
- */
- protected function initGlobals()
- {
- $globals = [];
- foreach ($this->extensions as $name => $extension) {
- if (!$extension instanceof GlobalsInterface) {
- $m = new \ReflectionMethod($extension, 'getGlobals');
-
- $parentClass = $m->getDeclaringClass()->getName();
- if ('Twig_Extension' !== $parentClass && 'Twig\Extension\AbstractExtension' !== $parentClass) {
- @trigger_error(sprintf('Defining the getGlobals() method in the "%s" extension without explicitly implementing Twig\Extension\GlobalsInterface is deprecated since version 1.23.', $name), E_USER_DEPRECATED);
- }
- }
-
- $extGlob = $extension->getGlobals();
- if (!\is_array($extGlob)) {
- throw new \UnexpectedValueException(sprintf('"%s::getGlobals()" must return an array of globals.', \get_class($extension)));
- }
-
- $globals[] = $extGlob;
- }
-
- $globals[] = $this->staging->getGlobals();
-
- return \call_user_func_array('array_merge', $globals);
- }
-
- /**
- * @internal
- */
- protected function initExtensions()
- {
- if ($this->extensionInitialized) {
- return;
- }
-
- $this->parsers = new \Twig_TokenParserBroker([], [], false);
- $this->filters = [];
- $this->functions = [];
- $this->tests = [];
- $this->visitors = [];
- $this->unaryOperators = [];
- $this->binaryOperators = [];
-
- foreach ($this->extensions as $extension) {
- $this->initExtension($extension);
- }
- $this->initExtension($this->staging);
- // Done at the end only, so that an exception during initialization does not mark the environment as initialized when catching the exception
- $this->extensionInitialized = true;
- }
-
- /**
- * @internal
- */
- protected function initExtension(ExtensionInterface $extension)
- {
- // filters
- foreach ($extension->getFilters() as $name => $filter) {
- if ($filter instanceof TwigFilter) {
- $name = $filter->getName();
- } else {
- @trigger_error(sprintf('Using an instance of "%s" for filter "%s" is deprecated since version 1.21. Use \Twig_SimpleFilter instead.', \get_class($filter), $name), E_USER_DEPRECATED);
- }
-
- $this->filters[$name] = $filter;
- }
-
- // functions
- foreach ($extension->getFunctions() as $name => $function) {
- if ($function instanceof TwigFunction) {
- $name = $function->getName();
- } else {
- @trigger_error(sprintf('Using an instance of "%s" for function "%s" is deprecated since version 1.21. Use \Twig_SimpleFunction instead.', \get_class($function), $name), E_USER_DEPRECATED);
- }
-
- $this->functions[$name] = $function;
- }
-
- // tests
- foreach ($extension->getTests() as $name => $test) {
- if ($test instanceof TwigTest) {
- $name = $test->getName();
- } else {
- @trigger_error(sprintf('Using an instance of "%s" for test "%s" is deprecated since version 1.21. Use \Twig_SimpleTest instead.', \get_class($test), $name), E_USER_DEPRECATED);
- }
-
- $this->tests[$name] = $test;
- }
-
- // token parsers
- foreach ($extension->getTokenParsers() as $parser) {
- if ($parser instanceof TokenParserInterface) {
- $this->parsers->addTokenParser($parser);
- } elseif ($parser instanceof \Twig_TokenParserBrokerInterface) {
- @trigger_error('Registering a \Twig_TokenParserBrokerInterface instance is deprecated since version 1.21.', E_USER_DEPRECATED);
-
- $this->parsers->addTokenParserBroker($parser);
- } else {
- throw new \LogicException('getTokenParsers() must return an array of \Twig_TokenParserInterface or \Twig_TokenParserBrokerInterface instances.');
- }
- }
-
- // node visitors
- foreach ($extension->getNodeVisitors() as $visitor) {
- $this->visitors[] = $visitor;
- }
-
- // operators
- if ($operators = $extension->getOperators()) {
- if (!\is_array($operators)) {
- throw new \InvalidArgumentException(sprintf('"%s::getOperators()" must return an array with operators, got "%s".', \get_class($extension), \is_object($operators) ? \get_class($operators) : \gettype($operators).(\is_resource($operators) ? '' : '#'.$operators)));
- }
-
- if (2 !== \count($operators)) {
- throw new \InvalidArgumentException(sprintf('"%s::getOperators()" must return an array of 2 elements, got %d.', \get_class($extension), \count($operators)));
- }
-
- $this->unaryOperators = array_merge($this->unaryOperators, $operators[0]);
- $this->binaryOperators = array_merge($this->binaryOperators, $operators[1]);
- }
- }
-
- /**
- * @deprecated since 1.22 (to be removed in 2.0)
- */
- protected function writeCacheFile($file, $content)
- {
- $this->cache->write($file, $content);
- }
-
- private function updateOptionsHash()
- {
- $hashParts = array_merge(
- array_keys($this->extensions),
- [
- (int) \function_exists('twig_template_get_attributes'),
- PHP_MAJOR_VERSION,
- PHP_MINOR_VERSION,
- self::VERSION,
- (int) $this->debug,
- $this->baseTemplateClass,
- (int) $this->strictVariables,
- ]
- );
- $this->optionsHash = implode(':', $hashParts);
- }
-}
-
-class_alias('Twig\Environment', 'Twig_Environment');
diff --git a/system/templateEngines/Twig/Twig1x/twig/twig/src/ExpressionParser.php b/system/templateEngines/Twig/Twig1x/twig/twig/src/ExpressionParser.php
deleted file mode 100644
index a3ff725..0000000
--- a/system/templateEngines/Twig/Twig1x/twig/twig/src/ExpressionParser.php
+++ /dev/null
@@ -1,834 +0,0 @@
-
- *
- * @internal
- */
-class ExpressionParser
-{
- const OPERATOR_LEFT = 1;
- const OPERATOR_RIGHT = 2;
-
- protected $parser;
- protected $unaryOperators;
- protected $binaryOperators;
-
- private $env;
-
- public function __construct(Parser $parser, $env = null)
- {
- $this->parser = $parser;
-
- if ($env instanceof Environment) {
- $this->env = $env;
- $this->unaryOperators = $env->getUnaryOperators();
- $this->binaryOperators = $env->getBinaryOperators();
- } else {
- @trigger_error('Passing the operators as constructor arguments to '.__METHOD__.' is deprecated since version 1.27. Pass the environment instead.', E_USER_DEPRECATED);
-
- $this->env = $parser->getEnvironment();
- $this->unaryOperators = func_get_arg(1);
- $this->binaryOperators = func_get_arg(2);
- }
- }
-
- public function parseExpression($precedence = 0, $allowArrow = false)
- {
- if ($allowArrow && $arrow = $this->parseArrow()) {
- return $arrow;
- }
-
- $expr = $this->getPrimary();
- $token = $this->parser->getCurrentToken();
- while ($this->isBinary($token) && $this->binaryOperators[$token->getValue()]['precedence'] >= $precedence) {
- $op = $this->binaryOperators[$token->getValue()];
- $this->parser->getStream()->next();
-
- if ('is not' === $token->getValue()) {
- $expr = $this->parseNotTestExpression($expr);
- } elseif ('is' === $token->getValue()) {
- $expr = $this->parseTestExpression($expr);
- } elseif (isset($op['callable'])) {
- $expr = \call_user_func($op['callable'], $this->parser, $expr);
- } else {
- $expr1 = $this->parseExpression(self::OPERATOR_LEFT === $op['associativity'] ? $op['precedence'] + 1 : $op['precedence']);
- $class = $op['class'];
- $expr = new $class($expr, $expr1, $token->getLine());
- }
-
- $token = $this->parser->getCurrentToken();
- }
-
- if (0 === $precedence) {
- return $this->parseConditionalExpression($expr);
- }
-
- return $expr;
- }
-
- /**
- * @return ArrowFunctionExpression|null
- */
- private function parseArrow()
- {
- $stream = $this->parser->getStream();
-
- // short array syntax (one argument, no parentheses)?
- if ($stream->look(1)->test(Token::ARROW_TYPE)) {
- $line = $stream->getCurrent()->getLine();
- $token = $stream->expect(Token::NAME_TYPE);
- $names = [new AssignNameExpression($token->getValue(), $token->getLine())];
- $stream->expect(Token::ARROW_TYPE);
-
- return new ArrowFunctionExpression($this->parseExpression(0), new Node($names), $line);
- }
-
- // first, determine if we are parsing an arrow function by finding => (long form)
- $i = 0;
- if (!$stream->look($i)->test(Token::PUNCTUATION_TYPE, '(')) {
- return null;
- }
- ++$i;
- while (true) {
- // variable name
- ++$i;
- if (!$stream->look($i)->test(Token::PUNCTUATION_TYPE, ',')) {
- break;
- }
- ++$i;
- }
- if (!$stream->look($i)->test(Token::PUNCTUATION_TYPE, ')')) {
- return null;
- }
- ++$i;
- if (!$stream->look($i)->test(Token::ARROW_TYPE)) {
- return null;
- }
-
- // yes, let's parse it properly
- $token = $stream->expect(Token::PUNCTUATION_TYPE, '(');
- $line = $token->getLine();
-
- $names = [];
- while (true) {
- $token = $stream->expect(Token::NAME_TYPE);
- $names[] = new AssignNameExpression($token->getValue(), $token->getLine());
-
- if (!$stream->nextIf(Token::PUNCTUATION_TYPE, ',')) {
- break;
- }
- }
- $stream->expect(Token::PUNCTUATION_TYPE, ')');
- $stream->expect(Token::ARROW_TYPE);
-
- return new ArrowFunctionExpression($this->parseExpression(0), new Node($names), $line);
- }
-
- protected function getPrimary()
- {
- $token = $this->parser->getCurrentToken();
-
- if ($this->isUnary($token)) {
- $operator = $this->unaryOperators[$token->getValue()];
- $this->parser->getStream()->next();
- $expr = $this->parseExpression($operator['precedence']);
- $class = $operator['class'];
-
- return $this->parsePostfixExpression(new $class($expr, $token->getLine()));
- } elseif ($token->test(Token::PUNCTUATION_TYPE, '(')) {
- $this->parser->getStream()->next();
- $expr = $this->parseExpression();
- $this->parser->getStream()->expect(Token::PUNCTUATION_TYPE, ')', 'An opened parenthesis is not properly closed');
-
- return $this->parsePostfixExpression($expr);
- }
-
- return $this->parsePrimaryExpression();
- }
-
- protected function parseConditionalExpression($expr)
- {
- while ($this->parser->getStream()->nextIf(Token::PUNCTUATION_TYPE, '?')) {
- if (!$this->parser->getStream()->nextIf(Token::PUNCTUATION_TYPE, ':')) {
- $expr2 = $this->parseExpression();
- if ($this->parser->getStream()->nextIf(Token::PUNCTUATION_TYPE, ':')) {
- $expr3 = $this->parseExpression();
- } else {
- $expr3 = new ConstantExpression('', $this->parser->getCurrentToken()->getLine());
- }
- } else {
- $expr2 = $expr;
- $expr3 = $this->parseExpression();
- }
-
- $expr = new ConditionalExpression($expr, $expr2, $expr3, $this->parser->getCurrentToken()->getLine());
- }
-
- return $expr;
- }
-
- protected function isUnary(Token $token)
- {
- return $token->test(Token::OPERATOR_TYPE) && isset($this->unaryOperators[$token->getValue()]);
- }
-
- protected function isBinary(Token $token)
- {
- return $token->test(Token::OPERATOR_TYPE) && isset($this->binaryOperators[$token->getValue()]);
- }
-
- public function parsePrimaryExpression()
- {
- $token = $this->parser->getCurrentToken();
- switch ($token->getType()) {
- case Token::NAME_TYPE:
- $this->parser->getStream()->next();
- switch ($token->getValue()) {
- case 'true':
- case 'TRUE':
- $node = new ConstantExpression(true, $token->getLine());
- break;
-
- case 'false':
- case 'FALSE':
- $node = new ConstantExpression(false, $token->getLine());
- break;
-
- case 'none':
- case 'NONE':
- case 'null':
- case 'NULL':
- $node = new ConstantExpression(null, $token->getLine());
- break;
-
- default:
- if ('(' === $this->parser->getCurrentToken()->getValue()) {
- $node = $this->getFunctionNode($token->getValue(), $token->getLine());
- } else {
- $node = new NameExpression($token->getValue(), $token->getLine());
- }
- }
- break;
-
- case Token::NUMBER_TYPE:
- $this->parser->getStream()->next();
- $node = new ConstantExpression($token->getValue(), $token->getLine());
- break;
-
- case Token::STRING_TYPE:
- case Token::INTERPOLATION_START_TYPE:
- $node = $this->parseStringExpression();
- break;
-
- case Token::OPERATOR_TYPE:
- if (preg_match(Lexer::REGEX_NAME, $token->getValue(), $matches) && $matches[0] == $token->getValue()) {
- // in this context, string operators are variable names
- $this->parser->getStream()->next();
- $node = new NameExpression($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\NegUnary';
- $posClass = 'Twig\Node\Expression\Unary\PosUnary';
- if (!(\in_array($ref->getName(), [$negClass, $posClass, 'Twig_Node_Expression_Unary_Neg', 'Twig_Node_Expression_Unary_Pos'])
- || $ref->isSubclassOf($negClass) || $ref->isSubclassOf($posClass)
- || $ref->isSubclassOf('Twig_Node_Expression_Unary_Neg') || $ref->isSubclassOf('Twig_Node_Expression_Unary_Pos'))
- ) {
- throw new SyntaxError(sprintf('Unexpected unary operator "%s".', $token->getValue()), $token->getLine(), $this->parser->getStream()->getSourceContext());
- }
-
- $this->parser->getStream()->next();
- $expr = $this->parsePrimaryExpression();
-
- $node = new $class($expr, $token->getLine());
- break;
- }
-
- // no break
- default:
- if ($token->test(Token::PUNCTUATION_TYPE, '[')) {
- $node = $this->parseArrayExpression();
- } elseif ($token->test(Token::PUNCTUATION_TYPE, '{')) {
- $node = $this->parseHashExpression();
- } elseif ($token->test(Token::OPERATOR_TYPE, '=') && ('==' === $this->parser->getStream()->look(-1)->getValue() || '!=' === $this->parser->getStream()->look(-1)->getValue())) {
- throw new SyntaxError(sprintf('Unexpected operator of value "%s". Did you try to use "===" or "!==" for strict comparison? Use "is same as(value)" instead.', $token->getValue()), $token->getLine(), $this->parser->getStream()->getSourceContext());
- } else {
- throw new SyntaxError(sprintf('Unexpected token "%s" of value "%s".', Token::typeToEnglish($token->getType()), $token->getValue()), $token->getLine(), $this->parser->getStream()->getSourceContext());
- }
- }
-
- return $this->parsePostfixExpression($node);
- }
-
- public function parseStringExpression()
- {
- $stream = $this->parser->getStream();
-
- $nodes = [];
- // a string cannot be followed by another string in a single expression
- $nextCanBeString = true;
- while (true) {
- if ($nextCanBeString && $token = $stream->nextIf(Token::STRING_TYPE)) {
- $nodes[] = new ConstantExpression($token->getValue(), $token->getLine());
- $nextCanBeString = false;
- } elseif ($stream->nextIf(Token::INTERPOLATION_START_TYPE)) {
- $nodes[] = $this->parseExpression();
- $stream->expect(Token::INTERPOLATION_END_TYPE);
- $nextCanBeString = true;
- } else {
- break;
- }
- }
-
- $expr = array_shift($nodes);
- foreach ($nodes as $node) {
- $expr = new ConcatBinary($expr, $node, $node->getTemplateLine());
- }
-
- return $expr;
- }
-
- public function parseArrayExpression()
- {
- $stream = $this->parser->getStream();
- $stream->expect(Token::PUNCTUATION_TYPE, '[', 'An array element was expected');
-
- $node = new ArrayExpression([], $stream->getCurrent()->getLine());
- $first = true;
- while (!$stream->test(Token::PUNCTUATION_TYPE, ']')) {
- if (!$first) {
- $stream->expect(Token::PUNCTUATION_TYPE, ',', 'An array element must be followed by a comma');
-
- // trailing ,?
- if ($stream->test(Token::PUNCTUATION_TYPE, ']')) {
- break;
- }
- }
- $first = false;
-
- $node->addElement($this->parseExpression());
- }
- $stream->expect(Token::PUNCTUATION_TYPE, ']', 'An opened array is not properly closed');
-
- return $node;
- }
-
- public function parseHashExpression()
- {
- $stream = $this->parser->getStream();
- $stream->expect(Token::PUNCTUATION_TYPE, '{', 'A hash element was expected');
-
- $node = new ArrayExpression([], $stream->getCurrent()->getLine());
- $first = true;
- while (!$stream->test(Token::PUNCTUATION_TYPE, '}')) {
- if (!$first) {
- $stream->expect(Token::PUNCTUATION_TYPE, ',', 'A hash value must be followed by a comma');
-
- // trailing ,?
- if ($stream->test(Token::PUNCTUATION_TYPE, '}')) {
- break;
- }
- }
- $first = false;
-
- // a hash key can be:
- //
- // * a number -- 12
- // * a string -- 'a'
- // * a name, which is equivalent to a string -- a
- // * an expression, which must be enclosed in parentheses -- (1 + 2)
- if (($token = $stream->nextIf(Token::STRING_TYPE)) || ($token = $stream->nextIf(Token::NAME_TYPE)) || $token = $stream->nextIf(Token::NUMBER_TYPE)) {
- $key = new ConstantExpression($token->getValue(), $token->getLine());
- } elseif ($stream->test(Token::PUNCTUATION_TYPE, '(')) {
- $key = $this->parseExpression();
- } else {
- $current = $stream->getCurrent();
-
- throw new SyntaxError(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".', Token::typeToEnglish($current->getType()), $current->getValue()), $current->getLine(), $stream->getSourceContext());
- }
-
- $stream->expect(Token::PUNCTUATION_TYPE, ':', 'A hash key must be followed by a colon (:)');
- $value = $this->parseExpression();
-
- $node->addElement($value, $key);
- }
- $stream->expect(Token::PUNCTUATION_TYPE, '}', 'An opened hash is not properly closed');
-
- return $node;
- }
-
- public function parsePostfixExpression($node)
- {
- while (true) {
- $token = $this->parser->getCurrentToken();
- if (Token::PUNCTUATION_TYPE == $token->getType()) {
- if ('.' == $token->getValue() || '[' == $token->getValue()) {
- $node = $this->parseSubscriptExpression($node);
- } elseif ('|' == $token->getValue()) {
- $node = $this->parseFilterExpression($node);
- } else {
- break;
- }
- } else {
- break;
- }
- }
-
- return $node;
- }
-
- public function getFunctionNode($name, $line)
- {
- switch ($name) {
- case 'parent':
- $this->parseArguments();
- if (!\count($this->parser->getBlockStack())) {
- throw new SyntaxError('Calling "parent" outside a block is forbidden.', $line, $this->parser->getStream()->getSourceContext());
- }
-
- if (!$this->parser->getParent() && !$this->parser->hasTraits()) {
- throw new SyntaxError('Calling "parent" on a template that does not extend nor "use" another template is forbidden.', $line, $this->parser->getStream()->getSourceContext());
- }
-
- return new ParentExpression($this->parser->peekBlockStack(), $line);
- case 'block':
- $args = $this->parseArguments();
- if (\count($args) < 1) {
- throw new SyntaxError('The "block" function takes one argument (the block name).', $line, $this->parser->getStream()->getSourceContext());
- }
-
- return new BlockReferenceExpression($args->getNode(0), \count($args) > 1 ? $args->getNode(1) : null, $line);
- case 'attribute':
- $args = $this->parseArguments();
- if (\count($args) < 2) {
- throw new SyntaxError('The "attribute" function takes at least two arguments (the variable and the attributes).', $line, $this->parser->getStream()->getSourceContext());
- }
-
- return new GetAttrExpression($args->getNode(0), $args->getNode(1), \count($args) > 2 ? $args->getNode(2) : null, Template::ANY_CALL, $line);
- default:
- if (null !== $alias = $this->parser->getImportedSymbol('function', $name)) {
- $arguments = new ArrayExpression([], $line);
- foreach ($this->parseArguments() as $n) {
- $arguments->addElement($n);
- }
-
- $node = new MethodCallExpression($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);
- }
- }
-
- public function parseSubscriptExpression($node)
- {
- $stream = $this->parser->getStream();
- $token = $stream->next();
- $lineno = $token->getLine();
- $arguments = new ArrayExpression([], $lineno);
- $type = Template::ANY_CALL;
- if ('.' == $token->getValue()) {
- $token = $stream->next();
- if (
- Token::NAME_TYPE == $token->getType()
- ||
- Token::NUMBER_TYPE == $token->getType()
- ||
- (Token::OPERATOR_TYPE == $token->getType() && preg_match(Lexer::REGEX_NAME, $token->getValue()))
- ) {
- $arg = new ConstantExpression($token->getValue(), $lineno);
-
- if ($stream->test(Token::PUNCTUATION_TYPE, '(')) {
- $type = Template::METHOD_CALL;
- foreach ($this->parseArguments() as $n) {
- $arguments->addElement($n);
- }
- }
- } else {
- throw new SyntaxError('Expected name or number.', $lineno, $stream->getSourceContext());
- }
-
- if ($node instanceof NameExpression && null !== $this->parser->getImportedSymbol('template', $node->getAttribute('name'))) {
- if (!$arg instanceof ConstantExpression) {
- throw new SyntaxError(sprintf('Dynamic macro names are not supported (called on "%s").', $node->getAttribute('name')), $token->getLine(), $stream->getSourceContext());
- }
-
- $name = $arg->getAttribute('value');
-
- if ($this->parser->isReservedMacroName($name)) {
- throw new SyntaxError(sprintf('"%s" cannot be called as macro as it is a reserved keyword.', $name), $token->getLine(), $stream->getSourceContext());
- }
-
- $node = new MethodCallExpression($node, 'get'.$name, $arguments, $lineno);
- $node->setAttribute('safe', true);
-
- return $node;
- }
- } else {
- $type = Template::ARRAY_CALL;
-
- // slice?
- $slice = false;
- if ($stream->test(Token::PUNCTUATION_TYPE, ':')) {
- $slice = true;
- $arg = new ConstantExpression(0, $token->getLine());
- } else {
- $arg = $this->parseExpression();
- }
-
- if ($stream->nextIf(Token::PUNCTUATION_TYPE, ':')) {
- $slice = true;
- }
-
- if ($slice) {
- if ($stream->test(Token::PUNCTUATION_TYPE, ']')) {
- $length = new ConstantExpression(null, $token->getLine());
- } else {
- $length = $this->parseExpression();
- }
-
- $class = $this->getFilterNodeClass('slice', $token->getLine());
- $arguments = new Node([$arg, $length]);
- $filter = new $class($node, new ConstantExpression('slice', $token->getLine()), $arguments, $token->getLine());
-
- $stream->expect(Token::PUNCTUATION_TYPE, ']');
-
- return $filter;
- }
-
- $stream->expect(Token::PUNCTUATION_TYPE, ']');
- }
-
- return new GetAttrExpression($node, $arg, $arguments, $type, $lineno);
- }
-
- public function parseFilterExpression($node)
- {
- $this->parser->getStream()->next();
-
- return $this->parseFilterExpressionRaw($node);
- }
-
- public function parseFilterExpressionRaw($node, $tag = null)
- {
- while (true) {
- $token = $this->parser->getStream()->expect(Token::NAME_TYPE);
-
- $name = new ConstantExpression($token->getValue(), $token->getLine());
- if (!$this->parser->getStream()->test(Token::PUNCTUATION_TYPE, '(')) {
- $arguments = new Node();
- } else {
- $arguments = $this->parseArguments(true, false, true);
- }
-
- $class = $this->getFilterNodeClass($name->getAttribute('value'), $token->getLine());
-
- $node = new $class($node, $name, $arguments, $token->getLine(), $tag);
-
- if (!$this->parser->getStream()->test(Token::PUNCTUATION_TYPE, '|')) {
- break;
- }
-
- $this->parser->getStream()->next();
- }
-
- return $node;
- }
-
- /**
- * Parses arguments.
- *
- * @param bool $namedArguments Whether to allow named arguments or not
- * @param bool $definition Whether we are parsing arguments for a function definition
- *
- * @return Node
- *
- * @throws SyntaxError
- */
- public function parseArguments($namedArguments = false, $definition = false, $allowArrow = false)
- {
- $args = [];
- $stream = $this->parser->getStream();
-
- $stream->expect(Token::PUNCTUATION_TYPE, '(', 'A list of arguments must begin with an opening parenthesis');
- while (!$stream->test(Token::PUNCTUATION_TYPE, ')')) {
- if (!empty($args)) {
- $stream->expect(Token::PUNCTUATION_TYPE, ',', 'Arguments must be separated by a comma');
- }
-
- if ($definition) {
- $token = $stream->expect(Token::NAME_TYPE, null, 'An argument must be a name');
- $value = new NameExpression($token->getValue(), $this->parser->getCurrentToken()->getLine());
- } else {
- $value = $this->parseExpression(0, $allowArrow);
- }
-
- $name = null;
- if ($namedArguments && $token = $stream->nextIf(Token::OPERATOR_TYPE, '=')) {
- if (!$value instanceof NameExpression) {
- throw new SyntaxError(sprintf('A parameter name must be a string, "%s" given.', \get_class($value)), $token->getLine(), $stream->getSourceContext());
- }
- $name = $value->getAttribute('name');
-
- if ($definition) {
- $value = $this->parsePrimaryExpression();
-
- if (!$this->checkConstantExpression($value)) {
- throw new SyntaxError(sprintf('A default value for an argument must be a constant (a boolean, a string, a number, or an array).'), $token->getLine(), $stream->getSourceContext());
- }
- } else {
- $value = $this->parseExpression(0, $allowArrow);
- }
- }
-
- if ($definition) {
- if (null === $name) {
- $name = $value->getAttribute('name');
- $value = new ConstantExpression(null, $this->parser->getCurrentToken()->getLine());
- }
- $args[$name] = $value;
- } else {
- if (null === $name) {
- $args[] = $value;
- } else {
- $args[$name] = $value;
- }
- }
- }
- $stream->expect(Token::PUNCTUATION_TYPE, ')', 'A list of arguments must be closed by a parenthesis');
-
- return new Node($args);
- }
-
- public function parseAssignmentExpression()
- {
- $stream = $this->parser->getStream();
- $targets = [];
- while (true) {
- $token = $this->parser->getCurrentToken();
- if ($stream->test(Token::OPERATOR_TYPE) && preg_match(Lexer::REGEX_NAME, $token->getValue())) {
- // in this context, string operators are variable names
- $this->parser->getStream()->next();
- } else {
- $stream->expect(Token::NAME_TYPE, null, 'Only variables can be assigned to');
- }
- $value = $token->getValue();
- if (\in_array(strtr($value, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), ['true', 'false', 'none', 'null'])) {
- throw new SyntaxError(sprintf('You cannot assign a value to "%s".', $value), $token->getLine(), $stream->getSourceContext());
- }
- $targets[] = new AssignNameExpression($value, $token->getLine());
-
- if (!$stream->nextIf(Token::PUNCTUATION_TYPE, ',')) {
- break;
- }
- }
-
- return new Node($targets);
- }
-
- public function parseMultitargetExpression()
- {
- $targets = [];
- while (true) {
- $targets[] = $this->parseExpression();
- if (!$this->parser->getStream()->nextIf(Token::PUNCTUATION_TYPE, ',')) {
- break;
- }
- }
-
- return new Node($targets);
- }
-
- private function parseNotTestExpression(\Twig_NodeInterface $node)
- {
- return new NotUnary($this->parseTestExpression($node), $this->parser->getCurrentToken()->getLine());
- }
-
- private function parseTestExpression(\Twig_NodeInterface $node)
- {
- $stream = $this->parser->getStream();
- list($name, $test) = $this->getTest($node->getTemplateLine());
-
- $class = $this->getTestNodeClass($test);
- $arguments = null;
- if ($stream->test(Token::PUNCTUATION_TYPE, '(')) {
- $arguments = $this->parseArguments(true);
- }
-
- return new $class($node, $name, $arguments, $this->parser->getCurrentToken()->getLine());
- }
-
- private function getTest($line)
- {
- $stream = $this->parser->getStream();
- $name = $stream->expect(Token::NAME_TYPE)->getValue();
-
- if ($test = $this->env->getTest($name)) {
- return [$name, $test];
- }
-
- if ($stream->test(Token::NAME_TYPE)) {
- // try 2-words tests
- $name = $name.' '.$this->parser->getCurrentToken()->getValue();
-
- if ($test = $this->env->getTest($name)) {
- $stream->next();
-
- return [$name, $test];
- }
- }
-
- $e = new SyntaxError(sprintf('Unknown "%s" test.', $name), $line, $stream->getSourceContext());
- $e->addSuggestions($name, array_keys($this->env->getTests()));
-
- throw $e;
- }
-
- private function getTestNodeClass($test)
- {
- if ($test instanceof TwigTest && $test->isDeprecated()) {
- $stream = $this->parser->getStream();
- $message = sprintf('Twig Test "%s" is deprecated', $test->getName());
- if (!\is_bool($test->getDeprecatedVersion())) {
- $message .= sprintf(' since version %s', $test->getDeprecatedVersion());
- }
- if ($test->getAlternative()) {
- $message .= sprintf('. Use "%s" instead', $test->getAlternative());
- }
- $src = $stream->getSourceContext();
- $message .= sprintf(' in %s at line %d.', $src->getPath() ? $src->getPath() : $src->getName(), $stream->getCurrent()->getLine());
-
- @trigger_error($message, E_USER_DEPRECATED);
- }
-
- if ($test instanceof TwigTest) {
- return $test->getNodeClass();
- }
-
- return $test instanceof \Twig_Test_Node ? $test->getClass() : 'Twig\Node\Expression\TestExpression';
- }
-
- protected function getFunctionNodeClass($name, $line)
- {
- if (false === $function = $this->env->getFunction($name)) {
- $e = new SyntaxError(sprintf('Unknown "%s" function.', $name), $line, $this->parser->getStream()->getSourceContext());
- $e->addSuggestions($name, array_keys($this->env->getFunctions()));
-
- throw $e;
- }
-
- if ($function instanceof TwigFunction && $function->isDeprecated()) {
- $message = sprintf('Twig Function "%s" is deprecated', $function->getName());
- if (!\is_bool($function->getDeprecatedVersion())) {
- $message .= sprintf(' since version %s', $function->getDeprecatedVersion());
- }
- if ($function->getAlternative()) {
- $message .= sprintf('. Use "%s" instead', $function->getAlternative());
- }
- $src = $this->parser->getStream()->getSourceContext();
- $message .= sprintf(' in %s at line %d.', $src->getPath() ? $src->getPath() : $src->getName(), $line);
-
- @trigger_error($message, E_USER_DEPRECATED);
- }
-
- if ($function instanceof TwigFunction) {
- return $function->getNodeClass();
- }
-
- return $function instanceof \Twig_Function_Node ? $function->getClass() : 'Twig\Node\Expression\FunctionExpression';
- }
-
- protected function getFilterNodeClass($name, $line)
- {
- if (false === $filter = $this->env->getFilter($name)) {
- $e = new SyntaxError(sprintf('Unknown "%s" filter.', $name), $line, $this->parser->getStream()->getSourceContext());
- $e->addSuggestions($name, array_keys($this->env->getFilters()));
-
- throw $e;
- }
-
- if ($filter instanceof TwigFilter && $filter->isDeprecated()) {
- $message = sprintf('Twig Filter "%s" is deprecated', $filter->getName());
- if (!\is_bool($filter->getDeprecatedVersion())) {
- $message .= sprintf(' since version %s', $filter->getDeprecatedVersion());
- }
- if ($filter->getAlternative()) {
- $message .= sprintf('. Use "%s" instead', $filter->getAlternative());
- }
- $src = $this->parser->getStream()->getSourceContext();
- $message .= sprintf(' in %s at line %d.', $src->getPath() ? $src->getPath() : $src->getName(), $line);
-
- @trigger_error($message, E_USER_DEPRECATED);
- }
-
- if ($filter instanceof TwigFilter) {
- return $filter->getNodeClass();
- }
-
- return $filter instanceof \Twig_Filter_Node ? $filter->getClass() : 'Twig\Node\Expression\FilterExpression';
- }
-
- // checks that the node only contains "constant" elements
- protected function checkConstantExpression(\Twig_NodeInterface $node)
- {
- if (!($node instanceof ConstantExpression || $node instanceof ArrayExpression
- || $node instanceof NegUnary || $node instanceof PosUnary
- )) {
- return false;
- }
-
- foreach ($node as $n) {
- if (!$this->checkConstantExpression($n)) {
- return false;
- }
- }
-
- return true;
- }
-}
-
-class_alias('Twig\ExpressionParser', 'Twig_ExpressionParser');
diff --git a/system/templateEngines/Twig/Twig1x/twig/twig/src/Extension/CoreExtension.php b/system/templateEngines/Twig/Twig1x/twig/twig/src/Extension/CoreExtension.php
deleted file mode 100644
index 5ff1e39..0000000
--- a/system/templateEngines/Twig/Twig1x/twig/twig/src/Extension/CoreExtension.php
+++ /dev/null
@@ -1,1728 +0,0 @@
-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.
- *
- * @param string $format The default date format string
- * @param string $dateIntervalFormat The default date interval format string
- */
- public function setDateFormat($format = null, $dateIntervalFormat = null)
- {
- if (null !== $format) {
- $this->dateFormats[0] = $format;
- }
-
- if (null !== $dateIntervalFormat) {
- $this->dateFormats[1] = $dateIntervalFormat;
- }
- }
-
- /**
- * Gets the default format to be used by the date filter.
- *
- * @return array The default date format string and the default date interval format string
- */
- public function getDateFormat()
- {
- return $this->dateFormats;
- }
-
- /**
- * Sets the default timezone to be used by the date filter.
- *
- * @param \DateTimeZone|string $timezone The default timezone string or a \DateTimeZone object
- */
- public function setTimezone($timezone)
- {
- $this->timezone = $timezone instanceof \DateTimeZone ? $timezone : new \DateTimeZone($timezone);
- }
-
- /**
- * Gets the default timezone to be used by the date filter.
- *
- * @return \DateTimeZone The default timezone currently in use
- */
- public function getTimezone()
- {
- if (null === $this->timezone) {
- $this->timezone = new \DateTimeZone(date_default_timezone_get());
- }
-
- return $this->timezone;
- }
-
- /**
- * Sets the default format to be used by the number_format filter.
- *
- * @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)
- {
- $this->numberFormat = [$decimal, $decimalPoint, $thousandSep];
- }
-
- /**
- * Get the default format used by the number_format filter.
- *
- * @return array The arguments for number_format()
- */
- public function getNumberFormat()
- {
- return $this->numberFormat;
- }
-
- public function getTokenParsers()
- {
- return [
- new ApplyTokenParser(),
- new ForTokenParser(),
- new IfTokenParser(),
- new ExtendsTokenParser(),
- new IncludeTokenParser(),
- new BlockTokenParser(),
- new UseTokenParser(),
- new FilterTokenParser(),
- new MacroTokenParser(),
- new ImportTokenParser(),
- new FromTokenParser(),
- new SetTokenParser(),
- new SpacelessTokenParser(),
- new FlushTokenParser(),
- new DoTokenParser(),
- new EmbedTokenParser(),
- new WithTokenParser(),
- new DeprecatedTokenParser(),
- ];
- }
-
- public function getFilters()
- {
- $filters = [
- // formatting filters
- new TwigFilter('date', 'twig_date_format_filter', ['needs_environment' => true]),
- new TwigFilter('date_modify', 'twig_date_modify_filter', ['needs_environment' => true]),
- new TwigFilter('format', 'sprintf'),
- new TwigFilter('replace', 'twig_replace_filter'),
- new TwigFilter('number_format', 'twig_number_format_filter', ['needs_environment' => true]),
- new TwigFilter('abs', 'abs'),
- new TwigFilter('round', 'twig_round'),
-
- // encoding
- new TwigFilter('url_encode', 'twig_urlencode_filter'),
- new TwigFilter('json_encode', 'twig_jsonencode_filter'),
- new TwigFilter('convert_encoding', 'twig_convert_encoding'),
-
- // string filters
- new TwigFilter('title', 'twig_title_string_filter', ['needs_environment' => true]),
- new TwigFilter('capitalize', 'twig_capitalize_string_filter', ['needs_environment' => true]),
- new TwigFilter('upper', 'strtoupper'),
- new TwigFilter('lower', 'strtolower'),
- new TwigFilter('striptags', 'strip_tags'),
- new TwigFilter('trim', 'twig_trim_filter'),
- new TwigFilter('nl2br', 'nl2br', ['pre_escape' => 'html', 'is_safe' => ['html']]),
- new TwigFilter('spaceless', 'twig_spaceless', ['is_safe' => ['html']]),
-
- // array helpers
- new TwigFilter('join', 'twig_join_filter'),
- new TwigFilter('split', 'twig_split_filter', ['needs_environment' => true]),
- new TwigFilter('sort', 'twig_sort_filter'),
- new TwigFilter('merge', 'twig_array_merge'),
- new TwigFilter('batch', 'twig_array_batch'),
- new TwigFilter('filter', 'twig_array_filter'),
- new TwigFilter('map', 'twig_array_map'),
- new TwigFilter('reduce', 'twig_array_reduce'),
-
- // string/array filters
- new TwigFilter('reverse', 'twig_reverse_filter', ['needs_environment' => true]),
- new TwigFilter('length', 'twig_length_filter', ['needs_environment' => true]),
- new TwigFilter('slice', 'twig_slice', ['needs_environment' => true]),
- new TwigFilter('first', 'twig_first', ['needs_environment' => true]),
- new TwigFilter('last', 'twig_last', ['needs_environment' => true]),
-
- // iteration and runtime
- new TwigFilter('default', '_twig_default_filter', ['node_class' => '\Twig\Node\Expression\Filter\DefaultFilter']),
- new TwigFilter('keys', 'twig_get_array_keys_filter'),
-
- // escaping
- new TwigFilter('escape', 'twig_escape_filter', ['needs_environment' => true, 'is_safe_callback' => 'twig_escape_filter_is_safe']),
- new TwigFilter('e', 'twig_escape_filter', ['needs_environment' => true, 'is_safe_callback' => 'twig_escape_filter_is_safe']),
- ];
-
- if (\function_exists('mb_get_info')) {
- $filters[] = new TwigFilter('upper', 'twig_upper_filter', ['needs_environment' => true]);
- $filters[] = new TwigFilter('lower', 'twig_lower_filter', ['needs_environment' => true]);
- }
-
- return $filters;
- }
-
- public function getFunctions()
- {
- return [
- new TwigFunction('max', 'max'),
- new TwigFunction('min', 'min'),
- new TwigFunction('range', 'range'),
- new TwigFunction('constant', 'twig_constant'),
- new TwigFunction('cycle', 'twig_cycle'),
- new TwigFunction('random', 'twig_random', ['needs_environment' => true]),
- new TwigFunction('date', 'twig_date_converter', ['needs_environment' => true]),
- new TwigFunction('include', 'twig_include', ['needs_environment' => true, 'needs_context' => true, 'is_safe' => ['all']]),
- new TwigFunction('source', 'twig_source', ['needs_environment' => true, 'is_safe' => ['all']]),
- ];
- }
-
- public function getTests()
- {
- return [
- new TwigTest('even', null, ['node_class' => '\Twig\Node\Expression\Test\EvenTest']),
- new TwigTest('odd', null, ['node_class' => '\Twig\Node\Expression\Test\OddTest']),
- new TwigTest('defined', null, ['node_class' => '\Twig\Node\Expression\Test\DefinedTest']),
- new TwigTest('sameas', null, ['node_class' => '\Twig\Node\Expression\Test\SameasTest', 'deprecated' => '1.21', 'alternative' => 'same as']),
- new TwigTest('same as', null, ['node_class' => '\Twig\Node\Expression\Test\SameasTest']),
- new TwigTest('none', null, ['node_class' => '\Twig\Node\Expression\Test\NullTest']),
- new TwigTest('null', null, ['node_class' => '\Twig\Node\Expression\Test\NullTest']),
- new TwigTest('divisibleby', null, ['node_class' => '\Twig\Node\Expression\Test\DivisiblebyTest', 'deprecated' => '1.21', 'alternative' => 'divisible by']),
- new TwigTest('divisible by', null, ['node_class' => '\Twig\Node\Expression\Test\DivisiblebyTest']),
- new TwigTest('constant', null, ['node_class' => '\Twig\Node\Expression\Test\ConstantTest']),
- new TwigTest('empty', 'twig_test_empty'),
- new TwigTest('iterable', 'twig_test_iterable'),
- ];
- }
-
- public function getOperators()
- {
- return [
- [
- 'not' => ['precedence' => 50, 'class' => '\Twig\Node\Expression\Unary\NotUnary'],
- '-' => ['precedence' => 500, 'class' => '\Twig\Node\Expression\Unary\NegUnary'],
- '+' => ['precedence' => 500, 'class' => '\Twig\Node\Expression\Unary\PosUnary'],
- ],
- [
- 'or' => ['precedence' => 10, 'class' => '\Twig\Node\Expression\Binary\OrBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
- 'and' => ['precedence' => 15, 'class' => '\Twig\Node\Expression\Binary\AndBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
- 'b-or' => ['precedence' => 16, 'class' => '\Twig\Node\Expression\Binary\BitwiseOrBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
- 'b-xor' => ['precedence' => 17, 'class' => '\Twig\Node\Expression\Binary\BitwiseXorBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
- 'b-and' => ['precedence' => 18, 'class' => '\Twig\Node\Expression\Binary\BitwiseAndBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
- '==' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\EqualBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
- '!=' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\NotEqualBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
- '<' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\LessBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
- '>' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\GreaterBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
- '>=' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\GreaterEqualBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
- '<=' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\LessEqualBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
- 'not in' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\NotInBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
- 'in' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\InBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
- 'matches' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\MatchesBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
- 'starts with' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\StartsWithBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
- 'ends with' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\EndsWithBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
- '..' => ['precedence' => 25, 'class' => '\Twig\Node\Expression\Binary\RangeBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
- '+' => ['precedence' => 30, 'class' => '\Twig\Node\Expression\Binary\AddBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
- '-' => ['precedence' => 30, 'class' => '\Twig\Node\Expression\Binary\SubBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
- '~' => ['precedence' => 40, 'class' => '\Twig\Node\Expression\Binary\ConcatBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
- '*' => ['precedence' => 60, 'class' => '\Twig\Node\Expression\Binary\MulBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
- '/' => ['precedence' => 60, 'class' => '\Twig\Node\Expression\Binary\DivBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
- '//' => ['precedence' => 60, 'class' => '\Twig\Node\Expression\Binary\FloorDivBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
- '%' => ['precedence' => 60, 'class' => '\Twig\Node\Expression\Binary\ModBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
- 'is' => ['precedence' => 100, 'associativity' => ExpressionParser::OPERATOR_LEFT],
- 'is not' => ['precedence' => 100, 'associativity' => ExpressionParser::OPERATOR_LEFT],
- '**' => ['precedence' => 200, 'class' => '\Twig\Node\Expression\Binary\PowerBinary', 'associativity' => ExpressionParser::OPERATOR_RIGHT],
- '??' => ['precedence' => 300, 'class' => '\Twig\Node\Expression\NullCoalesceExpression', 'associativity' => ExpressionParser::OPERATOR_RIGHT],
- ],
- ];
- }
-
- public function getName()
- {
- return 'core';
- }
-}
-
-class_alias('Twig\Extension\CoreExtension', 'Twig_Extension_Core');
-}
-
-namespace {
-use Twig\Environment;
-use Twig\Error\LoaderError;
-use Twig\Error\RuntimeError;
-use Twig\Loader\SourceContextLoaderInterface;
-use Twig\Markup;
-use Twig\Node\Expression\ConstantExpression;
-use Twig\Node\Node;
-
-/**
- * Cycles over a value.
- *
- * @param \ArrayAccess|array $values
- * @param int $position The cycle position
- *
- * @return string The next value in the cycle
- */
-function twig_cycle($values, $position)
-{
- if (!\is_array($values) && !$values instanceof \ArrayAccess) {
- return $values;
- }
-
- return $values[$position % \count($values)];
-}
-
-/**
- * Returns a random value depending on the supplied parameter type:
- * - a random item from a \Traversable or array
- * - a random character from a string
- * - a random integer between 0 and the integer parameter.
- *
- * @param \Traversable|array|int|float|string $values The values to pick a random item from
- * @param int|null $max Maximum value used when $values is an int
- *
- * @throws RuntimeError when $values is an empty array (does not apply to an empty string which is returned as is)
- *
- * @return mixed A random value from the given sequence
- */
-function twig_random(Environment $env, $values = null, $max = null)
-{
- if (null === $values) {
- return null === $max ? mt_rand() : mt_rand(0, $max);
- }
-
- if (\is_int($values) || \is_float($values)) {
- if (null === $max) {
- if ($values < 0) {
- $max = 0;
- $min = $values;
- } else {
- $max = $values;
- $min = 0;
- }
- } else {
- $min = $values;
- $max = $max;
- }
-
- return mt_rand($min, $max);
- }
-
- if (\is_string($values)) {
- if ('' === $values) {
- return '';
- }
- if (null !== $charset = $env->getCharset()) {
- if ('UTF-8' !== $charset) {
- $values = twig_convert_encoding($values, 'UTF-8', $charset);
- }
-
- // unicode version of str_split()
- // split at all positions, but not after the start and not before the end
- $values = preg_split('/(? $value) {
- $values[$i] = twig_convert_encoding($value, $charset, 'UTF-8');
- }
- }
- } else {
- return $values[mt_rand(0, \strlen($values) - 1)];
- }
- }
-
- if (!twig_test_iterable($values)) {
- return $values;
- }
-
- $values = twig_to_array($values);
-
- if (0 === \count($values)) {
- throw new RuntimeError('The random function cannot pick from an empty array.');
- }
-
- return $values[array_rand($values, 1)];
-}
-
-/**
- * Converts a date to the given format.
- *
- * {{ post.published_at|date("m/d/Y") }}
- *
- * @param \DateTime|\DateTimeInterface|\DateInterval|string $date A date
- * @param string|null $format The target format, null to use the default
- * @param \DateTimeZone|string|false|null $timezone The target timezone, null to use the default, false to leave unchanged
- *
- * @return string The formatted date
- */
-function twig_date_format_filter(Environment $env, $date, $format = null, $timezone = null)
-{
- if (null === $format) {
- $formats = $env->getExtension('\Twig\Extension\CoreExtension')->getDateFormat();
- $format = $date instanceof \DateInterval ? $formats[1] : $formats[0];
- }
-
- if ($date instanceof \DateInterval) {
- return $date->format($format);
- }
-
- return twig_date_converter($env, $date, $timezone)->format($format);
-}
-
-/**
- * Returns a new date object modified.
- *
- * {{ post.published_at|date_modify("-1day")|date("m/d/Y") }}
- *
- * @param \DateTime|string $date A date
- * @param string $modifier A modifier string
- *
- * @return \DateTime
- */
-function twig_date_modify_filter(Environment $env, $date, $modifier)
-{
- $date = twig_date_converter($env, $date, false);
- $resultDate = $date->modify($modifier);
-
- // 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;
-}
-
-/**
- * Converts an input to a \DateTime instance.
- *
- * {% if date(user.created_at) < date('+2days') %}
- * {# do something #}
- * {% endif %}
- *
- * @param \DateTime|\DateTimeInterface|string|null $date A date
- * @param \DateTimeZone|string|false|null $timezone The target timezone, null to use the default, false to leave unchanged
- *
- * @return \DateTimeInterface
- */
-function twig_date_converter(Environment $env, $date = null, $timezone = null)
-{
- // determine the timezone
- if (false !== $timezone) {
- if (null === $timezone) {
- $timezone = $env->getExtension('\Twig\Extension\CoreExtension')->getTimezone();
- } elseif (!$timezone instanceof \DateTimeZone) {
- $timezone = new \DateTimeZone($timezone);
- }
- }
-
- // 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($timezone);
- }
-
- return $date;
- }
-
- if (null === $date || 'now' === $date) {
- return new \DateTime($date, false !== $timezone ? $timezone : $env->getExtension('\Twig\Extension\CoreExtension')->getTimezone());
- }
-
- $asString = (string) $date;
- if (ctype_digit($asString) || (!empty($asString) && '-' === $asString[0] && ctype_digit(substr($asString, 1)))) {
- $date = new \DateTime('@'.$date);
- } else {
- $date = new \DateTime($date, $env->getExtension('\Twig\Extension\CoreExtension')->getTimezone());
- }
-
- if (false !== $timezone) {
- $date->setTimezone($timezone);
- }
-
- return $date;
-}
-
-/**
- * Replaces strings within a string.
- *
- * @param string $str String to replace in
- * @param array|\Traversable $from Replace values
- * @param string|null $to Replace to, deprecated (@see https://secure.php.net/manual/en/function.strtr.php)
- *
- * @return string
- */
-function twig_replace_filter($str, $from, $to = null)
-{
- if (\is_string($from) && \is_string($to)) {
- @trigger_error('Using "replace" with character by character replacement is deprecated since version 1.22 and will be removed in Twig 2.0', E_USER_DEPRECATED);
-
- return strtr($str, $from, $to);
- }
-
- if (!twig_test_iterable($from)) {
- throw new RuntimeError(sprintf('The "replace" filter expects an array or "Traversable" as replace values, got "%s".', \is_object($from) ? \get_class($from) : \gettype($from)));
- }
-
- return strtr($str, twig_to_array($from));
-}
-
-/**
- * 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 RuntimeError('The round filter only supports the "common", "ceil", and "floor" methods.');
- }
-
- return $method($value * pow(10, $precision)) / pow(10, $precision);
-}
-
-/**
- * Number format filter.
- *
- * All of the formatting options can be left null, in that case the defaults will
- * be used. Supplying any of the parameters will override the defaults set in the
- * environment object.
- *
- * @param mixed $number A float/int/string of the number to format
- * @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
- *
- * @return string The formatted number
- */
-function twig_number_format_filter(Environment $env, $number, $decimal = null, $decimalPoint = null, $thousandSep = null)
-{
- $defaults = $env->getExtension('\Twig\Extension\CoreExtension')->getNumberFormat();
- if (null === $decimal) {
- $decimal = $defaults[0];
- }
-
- if (null === $decimalPoint) {
- $decimalPoint = $defaults[1];
- }
-
- if (null === $thousandSep) {
- $thousandSep = $defaults[2];
- }
-
- return number_format((float) $number, $decimal, $decimalPoint, $thousandSep);
-}
-
-/**
- * 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
- *
- * @return string The URL encoded value
- */
-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, '', '&');
- }
-
- return rawurlencode($url);
-}
-
-/**
- * JSON encodes a variable.
- *
- * @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
- */
-function twig_jsonencode_filter($value, $options = 0)
-{
- if ($value instanceof Markup) {
- $value = (string) $value;
- } elseif (\is_array($value)) {
- array_walk_recursive($value, '_twig_markup2string');
- }
-
- return json_encode($value, $options);
-}
-
-function _twig_markup2string(&$value)
-{
- if ($value instanceof Markup) {
- $value = (string) $value;
- }
-}
-
-/**
- * Merges an array with another one.
- *
- * {% set items = { 'apple': 'fruit', 'orange': 'fruit' } %}
- *
- * {% set items = items|merge({ 'peugeot': 'car' }) %}
- *
- * {# items now contains { 'apple': 'fruit', 'orange': 'fruit', 'peugeot': 'car' } #}
- *
- * @param array|\Traversable $arr1 An array
- * @param array|\Traversable $arr2 An array
- *
- * @return array The merged array
- */
-function twig_array_merge($arr1, $arr2)
-{
- if (!twig_test_iterable($arr1)) {
- throw new RuntimeError(sprintf('The merge filter only works with arrays or "Traversable", got "%s" as first argument.', \gettype($arr1)));
- }
-
- if (!twig_test_iterable($arr2)) {
- throw new RuntimeError(sprintf('The merge filter only works with arrays or "Traversable", got "%s" as second argument.', \gettype($arr2)));
- }
-
- return array_merge(twig_to_array($arr1), twig_to_array($arr2));
-}
-
-/**
- * Slices a variable.
- *
- * @param mixed $item A variable
- * @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(Environment $env, $item, $start, $length = null, $preserveKeys = false)
-{
- if ($item instanceof \Traversable) {
- while ($item instanceof \IteratorAggregate) {
- $item = $item->getIterator();
- }
-
- if ($start >= 0 && $length >= 0 && $item instanceof \Iterator) {
- try {
- return iterator_to_array(new \LimitIterator($item, $start, null === $length ? -1 : $length), $preserveKeys);
- } catch (\OutOfBoundsException $e) {
- return [];
- }
- }
-
- $item = iterator_to_array($item, $preserveKeys);
- }
-
- if (\is_array($item)) {
- return \array_slice($item, $start, $length, $preserveKeys);
- }
-
- $item = (string) $item;
-
- if (\function_exists('mb_get_info') && null !== $charset = $env->getCharset()) {
- return (string) mb_substr($item, $start, null === $length ? mb_strlen($item, $charset) - $start : $length, $charset);
- }
-
- return (string) (null === $length ? substr($item, $start) : substr($item, $start, $length));
-}
-
-/**
- * Returns the first element of the item.
- *
- * @param mixed $item A variable
- *
- * @return mixed The first element of the item
- */
-function twig_first(Environment $env, $item)
-{
- $elements = twig_slice($env, $item, 0, 1, false);
-
- return \is_string($elements) ? $elements : current($elements);
-}
-
-/**
- * Returns the last element of the item.
- *
- * @param mixed $item A variable
- *
- * @return mixed The last element of the item
- */
-function twig_last(Environment $env, $item)
-{
- $elements = twig_slice($env, $item, -1, 1, false);
-
- return \is_string($elements) ? $elements : current($elements);
-}
-
-/**
- * Joins the values to a string.
- *
- * The separators between elements are empty strings per default, you can define them with the optional parameters.
- *
- * {{ [1, 2, 3]|join(', ', ' and ') }}
- * {# returns 1, 2 and 3 #}
- *
- * {{ [1, 2, 3]|join('|') }}
- * {# returns 1|2|3 #}
- *
- * {{ [1, 2, 3]|join }}
- * {# returns 123 #}
- *
- * @param array $value An array
- * @param string $glue The separator
- * @param string|null $and The separator for the last pair
- *
- * @return string The concatenated string
- */
-function twig_join_filter($value, $glue = '', $and = null)
-{
- if (!twig_test_iterable($value)) {
- $value = (array) $value;
- }
-
- $value = twig_to_array($value, false);
-
- if (0 === \count($value)) {
- return '';
- }
-
- if (null === $and || $and === $glue) {
- return implode($glue, $value);
- }
-
- if (1 === \count($value)) {
- return $value[0];
- }
-
- return implode($glue, \array_slice($value, 0, -1)).$and.$value[\count($value) - 1];
-}
-
-/**
- * Splits the string into an array.
- *
- * {{ "one,two,three"|split(',') }}
- * {# returns [one, two, three] #}
- *
- * {{ "one,two,three,four,five"|split(',', 3) }}
- * {# returns [one, two, "three,four,five"] #}
- *
- * {{ "123"|split('') }}
- * {# returns [1, 2, 3] #}
- *
- * {{ "aabbcc"|split('', 2) }}
- * {# returns [aa, bb, cc] #}
- *
- * @param string $value A string
- * @param string $delimiter The delimiter
- * @param int $limit The limit
- *
- * @return array The split string as an array
- */
-function twig_split_filter(Environment $env, $value, $delimiter, $limit = null)
-{
- if (\strlen($delimiter) > 0) {
- 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);
- }
-
- if ($limit <= 1) {
- return preg_split('/(?getIterator();
- }
-
- if ($array instanceof \Iterator) {
- $keys = [];
- $array->rewind();
- while ($array->valid()) {
- $keys[] = $array->key();
- $array->next();
- }
-
- return $keys;
- }
-
- $keys = [];
- foreach ($array as $key => $item) {
- $keys[] = $key;
- }
-
- return $keys;
- }
-
- if (!\is_array($array)) {
- return [];
- }
-
- return array_keys($array);
-}
-
-/**
- * Reverses a variable.
- *
- * @param array|\Traversable|string $item An array, a \Traversable instance, or a string
- * @param bool $preserveKeys Whether to preserve key or not
- *
- * @return mixed The reversed input
- */
-function twig_reverse_filter(Environment $env, $item, $preserveKeys = false)
-{
- if ($item instanceof \Traversable) {
- return array_reverse(iterator_to_array($item), $preserveKeys);
- }
-
- if (\is_array($item)) {
- return array_reverse($item, $preserveKeys);
- }
-
- if (null !== $charset = $env->getCharset()) {
- $string = (string) $item;
-
- if ('UTF-8' !== $charset) {
- $item = twig_convert_encoding($string, 'UTF-8', $charset);
- }
-
- preg_match_all('/./us', $item, $matches);
-
- $string = implode('', array_reverse($matches[0]));
-
- if ('UTF-8' !== $charset) {
- $string = twig_convert_encoding($string, $charset, 'UTF-8');
- }
-
- return $string;
- }
-
- return strrev((string) $item);
-}
-
-/**
- * Sorts an array.
- *
- * @param array|\Traversable $array
- *
- * @return array
- */
-function twig_sort_filter($array)
-{
- if ($array instanceof \Traversable) {
- $array = iterator_to_array($array);
- } elseif (!\is_array($array)) {
- throw new RuntimeError(sprintf('The sort filter only works with arrays or "Traversable", got "%s".', \gettype($array)));
- }
-
- asort($array);
-
- return $array;
-}
-
-/**
- * @internal
- */
-function twig_in_filter($value, $compare)
-{
- if ($value instanceof Markup) {
- $value = (string) $value;
- }
- if ($compare instanceof Markup) {
- $compare = (string) $compare;
- }
-
- if (\is_array($compare)) {
- return \in_array($value, $compare, \is_object($value) || \is_resource($value));
- } elseif (\is_string($compare) && (\is_string($value) || \is_int($value) || \is_float($value))) {
- return '' === $value || false !== strpos($compare, (string) $value);
- } elseif ($compare instanceof \Traversable) {
- if (\is_object($value) || \is_resource($value)) {
- foreach ($compare as $item) {
- if ($item === $value) {
- return true;
- }
- }
- } else {
- foreach ($compare as $item) {
- if ($item == $value) {
- return true;
- }
- }
- }
-
- return false;
- }
-
- return false;
-}
-
-/**
- * Returns a trimmed string.
- *
- * @return string
- *
- * @throws RuntimeError When an invalid trimming side is used (not a string or not 'left', 'right', or 'both')
- */
-function twig_trim_filter($string, $characterMask = null, $side = 'both')
-{
- if (null === $characterMask) {
- $characterMask = " \t\n\r\0\x0B";
- }
-
- switch ($side) {
- case 'both':
- return trim($string, $characterMask);
- case 'left':
- return ltrim($string, $characterMask);
- case 'right':
- return rtrim($string, $characterMask);
- default:
- throw new RuntimeError('Trimming side must be "left", "right" or "both".');
- }
-}
-
-/**
- * Removes whitespaces between HTML tags.
- *
- * @return string
- */
-function twig_spaceless($content)
-{
- return trim(preg_replace('/>\s+', '><', $content));
-}
-
-/**
- * Escapes a string.
- *
- * @param mixed $string The value to be escaped
- * @param string $strategy The escaping strategy
- * @param string $charset The charset
- * @param bool $autoescape Whether the function is called by the auto-escaping feature (true) or by the developer (false)
- *
- * @return string
- */
-function twig_escape_filter(Environment $env, $string, $strategy = 'html', $charset = null, $autoescape = false)
-{
- if ($autoescape && $string instanceof Markup) {
- return $string;
- }
-
- if (!\is_string($string)) {
- if (\is_object($string) && method_exists($string, '__toString')) {
- $string = (string) $string;
- } elseif (\in_array($strategy, ['html', 'js', 'css', 'html_attr', 'url'])) {
- return $string;
- }
- }
-
- if ('' === $string) {
- return '';
- }
-
- if (null === $charset) {
- $charset = $env->getCharset();
- }
-
- switch ($strategy) {
- case 'html':
- // see https://secure.php.net/htmlspecialchars
-
- // Using a static variable to avoid initializing the array
- // each time the function is called. Moving the declaration on the
- // top of the function slow downs other escaping strategies.
- static $htmlspecialcharsCharsets = [
- '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);
- }
-
- if (isset($htmlspecialcharsCharsets[strtoupper($charset)])) {
- // cache the lowercase variant for future iterations
- $htmlspecialcharsCharsets[$charset] = true;
-
- return htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE, $charset);
- }
-
- $string = twig_convert_encoding($string, 'UTF-8', $charset);
- $string = htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
-
- return twig_convert_encoding($string, $charset, 'UTF-8');
-
- case 'js':
- // escape all non-alphanumeric characters
- // into their \x or \uHHHH representations
- if ('UTF-8' !== $charset) {
- $string = twig_convert_encoding($string, 'UTF-8', $charset);
- }
-
- if (!preg_match('//u', $string)) {
- throw new RuntimeError('The string to escape is not a valid UTF-8 string.');
- }
-
- $string = preg_replace_callback('#[^a-zA-Z0-9,\._]#Su', '_twig_escape_js_callback', $string);
-
- if ('UTF-8' !== $charset) {
- $string = twig_convert_encoding($string, $charset, 'UTF-8');
- }
-
- return $string;
-
- case 'css':
- if ('UTF-8' !== $charset) {
- $string = twig_convert_encoding($string, 'UTF-8', $charset);
- }
-
- if (!preg_match('//u', $string)) {
- throw new RuntimeError('The string to escape is not a valid UTF-8 string.');
- }
-
- $string = preg_replace_callback('#[^a-zA-Z0-9]#Su', '_twig_escape_css_callback', $string);
-
- if ('UTF-8' !== $charset) {
- $string = twig_convert_encoding($string, $charset, 'UTF-8');
- }
-
- return $string;
-
- case 'html_attr':
- if ('UTF-8' !== $charset) {
- $string = twig_convert_encoding($string, 'UTF-8', $charset);
- }
-
- if (!preg_match('//u', $string)) {
- throw new RuntimeError('The string to escape is not a valid UTF-8 string.');
- }
-
- $string = preg_replace_callback('#[^a-zA-Z0-9,\.\-_]#Su', '_twig_escape_html_attr_callback', $string);
-
- if ('UTF-8' !== $charset) {
- $string = twig_convert_encoding($string, $charset, 'UTF-8');
- }
-
- return $string;
-
- case 'url':
- return rawurlencode($string);
-
- default:
- static $escapers;
-
- if (null === $escapers) {
- $escapers = $env->getExtension('\Twig\Extension\CoreExtension')->getEscapers();
- }
-
- if (isset($escapers[$strategy])) {
- return \call_user_func($escapers[$strategy], $env, $string, $charset);
- }
-
- $validStrategies = implode(', ', array_merge(['html', 'js', 'url', 'css', 'html_attr'], array_keys($escapers)));
-
- throw new RuntimeError(sprintf('Invalid escaping strategy "%s" (valid ones: %s).', $strategy, $validStrategies));
- }
-}
-
-/**
- * @internal
- */
-function twig_escape_filter_is_safe(Node $filterArgs)
-{
- foreach ($filterArgs as $arg) {
- if ($arg instanceof ConstantExpression) {
- return [$arg->getAttribute('value')];
- }
-
- return [];
- }
-
- return ['html'];
-}
-
-if (\function_exists('mb_convert_encoding')) {
- function twig_convert_encoding($string, $to, $from)
- {
- return mb_convert_encoding($string, $to, $from);
- }
-} elseif (\function_exists('iconv')) {
- function twig_convert_encoding($string, $to, $from)
- {
- return iconv($from, $to, $string);
- }
-} else {
- function twig_convert_encoding($string, $to, $from)
- {
- throw new RuntimeError('No suitable convert encoding function (use UTF-8 as your encoding or install the iconv or mbstring extension).');
- }
-}
-
-if (\function_exists('mb_ord')) {
- function twig_ord($string)
- {
- return mb_ord($string, 'UTF-8');
- }
-} else {
- function twig_ord($string)
- {
- $code = ($string = unpack('C*', substr($string, 0, 4))) ? $string[1] : 0;
- if (0xF0 <= $code) {
- return (($code - 0xF0) << 18) + (($string[2] - 0x80) << 12) + (($string[3] - 0x80) << 6) + $string[4] - 0x80;
- }
- if (0xE0 <= $code) {
- return (($code - 0xE0) << 12) + (($string[2] - 0x80) << 6) + $string[3] - 0x80;
- }
- if (0xC0 <= $code) {
- return (($code - 0xC0) << 6) + $string[2] - 0x80;
- }
-
- return $code;
- }
-}
-
-function _twig_escape_js_callback($matches)
-{
- $char = $matches[0];
-
- /*
- * A few characters have short escape sequences in JSON and JavaScript.
- * Escape sequences supported only by JavaScript, not JSON, are ommitted.
- * \" is also supported but omitted, because the resulting string is not HTML safe.
- */
- static $shortMap = [
- '\\' => '\\\\',
- '/' => '\\/',
- "\x08" => '\b',
- "\x0C" => '\f',
- "\x0A" => '\n',
- "\x0D" => '\r',
- "\x09" => '\t',
- ];
-
- if (isset($shortMap[$char])) {
- return $shortMap[$char];
- }
-
- // \uHHHH
- $char = twig_convert_encoding($char, 'UTF-16BE', 'UTF-8');
- $char = strtoupper(bin2hex($char));
-
- if (4 >= \strlen($char)) {
- return sprintf('\u%04s', $char);
- }
-
- return sprintf('\u%04s\u%04s', substr($char, 0, -4), substr($char, -4));
-}
-
-function _twig_escape_css_callback($matches)
-{
- $char = $matches[0];
-
- return sprintf('\\%X ', 1 === \strlen($char) ? \ord($char) : twig_ord($char));
-}
-
-/**
- * This function is adapted from code coming from Zend Framework.
- *
- * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (https://www.zend.com)
- * @license https://framework.zend.com/license/new-bsd New BSD License
- */
-function _twig_escape_html_attr_callback($matches)
-{
- $chr = $matches[0];
- $ord = \ord($chr);
-
- /*
- * The following replaces characters undefined in HTML with the
- * hex entity for the Unicode replacement character.
- */
- if (($ord <= 0x1f && "\t" != $chr && "\n" != $chr && "\r" != $chr) || ($ord >= 0x7f && $ord <= 0x9f)) {
- return '�';
- }
-
- /*
- * Check if the current character to escape has a name entity we should
- * replace it with while grabbing the hex value of the character.
- */
- if (1 == \strlen($chr)) {
- /*
- * While HTML supports far more named entities, the lowest common denominator
- * has become HTML5's XML Serialisation which is restricted to the those named
- * entities that XML supports. Using HTML entities would result in this error:
- * XML Parsing Error: undefined entity
- */
- static $entityMap = [
- 34 => '"', /* quotation mark */
- 38 => '&', /* ampersand */
- 60 => '<', /* less-than sign */
- 62 => '>', /* greater-than sign */
- ];
-
- if (isset($entityMap[$ord])) {
- return $entityMap[$ord];
- }
-
- return sprintf('%02X;', $ord);
- }
-
- /*
- * Per OWASP recommendations, we'll use hex entities for any other
- * characters where a named entity does not exist.
- */
- return sprintf('%04X;', twig_ord($chr));
-}
-
-// add multibyte extensions if possible
-if (\function_exists('mb_get_info')) {
- /**
- * Returns the length of a variable.
- *
- * @param mixed $thing A variable
- *
- * @return int The length of the value
- */
- function twig_length_filter(Environment $env, $thing)
- {
- if (null === $thing) {
- return 0;
- }
-
- if (is_scalar($thing)) {
- return mb_strlen($thing, $env->getCharset());
- }
-
- if ($thing instanceof \Countable || \is_array($thing) || $thing instanceof \SimpleXMLElement) {
- return \count($thing);
- }
-
- if ($thing instanceof \Traversable) {
- return iterator_count($thing);
- }
-
- if (\is_object($thing) && method_exists($thing, '__toString')) {
- return mb_strlen((string) $thing, $env->getCharset());
- }
-
- return 1;
- }
-
- /**
- * Converts a string to uppercase.
- *
- * @param string $string A string
- *
- * @return string The uppercased string
- */
- function twig_upper_filter(Environment $env, $string)
- {
- if (null !== $charset = $env->getCharset()) {
- return mb_strtoupper($string, $charset);
- }
-
- return strtoupper($string);
- }
-
- /**
- * Converts a string to lowercase.
- *
- * @param string $string A string
- *
- * @return string The lowercased string
- */
- function twig_lower_filter(Environment $env, $string)
- {
- if (null !== $charset = $env->getCharset()) {
- return mb_strtolower($string, $charset);
- }
-
- return strtolower($string);
- }
-
- /**
- * Returns a titlecased string.
- *
- * @param string $string A string
- *
- * @return string The titlecased string
- */
- function twig_title_string_filter(Environment $env, $string)
- {
- if (null !== $charset = $env->getCharset()) {
- return mb_convert_case($string, MB_CASE_TITLE, $charset);
- }
-
- return ucwords(strtolower($string));
- }
-
- /**
- * Returns a capitalized string.
- *
- * @param string $string A string
- *
- * @return string The capitalized string
- */
- function twig_capitalize_string_filter(Environment $env, $string)
- {
- if (null !== $charset = $env->getCharset()) {
- return mb_strtoupper(mb_substr($string, 0, 1, $charset), $charset).mb_strtolower(mb_substr($string, 1, mb_strlen($string, $charset), $charset), $charset);
- }
-
- return ucfirst(strtolower($string));
- }
-}
-// and byte fallback
-else {
- /**
- * Returns the length of a variable.
- *
- * @param mixed $thing A variable
- *
- * @return int The length of the value
- */
- function twig_length_filter(Environment $env, $thing)
- {
- if (null === $thing) {
- return 0;
- }
-
- if (is_scalar($thing)) {
- return \strlen($thing);
- }
-
- if ($thing instanceof \SimpleXMLElement) {
- return \count($thing);
- }
-
- if (\is_object($thing) && method_exists($thing, '__toString') && !$thing instanceof \Countable) {
- return \strlen((string) $thing);
- }
-
- if ($thing instanceof \Countable || \is_array($thing)) {
- return \count($thing);
- }
-
- if ($thing instanceof \IteratorAggregate) {
- return iterator_count($thing);
- }
-
- return 1;
- }
-
- /**
- * Returns a titlecased string.
- *
- * @param string $string A string
- *
- * @return string The titlecased string
- */
- function twig_title_string_filter(Environment $env, $string)
- {
- return ucwords(strtolower($string));
- }
-
- /**
- * Returns a capitalized string.
- *
- * @param string $string A string
- *
- * @return string The capitalized string
- */
- function twig_capitalize_string_filter(Environment $env, $string)
- {
- return ucfirst(strtolower($string));
- }
-}
-
-/**
- * @internal
- */
-function twig_ensure_traversable($seq)
-{
- if ($seq instanceof \Traversable || \is_array($seq)) {
- return $seq;
- }
-
- return [];
-}
-
-/**
- * @internal
- */
-function twig_to_array($seq, $preserveKeys = true)
-{
- if ($seq instanceof \Traversable) {
- return iterator_to_array($seq, $preserveKeys);
- }
-
- if (!\is_array($seq)) {
- return $seq;
- }
-
- return $preserveKeys ? $seq : array_values($seq);
-}
-
-/**
- * Checks if a variable is empty.
- *
- * {# evaluates to true if the foo variable is null, false, or the empty string #}
- * {% if foo is empty %}
- * {# ... #}
- * {% endif %}
- *
- * @param mixed $value A variable
- *
- * @return bool true if the value is empty, false otherwise
- */
-function twig_test_empty($value)
-{
- if ($value instanceof \Countable) {
- return 0 == \count($value);
- }
-
- if ($value instanceof \Traversable) {
- return !iterator_count($value);
- }
-
- if (\is_object($value) && method_exists($value, '__toString')) {
- return '' === (string) $value;
- }
-
- return '' === $value || false === $value || null === $value || [] === $value;
-}
-
-/**
- * Checks if a variable is traversable.
- *
- * {# evaluates to true if the foo variable is an array or a traversable object #}
- * {% if foo is iterable %}
- * {# ... #}
- * {% endif %}
- *
- * @param mixed $value A variable
- *
- * @return bool true if the value is traversable
- */
-function twig_test_iterable($value)
-{
- return $value instanceof \Traversable || \is_array($value);
-}
-
-/**
- * Renders a template.
- *
- * @param array $context
- * @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 $withContext
- * @param bool $ignoreMissing 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(Environment $env, $context, $template, $variables = [], $withContext = true, $ignoreMissing = false, $sandboxed = false)
-{
- $alreadySandboxed = false;
- $sandbox = null;
- if ($withContext) {
- $variables = array_merge($context, $variables);
- }
-
- if ($isSandboxed = $sandboxed && $env->hasExtension('\Twig\Extension\SandboxExtension')) {
- $sandbox = $env->getExtension('\Twig\Extension\SandboxExtension');
- if (!$alreadySandboxed = $sandbox->isSandboxed()) {
- $sandbox->enableSandbox();
- }
- }
-
- $loaded = null;
- try {
- $loaded = $env->resolveTemplate($template);
- } catch (LoaderError $e) {
- if (!$ignoreMissing) {
- if ($isSandboxed && !$alreadySandboxed) {
- $sandbox->disableSandbox();
- }
-
- throw $e;
- }
- } catch (\Throwable $e) {
- if ($isSandboxed && !$alreadySandboxed) {
- $sandbox->disableSandbox();
- }
-
- throw $e;
- } catch (\Exception $e) {
- if ($isSandboxed && !$alreadySandboxed) {
- $sandbox->disableSandbox();
- }
-
- throw $e;
- }
-
- try {
- $ret = $loaded ? $loaded->render($variables) : '';
- } catch (\Exception $e) {
- if ($isSandboxed && !$alreadySandboxed) {
- $sandbox->disableSandbox();
- }
-
- throw $e;
- }
-
- if ($isSandboxed && !$alreadySandboxed) {
- $sandbox->disableSandbox();
- }
-
- return $ret;
-}
-
-/**
- * Returns a template content without rendering it.
- *
- * @param string $name The template name
- * @param bool $ignoreMissing Whether to ignore missing templates or not
- *
- * @return string The template source
- */
-function twig_source(Environment $env, $name, $ignoreMissing = false)
-{
- $loader = $env->getLoader();
- try {
- if (!$loader instanceof SourceContextLoaderInterface) {
- return $loader->getSource($name);
- } else {
- return $loader->getSourceContext($name)->getCode();
- }
- } catch (LoaderError $e) {
- if (!$ignoreMissing) {
- throw $e;
- }
- }
-}
-
-/**
- * Provides the ability to get constants from instances as well as class/global constants.
- *
- * @param string $constant The name of the constant
- * @param object|null $object The object to get the constant from
- *
- * @return string
- */
-function twig_constant($constant, $object = null)
-{
- if (null !== $object) {
- $constant = \get_class($object).'::'.$constant;
- }
-
- return \constant($constant);
-}
-
-/**
- * Checks if a constant exists.
- *
- * @param string $constant The name of the constant
- * @param object|null $object The object to get the constant from
- *
- * @return bool
- */
-function twig_constant_is_defined($constant, $object = null)
-{
- if (null !== $object) {
- $constant = \get_class($object).'::'.$constant;
- }
-
- return \defined($constant);
-}
-
-/**
- * Batches item.
- *
- * @param array $items An array of items
- * @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, $preserveKeys = true)
-{
- if (!twig_test_iterable($items)) {
- throw new RuntimeError(sprintf('The "batch" filter expects an array or "Traversable", got "%s".', \is_object($items) ? \get_class($items) : \gettype($items)));
- }
-
- $size = ceil($size);
-
- $result = array_chunk(twig_to_array($items, $preserveKeys), $size, $preserveKeys);
-
- if (null !== $fill && $result) {
- $last = \count($result) - 1;
- if ($fillCount = $size - \count($result[$last])) {
- for ($i = 0; $i < $fillCount; ++$i) {
- $result[$last][] = $fill;
- }
- }
- }
-
- return $result;
-}
-
-function twig_array_filter($array, $arrow)
-{
- if (\is_array($array)) {
- if (\PHP_VERSION_ID >= 50600) {
- return array_filter($array, $arrow, \ARRAY_FILTER_USE_BOTH);
- }
-
- return array_filter($array, $arrow);
- }
-
- // the IteratorIterator wrapping is needed as some internal PHP classes are \Traversable but do not implement \Iterator
- return new \CallbackFilterIterator(new \IteratorIterator($array), $arrow);
-}
-
-function twig_array_map($array, $arrow)
-{
- $r = [];
- foreach ($array as $k => $v) {
- $r[$k] = $arrow($v, $k);
- }
-
- return $r;
-}
-
-function twig_array_reduce($array, $arrow, $initial = null)
-{
- if (!\is_array($array)) {
- $array = iterator_to_array($array);
- }
-
- return array_reduce($array, $arrow, $initial);
-}
-}
diff --git a/system/templateEngines/Twig/Twig1x/twig/twig/src/Extension/DebugExtension.php b/system/templateEngines/Twig/Twig1x/twig/twig/src/Extension/DebugExtension.php
deleted file mode 100644
index 09b0223..0000000
--- a/system/templateEngines/Twig/Twig1x/twig/twig/src/Extension/DebugExtension.php
+++ /dev/null
@@ -1,76 +0,0 @@
- $isDumpOutputHtmlSafe ? ['html'] : [], 'needs_context' => true, 'needs_environment' => true, 'is_variadic' => true]),
- ];
- }
-
- public function getName()
- {
- return 'debug';
- }
-}
-
-class_alias('Twig\Extension\DebugExtension', 'Twig_Extension_Debug');
-}
-
-namespace {
-use Twig\Environment;
-use Twig\Template;
-use Twig\TemplateWrapper;
-
-function twig_var_dump(Environment $env, $context, array $vars = [])
-{
- if (!$env->isDebug()) {
- return;
- }
-
- ob_start();
-
- if (!$vars) {
- $vars = [];
- foreach ($context as $key => $value) {
- if (!$value instanceof Template && !$value instanceof TemplateWrapper) {
- $vars[$key] = $value;
- }
- }
-
- var_dump($vars);
- } else {
- foreach ($vars as $var) {
- var_dump($var);
- }
- }
-
- return ob_get_clean();
-}
-}
diff --git a/system/templateEngines/Twig/Twig1x/twig/twig/src/Lexer.php b/system/templateEngines/Twig/Twig1x/twig/twig/src/Lexer.php
deleted file mode 100644
index 697a6cf..0000000
--- a/system/templateEngines/Twig/Twig1x/twig/twig/src/Lexer.php
+++ /dev/null
@@ -1,534 +0,0 @@
-
- */
-class Lexer implements \Twig_LexerInterface
-{
- protected $tokens;
- protected $code;
- protected $cursor;
- protected $lineno;
- protected $end;
- protected $state;
- protected $states;
- protected $brackets;
- protected $env;
- // to be renamed to $name in 2.0 (where it is private)
- protected $filename;
- protected $options;
- protected $regexes;
- protected $position;
- protected $positions;
- protected $currentVarBlockLine;
-
- private $source;
-
- const STATE_DATA = 0;
- const STATE_BLOCK = 1;
- const STATE_VAR = 2;
- const STATE_STRING = 3;
- const STATE_INTERPOLATION = 4;
-
- const REGEX_NAME = '/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/A';
- const REGEX_NUMBER = '/[0-9]+(?:\.[0-9]+)?([Ee][\+\-][0-9]+)?/A';
- const REGEX_STRING = '/"([^#"\\\\]*(?:\\\\.[^#"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\'/As';
- const REGEX_DQ_STRING_DELIM = '/"/A';
- const REGEX_DQ_STRING_PART = '/[^#"\\\\]*(?:(?:\\\\.|#(?!\{))[^#"\\\\]*)*/As';
- const PUNCTUATION = '()[]{}?:.,|';
-
- public function __construct(Environment $env, array $options = [])
- {
- $this->env = $env;
-
- $this->options = array_merge([
- 'tag_comment' => ['{#', '#}'],
- 'tag_block' => ['{%', '%}'],
- 'tag_variable' => ['{{', '}}'],
- 'whitespace_trim' => '-',
- 'whitespace_line_trim' => '~',
- 'whitespace_line_chars' => ' \t\0\x0B',
- 'interpolation' => ['#{', '}'],
- ], $options);
-
- // when PHP 7.3 is the min version, we will be able to remove the '#' part in preg_quote as it's part of the default
- $this->regexes = [
- // }}
- 'lex_var' => '{
- \s*
- (?:'.
- preg_quote($this->options['whitespace_trim'].$this->options['tag_variable'][1], '#').'\s*'. // -}}\s*
- '|'.
- preg_quote($this->options['whitespace_line_trim'].$this->options['tag_variable'][1], '#').'['.$this->options['whitespace_line_chars'].']*'. // ~}}[ \t\0\x0B]*
- '|'.
- preg_quote($this->options['tag_variable'][1], '#'). // }}
- ')
- }Ax',
-
- // %}
- 'lex_block' => '{
- \s*
- (?:'.
- preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '#').'\s*\n?'. // -%}\s*\n?
- '|'.
- preg_quote($this->options['whitespace_line_trim'].$this->options['tag_block'][1], '#').'['.$this->options['whitespace_line_chars'].']*'. // ~%}[ \t\0\x0B]*
- '|'.
- preg_quote($this->options['tag_block'][1], '#').'\n?'. // %}\n?
- ')
- }Ax',
-
- // {% endverbatim %}
- 'lex_raw_data' => '{'.
- preg_quote($this->options['tag_block'][0], '#'). // {%
- '('.
- $this->options['whitespace_trim']. // -
- '|'.
- $this->options['whitespace_line_trim']. // ~
- ')?\s*'.
- '(?:end%s)'. // endraw or endverbatim
- '\s*'.
- '(?:'.
- preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '#').'\s*'. // -%}
- '|'.
- preg_quote($this->options['whitespace_line_trim'].$this->options['tag_block'][1], '#').'['.$this->options['whitespace_line_chars'].']*'. // ~%}[ \t\0\x0B]*
- '|'.
- preg_quote($this->options['tag_block'][1], '#'). // %}
- ')
- }sx',
-
- 'operator' => $this->getOperatorRegex(),
-
- // #}
- 'lex_comment' => '{
- (?:'.
- preg_quote($this->options['whitespace_trim']).preg_quote($this->options['tag_comment'][1], '#').'\s*\n?'. // -#}\s*\n?
- '|'.
- preg_quote($this->options['whitespace_line_trim'].$this->options['tag_comment'][1], '#').'['.$this->options['whitespace_line_chars'].']*'. // ~#}[ \t\0\x0B]*
- '|'.
- preg_quote($this->options['tag_comment'][1], '#').'\n?'. // #}\n?
- ')
- }sx',
-
- // verbatim %}
- 'lex_block_raw' => '{
- \s*
- (raw|verbatim)
- \s*
- (?:'.
- preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '#').'\s*'. // -%}\s*
- '|'.
- preg_quote($this->options['whitespace_line_trim'].$this->options['tag_block'][1], '#').'['.$this->options['whitespace_line_chars'].']*'. // ~%}[ \t\0\x0B]*
- '|'.
- preg_quote($this->options['tag_block'][1], '#'). // %}
- ')
- }Asx',
-
- 'lex_block_line' => '{\s*line\s+(\d+)\s*'.preg_quote($this->options['tag_block'][1], '#').'}As',
-
- // {{ or {% or {#
- 'lex_tokens_start' => '{
- ('.
- preg_quote($this->options['tag_variable'][0], '#'). // {{
- '|'.
- preg_quote($this->options['tag_block'][0], '#'). // {%
- '|'.
- preg_quote($this->options['tag_comment'][0], '#'). // {#
- ')('.
- preg_quote($this->options['whitespace_trim'], '#'). // -
- '|'.
- preg_quote($this->options['whitespace_line_trim'], '#'). // ~
- ')?
- }sx',
- 'interpolation_start' => '{'.preg_quote($this->options['interpolation'][0], '#').'\s*}A',
- 'interpolation_end' => '{\s*'.preg_quote($this->options['interpolation'][1], '#').'}A',
- ];
- }
-
- public function tokenize($code, $name = null)
- {
- if (!$code instanceof Source) {
- @trigger_error(sprintf('Passing a string as the $code argument of %s() is deprecated since version 1.27 and will be removed in 2.0. Pass a \Twig\Source instance instead.', __METHOD__), E_USER_DEPRECATED);
- $this->source = new Source($code, $name);
- } else {
- $this->source = $code;
- }
-
- if (((int) ini_get('mbstring.func_overload')) & 2) {
- @trigger_error('Support for having "mbstring.func_overload" different from 0 is deprecated version 1.29 and will be removed in 2.0.', E_USER_DEPRECATED);
- }
-
- 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(["\r\n", "\r"], "\n", $this->source->getCode());
- $this->filename = $this->source->getName();
- $this->cursor = 0;
- $this->lineno = 1;
- $this->end = \strlen($this->code);
- $this->tokens = [];
- $this->state = self::STATE_DATA;
- $this->states = [];
- $this->brackets = [];
- $this->position = -1;
-
- // find all token starts in one go
- preg_match_all($this->regexes['lex_tokens_start'], $this->code, $matches, PREG_OFFSET_CAPTURE);
- $this->positions = $matches;
-
- while ($this->cursor < $this->end) {
- // dispatch to the lexing functions depending
- // on the current state
- switch ($this->state) {
- case self::STATE_DATA:
- $this->lexData();
- break;
-
- case self::STATE_BLOCK:
- $this->lexBlock();
- break;
-
- case self::STATE_VAR:
- $this->lexVar();
- break;
-
- case self::STATE_STRING:
- $this->lexString();
- break;
-
- case self::STATE_INTERPOLATION:
- $this->lexInterpolation();
- break;
- }
- }
-
- $this->pushToken(Token::EOF_TYPE);
-
- if (!empty($this->brackets)) {
- list($expect, $lineno) = array_pop($this->brackets);
- throw new SyntaxError(sprintf('Unclosed "%s".', $expect), $lineno, $this->source);
- }
-
- if ($mbEncoding) {
- mb_internal_encoding($mbEncoding);
- }
-
- return new TokenStream($this->tokens, $this->source);
- }
-
- protected function lexData()
- {
- // if no matches are left we return the rest of the template as simple text token
- if ($this->position == \count($this->positions[0]) - 1) {
- $this->pushToken(Token::TEXT_TYPE, substr($this->code, $this->cursor));
- $this->cursor = $this->end;
-
- return;
- }
-
- // Find the first token after the current cursor
- $position = $this->positions[0][++$this->position];
- while ($position[1] < $this->cursor) {
- if ($this->position == \count($this->positions[0]) - 1) {
- return;
- }
- $position = $this->positions[0][++$this->position];
- }
-
- // push the template text first
- $text = $textContent = substr($this->code, $this->cursor, $position[1] - $this->cursor);
-
- // trim?
- if (isset($this->positions[2][$this->position][0])) {
- if ($this->options['whitespace_trim'] === $this->positions[2][$this->position][0]) {
- // whitespace_trim detected ({%-, {{- or {#-)
- $text = rtrim($text);
- } elseif ($this->options['whitespace_line_trim'] === $this->positions[2][$this->position][0]) {
- // whitespace_line_trim detected ({%~, {{~ or {#~)
- // don't trim \r and \n
- $text = rtrim($text, " \t\0\x0B");
- }
- }
- $this->pushToken(Token::TEXT_TYPE, $text);
- $this->moveCursor($textContent.$position[0]);
-
- switch ($this->positions[1][$this->position][0]) {
- case $this->options['tag_comment'][0]:
- $this->lexComment();
- break;
-
- case $this->options['tag_block'][0]:
- // raw data?
- if (preg_match($this->regexes['lex_block_raw'], $this->code, $match, 0, $this->cursor)) {
- $this->moveCursor($match[0]);
- $this->lexRawData($match[1]);
- // {% line \d+ %}
- } elseif (preg_match($this->regexes['lex_block_line'], $this->code, $match, 0, $this->cursor)) {
- $this->moveCursor($match[0]);
- $this->lineno = (int) $match[1];
- } else {
- $this->pushToken(Token::BLOCK_START_TYPE);
- $this->pushState(self::STATE_BLOCK);
- $this->currentVarBlockLine = $this->lineno;
- }
- break;
-
- case $this->options['tag_variable'][0]:
- $this->pushToken(Token::VAR_START_TYPE);
- $this->pushState(self::STATE_VAR);
- $this->currentVarBlockLine = $this->lineno;
- break;
- }
- }
-
- protected function lexBlock()
- {
- if (empty($this->brackets) && preg_match($this->regexes['lex_block'], $this->code, $match, 0, $this->cursor)) {
- $this->pushToken(Token::BLOCK_END_TYPE);
- $this->moveCursor($match[0]);
- $this->popState();
- } else {
- $this->lexExpression();
- }
- }
-
- protected function lexVar()
- {
- if (empty($this->brackets) && preg_match($this->regexes['lex_var'], $this->code, $match, 0, $this->cursor)) {
- $this->pushToken(Token::VAR_END_TYPE);
- $this->moveCursor($match[0]);
- $this->popState();
- } else {
- $this->lexExpression();
- }
- }
-
- protected function lexExpression()
- {
- // whitespace
- if (preg_match('/\s+/A', $this->code, $match, 0, $this->cursor)) {
- $this->moveCursor($match[0]);
-
- if ($this->cursor >= $this->end) {
- throw new SyntaxError(sprintf('Unclosed "%s".', self::STATE_BLOCK === $this->state ? 'block' : 'variable'), $this->currentVarBlockLine, $this->source);
- }
- }
-
- // arrow function
- if ('=' === $this->code[$this->cursor] && '>' === $this->code[$this->cursor + 1]) {
- $this->pushToken(Token::ARROW_TYPE, '=>');
- $this->moveCursor('=>');
- }
- // operators
- elseif (preg_match($this->regexes['operator'], $this->code, $match, 0, $this->cursor)) {
- $this->pushToken(Token::OPERATOR_TYPE, preg_replace('/\s+/', ' ', $match[0]));
- $this->moveCursor($match[0]);
- }
- // names
- elseif (preg_match(self::REGEX_NAME, $this->code, $match, 0, $this->cursor)) {
- $this->pushToken(Token::NAME_TYPE, $match[0]);
- $this->moveCursor($match[0]);
- }
- // numbers
- elseif (preg_match(self::REGEX_NUMBER, $this->code, $match, 0, $this->cursor)) {
- $number = (float) $match[0]; // floats
- if (ctype_digit($match[0]) && $number <= PHP_INT_MAX) {
- $number = (int) $match[0]; // integers lower than the maximum
- }
- $this->pushToken(Token::NUMBER_TYPE, $number);
- $this->moveCursor($match[0]);
- }
- // punctuation
- elseif (false !== strpos(self::PUNCTUATION, $this->code[$this->cursor])) {
- // opening bracket
- if (false !== strpos('([{', $this->code[$this->cursor])) {
- $this->brackets[] = [$this->code[$this->cursor], $this->lineno];
- }
- // closing bracket
- elseif (false !== strpos(')]}', $this->code[$this->cursor])) {
- if (empty($this->brackets)) {
- throw new SyntaxError(sprintf('Unexpected "%s".', $this->code[$this->cursor]), $this->lineno, $this->source);
- }
-
- list($expect, $lineno) = array_pop($this->brackets);
- if ($this->code[$this->cursor] != strtr($expect, '([{', ')]}')) {
- throw new SyntaxError(sprintf('Unclosed "%s".', $expect), $lineno, $this->source);
- }
- }
-
- $this->pushToken(Token::PUNCTUATION_TYPE, $this->code[$this->cursor]);
- ++$this->cursor;
- }
- // strings
- elseif (preg_match(self::REGEX_STRING, $this->code, $match, 0, $this->cursor)) {
- $this->pushToken(Token::STRING_TYPE, stripcslashes(substr($match[0], 1, -1)));
- $this->moveCursor($match[0]);
- }
- // opening double quoted string
- elseif (preg_match(self::REGEX_DQ_STRING_DELIM, $this->code, $match, 0, $this->cursor)) {
- $this->brackets[] = ['"', $this->lineno];
- $this->pushState(self::STATE_STRING);
- $this->moveCursor($match[0]);
- }
- // unlexable
- else {
- throw new SyntaxError(sprintf('Unexpected character "%s".', $this->code[$this->cursor]), $this->lineno, $this->source);
- }
- }
-
- protected function lexRawData($tag)
- {
- if ('raw' === $tag) {
- @trigger_error(sprintf('Twig Tag "raw" is deprecated since version 1.21. Use "verbatim" instead in %s at line %d.', $this->filename, $this->lineno), E_USER_DEPRECATED);
- }
-
- if (!preg_match(str_replace('%s', $tag, $this->regexes['lex_raw_data']), $this->code, $match, PREG_OFFSET_CAPTURE, $this->cursor)) {
- throw new SyntaxError(sprintf('Unexpected end of file: Unclosed "%s" block.', $tag), $this->lineno, $this->source);
- }
-
- $text = substr($this->code, $this->cursor, $match[0][1] - $this->cursor);
- $this->moveCursor($text.$match[0][0]);
-
- // trim?
- if (isset($match[1][0])) {
- if ($this->options['whitespace_trim'] === $match[1][0]) {
- // whitespace_trim detected ({%-, {{- or {#-)
- $text = rtrim($text);
- } else {
- // whitespace_line_trim detected ({%~, {{~ or {#~)
- // don't trim \r and \n
- $text = rtrim($text, " \t\0\x0B");
- }
- }
-
- $this->pushToken(Token::TEXT_TYPE, $text);
- }
-
- protected function lexComment()
- {
- if (!preg_match($this->regexes['lex_comment'], $this->code, $match, PREG_OFFSET_CAPTURE, $this->cursor)) {
- throw new SyntaxError('Unclosed comment.', $this->lineno, $this->source);
- }
-
- $this->moveCursor(substr($this->code, $this->cursor, $match[0][1] - $this->cursor).$match[0][0]);
- }
-
- protected function lexString()
- {
- if (preg_match($this->regexes['interpolation_start'], $this->code, $match, 0, $this->cursor)) {
- $this->brackets[] = [$this->options['interpolation'][0], $this->lineno];
- $this->pushToken(Token::INTERPOLATION_START_TYPE);
- $this->moveCursor($match[0]);
- $this->pushState(self::STATE_INTERPOLATION);
- } elseif (preg_match(self::REGEX_DQ_STRING_PART, $this->code, $match, 0, $this->cursor) && \strlen($match[0]) > 0) {
- $this->pushToken(Token::STRING_TYPE, stripcslashes($match[0]));
- $this->moveCursor($match[0]);
- } elseif (preg_match(self::REGEX_DQ_STRING_DELIM, $this->code, $match, 0, $this->cursor)) {
- list($expect, $lineno) = array_pop($this->brackets);
- if ('"' != $this->code[$this->cursor]) {
- throw new SyntaxError(sprintf('Unclosed "%s".', $expect), $lineno, $this->source);
- }
-
- $this->popState();
- ++$this->cursor;
- } else {
- // unlexable
- throw new SyntaxError(sprintf('Unexpected character "%s".', $this->code[$this->cursor]), $this->lineno, $this->source);
- }
- }
-
- protected function lexInterpolation()
- {
- $bracket = end($this->brackets);
- if ($this->options['interpolation'][0] === $bracket[0] && preg_match($this->regexes['interpolation_end'], $this->code, $match, 0, $this->cursor)) {
- array_pop($this->brackets);
- $this->pushToken(Token::INTERPOLATION_END_TYPE);
- $this->moveCursor($match[0]);
- $this->popState();
- } else {
- $this->lexExpression();
- }
- }
-
- protected function pushToken($type, $value = '')
- {
- // do not push empty text tokens
- if (Token::TEXT_TYPE === $type && '' === $value) {
- return;
- }
-
- $this->tokens[] = new Token($type, $value, $this->lineno);
- }
-
- protected function moveCursor($text)
- {
- $this->cursor += \strlen($text);
- $this->lineno += substr_count($text, "\n");
- }
-
- protected function getOperatorRegex()
- {
- $operators = array_merge(
- ['='],
- array_keys($this->env->getUnaryOperators()),
- array_keys($this->env->getBinaryOperators())
- );
-
- $operators = array_combine($operators, array_map('strlen', $operators));
- arsort($operators);
-
- $regex = [];
- foreach ($operators as $operator => $length) {
- // an operator that ends with a character must be followed by
- // a whitespace or a parenthesis
- if (ctype_alpha($operator[$length - 1])) {
- $r = preg_quote($operator, '/').'(?=[\s()])';
- } else {
- $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';
- }
-
- protected function pushState($state)
- {
- $this->states[] = $this->state;
- $this->state = $state;
- }
-
- protected function popState()
- {
- if (0 === \count($this->states)) {
- throw new \LogicException('Cannot pop state without a previous state.');
- }
-
- $this->state = array_pop($this->states);
- }
-}
-
-class_alias('Twig\Lexer', 'Twig_Lexer');
diff --git a/system/templateEngines/Twig/Twig1x/twig/twig/src/Loader/FilesystemLoader.php b/system/templateEngines/Twig/Twig1x/twig/twig/src/Loader/FilesystemLoader.php
deleted file mode 100644
index 19b43a2..0000000
--- a/system/templateEngines/Twig/Twig1x/twig/twig/src/Loader/FilesystemLoader.php
+++ /dev/null
@@ -1,323 +0,0 @@
-
- */
-class FilesystemLoader implements LoaderInterface, ExistsLoaderInterface, SourceContextLoaderInterface
-{
- /** Identifier of the main namespace. */
- const MAIN_NAMESPACE = '__main__';
-
- protected $paths = [];
- protected $cache = [];
- protected $errorCache = [];
-
- private $rootPath;
-
- /**
- * @param string|array $paths A path or an array of paths where to look for templates
- * @param string|null $rootPath The root path common to all relative paths (null for getcwd())
- */
- public function __construct($paths = [], $rootPath = null)
- {
- $this->rootPath = (null === $rootPath ? getcwd() : $rootPath).\DIRECTORY_SEPARATOR;
- if (false !== $realPath = realpath($rootPath)) {
- $this->rootPath = $realPath.\DIRECTORY_SEPARATOR;
- }
-
- if ($paths) {
- $this->setPaths($paths);
- }
- }
-
- /**
- * Returns the paths to the templates.
- *
- * @param string $namespace A path namespace
- *
- * @return array The array of paths where to look for templates
- */
- public function getPaths($namespace = self::MAIN_NAMESPACE)
- {
- return isset($this->paths[$namespace]) ? $this->paths[$namespace] : [];
- }
-
- /**
- * Returns the path namespaces.
- *
- * The main namespace is always defined.
- *
- * @return array The array of defined namespaces
- */
- public function getNamespaces()
- {
- return array_keys($this->paths);
- }
-
- /**
- * Sets the paths where templates are stored.
- *
- * @param string|array $paths A path or an array of paths where to look for templates
- * @param string $namespace A path namespace
- */
- public function setPaths($paths, $namespace = self::MAIN_NAMESPACE)
- {
- if (!\is_array($paths)) {
- $paths = [$paths];
- }
-
- $this->paths[$namespace] = [];
- foreach ($paths as $path) {
- $this->addPath($path, $namespace);
- }
- }
-
- /**
- * Adds a path where templates are stored.
- *
- * @param string $path A path where to look for templates
- * @param string $namespace A path namespace
- *
- * @throws LoaderError
- */
- public function addPath($path, $namespace = self::MAIN_NAMESPACE)
- {
- // invalidate the cache
- $this->cache = $this->errorCache = [];
-
- $checkPath = $this->isAbsolutePath($path) ? $path : $this->rootPath.$path;
- if (!is_dir($checkPath)) {
- throw new LoaderError(sprintf('The "%s" directory does not exist ("%s").', $path, $checkPath));
- }
-
- $this->paths[$namespace][] = rtrim($path, '/\\');
- }
-
- /**
- * Prepends a path where templates are stored.
- *
- * @param string $path A path where to look for templates
- * @param string $namespace A path namespace
- *
- * @throws LoaderError
- */
- public function prependPath($path, $namespace = self::MAIN_NAMESPACE)
- {
- // invalidate the cache
- $this->cache = $this->errorCache = [];
-
- $checkPath = $this->isAbsolutePath($path) ? $path : $this->rootPath.$path;
- if (!is_dir($checkPath)) {
- throw new LoaderError(sprintf('The "%s" directory does not exist ("%s").', $path, $checkPath));
- }
-
- $path = rtrim($path, '/\\');
-
- if (!isset($this->paths[$namespace])) {
- $this->paths[$namespace][] = $path;
- } else {
- array_unshift($this->paths[$namespace], $path);
- }
- }
-
- public function getSource($name)
- {
- @trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', \get_class($this)), E_USER_DEPRECATED);
-
- if (null === ($path = $this->findTemplate($name)) || false === $path) {
- return '';
- }
-
- return file_get_contents($path);
- }
-
- public function getSourceContext($name)
- {
- if (null === ($path = $this->findTemplate($name)) || false === $path) {
- return new Source('', $name, '');
- }
-
- return new Source(file_get_contents($path), $name, $path);
- }
-
- public function getCacheKey($name)
- {
- if (null === ($path = $this->findTemplate($name)) || false === $path) {
- return '';
- }
- $len = \strlen($this->rootPath);
- if (0 === strncmp($this->rootPath, $path, $len)) {
- return substr($path, $len);
- }
-
- return $path;
- }
-
- public function exists($name)
- {
- $name = $this->normalizeName($name);
-
- if (isset($this->cache[$name])) {
- return true;
- }
-
- try {
- return null !== ($path = $this->findTemplate($name, false)) && false !== $path;
- } catch (LoaderError $e) {
- @trigger_error(sprintf('In %s::findTemplate(), you must accept a second argument that when set to "false" returns "false" instead of throwing an exception. Not supporting this argument is deprecated since version 1.27.', \get_class($this)), E_USER_DEPRECATED);
-
- return false;
- }
- }
-
- public function isFresh($name, $time)
- {
- // false support to be removed in 3.0
- if (null === ($path = $this->findTemplate($name)) || false === $path) {
- return false;
- }
-
- return filemtime($path) < $time;
- }
-
- /**
- * Checks if the template can be found.
- *
- * @param string $name The template name
- *
- * @return string|false|null The template name or false/null
- */
- protected function findTemplate($name)
- {
- $throw = \func_num_args() > 1 ? func_get_arg(1) : true;
- $name = $this->normalizeName($name);
-
- if (isset($this->cache[$name])) {
- return $this->cache[$name];
- }
-
- if (isset($this->errorCache[$name])) {
- if (!$throw) {
- return false;
- }
-
- throw new LoaderError($this->errorCache[$name]);
- }
-
- try {
- $this->validateName($name);
-
- list($namespace, $shortname) = $this->parseName($name);
- } catch (LoaderError $e) {
- if (!$throw) {
- return false;
- }
-
- throw $e;
- }
-
- if (!isset($this->paths[$namespace])) {
- $this->errorCache[$name] = sprintf('There are no registered paths for namespace "%s".', $namespace);
-
- if (!$throw) {
- return false;
- }
-
- throw new LoaderError($this->errorCache[$name]);
- }
-
- foreach ($this->paths[$namespace] as $path) {
- if (!$this->isAbsolutePath($path)) {
- $path = $this->rootPath.$path;
- }
-
- if (is_file($path.'/'.$shortname)) {
- if (false !== $realpath = realpath($path.'/'.$shortname)) {
- return $this->cache[$name] = $realpath;
- }
-
- return $this->cache[$name] = $path.'/'.$shortname;
- }
- }
-
- $this->errorCache[$name] = sprintf('Unable to find template "%s" (looked into: %s).', $name, implode(', ', $this->paths[$namespace]));
-
- if (!$throw) {
- return false;
- }
-
- throw new LoaderError($this->errorCache[$name]);
- }
-
- protected function parseName($name, $default = self::MAIN_NAMESPACE)
- {
- if (isset($name[0]) && '@' == $name[0]) {
- if (false === $pos = strpos($name, '/')) {
- throw new LoaderError(sprintf('Malformed namespaced template name "%s" (expecting "@namespace/template_name").', $name));
- }
-
- $namespace = substr($name, 1, $pos - 1);
- $shortname = substr($name, $pos + 1);
-
- return [$namespace, $shortname];
- }
-
- return [$default, $name];
- }
-
- protected function normalizeName($name)
- {
- return preg_replace('#/{2,}#', '/', str_replace('\\', '/', (string) $name));
- }
-
- protected function validateName($name)
- {
- if (false !== strpos($name, "\0")) {
- throw new LoaderError('A template name cannot contain NUL bytes.');
- }
-
- $name = ltrim($name, '/');
- $parts = explode('/', $name);
- $level = 0;
- foreach ($parts as $part) {
- if ('..' === $part) {
- --$level;
- } elseif ('.' !== $part) {
- ++$level;
- }
-
- if ($level < 0) {
- throw new LoaderError(sprintf('Looks like you try to load a template outside configured directories (%s).', $name));
- }
- }
- }
-
- private function isAbsolutePath($file)
- {
- return strspn($file, '/\\', 0, 1)
- || (\strlen($file) > 3 && ctype_alpha($file[0])
- && ':' === substr($file, 1, 1)
- && strspn($file, '/\\', 2, 1)
- )
- || null !== parse_url($file, PHP_URL_SCHEME)
- ;
- }
-}
-
-class_alias('Twig\Loader\FilesystemLoader', 'Twig_Loader_Filesystem');
diff --git a/system/templateEngines/Twig/Twig1x/twig/twig/src/Node/Expression/NullCoalesceExpression.php b/system/templateEngines/Twig/Twig1x/twig/twig/src/Node/Expression/NullCoalesceExpression.php
deleted file mode 100644
index 917d31a..0000000
--- a/system/templateEngines/Twig/Twig1x/twig/twig/src/Node/Expression/NullCoalesceExpression.php
+++ /dev/null
@@ -1,62 +0,0 @@
-getTemplateLine());
- // for "block()", we don't need the null test as the return value is always a string
- if (!$left instanceof BlockReferenceExpression) {
- $test = new AndBinary(
- $test,
- new NotUnary(new NullTest($left, 'null', new Node(), $left->getTemplateLine()), $left->getTemplateLine()),
- $left->getTemplateLine()
- );
- }
-
- parent::__construct($test, $left, $right, $lineno);
- }
-
- public function compile(Compiler $compiler)
- {
- /*
- * This optimizes only one case. PHP 7 also supports more complex expressions
- * that can return null. So, for instance, if log is defined, log("foo") ?? "..." works,
- * but log($a["foo"]) ?? "..." does not if $a["foo"] is not defined. More advanced
- * cases might be implemented as an optimizer node visitor, but has not been done
- * as benefits are probably not worth the added complexity.
- */
- if (\PHP_VERSION_ID >= 70000 && $this->getNode('expr2') instanceof NameExpression) {
- $this->getNode('expr2')->setAttribute('always_defined', true);
- $compiler
- ->raw('((')
- ->subcompile($this->getNode('expr2'))
- ->raw(') ?? (')
- ->subcompile($this->getNode('expr3'))
- ->raw('))')
- ;
- } else {
- parent::compile($compiler);
- }
- }
-}
-
-class_alias('Twig\Node\Expression\NullCoalesceExpression', 'Twig_Node_Expression_NullCoalesce');
diff --git a/system/templateEngines/Twig/Twig1x/twig/twig/src/Node/MacroNode.php b/system/templateEngines/Twig/Twig1x/twig/twig/src/Node/MacroNode.php
deleted file mode 100644
index 6eb6795..0000000
--- a/system/templateEngines/Twig/Twig1x/twig/twig/src/Node/MacroNode.php
+++ /dev/null
@@ -1,136 +0,0 @@
-
- */
-class MacroNode extends Node
-{
- const VARARGS_NAME = 'varargs';
-
- public function __construct($name, \Twig_NodeInterface $body, \Twig_NodeInterface $arguments, $lineno, $tag = null)
- {
- foreach ($arguments as $argumentName => $argument) {
- if (self::VARARGS_NAME === $argumentName) {
- throw new SyntaxError(sprintf('The argument "%s" in macro "%s" cannot be defined because the variable "%s" is reserved for arbitrary arguments.', self::VARARGS_NAME, $name, self::VARARGS_NAME), $argument->getTemplateLine(), $argument->getSourceContext());
- }
- }
-
- parent::__construct(['body' => $body, 'arguments' => $arguments], ['name' => $name], $lineno, $tag);
- }
-
- public function compile(Compiler $compiler)
- {
- $compiler
- ->addDebugInfo($this)
- ->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.'__ = ')
- ->subcompile($default)
- ;
-
- if (++$pos < $count) {
- $compiler->raw(', ');
- }
- }
-
- if (\PHP_VERSION_ID >= 50600) {
- if ($count) {
- $compiler->raw(', ');
- }
-
- $compiler->raw('...$__varargs__');
- }
-
- $compiler
- ->raw(")\n")
- ->write("{\n")
- ->indent()
- ;
-
- $compiler
- ->write("\$context = \$this->env->mergeGlobals([\n")
- ->indent()
- ;
-
- foreach ($this->getNode('arguments') as $name => $default) {
- $compiler
- ->write('')
- ->string($name)
- ->raw(' => $__'.$name.'__')
- ->raw(",\n")
- ;
- }
-
- $compiler
- ->write('')
- ->string(self::VARARGS_NAME)
- ->raw(' => ')
- ;
-
- if (\PHP_VERSION_ID >= 50600) {
- $compiler->raw("\$__varargs__,\n");
- } else {
- $compiler
- ->raw('func_num_args() > ')
- ->repr($count)
- ->raw(' ? array_slice(func_get_args(), ')
- ->repr($count)
- ->raw(") : [],\n")
- ;
- }
-
- $compiler
- ->outdent()
- ->write("]);\n\n")
- ->write("\$blocks = [];\n\n")
- ;
- if ($compiler->getEnvironment()->isDebug()) {
- $compiler->write("ob_start();\n");
- } else {
- $compiler->write("ob_start(function () { return ''; });\n");
- }
- $compiler
- ->write("try {\n")
- ->indent()
- ->subcompile($this->getNode('body'))
- ->outdent()
- ->write("} catch (\Exception \$e) {\n")
- ->indent()
- ->write("ob_end_clean();\n\n")
- ->write("throw \$e;\n")
- ->outdent()
- ->write("} catch (\Throwable \$e) {\n")
- ->indent()
- ->write("ob_end_clean();\n\n")
- ->write("throw \$e;\n")
- ->outdent()
- ->write("}\n\n")
- ->write("return ('' === \$tmp = ob_get_clean()) ? '' : new Markup(\$tmp, \$this->env->getCharset());\n")
- ->outdent()
- ->write("}\n\n")
- ;
- }
-}
-
-class_alias('Twig\Node\MacroNode', 'Twig_Node_Macro');
diff --git a/system/templateEngines/Twig/Twig1x/twig/twig/src/Node/SetNode.php b/system/templateEngines/Twig/Twig1x/twig/twig/src/Node/SetNode.php
deleted file mode 100644
index 656103b..0000000
--- a/system/templateEngines/Twig/Twig1x/twig/twig/src/Node/SetNode.php
+++ /dev/null
@@ -1,107 +0,0 @@
-
- */
-class SetNode extends Node implements NodeCaptureInterface
-{
- public function __construct($capture, \Twig_NodeInterface $names, \Twig_NodeInterface $values, $lineno, $tag = null)
- {
- parent::__construct(['names' => $names, 'values' => $values], ['capture' => $capture, 'safe' => false], $lineno, $tag);
-
- /*
- * Optimizes the node when capture is used for a large block of text.
- *
- * {% set foo %}foo{% endset %} is compiled to $context['foo'] = new Twig\Markup("foo");
- */
- if ($this->getAttribute('capture')) {
- $this->setAttribute('safe', true);
-
- $values = $this->getNode('values');
- if ($values instanceof TextNode) {
- $this->setNode('values', new ConstantExpression($values->getAttribute('data'), $values->getTemplateLine()));
- $this->setAttribute('capture', false);
- }
- }
- }
-
- public function compile(Compiler $compiler)
- {
- $compiler->addDebugInfo($this);
-
- if (\count($this->getNode('names')) > 1) {
- $compiler->write('list(');
- foreach ($this->getNode('names') as $idx => $node) {
- if ($idx) {
- $compiler->raw(', ');
- }
-
- $compiler->subcompile($node);
- }
- $compiler->raw(')');
- } else {
- if ($this->getAttribute('capture')) {
- if ($compiler->getEnvironment()->isDebug()) {
- $compiler->write("ob_start();\n");
- } else {
- $compiler->write("ob_start(function () { return ''; });\n");
- }
- $compiler
- ->subcompile($this->getNode('values'))
- ;
- }
-
- $compiler->subcompile($this->getNode('names'), false);
-
- if ($this->getAttribute('capture')) {
- $compiler->raw(" = ('' === \$tmp = ob_get_clean()) ? '' : new Markup(\$tmp, \$this->env->getCharset())");
- }
- }
-
- if (!$this->getAttribute('capture')) {
- $compiler->raw(' = ');
-
- if (\count($this->getNode('names')) > 1) {
- $compiler->write('[');
- foreach ($this->getNode('values') as $idx => $value) {
- if ($idx) {
- $compiler->raw(', ');
- }
-
- $compiler->subcompile($value);
- }
- $compiler->raw(']');
- } else {
- if ($this->getAttribute('safe')) {
- $compiler
- ->raw("('' === \$tmp = ")
- ->subcompile($this->getNode('values'))
- ->raw(") ? '' : new Markup(\$tmp, \$this->env->getCharset())")
- ;
- } else {
- $compiler->subcompile($this->getNode('values'));
- }
- }
- }
-
- $compiler->raw(";\n");
- }
-}
-
-class_alias('Twig\Node\SetNode', 'Twig_Node_Set');
diff --git a/system/templateEngines/Twig/Twig1x/twig/twig/src/Node/SpacelessNode.php b/system/templateEngines/Twig/Twig1x/twig/twig/src/Node/SpacelessNode.php
deleted file mode 100644
index c8d32da..0000000
--- a/system/templateEngines/Twig/Twig1x/twig/twig/src/Node/SpacelessNode.php
+++ /dev/null
@@ -1,47 +0,0 @@
-
- */
-class SpacelessNode extends Node
-{
- public function __construct(\Twig_NodeInterface $body, $lineno, $tag = 'spaceless')
- {
- parent::__construct(['body' => $body], [], $lineno, $tag);
- }
-
- public function compile(Compiler $compiler)
- {
- $compiler
- ->addDebugInfo($this)
- ;
- if ($compiler->getEnvironment()->isDebug()) {
- $compiler->write("ob_start();\n");
- } else {
- $compiler->write("ob_start(function () { return ''; });\n");
- }
- $compiler
- ->subcompile($this->getNode('body'))
- ->write("echo trim(preg_replace('/>\s+', '><', ob_get_clean()));\n")
- ;
- }
-}
-
-class_alias('Twig\Node\SpacelessNode', 'Twig_Node_Spaceless');
diff --git a/system/templateEngines/Twig/Twig1x/twig/twig/src/NodeVisitor/SandboxNodeVisitor.php b/system/templateEngines/Twig/Twig1x/twig/twig/src/NodeVisitor/SandboxNodeVisitor.php
deleted file mode 100644
index c940339..0000000
--- a/system/templateEngines/Twig/Twig1x/twig/twig/src/NodeVisitor/SandboxNodeVisitor.php
+++ /dev/null
@@ -1,137 +0,0 @@
-
- */
-class SandboxNodeVisitor extends AbstractNodeVisitor
-{
- protected $inAModule = false;
- protected $tags;
- protected $filters;
- protected $functions;
-
- private $needsToStringWrap = false;
-
- protected function doEnterNode(Node $node, Environment $env)
- {
- if ($node instanceof ModuleNode) {
- $this->inAModule = true;
- $this->tags = [];
- $this->filters = [];
- $this->functions = [];
-
- return $node;
- } elseif ($this->inAModule) {
- // look for tags
- if ($node->getNodeTag() && !isset($this->tags[$node->getNodeTag()])) {
- $this->tags[$node->getNodeTag()] = $node;
- }
-
- // look for filters
- if ($node instanceof FilterExpression && !isset($this->filters[$node->getNode('filter')->getAttribute('value')])) {
- $this->filters[$node->getNode('filter')->getAttribute('value')] = $node;
- }
-
- // look for functions
- if ($node instanceof FunctionExpression && !isset($this->functions[$node->getAttribute('name')])) {
- $this->functions[$node->getAttribute('name')] = $node;
- }
-
- // the .. operator is equivalent to the range() function
- if ($node instanceof RangeBinary && !isset($this->functions['range'])) {
- $this->functions['range'] = $node;
- }
-
- if ($node instanceof PrintNode) {
- $this->needsToStringWrap = true;
- $this->wrapNode($node, 'expr');
- }
-
- if ($node instanceof SetNode && !$node->getAttribute('capture')) {
- $this->needsToStringWrap = true;
- }
-
- // wrap outer nodes that can implicitly call __toString()
- if ($this->needsToStringWrap) {
- if ($node instanceof ConcatBinary) {
- $this->wrapNode($node, 'left');
- $this->wrapNode($node, 'right');
- }
- if ($node instanceof FilterExpression) {
- $this->wrapNode($node, 'node');
- $this->wrapArrayNode($node, 'arguments');
- }
- if ($node instanceof FunctionExpression) {
- $this->wrapArrayNode($node, 'arguments');
- }
- }
- }
-
- return $node;
- }
-
- protected function doLeaveNode(Node $node, Environment $env)
- {
- if ($node instanceof ModuleNode) {
- $this->inAModule = false;
-
- $node->getNode('constructor_end')->setNode('_security_check', new Node([new CheckSecurityNode($this->filters, $this->tags, $this->functions), $node->getNode('display_start')]));
- } elseif ($this->inAModule) {
- if ($node instanceof PrintNode || $node instanceof SetNode) {
- $this->needsToStringWrap = false;
- }
- }
-
- return $node;
- }
-
- private function wrapNode(Node $node, $name)
- {
- $expr = $node->getNode($name);
- if ($expr instanceof NameExpression || $expr instanceof GetAttrExpression) {
- $node->setNode($name, new CheckToStringNode($expr));
- }
- }
-
- private function wrapArrayNode(Node $node, $name)
- {
- $args = $node->getNode($name);
- foreach ($args as $name => $_) {
- $this->wrapNode($args, $name);
- }
- }
-
- public function getPriority()
- {
- return 0;
- }
-}
-
-class_alias('Twig\NodeVisitor\SandboxNodeVisitor', 'Twig_NodeVisitor_Sandbox');
diff --git a/system/templateEngines/Twig/Twig1x/twig/twig/src/Parser.php b/system/templateEngines/Twig/Twig1x/twig/twig/src/Parser.php
deleted file mode 100644
index 9fb6a83..0000000
--- a/system/templateEngines/Twig/Twig1x/twig/twig/src/Parser.php
+++ /dev/null
@@ -1,439 +0,0 @@
-
- */
-class Parser implements \Twig_ParserInterface
-{
- protected $stack = [];
- protected $stream;
- protected $parent;
- protected $handlers;
- protected $visitors;
- protected $expressionParser;
- protected $blocks;
- protected $blockStack;
- protected $macros;
- protected $env;
- protected $reservedMacroNames;
- protected $importedSymbols;
- protected $traits;
- protected $embeddedTemplates = [];
- private $varNameSalt = 0;
-
- public function __construct(Environment $env)
- {
- $this->env = $env;
- }
-
- /**
- * @deprecated since 1.27 (to be removed in 2.0)
- */
- public function getEnvironment()
- {
- @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0.', E_USER_DEPRECATED);
-
- return $this->env;
- }
-
- public function getVarName()
- {
- return sprintf('__internal_%s', hash('sha256', __METHOD__.$this->stream->getSourceContext()->getCode().$this->varNameSalt++));
- }
-
- /**
- * @deprecated since 1.27 (to be removed in 2.0). Use $parser->getStream()->getSourceContext()->getPath() instead.
- */
- public function getFilename()
- {
- @trigger_error(sprintf('The "%s" method is deprecated since version 1.27 and will be removed in 2.0. Use $parser->getStream()->getSourceContext()->getPath() instead.', __METHOD__), E_USER_DEPRECATED);
-
- return $this->stream->getSourceContext()->getName();
- }
-
- public function parse(TokenStream $stream, $test = null, $dropNeedle = false)
- {
- // push all variables into the stack to keep the current state of the parser
- // using get_object_vars() instead of foreach would lead to https://bugs.php.net/71336
- // This hack can be removed when min version if PHP 7.0
- $vars = [];
- foreach ($this as $k => $v) {
- $vars[$k] = $v;
- }
-
- unset($vars['stack'], $vars['env'], $vars['handlers'], $vars['visitors'], $vars['expressionParser'], $vars['reservedMacroNames']);
- $this->stack[] = $vars;
-
- // tag handlers
- if (null === $this->handlers) {
- $this->handlers = $this->env->getTokenParsers();
- $this->handlers->setParser($this);
- }
-
- // node visitors
- if (null === $this->visitors) {
- $this->visitors = $this->env->getNodeVisitors();
- }
-
- if (null === $this->expressionParser) {
- $this->expressionParser = new ExpressionParser($this, $this->env);
- }
-
- $this->stream = $stream;
- $this->parent = null;
- $this->blocks = [];
- $this->macros = [];
- $this->traits = [];
- $this->blockStack = [];
- $this->importedSymbols = [[]];
- $this->embeddedTemplates = [];
- $this->varNameSalt = 0;
-
- try {
- $body = $this->subparse($test, $dropNeedle);
-
- if (null !== $this->parent && null === $body = $this->filterBodyNodes($body)) {
- $body = new Node();
- }
- } catch (SyntaxError $e) {
- if (!$e->getSourceContext()) {
- $e->setSourceContext($this->stream->getSourceContext());
- }
-
- if (!$e->getTemplateLine()) {
- $e->setTemplateLine($this->stream->getCurrent()->getLine());
- }
-
- throw $e;
- }
-
- $node = new ModuleNode(new BodyNode([$body]), $this->parent, new Node($this->blocks), new Node($this->macros), new Node($this->traits), $this->embeddedTemplates, $stream->getSourceContext());
-
- $traverser = new NodeTraverser($this->env, $this->visitors);
-
- $node = $traverser->traverse($node);
-
- // restore previous stack so previous parse() call can resume working
- foreach (array_pop($this->stack) as $key => $val) {
- $this->$key = $val;
- }
-
- return $node;
- }
-
- public function subparse($test, $dropNeedle = false)
- {
- $lineno = $this->getCurrentToken()->getLine();
- $rv = [];
- while (!$this->stream->isEOF()) {
- switch ($this->getCurrentToken()->getType()) {
- case Token::TEXT_TYPE:
- $token = $this->stream->next();
- $rv[] = new TextNode($token->getValue(), $token->getLine());
- break;
-
- case Token::VAR_START_TYPE:
- $token = $this->stream->next();
- $expr = $this->expressionParser->parseExpression();
- $this->stream->expect(Token::VAR_END_TYPE);
- $rv[] = new PrintNode($expr, $token->getLine());
- break;
-
- case Token::BLOCK_START_TYPE:
- $this->stream->next();
- $token = $this->getCurrentToken();
-
- if (Token::NAME_TYPE !== $token->getType()) {
- throw new SyntaxError('A block must start with a tag name.', $token->getLine(), $this->stream->getSourceContext());
- }
-
- if (null !== $test && \call_user_func($test, $token)) {
- if ($dropNeedle) {
- $this->stream->next();
- }
-
- if (1 === \count($rv)) {
- return $rv[0];
- }
-
- return new Node($rv, [], $lineno);
- }
-
- $subparser = $this->handlers->getTokenParser($token->getValue());
- if (null === $subparser) {
- if (null !== $test) {
- $e = new SyntaxError(sprintf('Unexpected "%s" tag', $token->getValue()), $token->getLine(), $this->stream->getSourceContext());
-
- if (\is_array($test) && isset($test[0]) && $test[0] instanceof TokenParserInterface) {
- $e->appendMessage(sprintf(' (expecting closing tag for the "%s" tag defined near line %s).', $test[0]->getTag(), $lineno));
- }
- } else {
- $e = new SyntaxError(sprintf('Unknown "%s" tag.', $token->getValue()), $token->getLine(), $this->stream->getSourceContext());
- $e->addSuggestions($token->getValue(), array_keys($this->env->getTags()));
- }
-
- throw $e;
- }
-
- $this->stream->next();
-
- $node = $subparser->parse($token);
- if (null !== $node) {
- $rv[] = $node;
- }
- break;
-
- default:
- throw new SyntaxError('Lexer or parser ended up in unsupported state.', $this->getCurrentToken()->getLine(), $this->stream->getSourceContext());
- }
- }
-
- if (1 === \count($rv)) {
- return $rv[0];
- }
-
- return new Node($rv, [], $lineno);
- }
-
- /**
- * @deprecated since 1.27 (to be removed in 2.0)
- */
- public function addHandler($name, $class)
- {
- @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0.', E_USER_DEPRECATED);
-
- $this->handlers[$name] = $class;
- }
-
- /**
- * @deprecated since 1.27 (to be removed in 2.0)
- */
- public function addNodeVisitor(NodeVisitorInterface $visitor)
- {
- @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0.', E_USER_DEPRECATED);
-
- $this->visitors[] = $visitor;
- }
-
- public function getBlockStack()
- {
- return $this->blockStack;
- }
-
- public function peekBlockStack()
- {
- return isset($this->blockStack[\count($this->blockStack) - 1]) ? $this->blockStack[\count($this->blockStack) - 1] : null;
- }
-
- public function popBlockStack()
- {
- array_pop($this->blockStack);
- }
-
- public function pushBlockStack($name)
- {
- $this->blockStack[] = $name;
- }
-
- public function hasBlock($name)
- {
- return isset($this->blocks[$name]);
- }
-
- public function getBlock($name)
- {
- return $this->blocks[$name];
- }
-
- public function setBlock($name, BlockNode $value)
- {
- $this->blocks[$name] = new BodyNode([$value], [], $value->getTemplateLine());
- }
-
- public function hasMacro($name)
- {
- return isset($this->macros[$name]);
- }
-
- public function setMacro($name, MacroNode $node)
- {
- if ($this->isReservedMacroName($name)) {
- throw new SyntaxError(sprintf('"%s" cannot be used as a macro name as it is a reserved keyword.', $name), $node->getTemplateLine(), $this->stream->getSourceContext());
- }
-
- $this->macros[$name] = $node;
- }
-
- public function isReservedMacroName($name)
- {
- if (null === $this->reservedMacroNames) {
- $this->reservedMacroNames = [];
- $r = new \ReflectionClass($this->env->getBaseTemplateClass());
- foreach ($r->getMethods() as $method) {
- $methodName = strtr($method->getName(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
-
- if ('get' === substr($methodName, 0, 3) && isset($methodName[3])) {
- $this->reservedMacroNames[] = substr($methodName, 3);
- }
- }
- }
-
- return \in_array(strtr($name, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), $this->reservedMacroNames);
- }
-
- public function addTrait($trait)
- {
- $this->traits[] = $trait;
- }
-
- public function hasTraits()
- {
- return \count($this->traits) > 0;
- }
-
- public function embedTemplate(ModuleNode $template)
- {
- $template->setIndex(mt_rand());
-
- $this->embeddedTemplates[] = $template;
- }
-
- public function addImportedSymbol($type, $alias, $name = null, AbstractExpression $node = null)
- {
- $this->importedSymbols[0][$type][$alias] = ['name' => $name, 'node' => $node];
- }
-
- public function getImportedSymbol($type, $alias)
- {
- if (null !== $this->peekBlockStack()) {
- foreach ($this->importedSymbols as $functions) {
- if (isset($functions[$type][$alias])) {
- if (\count($this->blockStack) > 1) {
- return null;
- }
-
- return $functions[$type][$alias];
- }
- }
- } else {
- return isset($this->importedSymbols[0][$type][$alias]) ? $this->importedSymbols[0][$type][$alias] : null;
- }
- }
-
- public function isMainScope()
- {
- return 1 === \count($this->importedSymbols);
- }
-
- public function pushLocalScope()
- {
- array_unshift($this->importedSymbols, []);
- }
-
- public function popLocalScope()
- {
- array_shift($this->importedSymbols);
- }
-
- /**
- * @return ExpressionParser
- */
- public function getExpressionParser()
- {
- return $this->expressionParser;
- }
-
- public function getParent()
- {
- return $this->parent;
- }
-
- public function setParent($parent)
- {
- $this->parent = $parent;
- }
-
- /**
- * @return TokenStream
- */
- public function getStream()
- {
- return $this->stream;
- }
-
- /**
- * @return Token
- */
- public function getCurrentToken()
- {
- return $this->stream->getCurrent();
- }
-
- protected function filterBodyNodes(\Twig_NodeInterface $node)
- {
- // check that the body does not contain non-empty output nodes
- if (
- ($node instanceof TextNode && !ctype_space($node->getAttribute('data')))
- ||
- (!$node instanceof TextNode && !$node instanceof BlockReferenceNode && $node instanceof NodeOutputInterface)
- ) {
- if (false !== strpos((string) $node, \chr(0xEF).\chr(0xBB).\chr(0xBF))) {
- $t = substr($node->getAttribute('data'), 3);
- if ('' === $t || ctype_space($t)) {
- // bypass empty nodes starting with a BOM
- return;
- }
- }
-
- throw new SyntaxError('A template that extends another one cannot include content outside Twig blocks. Did you forget to put the content inside a {% block %} tag?', $node->getTemplateLine(), $this->stream->getSourceContext());
- }
-
- // bypass nodes that will "capture" the output
- if ($node instanceof NodeCaptureInterface) {
- return $node;
- }
-
- if ($node instanceof NodeOutputInterface) {
- return;
- }
-
- foreach ($node as $k => $n) {
- if (null !== $n && null === $this->filterBodyNodes($n)) {
- $node->removeNode($k);
- }
- }
-
- return $node;
- }
-}
-
-class_alias('Twig\Parser', 'Twig_Parser');
diff --git a/system/templateEngines/Twig/Twig1x/twig/twig/src/Sandbox/SecurityPolicy.php b/system/templateEngines/Twig/Twig1x/twig/twig/src/Sandbox/SecurityPolicy.php
deleted file mode 100644
index 6038435..0000000
--- a/system/templateEngines/Twig/Twig1x/twig/twig/src/Sandbox/SecurityPolicy.php
+++ /dev/null
@@ -1,129 +0,0 @@
-
- */
-class SecurityPolicy implements SecurityPolicyInterface
-{
- protected $allowedTags;
- protected $allowedFilters;
- protected $allowedMethods;
- protected $allowedProperties;
- protected $allowedFunctions;
-
- public function __construct(array $allowedTags = [], array $allowedFilters = [], array $allowedMethods = [], array $allowedProperties = [], array $allowedFunctions = [])
- {
- $this->allowedTags = $allowedTags;
- $this->allowedFilters = $allowedFilters;
- $this->setAllowedMethods($allowedMethods);
- $this->allowedProperties = $allowedProperties;
- $this->allowedFunctions = $allowedFunctions;
- }
-
- public function setAllowedTags(array $tags)
- {
- $this->allowedTags = $tags;
- }
-
- public function setAllowedFilters(array $filters)
- {
- $this->allowedFilters = $filters;
- }
-
- public function setAllowedMethods(array $methods)
- {
- $this->allowedMethods = [];
- foreach ($methods as $class => $m) {
- $this->allowedMethods[$class] = array_map(function ($value) { return strtr($value, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'); }, \is_array($m) ? $m : [$m]);
- }
- }
-
- public function setAllowedProperties(array $properties)
- {
- $this->allowedProperties = $properties;
- }
-
- public function setAllowedFunctions(array $functions)
- {
- $this->allowedFunctions = $functions;
- }
-
- public function checkSecurity($tags, $filters, $functions)
- {
- foreach ($tags as $tag) {
- if (!\in_array($tag, $this->allowedTags)) {
- throw new SecurityNotAllowedTagError(sprintf('Tag "%s" is not allowed.', $tag), $tag);
- }
- }
-
- foreach ($filters as $filter) {
- if (!\in_array($filter, $this->allowedFilters)) {
- throw new SecurityNotAllowedFilterError(sprintf('Filter "%s" is not allowed.', $filter), $filter);
- }
- }
-
- foreach ($functions as $function) {
- if (!\in_array($function, $this->allowedFunctions)) {
- throw new SecurityNotAllowedFunctionError(sprintf('Function "%s" is not allowed.', $function), $function);
- }
- }
- }
-
- public function checkMethodAllowed($obj, $method)
- {
- if ($obj instanceof \Twig_TemplateInterface || $obj instanceof Markup) {
- return;
- }
-
- $allowed = false;
- $method = strtr($method, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
- foreach ($this->allowedMethods as $class => $methods) {
- if ($obj instanceof $class) {
- $allowed = \in_array($method, $methods);
-
- break;
- }
- }
-
- if (!$allowed) {
- $class = \get_class($obj);
- throw new SecurityNotAllowedMethodError(sprintf('Calling "%s" method on a "%s" object is not allowed.', $method, $class), $class, $method);
- }
- }
-
- public function checkPropertyAllowed($obj, $property)
- {
- $allowed = false;
- foreach ($this->allowedProperties as $class => $properties) {
- if ($obj instanceof $class) {
- $allowed = \in_array($property, \is_array($properties) ? $properties : [$properties]);
-
- break;
- }
- }
-
- if (!$allowed) {
- $class = \get_class($obj);
- throw new SecurityNotAllowedPropertyError(sprintf('Calling "%s" property on a "%s" object is not allowed.', $property, $class), $class, $property);
- }
- }
-}
-
-class_alias('Twig\Sandbox\SecurityPolicy', 'Twig_Sandbox_SecurityPolicy');
diff --git a/system/templateEngines/Twig/Twig1x/twig/twig/src/Template.php b/system/templateEngines/Twig/Twig1x/twig/twig/src/Template.php
deleted file mode 100644
index 704125e..0000000
--- a/system/templateEngines/Twig/Twig1x/twig/twig/src/Template.php
+++ /dev/null
@@ -1,733 +0,0 @@
-load()
- * instead, which returns an instance of \Twig\TemplateWrapper.
- *
- * @author Fabien Potencier
- *
- * @internal
- */
-abstract class Template implements \Twig_TemplateInterface
-{
- /**
- * @internal
- */
- protected static $cache = [];
-
- protected $parent;
- protected $parents = [];
- protected $env;
- protected $blocks = [];
- protected $traits = [];
- protected $sandbox;
-
- public function __construct(Environment $env)
- {
- $this->env = $env;
- }
-
- /**
- * @internal this method will be removed in 2.0 and is only used internally to provide an upgrade path from 1.x to 2.0
- */
- public function __toString()
- {
- return $this->getTemplateName();
- }
-
- /**
- * Returns the template name.
- *
- * @return string The template name
- */
- abstract public function getTemplateName();
-
- /**
- * Returns debug information about the template.
- *
- * @return array Debug information
- */
- public function getDebugInfo()
- {
- return [];
- }
-
- /**
- * Returns the template source code.
- *
- * @return string The template source code
- *
- * @deprecated since 1.27 (to be removed in 2.0). Use getSourceContext() instead
- */
- public function getSource()
- {
- @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', E_USER_DEPRECATED);
-
- return '';
- }
-
- /**
- * Returns information about the original template source code.
- *
- * @return Source
- */
- public function getSourceContext()
- {
- return new Source('', $this->getTemplateName());
- }
-
- /**
- * @deprecated since 1.20 (to be removed in 2.0)
- */
- public function getEnvironment()
- {
- @trigger_error('The '.__METHOD__.' method is deprecated since version 1.20 and will be removed in 2.0.', E_USER_DEPRECATED);
-
- return $this->env;
- }
-
- /**
- * Returns the parent template.
- *
- * This method is for internal use only and should never be called
- * directly.
- *
- * @param array $context
- *
- * @return \Twig_TemplateInterface|TemplateWrapper|false The parent template or false if there is no parent
- *
- * @internal
- */
- public function getParent(array $context)
- {
- if (null !== $this->parent) {
- return $this->parent;
- }
-
- try {
- $parent = $this->doGetParent($context);
-
- if (false === $parent) {
- return false;
- }
-
- if ($parent instanceof self || $parent instanceof TemplateWrapper) {
- return $this->parents[$parent->getSourceContext()->getName()] = $parent;
- }
-
- if (!isset($this->parents[$parent])) {
- $this->parents[$parent] = $this->loadTemplate($parent);
- }
- } catch (LoaderError $e) {
- $e->setSourceContext(null);
- $e->guess();
-
- throw $e;
- }
-
- return $this->parents[$parent];
- }
-
- protected function doGetParent(array $context)
- {
- return false;
- }
-
- public function isTraitable()
- {
- return true;
- }
-
- /**
- * Displays a parent block.
- *
- * This method is for internal use only and should never be called
- * directly.
- *
- * @param string $name The block name to display from the parent
- * @param array $context The context
- * @param array $blocks The current set of blocks
- */
- public function displayParentBlock($name, array $context, array $blocks = [])
- {
- $name = (string) $name;
-
- if (isset($this->traits[$name])) {
- $this->traits[$name][0]->displayBlock($name, $context, $blocks, false);
- } elseif (false !== $parent = $this->getParent($context)) {
- $parent->displayBlock($name, $context, $blocks, false);
- } else {
- throw new RuntimeError(sprintf('The template has no parent and no traits defining the "%s" block.', $name), -1, $this->getSourceContext());
- }
- }
-
- /**
- * Displays a block.
- *
- * 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 bool $useBlocks Whether to use the current set of blocks
- */
- public function displayBlock($name, array $context, array $blocks = [], $useBlocks = true)
- {
- $name = (string) $name;
-
- if ($useBlocks && isset($blocks[$name])) {
- $template = $blocks[$name][0];
- $block = $blocks[$name][1];
- } elseif (isset($this->blocks[$name])) {
- $template = $this->blocks[$name][0];
- $block = $this->blocks[$name][1];
- } else {
- $template = null;
- $block = null;
- }
-
- // avoid RCEs when sandbox is enabled
- if (null !== $template && !$template instanceof self) {
- throw new \LogicException('A block must be a method on a \Twig\Template instance.');
- }
-
- if (null !== $template) {
- try {
- $template->$block($context, $blocks);
- } catch (Error $e) {
- if (!$e->getSourceContext()) {
- $e->setSourceContext($template->getSourceContext());
- }
-
- // this is mostly useful for \Twig\Error\LoaderError exceptions
- // see \Twig\Error\LoaderError
- if (-1 === $e->getTemplateLine()) {
- $e->guess();
- }
-
- throw $e;
- } catch (\Exception $e) {
- $e = new RuntimeError(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $template->getSourceContext(), $e);
- $e->guess();
-
- throw $e;
- }
- } elseif (false !== $parent = $this->getParent($context)) {
- $parent->displayBlock($name, $context, array_merge($this->blocks, $blocks), false);
- } else {
- @trigger_error(sprintf('Silent display of undefined block "%s" in template "%s" is deprecated since version 1.29 and will throw an exception in 2.0. Use the "block(\'%s\') is defined" expression to test for block existence.', $name, $this->getTemplateName(), $name), E_USER_DEPRECATED);
- }
- }
-
- /**
- * Renders a parent block.
- *
- * This method is for internal use only and should never be called
- * directly.
- *
- * @param string $name The block name to render from the parent
- * @param array $context The context
- * @param array $blocks The current set of blocks
- *
- * @return string The rendered block
- */
- public function renderParentBlock($name, array $context, array $blocks = [])
- {
- if ($this->env->isDebug()) {
- ob_start();
- } else {
- ob_start(function () { return ''; });
- }
- $this->displayParentBlock($name, $context, $blocks);
-
- return ob_get_clean();
- }
-
- /**
- * Renders a block.
- *
- * 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 bool $useBlocks Whether to use the current set of blocks
- *
- * @return string The rendered block
- */
- public function renderBlock($name, array $context, array $blocks = [], $useBlocks = true)
- {
- if ($this->env->isDebug()) {
- ob_start();
- } else {
- ob_start(function () { return ''; });
- }
- $this->displayBlock($name, $context, $blocks, $useBlocks);
-
- return ob_get_clean();
- }
-
- /**
- * Returns whether a block exists or not in the current context of the template.
- *
- * This method checks blocks defined in the current template
- * or defined in "used" traits or defined in parent templates.
- *
- * @param string $name The block name
- * @param array $context The context
- * @param array $blocks The current set of blocks
- *
- * @return bool true if the block exists, false otherwise
- */
- public function hasBlock($name, array $context = null, array $blocks = [])
- {
- if (null === $context) {
- @trigger_error('The '.__METHOD__.' method is internal and should never be called; calling it directly is deprecated since version 1.28 and won\'t be possible anymore in 2.0.', E_USER_DEPRECATED);
-
- return isset($this->blocks[(string) $name]);
- }
-
- if (isset($blocks[$name])) {
- return $blocks[$name][0] instanceof self;
- }
-
- if (isset($this->blocks[$name])) {
- return true;
- }
-
- if (false !== $parent = $this->getParent($context)) {
- return $parent->hasBlock($name, $context);
- }
-
- return false;
- }
-
- /**
- * Returns all block names in the current context of the template.
- *
- * This method checks blocks defined in the current template
- * or defined in "used" traits or defined in parent templates.
- *
- * @param array $context The context
- * @param array $blocks The current set of blocks
- *
- * @return array An array of block names
- */
- public function getBlockNames(array $context = null, array $blocks = [])
- {
- if (null === $context) {
- @trigger_error('The '.__METHOD__.' method is internal and should never be called; calling it directly is deprecated since version 1.28 and won\'t be possible anymore in 2.0.', E_USER_DEPRECATED);
-
- return array_keys($this->blocks);
- }
-
- $names = array_merge(array_keys($blocks), array_keys($this->blocks));
-
- if (false !== $parent = $this->getParent($context)) {
- $names = array_merge($names, $parent->getBlockNames($context));
- }
-
- return array_unique($names);
- }
-
- /**
- * @return Template|TemplateWrapper
- */
- protected function loadTemplate($template, $templateName = null, $line = null, $index = null)
- {
- try {
- if (\is_array($template)) {
- return $this->env->resolveTemplate($template);
- }
-
- if ($template instanceof self || $template instanceof TemplateWrapper) {
- return $template;
- }
-
- if ($template === $this->getTemplateName()) {
- $class = \get_class($this);
- if (false !== $pos = strrpos($class, '___', -1)) {
- $class = substr($class, 0, $pos);
- }
-
- return $this->env->loadClass($class, $template, $index);
- }
-
- return $this->env->loadTemplate($template, $index);
- } catch (Error $e) {
- if (!$e->getSourceContext()) {
- $e->setSourceContext($templateName ? new Source('', $templateName) : $this->getSourceContext());
- }
-
- if ($e->getTemplateLine() > 0) {
- throw $e;
- }
-
- if (!$line) {
- $e->guess();
- } else {
- $e->setTemplateLine($line);
- }
-
- throw $e;
- }
- }
-
- /**
- * @internal
- *
- * @return Template
- */
- protected function unwrap()
- {
- return $this;
- }
-
- /**
- * Returns all blocks.
- *
- * This method is for internal use only and should never be called
- * directly.
- *
- * @return array An array of blocks
- */
- public function getBlocks()
- {
- return $this->blocks;
- }
-
- public function display(array $context, array $blocks = [])
- {
- $this->displayWithErrorHandling($this->env->mergeGlobals($context), array_merge($this->blocks, $blocks));
- }
-
- public function render(array $context)
- {
- $level = ob_get_level();
- if ($this->env->isDebug()) {
- ob_start();
- } else {
- ob_start(function () { return ''; });
- }
- try {
- $this->display($context);
- } catch (\Exception $e) {
- while (ob_get_level() > $level) {
- ob_end_clean();
- }
-
- throw $e;
- } catch (\Throwable $e) {
- while (ob_get_level() > $level) {
- ob_end_clean();
- }
-
- throw $e;
- }
-
- return ob_get_clean();
- }
-
- protected function displayWithErrorHandling(array $context, array $blocks = [])
- {
- try {
- $this->doDisplay($context, $blocks);
- } catch (Error $e) {
- if (!$e->getSourceContext()) {
- $e->setSourceContext($this->getSourceContext());
- }
-
- // this is mostly useful for \Twig\Error\LoaderError exceptions
- // see \Twig\Error\LoaderError
- if (-1 === $e->getTemplateLine()) {
- $e->guess();
- }
-
- throw $e;
- } catch (\Exception $e) {
- $e = new RuntimeError(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $this->getSourceContext(), $e);
- $e->guess();
-
- throw $e;
- }
- }
-
- /**
- * Auto-generated method to display the template with the given context.
- *
- * @param array $context An array of parameters to pass to the template
- * @param array $blocks An array of blocks to pass to the template
- */
- abstract protected function doDisplay(array $context, array $blocks = []);
-
- /**
- * Returns a variable from the context.
- *
- * This method is for internal use only and should never be called
- * directly.
- *
- * This method should not be overridden in a sub-class as this is an
- * implementation detail that has been introduced to optimize variable
- * 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 bool $ignoreStrictCheck Whether to ignore the strict variable check or not
- *
- * @return mixed The content of the context variable
- *
- * @throws RuntimeError if the variable does not exist and Twig is running in strict mode
- *
- * @internal
- */
- final protected function getContext($context, $item, $ignoreStrictCheck = false)
- {
- if (!\array_key_exists($item, $context)) {
- if ($ignoreStrictCheck || !$this->env->isStrictVariables()) {
- return;
- }
-
- throw new RuntimeError(sprintf('Variable "%s" does not exist.', $item), -1, $this->getSourceContext());
- }
-
- return $context[$item];
- }
-
- /**
- * 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 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
- *
- * @throws RuntimeError if the attribute does not exist and Twig is running in strict mode and $isDefinedTest is false
- *
- * @internal
- */
- protected function getAttribute($object, $item, array $arguments = [], $type = self::ANY_CALL, $isDefinedTest = false, $ignoreStrictCheck = false)
- {
- // array
- if (self::METHOD_CALL !== $type) {
- $arrayItem = \is_bool($item) || \is_float($item) ? (int) $item : $item;
-
- if (((\is_array($object) || $object instanceof \ArrayObject) && (isset($object[$arrayItem]) || \array_key_exists($arrayItem, (array) $object)))
- || ($object instanceof \ArrayAccess && isset($object[$arrayItem]))
- ) {
- if ($isDefinedTest) {
- return true;
- }
-
- return $object[$arrayItem];
- }
-
- if (self::ARRAY_CALL === $type || !\is_object($object)) {
- if ($isDefinedTest) {
- return false;
- }
-
- if ($ignoreStrictCheck || !$this->env->isStrictVariables()) {
- return;
- }
-
- 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)) {
- 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 (self::ARRAY_CALL === $type) {
- if (null === $object) {
- $message = sprintf('Impossible to access a key ("%s") on a null variable.', $item);
- } else {
- $message = sprintf('Impossible to access a key ("%s") on a %s variable ("%s").', $item, \gettype($object), $object);
- }
- } elseif (null === $object) {
- $message = sprintf('Impossible to access an attribute ("%s") on a null variable.', $item);
- } else {
- $message = sprintf('Impossible to access an attribute ("%s") on a %s variable ("%s").', $item, \gettype($object), $object);
- }
-
- throw new RuntimeError($message, -1, $this->getSourceContext());
- }
- }
-
- if (!\is_object($object)) {
- if ($isDefinedTest) {
- return false;
- }
-
- if ($ignoreStrictCheck || !$this->env->isStrictVariables()) {
- return;
- }
-
- if (null === $object) {
- $message = sprintf('Impossible to invoke a method ("%s") on a null variable.', $item);
- } elseif (\is_array($object)) {
- $message = sprintf('Impossible to invoke a method ("%s") on an array.', $item);
- } else {
- $message = sprintf('Impossible to invoke a method ("%s") on a %s variable ("%s").', $item, \gettype($object), $object);
- }
-
- throw new RuntimeError($message, -1, $this->getSourceContext());
- }
-
- // object property
- if (self::METHOD_CALL !== $type && !$object instanceof self) { // \Twig\Template does not have public properties, and we don't want to allow access to internal ones
- if (isset($object->$item) || \array_key_exists((string) $item, (array) $object)) {
- if ($isDefinedTest) {
- return true;
- }
-
- if ($this->env->hasExtension('\Twig\Extension\SandboxExtension')) {
- $this->env->getExtension('\Twig\Extension\SandboxExtension')->checkPropertyAllowed($object, $item);
- }
-
- return $object->$item;
- }
- }
-
- $class = \get_class($object);
-
- // object method
- if (!isset(self::$cache[$class])) {
- // get_class_methods returns all methods accessible in the scope, but we only want public ones to be accessible in templates
- if ($object instanceof self) {
- $ref = new \ReflectionClass($class);
- $methods = [];
-
- foreach ($ref->getMethods(\ReflectionMethod::IS_PUBLIC) as $refMethod) {
- // Accessing the environment from templates is forbidden to prevent untrusted changes to the environment
- if ('getenvironment' !== strtr($refMethod->name, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')) {
- $methods[] = $refMethod->name;
- }
- }
- } else {
- $methods = get_class_methods($object);
- }
- // sort values to have consistent behavior, so that "get" methods win precedence over "is" methods
- sort($methods);
-
- $cache = [];
-
- foreach ($methods as $method) {
- $cache[$method] = $method;
- $cache[$lcName = strtr($method, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')] = $method;
-
- if ('g' === $lcName[0] && 0 === strpos($lcName, 'get')) {
- $name = substr($method, 3);
- $lcName = substr($lcName, 3);
- } elseif ('i' === $lcName[0] && 0 === strpos($lcName, 'is')) {
- $name = substr($method, 2);
- $lcName = substr($lcName, 2);
- } else {
- continue;
- }
-
- // skip get() and is() methods (in which case, $name is empty)
- if ($name) {
- if (!isset($cache[$name])) {
- $cache[$name] = $method;
- }
- if (!isset($cache[$lcName])) {
- $cache[$lcName] = $method;
- }
- }
- }
- self::$cache[$class] = $cache;
- }
-
- $call = false;
- if (isset(self::$cache[$class][$item])) {
- $method = self::$cache[$class][$item];
- } elseif (isset(self::$cache[$class][$lcItem = strtr($item, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')])) {
- $method = self::$cache[$class][$lcItem];
- } elseif (isset(self::$cache[$class]['__call'])) {
- $method = $item;
- $call = true;
- } else {
- if ($isDefinedTest) {
- return false;
- }
-
- if ($ignoreStrictCheck || !$this->env->isStrictVariables()) {
- return;
- }
-
- throw new RuntimeError(sprintf('Neither the property "%1$s" nor one of the methods "%1$s()", "get%1$s()"/"is%1$s()" or "__call()" exist and have public access in class "%2$s".', $item, $class), -1, $this->getSourceContext());
- }
-
- if ($isDefinedTest) {
- return true;
- }
-
- if ($this->env->hasExtension('\Twig\Extension\SandboxExtension')) {
- $this->env->getExtension('\Twig\Extension\SandboxExtension')->checkMethodAllowed($object, $method);
- }
-
- // 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 {
- if (!$arguments) {
- $ret = $object->$method();
- } else {
- $ret = \call_user_func_array([$object, $method], $arguments);
- }
- } catch (\BadMethodCallException $e) {
- if ($call && ($ignoreStrictCheck || !$this->env->isStrictVariables())) {
- return;
- }
- throw $e;
- }
-
- // @deprecated in 1.28
- if ($object instanceof \Twig_TemplateInterface) {
- $self = $object->getTemplateName() === $this->getTemplateName();
- $message = sprintf('Calling "%s" on template "%s" from template "%s" is deprecated since version 1.28 and won\'t be supported anymore in 2.0.', $item, $object->getTemplateName(), $this->getTemplateName());
- if ('renderBlock' === $method || 'displayBlock' === $method) {
- $message .= sprintf(' Use block("%s"%s) instead).', $arguments[0], $self ? '' : ', template');
- } elseif ('hasBlock' === $method) {
- $message .= sprintf(' Use "block("%s"%s) is defined" instead).', $arguments[0], $self ? '' : ', template');
- } elseif ('render' === $method || 'display' === $method) {
- $message .= sprintf(' Use include("%s") instead).', $object->getTemplateName());
- }
- @trigger_error($message, E_USER_DEPRECATED);
-
- return '' === $ret ? '' : new Markup($ret, $this->env->getCharset());
- }
-
- return $ret;
- }
-}
-
-class_alias('Twig\Template', 'Twig_Template');
diff --git a/system/templateEngines/Twig/Twig1x/twig/twig/src/TemplateWrapper.php b/system/templateEngines/Twig/Twig1x/twig/twig/src/TemplateWrapper.php
deleted file mode 100644
index e265409..0000000
--- a/system/templateEngines/Twig/Twig1x/twig/twig/src/TemplateWrapper.php
+++ /dev/null
@@ -1,161 +0,0 @@
-
- */
-final class TemplateWrapper
-{
- private $env;
- private $template;
-
- /**
- * This method is for internal use only and should never be called
- * directly (use Twig\Environment::load() instead).
- *
- * @internal
- */
- public function __construct(Environment $env, Template $template)
- {
- $this->env = $env;
- $this->template = $template;
- }
-
- /**
- * Renders the template.
- *
- * @param array $context An array of parameters to pass to the template
- *
- * @return string The rendered template
- */
- public function render($context = [])
- {
- // using func_get_args() allows to not expose the blocks argument
- // as it should only be used by internal code
- return $this->template->render($context, \func_num_args() > 1 ? func_get_arg(1) : []);
- }
-
- /**
- * Displays the template.
- *
- * @param array $context An array of parameters to pass to the template
- */
- public function display($context = [])
- {
- // using func_get_args() allows to not expose the blocks argument
- // as it should only be used by internal code
- $this->template->display($context, \func_num_args() > 1 ? func_get_arg(1) : []);
- }
-
- /**
- * Checks if a block is defined.
- *
- * @param string $name The block name
- * @param array $context An array of parameters to pass to the template
- *
- * @return bool
- */
- public function hasBlock($name, $context = [])
- {
- return $this->template->hasBlock($name, $context);
- }
-
- /**
- * Returns defined block names in the template.
- *
- * @param array $context An array of parameters to pass to the template
- *
- * @return string[] An array of defined template block names
- */
- public function getBlockNames($context = [])
- {
- return $this->template->getBlockNames($context);
- }
-
- /**
- * Renders a template block.
- *
- * @param string $name The block name to render
- * @param array $context An array of parameters to pass to the template
- *
- * @return string The rendered block
- */
- public function renderBlock($name, $context = [])
- {
- $context = $this->env->mergeGlobals($context);
- $level = ob_get_level();
- if ($this->env->isDebug()) {
- ob_start();
- } else {
- ob_start(function () { return ''; });
- }
- try {
- $this->template->displayBlock($name, $context);
- } catch (\Exception $e) {
- while (ob_get_level() > $level) {
- ob_end_clean();
- }
-
- throw $e;
- } catch (\Throwable $e) {
- while (ob_get_level() > $level) {
- ob_end_clean();
- }
-
- throw $e;
- }
-
- return ob_get_clean();
- }
-
- /**
- * Displays a template block.
- *
- * @param string $name The block name to render
- * @param array $context An array of parameters to pass to the template
- */
- public function displayBlock($name, $context = [])
- {
- $this->template->displayBlock($name, $this->env->mergeGlobals($context));
- }
-
- /**
- * @return Source
- */
- public function getSourceContext()
- {
- return $this->template->getSourceContext();
- }
-
- /**
- * @return string
- */
- public function getTemplateName()
- {
- return $this->template->getTemplateName();
- }
-
- /**
- * @internal
- *
- * @return Template
- */
- public function unwrap()
- {
- return $this->template;
- }
-}
-
-class_alias('Twig\TemplateWrapper', 'Twig_TemplateWrapper');
diff --git a/system/templateEngines/Twig/Twig1x/twig/twig/src/TokenParser/ExtendsTokenParser.php b/system/templateEngines/Twig/Twig1x/twig/twig/src/TokenParser/ExtendsTokenParser.php
deleted file mode 100644
index e66789a..0000000
--- a/system/templateEngines/Twig/Twig1x/twig/twig/src/TokenParser/ExtendsTokenParser.php
+++ /dev/null
@@ -1,54 +0,0 @@
-parser->getStream();
-
- if ($this->parser->peekBlockStack()) {
- throw new SyntaxError('Cannot use "extend" in a block.', $token->getLine(), $stream->getSourceContext());
- } elseif (!$this->parser->isMainScope()) {
- throw new SyntaxError('Cannot use "extend" in a macro.', $token->getLine(), $stream->getSourceContext());
- }
-
- if (null !== $this->parser->getParent()) {
- throw new SyntaxError('Multiple extends tags are forbidden.', $token->getLine(), $stream->getSourceContext());
- }
- $this->parser->setParent($this->parser->getExpressionParser()->parseExpression());
-
- $stream->expect(Token::BLOCK_END_TYPE);
-
- return new Node();
- }
-
- public function getTag()
- {
- return 'extends';
- }
-}
-
-class_alias('Twig\TokenParser\ExtendsTokenParser', 'Twig_TokenParser_Extends');
diff --git a/system/templateEngines/Twig/Twig1x/twig/twig/src/TokenParser/FromTokenParser.php b/system/templateEngines/Twig/Twig1x/twig/twig/src/TokenParser/FromTokenParser.php
deleted file mode 100644
index 4cce650..0000000
--- a/system/templateEngines/Twig/Twig1x/twig/twig/src/TokenParser/FromTokenParser.php
+++ /dev/null
@@ -1,72 +0,0 @@
-parser->getExpressionParser()->parseExpression();
- $stream = $this->parser->getStream();
- $stream->expect(Token::NAME_TYPE, 'import');
-
- $targets = [];
- do {
- $name = $stream->expect(Token::NAME_TYPE)->getValue();
-
- $alias = $name;
- if ($stream->nextIf('as')) {
- $alias = $stream->expect(Token::NAME_TYPE)->getValue();
- }
-
- $targets[$name] = $alias;
-
- if (!$stream->nextIf(Token::PUNCTUATION_TYPE, ',')) {
- break;
- }
- } while (true);
-
- $stream->expect(Token::BLOCK_END_TYPE);
-
- $var = new AssignNameExpression($this->parser->getVarName(), $token->getLine());
- $node = new ImportNode($macro, $var, $token->getLine(), $this->getTag());
-
- foreach ($targets as $name => $alias) {
- if ($this->parser->isReservedMacroName($name)) {
- throw new SyntaxError(sprintf('"%s" cannot be an imported macro as it is a reserved keyword.', $name), $token->getLine(), $stream->getSourceContext());
- }
-
- $this->parser->addImportedSymbol('function', $alias, 'get'.$name, $var);
- }
-
- return $node;
- }
-
- public function getTag()
- {
- return 'from';
- }
-}
-
-class_alias('Twig\TokenParser\FromTokenParser', 'Twig_TokenParser_From');
diff --git a/system/templateEngines/Twig/Twig1x/twig/twig/src/TokenParser/ImportTokenParser.php b/system/templateEngines/Twig/Twig1x/twig/twig/src/TokenParser/ImportTokenParser.php
deleted file mode 100644
index 88395b9..0000000
--- a/system/templateEngines/Twig/Twig1x/twig/twig/src/TokenParser/ImportTokenParser.php
+++ /dev/null
@@ -1,45 +0,0 @@
-parser->getExpressionParser()->parseExpression();
- $this->parser->getStream()->expect(Token::NAME_TYPE, 'as');
- $var = new AssignNameExpression($this->parser->getStream()->expect(Token::NAME_TYPE)->getValue(), $token->getLine());
- $this->parser->getStream()->expect(Token::BLOCK_END_TYPE);
-
- $this->parser->addImportedSymbol('template', $var->getAttribute('name'));
-
- return new ImportNode($macro, $var, $token->getLine(), $this->getTag());
- }
-
- public function getTag()
- {
- return 'import';
- }
-}
-
-class_alias('Twig\TokenParser\ImportTokenParser', 'Twig_TokenParser_Import');
diff --git a/system/templateEngines/Twig/Twig1x/twig/twig/src/TokenStream.php b/system/templateEngines/Twig/Twig1x/twig/twig/src/TokenStream.php
deleted file mode 100644
index 4597816..0000000
--- a/system/templateEngines/Twig/Twig1x/twig/twig/src/TokenStream.php
+++ /dev/null
@@ -1,201 +0,0 @@
-
- */
-class TokenStream
-{
- protected $tokens;
- protected $current = 0;
- protected $filename;
-
- private $source;
-
- /**
- * @param array $tokens An array of tokens
- * @param string|null $name The name of the template which tokens are associated with
- * @param string|null $source The source code associated with the tokens
- */
- public function __construct(array $tokens, $name = null, $source = null)
- {
- if (!$name instanceof Source) {
- if (null !== $name || null !== $source) {
- @trigger_error(sprintf('Passing a string as the $name argument of %s() is deprecated since version 1.27. Pass a \Twig\Source instance instead.', __METHOD__), E_USER_DEPRECATED);
- }
- $this->source = new Source($source, $name);
- } else {
- $this->source = $name;
- }
-
- $this->tokens = $tokens;
-
- // deprecated, not used anymore, to be removed in 2.0
- $this->filename = $this->source->getName();
- }
-
- public function __toString()
- {
- return implode("\n", $this->tokens);
- }
-
- public function injectTokens(array $tokens)
- {
- $this->tokens = array_merge(\array_slice($this->tokens, 0, $this->current), $tokens, \array_slice($this->tokens, $this->current));
- }
-
- /**
- * Sets the pointer to the next token and returns the old one.
- *
- * @return Token
- */
- public function next()
- {
- if (!isset($this->tokens[++$this->current])) {
- throw new SyntaxError('Unexpected end of template.', $this->tokens[$this->current - 1]->getLine(), $this->source);
- }
-
- 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 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.
- *
- * @return Token
- */
- public function expect($type, $value = null, $message = null)
- {
- $token = $this->tokens[$this->current];
- if (!$token->test($type, $value)) {
- $line = $token->getLine();
- throw new SyntaxError(sprintf('%sUnexpected token "%s"%s ("%s" expected%s).',
- $message ? $message.'. ' : '',
- Token::typeToEnglish($token->getType()),
- $token->getValue() ? sprintf(' of value "%s"', $token->getValue()) : '',
- Token::typeToEnglish($type), $value ? sprintf(' with value "%s"', $value) : ''),
- $line,
- $this->source
- );
- }
- $this->next();
-
- return $token;
- }
-
- /**
- * Looks at the next token.
- *
- * @param int $number
- *
- * @return Token
- */
- public function look($number = 1)
- {
- if (!isset($this->tokens[$this->current + $number])) {
- throw new SyntaxError('Unexpected end of template.', $this->tokens[$this->current + $number - 1]->getLine(), $this->source);
- }
-
- return $this->tokens[$this->current + $number];
- }
-
- /**
- * Tests the current token.
- *
- * @return bool
- */
- public function test($primary, $secondary = null)
- {
- return $this->tokens[$this->current]->test($primary, $secondary);
- }
-
- /**
- * Checks if end of stream was reached.
- *
- * @return bool
- */
- public function isEOF()
- {
- return Token::EOF_TYPE === $this->tokens[$this->current]->getType();
- }
-
- /**
- * @return Token
- */
- public function getCurrent()
- {
- return $this->tokens[$this->current];
- }
-
- /**
- * Gets the name associated with this stream (null if not defined).
- *
- * @return string|null
- *
- * @deprecated since 1.27 (to be removed in 2.0)
- */
- public function getFilename()
- {
- @trigger_error(sprintf('The %s() method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', __METHOD__), E_USER_DEPRECATED);
-
- return $this->source->getName();
- }
-
- /**
- * Gets the source code associated with this stream.
- *
- * @return string
- *
- * @internal Don't use this as it might be empty depending on the environment configuration
- *
- * @deprecated since 1.27 (to be removed in 2.0)
- */
- public function getSource()
- {
- @trigger_error(sprintf('The %s() method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', __METHOD__), E_USER_DEPRECATED);
-
- return $this->source->getCode();
- }
-
- /**
- * Gets the source associated with this stream.
- *
- * @return Source
- *
- * @internal
- */
- public function getSourceContext()
- {
- return $this->source;
- }
-}
-
-class_alias('Twig\TokenStream', 'Twig_TokenStream');
diff --git a/system/templateEngines/Twig/Twig1x/vendor/autoload.php b/system/templateEngines/Twig/Twig1x/vendor/autoload.php
new file mode 100644
index 0000000..ba87517
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/autoload.php
@@ -0,0 +1,7 @@
+
+ * Jordi Boggiano
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer\Autoload;
+
+/**
+ * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
+ *
+ * $loader = new \Composer\Autoload\ClassLoader();
+ *
+ * // register classes with namespaces
+ * $loader->add('Symfony\Component', __DIR__.'/component');
+ * $loader->add('Symfony', __DIR__.'/framework');
+ *
+ * // activate the autoloader
+ * $loader->register();
+ *
+ * // to enable searching the include path (eg. for PEAR packages)
+ * $loader->setUseIncludePath(true);
+ *
+ * In this example, if you try to use a class in the Symfony\Component
+ * namespace or one of its children (Symfony\Component\Console for instance),
+ * the autoloader will first look for the class under the component/
+ * directory, and it will then fallback to the framework/ directory if not
+ * found before giving up.
+ *
+ * This class is loosely based on the Symfony UniversalClassLoader.
+ *
+ * @author Fabien Potencier
+ * @author Jordi Boggiano
+ * @see https://www.php-fig.org/psr/psr-0/
+ * @see https://www.php-fig.org/psr/psr-4/
+ */
+class ClassLoader
+{
+ /** @var ?string */
+ private $vendorDir;
+
+ // PSR-4
+ /**
+ * @var array[]
+ * @psalm-var array>
+ */
+ private $prefixLengthsPsr4 = array();
+ /**
+ * @var array[]
+ * @psalm-var array>
+ */
+ private $prefixDirsPsr4 = array();
+ /**
+ * @var array[]
+ * @psalm-var array
+ */
+ private $fallbackDirsPsr4 = array();
+
+ // PSR-0
+ /**
+ * @var array[]
+ * @psalm-var array>
+ */
+ private $prefixesPsr0 = array();
+ /**
+ * @var array[]
+ * @psalm-var array
+ */
+ private $fallbackDirsPsr0 = array();
+
+ /** @var bool */
+ private $useIncludePath = false;
+
+ /**
+ * @var string[]
+ * @psalm-var array
+ */
+ private $classMap = array();
+
+ /** @var bool */
+ private $classMapAuthoritative = false;
+
+ /**
+ * @var bool[]
+ * @psalm-var array
+ */
+ private $missingClasses = array();
+
+ /** @var ?string */
+ private $apcuPrefix;
+
+ /**
+ * @var self[]
+ */
+ private static $registeredLoaders = array();
+
+ /**
+ * @param ?string $vendorDir
+ */
+ public function __construct($vendorDir = null)
+ {
+ $this->vendorDir = $vendorDir;
+ }
+
+ /**
+ * @return string[]
+ */
+ public function getPrefixes()
+ {
+ if (!empty($this->prefixesPsr0)) {
+ return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
+ }
+
+ return array();
+ }
+
+ /**
+ * @return array[]
+ * @psalm-return array>
+ */
+ public function getPrefixesPsr4()
+ {
+ return $this->prefixDirsPsr4;
+ }
+
+ /**
+ * @return array[]
+ * @psalm-return array
+ */
+ public function getFallbackDirs()
+ {
+ return $this->fallbackDirsPsr0;
+ }
+
+ /**
+ * @return array[]
+ * @psalm-return array
+ */
+ public function getFallbackDirsPsr4()
+ {
+ return $this->fallbackDirsPsr4;
+ }
+
+ /**
+ * @return string[] Array of classname => path
+ * @psalm-return array
+ */
+ public function getClassMap()
+ {
+ return $this->classMap;
+ }
+
+ /**
+ * @param string[] $classMap Class to filename map
+ * @psalm-param array $classMap
+ *
+ * @return void
+ */
+ public function addClassMap(array $classMap)
+ {
+ if ($this->classMap) {
+ $this->classMap = array_merge($this->classMap, $classMap);
+ } else {
+ $this->classMap = $classMap;
+ }
+ }
+
+ /**
+ * Registers a set of PSR-0 directories for a given prefix, either
+ * appending or prepending to the ones previously set for this prefix.
+ *
+ * @param string $prefix The prefix
+ * @param string[]|string $paths The PSR-0 root directories
+ * @param bool $prepend Whether to prepend the directories
+ *
+ * @return void
+ */
+ public function add($prefix, $paths, $prepend = false)
+ {
+ if (!$prefix) {
+ if ($prepend) {
+ $this->fallbackDirsPsr0 = array_merge(
+ (array) $paths,
+ $this->fallbackDirsPsr0
+ );
+ } else {
+ $this->fallbackDirsPsr0 = array_merge(
+ $this->fallbackDirsPsr0,
+ (array) $paths
+ );
+ }
+
+ return;
+ }
+
+ $first = $prefix[0];
+ if (!isset($this->prefixesPsr0[$first][$prefix])) {
+ $this->prefixesPsr0[$first][$prefix] = (array) $paths;
+
+ return;
+ }
+ if ($prepend) {
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
+ (array) $paths,
+ $this->prefixesPsr0[$first][$prefix]
+ );
+ } else {
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
+ $this->prefixesPsr0[$first][$prefix],
+ (array) $paths
+ );
+ }
+ }
+
+ /**
+ * Registers a set of PSR-4 directories for a given namespace, either
+ * appending or prepending to the ones previously set for this namespace.
+ *
+ * @param string $prefix The prefix/namespace, with trailing '\\'
+ * @param string[]|string $paths The PSR-4 base directories
+ * @param bool $prepend Whether to prepend the directories
+ *
+ * @throws \InvalidArgumentException
+ *
+ * @return void
+ */
+ public function addPsr4($prefix, $paths, $prepend = false)
+ {
+ if (!$prefix) {
+ // Register directories for the root namespace.
+ if ($prepend) {
+ $this->fallbackDirsPsr4 = array_merge(
+ (array) $paths,
+ $this->fallbackDirsPsr4
+ );
+ } else {
+ $this->fallbackDirsPsr4 = array_merge(
+ $this->fallbackDirsPsr4,
+ (array) $paths
+ );
+ }
+ } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
+ // Register directories for a new namespace.
+ $length = strlen($prefix);
+ if ('\\' !== $prefix[$length - 1]) {
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+ }
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
+ } elseif ($prepend) {
+ // Prepend directories for an already registered namespace.
+ $this->prefixDirsPsr4[$prefix] = array_merge(
+ (array) $paths,
+ $this->prefixDirsPsr4[$prefix]
+ );
+ } else {
+ // Append directories for an already registered namespace.
+ $this->prefixDirsPsr4[$prefix] = array_merge(
+ $this->prefixDirsPsr4[$prefix],
+ (array) $paths
+ );
+ }
+ }
+
+ /**
+ * Registers a set of PSR-0 directories for a given prefix,
+ * replacing any others previously set for this prefix.
+ *
+ * @param string $prefix The prefix
+ * @param string[]|string $paths The PSR-0 base directories
+ *
+ * @return void
+ */
+ public function set($prefix, $paths)
+ {
+ if (!$prefix) {
+ $this->fallbackDirsPsr0 = (array) $paths;
+ } else {
+ $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
+ }
+ }
+
+ /**
+ * Registers a set of PSR-4 directories for a given namespace,
+ * replacing any others previously set for this namespace.
+ *
+ * @param string $prefix The prefix/namespace, with trailing '\\'
+ * @param string[]|string $paths The PSR-4 base directories
+ *
+ * @throws \InvalidArgumentException
+ *
+ * @return void
+ */
+ public function setPsr4($prefix, $paths)
+ {
+ if (!$prefix) {
+ $this->fallbackDirsPsr4 = (array) $paths;
+ } else {
+ $length = strlen($prefix);
+ if ('\\' !== $prefix[$length - 1]) {
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+ }
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
+ }
+ }
+
+ /**
+ * Turns on searching the include path for class files.
+ *
+ * @param bool $useIncludePath
+ *
+ * @return void
+ */
+ public function setUseIncludePath($useIncludePath)
+ {
+ $this->useIncludePath = $useIncludePath;
+ }
+
+ /**
+ * Can be used to check if the autoloader uses the include path to check
+ * for classes.
+ *
+ * @return bool
+ */
+ public function getUseIncludePath()
+ {
+ return $this->useIncludePath;
+ }
+
+ /**
+ * Turns off searching the prefix and fallback directories for classes
+ * that have not been registered with the class map.
+ *
+ * @param bool $classMapAuthoritative
+ *
+ * @return void
+ */
+ public function setClassMapAuthoritative($classMapAuthoritative)
+ {
+ $this->classMapAuthoritative = $classMapAuthoritative;
+ }
+
+ /**
+ * Should class lookup fail if not found in the current class map?
+ *
+ * @return bool
+ */
+ public function isClassMapAuthoritative()
+ {
+ return $this->classMapAuthoritative;
+ }
+
+ /**
+ * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
+ *
+ * @param string|null $apcuPrefix
+ *
+ * @return void
+ */
+ public function setApcuPrefix($apcuPrefix)
+ {
+ $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
+ }
+
+ /**
+ * The APCu prefix in use, or null if APCu caching is not enabled.
+ *
+ * @return string|null
+ */
+ public function getApcuPrefix()
+ {
+ return $this->apcuPrefix;
+ }
+
+ /**
+ * Registers this instance as an autoloader.
+ *
+ * @param bool $prepend Whether to prepend the autoloader or not
+ *
+ * @return void
+ */
+ public function register($prepend = false)
+ {
+ spl_autoload_register(array($this, 'loadClass'), true, $prepend);
+
+ if (null === $this->vendorDir) {
+ return;
+ }
+
+ if ($prepend) {
+ self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
+ } else {
+ unset(self::$registeredLoaders[$this->vendorDir]);
+ self::$registeredLoaders[$this->vendorDir] = $this;
+ }
+ }
+
+ /**
+ * Unregisters this instance as an autoloader.
+ *
+ * @return void
+ */
+ public function unregister()
+ {
+ spl_autoload_unregister(array($this, 'loadClass'));
+
+ if (null !== $this->vendorDir) {
+ unset(self::$registeredLoaders[$this->vendorDir]);
+ }
+ }
+
+ /**
+ * Loads the given class or interface.
+ *
+ * @param string $class The name of the class
+ * @return true|null True if loaded, null otherwise
+ */
+ public function loadClass($class)
+ {
+ if ($file = $this->findFile($class)) {
+ includeFile($file);
+
+ return true;
+ }
+
+ return null;
+ }
+
+ /**
+ * Finds the path to the file where the class is defined.
+ *
+ * @param string $class The name of the class
+ *
+ * @return string|false The path if found, false otherwise
+ */
+ public function findFile($class)
+ {
+ // class map lookup
+ if (isset($this->classMap[$class])) {
+ return $this->classMap[$class];
+ }
+ if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
+ return false;
+ }
+ if (null !== $this->apcuPrefix) {
+ $file = apcu_fetch($this->apcuPrefix.$class, $hit);
+ if ($hit) {
+ return $file;
+ }
+ }
+
+ $file = $this->findFileWithExtension($class, '.php');
+
+ // Search for Hack files if we are running on HHVM
+ if (false === $file && defined('HHVM_VERSION')) {
+ $file = $this->findFileWithExtension($class, '.hh');
+ }
+
+ if (null !== $this->apcuPrefix) {
+ apcu_add($this->apcuPrefix.$class, $file);
+ }
+
+ if (false === $file) {
+ // Remember that this class does not exist.
+ $this->missingClasses[$class] = true;
+ }
+
+ return $file;
+ }
+
+ /**
+ * Returns the currently registered loaders indexed by their corresponding vendor directories.
+ *
+ * @return self[]
+ */
+ public static function getRegisteredLoaders()
+ {
+ return self::$registeredLoaders;
+ }
+
+ /**
+ * @param string $class
+ * @param string $ext
+ * @return string|false
+ */
+ private function findFileWithExtension($class, $ext)
+ {
+ // PSR-4 lookup
+ $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
+
+ $first = $class[0];
+ if (isset($this->prefixLengthsPsr4[$first])) {
+ $subPath = $class;
+ while (false !== $lastPos = strrpos($subPath, '\\')) {
+ $subPath = substr($subPath, 0, $lastPos);
+ $search = $subPath . '\\';
+ if (isset($this->prefixDirsPsr4[$search])) {
+ $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
+ foreach ($this->prefixDirsPsr4[$search] as $dir) {
+ if (file_exists($file = $dir . $pathEnd)) {
+ return $file;
+ }
+ }
+ }
+ }
+ }
+
+ // PSR-4 fallback dirs
+ foreach ($this->fallbackDirsPsr4 as $dir) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
+ return $file;
+ }
+ }
+
+ // PSR-0 lookup
+ if (false !== $pos = strrpos($class, '\\')) {
+ // namespaced class name
+ $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
+ . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
+ } else {
+ // PEAR-like class name
+ $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
+ }
+
+ if (isset($this->prefixesPsr0[$first])) {
+ foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
+ if (0 === strpos($class, $prefix)) {
+ foreach ($dirs as $dir) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+ return $file;
+ }
+ }
+ }
+ }
+ }
+
+ // PSR-0 fallback dirs
+ foreach ($this->fallbackDirsPsr0 as $dir) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+ return $file;
+ }
+ }
+
+ // PSR-0 include paths.
+ if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
+ return $file;
+ }
+
+ return false;
+ }
+}
+
+/**
+ * Scope isolated include.
+ *
+ * Prevents access to $this/self from included files.
+ *
+ * @param string $file
+ * @return void
+ * @private
+ */
+function includeFile($file)
+{
+ include $file;
+}
diff --git a/system/templateEngines/Twig/Twig1x/vendor/composer/InstalledVersions.php b/system/templateEngines/Twig/Twig1x/vendor/composer/InstalledVersions.php
new file mode 100644
index 0000000..d50e0c9
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/composer/InstalledVersions.php
@@ -0,0 +1,350 @@
+
+ * Jordi Boggiano
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer;
+
+use Composer\Autoload\ClassLoader;
+use Composer\Semver\VersionParser;
+
+/**
+ * This class is copied in every Composer installed project and available to all
+ *
+ * See also https://getcomposer.org/doc/07-runtime.md#installed-versions
+ *
+ * To require its presence, you can require `composer-runtime-api ^2.0`
+ */
+class InstalledVersions
+{
+ /**
+ * @var mixed[]|null
+ * @psalm-var array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array}|array{}|null
+ */
+ private static $installed;
+
+ /**
+ * @var bool|null
+ */
+ private static $canGetVendors;
+
+ /**
+ * @var array[]
+ * @psalm-var array}>
+ */
+ private static $installedByVendor = array();
+
+ /**
+ * Returns a list of all package names which are present, either by being installed, replaced or provided
+ *
+ * @return string[]
+ * @psalm-return list
+ */
+ public static function getInstalledPackages()
+ {
+ $packages = array();
+ foreach (self::getInstalled() as $installed) {
+ $packages[] = array_keys($installed['versions']);
+ }
+
+ if (1 === \count($packages)) {
+ return $packages[0];
+ }
+
+ return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
+ }
+
+ /**
+ * Returns a list of all package names with a specific type e.g. 'library'
+ *
+ * @param string $type
+ * @return string[]
+ * @psalm-return list
+ */
+ public static function getInstalledPackagesByType($type)
+ {
+ $packagesByType = array();
+
+ foreach (self::getInstalled() as $installed) {
+ foreach ($installed['versions'] as $name => $package) {
+ if (isset($package['type']) && $package['type'] === $type) {
+ $packagesByType[] = $name;
+ }
+ }
+ }
+
+ return $packagesByType;
+ }
+
+ /**
+ * Checks whether the given package is installed
+ *
+ * This also returns true if the package name is provided or replaced by another package
+ *
+ * @param string $packageName
+ * @param bool $includeDevRequirements
+ * @return bool
+ */
+ public static function isInstalled($packageName, $includeDevRequirements = true)
+ {
+ foreach (self::getInstalled() as $installed) {
+ if (isset($installed['versions'][$packageName])) {
+ return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']);
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Checks whether the given package satisfies a version constraint
+ *
+ * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
+ *
+ * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
+ *
+ * @param VersionParser $parser Install composer/semver to have access to this class and functionality
+ * @param string $packageName
+ * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
+ * @return bool
+ */
+ public static function satisfies(VersionParser $parser, $packageName, $constraint)
+ {
+ $constraint = $parser->parseConstraints($constraint);
+ $provided = $parser->parseConstraints(self::getVersionRanges($packageName));
+
+ return $provided->matches($constraint);
+ }
+
+ /**
+ * Returns a version constraint representing all the range(s) which are installed for a given package
+ *
+ * It is easier to use this via isInstalled() with the $constraint argument if you need to check
+ * whether a given version of a package is installed, and not just whether it exists
+ *
+ * @param string $packageName
+ * @return string Version constraint usable with composer/semver
+ */
+ public static function getVersionRanges($packageName)
+ {
+ foreach (self::getInstalled() as $installed) {
+ if (!isset($installed['versions'][$packageName])) {
+ continue;
+ }
+
+ $ranges = array();
+ if (isset($installed['versions'][$packageName]['pretty_version'])) {
+ $ranges[] = $installed['versions'][$packageName]['pretty_version'];
+ }
+ if (array_key_exists('aliases', $installed['versions'][$packageName])) {
+ $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
+ }
+ if (array_key_exists('replaced', $installed['versions'][$packageName])) {
+ $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
+ }
+ if (array_key_exists('provided', $installed['versions'][$packageName])) {
+ $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
+ }
+
+ return implode(' || ', $ranges);
+ }
+
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+ }
+
+ /**
+ * @param string $packageName
+ * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
+ */
+ public static function getVersion($packageName)
+ {
+ foreach (self::getInstalled() as $installed) {
+ if (!isset($installed['versions'][$packageName])) {
+ continue;
+ }
+
+ if (!isset($installed['versions'][$packageName]['version'])) {
+ return null;
+ }
+
+ return $installed['versions'][$packageName]['version'];
+ }
+
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+ }
+
+ /**
+ * @param string $packageName
+ * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
+ */
+ public static function getPrettyVersion($packageName)
+ {
+ foreach (self::getInstalled() as $installed) {
+ if (!isset($installed['versions'][$packageName])) {
+ continue;
+ }
+
+ if (!isset($installed['versions'][$packageName]['pretty_version'])) {
+ return null;
+ }
+
+ return $installed['versions'][$packageName]['pretty_version'];
+ }
+
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+ }
+
+ /**
+ * @param string $packageName
+ * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
+ */
+ public static function getReference($packageName)
+ {
+ foreach (self::getInstalled() as $installed) {
+ if (!isset($installed['versions'][$packageName])) {
+ continue;
+ }
+
+ if (!isset($installed['versions'][$packageName]['reference'])) {
+ return null;
+ }
+
+ return $installed['versions'][$packageName]['reference'];
+ }
+
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+ }
+
+ /**
+ * @param string $packageName
+ * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
+ */
+ public static function getInstallPath($packageName)
+ {
+ foreach (self::getInstalled() as $installed) {
+ if (!isset($installed['versions'][$packageName])) {
+ continue;
+ }
+
+ return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
+ }
+
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+ }
+
+ /**
+ * @return array
+ * @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}
+ */
+ public static function getRootPackage()
+ {
+ $installed = self::getInstalled();
+
+ return $installed[0]['root'];
+ }
+
+ /**
+ * Returns the raw installed.php data for custom implementations
+ *
+ * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
+ * @return array[]
+ * @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array}
+ */
+ public static function getRawData()
+ {
+ @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
+
+ if (null === self::$installed) {
+ // only require the installed.php file if this file is loaded from its dumped location,
+ // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
+ if (substr(__DIR__, -8, 1) !== 'C') {
+ self::$installed = include __DIR__ . '/installed.php';
+ } else {
+ self::$installed = array();
+ }
+ }
+
+ return self::$installed;
+ }
+
+ /**
+ * Returns the raw data of all installed.php which are currently loaded for custom implementations
+ *
+ * @return array[]
+ * @psalm-return list}>
+ */
+ public static function getAllRawData()
+ {
+ return self::getInstalled();
+ }
+
+ /**
+ * Lets you reload the static array from another file
+ *
+ * This is only useful for complex integrations in which a project needs to use
+ * this class but then also needs to execute another project's autoloader in process,
+ * and wants to ensure both projects have access to their version of installed.php.
+ *
+ * A typical case would be PHPUnit, where it would need to make sure it reads all
+ * the data it needs from this class, then call reload() with
+ * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
+ * the project in which it runs can then also use this class safely, without
+ * interference between PHPUnit's dependencies and the project's dependencies.
+ *
+ * @param array[] $data A vendor/composer/installed.php data set
+ * @return void
+ *
+ * @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array} $data
+ */
+ public static function reload($data)
+ {
+ self::$installed = $data;
+ self::$installedByVendor = array();
+ }
+
+ /**
+ * @return array[]
+ * @psalm-return list}>
+ */
+ private static function getInstalled()
+ {
+ if (null === self::$canGetVendors) {
+ self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
+ }
+
+ $installed = array();
+
+ if (self::$canGetVendors) {
+ foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
+ if (isset(self::$installedByVendor[$vendorDir])) {
+ $installed[] = self::$installedByVendor[$vendorDir];
+ } elseif (is_file($vendorDir.'/composer/installed.php')) {
+ $installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
+ if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
+ self::$installed = $installed[count($installed) - 1];
+ }
+ }
+ }
+ }
+
+ if (null === self::$installed) {
+ // only require the installed.php file if this file is loaded from its dumped location,
+ // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
+ if (substr(__DIR__, -8, 1) !== 'C') {
+ self::$installed = require __DIR__ . '/installed.php';
+ } else {
+ self::$installed = array();
+ }
+ }
+ $installed[] = self::$installed;
+
+ return $installed;
+ }
+}
diff --git a/system/templateEngines/Twig/Twig1x/composer/LICENSE b/system/templateEngines/Twig/Twig1x/vendor/composer/LICENSE
similarity index 100%
rename from system/templateEngines/Twig/Twig1x/composer/LICENSE
rename to system/templateEngines/Twig/Twig1x/vendor/composer/LICENSE
diff --git a/system/templateEngines/Twig/Twig1x/vendor/composer/autoload_classmap.php b/system/templateEngines/Twig/Twig1x/vendor/composer/autoload_classmap.php
new file mode 100644
index 0000000..b26f1b1
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/composer/autoload_classmap.php
@@ -0,0 +1,10 @@
+ $vendorDir . '/composer/InstalledVersions.php',
+);
diff --git a/system/templateEngines/Twig/Twig1x/composer/autoload_files.php b/system/templateEngines/Twig/Twig1x/vendor/composer/autoload_files.php
similarity index 100%
rename from system/templateEngines/Twig/Twig1x/composer/autoload_files.php
rename to system/templateEngines/Twig/Twig1x/vendor/composer/autoload_files.php
diff --git a/system/templateEngines/Twig/Twig1x/composer/autoload_namespaces.php b/system/templateEngines/Twig/Twig1x/vendor/composer/autoload_namespaces.php
similarity index 100%
rename from system/templateEngines/Twig/Twig1x/composer/autoload_namespaces.php
rename to system/templateEngines/Twig/Twig1x/vendor/composer/autoload_namespaces.php
diff --git a/system/templateEngines/Twig/Twig1x/composer/autoload_psr4.php b/system/templateEngines/Twig/Twig1x/vendor/composer/autoload_psr4.php
similarity index 100%
rename from system/templateEngines/Twig/Twig1x/composer/autoload_psr4.php
rename to system/templateEngines/Twig/Twig1x/vendor/composer/autoload_psr4.php
diff --git a/system/templateEngines/Twig/Twig1x/vendor/composer/autoload_real.php b/system/templateEngines/Twig/Twig1x/vendor/composer/autoload_real.php
new file mode 100644
index 0000000..3c8f095
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/composer/autoload_real.php
@@ -0,0 +1,78 @@
+= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
+ if ($useStaticLoader) {
+ require __DIR__ . '/autoload_static.php';
+
+ call_user_func(\Composer\Autoload\ComposerStaticInitd25cb76cddd6d156bbe462150d7e99ae::getInitializer($loader));
+ } else {
+ $map = require __DIR__ . '/autoload_namespaces.php';
+ foreach ($map as $namespace => $path) {
+ $loader->set($namespace, $path);
+ }
+
+ $map = require __DIR__ . '/autoload_psr4.php';
+ foreach ($map as $namespace => $path) {
+ $loader->setPsr4($namespace, $path);
+ }
+
+ $classMap = require __DIR__ . '/autoload_classmap.php';
+ if ($classMap) {
+ $loader->addClassMap($classMap);
+ }
+ }
+
+ $loader->register(true);
+
+ if ($useStaticLoader) {
+ $includeFiles = Composer\Autoload\ComposerStaticInitd25cb76cddd6d156bbe462150d7e99ae::$files;
+ } else {
+ $includeFiles = require __DIR__ . '/autoload_files.php';
+ }
+ foreach ($includeFiles as $fileIdentifier => $file) {
+ composerRequired25cb76cddd6d156bbe462150d7e99ae($fileIdentifier, $file);
+ }
+
+ return $loader;
+ }
+}
+
+/**
+ * @param string $fileIdentifier
+ * @param string $file
+ * @return void
+ */
+function composerRequired25cb76cddd6d156bbe462150d7e99ae($fileIdentifier, $file)
+{
+ if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
+ $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
+
+ require $file;
+ }
+}
diff --git a/system/templateEngines/Twig/Twig1x/vendor/composer/autoload_static.php b/system/templateEngines/Twig/Twig1x/vendor/composer/autoload_static.php
new file mode 100644
index 0000000..b279c1d
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/composer/autoload_static.php
@@ -0,0 +1,59 @@
+ __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
+ );
+
+ public static $prefixLengthsPsr4 = array (
+ 'T' =>
+ array (
+ 'Twig\\' => 5,
+ ),
+ 'S' =>
+ array (
+ 'Symfony\\Polyfill\\Ctype\\' => 23,
+ ),
+ );
+
+ public static $prefixDirsPsr4 = array (
+ 'Twig\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/twig/twig/src',
+ ),
+ 'Symfony\\Polyfill\\Ctype\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/symfony/polyfill-ctype',
+ ),
+ );
+
+ public static $prefixesPsr0 = array (
+ 'T' =>
+ array (
+ 'Twig_' =>
+ array (
+ 0 => __DIR__ . '/..' . '/twig/twig/lib',
+ ),
+ ),
+ );
+
+ public static $classMap = array (
+ 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
+ );
+
+ public static function getInitializer(ClassLoader $loader)
+ {
+ return \Closure::bind(function () use ($loader) {
+ $loader->prefixLengthsPsr4 = ComposerStaticInitd25cb76cddd6d156bbe462150d7e99ae::$prefixLengthsPsr4;
+ $loader->prefixDirsPsr4 = ComposerStaticInitd25cb76cddd6d156bbe462150d7e99ae::$prefixDirsPsr4;
+ $loader->prefixesPsr0 = ComposerStaticInitd25cb76cddd6d156bbe462150d7e99ae::$prefixesPsr0;
+ $loader->classMap = ComposerStaticInitd25cb76cddd6d156bbe462150d7e99ae::$classMap;
+
+ }, null, ClassLoader::class);
+ }
+}
diff --git a/system/templateEngines/Twig/Twig1x/vendor/composer/installed.json b/system/templateEngines/Twig/Twig1x/vendor/composer/installed.json
new file mode 100644
index 0000000..dc33600
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/composer/installed.json
@@ -0,0 +1,161 @@
+{
+ "packages": [
+ {
+ "name": "symfony/polyfill-ctype",
+ "version": "v1.19.0",
+ "version_normalized": "1.19.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-ctype.git",
+ "reference": "aed596913b70fae57be53d86faa2e9ef85a2297b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/aed596913b70fae57be53d86faa2e9ef85a2297b",
+ "reference": "aed596913b70fae57be53d86faa2e9ef85a2297b",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "suggest": {
+ "ext-ctype": "For best performance"
+ },
+ "time": "2020-10-23T09:01:57+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.19-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Ctype\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Gert de Pagter",
+ "email": "BackEndTea@gmail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for ctype functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "ctype",
+ "polyfill",
+ "portable"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-ctype/tree/v1.19.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "install-path": "../symfony/polyfill-ctype"
+ },
+ {
+ "name": "twig/twig",
+ "version": "v1.41.0",
+ "version_normalized": "1.41.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/twigphp/Twig.git",
+ "reference": "575cd5028362da591facde1ef5d7b94553c375c9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/twigphp/Twig/zipball/575cd5028362da591facde1ef5d7b94553c375c9",
+ "reference": "575cd5028362da591facde1ef5d7b94553c375c9",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.4.0",
+ "symfony/polyfill-ctype": "^1.8"
+ },
+ "require-dev": {
+ "psr/container": "^1.0",
+ "symfony/debug": "^2.7",
+ "symfony/phpunit-bridge": "^3.4.19|^4.1.8"
+ },
+ "time": "2019-05-14T11:59:08+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.41-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-0": {
+ "Twig_": "lib/"
+ },
+ "psr-4": {
+ "Twig\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
+ },
+ {
+ "name": "Armin Ronacher",
+ "email": "armin.ronacher@active-4.com",
+ "role": "Project Founder"
+ },
+ {
+ "name": "Twig Team",
+ "homepage": "https://twig.symfony.com/contributors",
+ "role": "Contributors"
+ }
+ ],
+ "description": "Twig, the flexible, fast, and secure template language for PHP",
+ "homepage": "https://twig.symfony.com",
+ "keywords": [
+ "templating"
+ ],
+ "support": {
+ "issues": "https://github.com/twigphp/Twig/issues",
+ "source": "https://github.com/twigphp/Twig/tree/1.x"
+ },
+ "install-path": "../twig/twig"
+ }
+ ],
+ "dev": true,
+ "dev-package-names": []
+}
diff --git a/system/templateEngines/Twig/Twig1x/vendor/composer/installed.php b/system/templateEngines/Twig/Twig1x/vendor/composer/installed.php
new file mode 100644
index 0000000..25dc620
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/composer/installed.php
@@ -0,0 +1,41 @@
+ array(
+ 'pretty_version' => 'dev-master',
+ 'version' => 'dev-master',
+ 'type' => 'library',
+ 'install_path' => __DIR__ . '/../../',
+ 'aliases' => array(),
+ 'reference' => '5f95caecf5ad6c259def076c6ebaa5a42461206e',
+ 'name' => '__root__',
+ 'dev' => true,
+ ),
+ 'versions' => array(
+ '__root__' => array(
+ 'pretty_version' => 'dev-master',
+ 'version' => 'dev-master',
+ 'type' => 'library',
+ 'install_path' => __DIR__ . '/../../',
+ 'aliases' => array(),
+ 'reference' => '5f95caecf5ad6c259def076c6ebaa5a42461206e',
+ 'dev_requirement' => false,
+ ),
+ 'symfony/polyfill-ctype' => array(
+ 'pretty_version' => 'v1.19.0',
+ 'version' => '1.19.0.0',
+ 'type' => 'library',
+ 'install_path' => __DIR__ . '/../symfony/polyfill-ctype',
+ 'aliases' => array(),
+ 'reference' => 'aed596913b70fae57be53d86faa2e9ef85a2297b',
+ 'dev_requirement' => false,
+ ),
+ 'twig/twig' => array(
+ 'pretty_version' => 'v1.41.0',
+ 'version' => '1.41.0.0',
+ 'type' => 'library',
+ 'install_path' => __DIR__ . '/../twig/twig',
+ 'aliases' => array(),
+ 'reference' => '575cd5028362da591facde1ef5d7b94553c375c9',
+ 'dev_requirement' => false,
+ ),
+ ),
+);
diff --git a/system/templateEngines/Twig/Twig1x/symfony/polyfill-ctype/Ctype.php b/system/templateEngines/Twig/Twig1x/vendor/symfony/polyfill-ctype/Ctype.php
similarity index 100%
rename from system/templateEngines/Twig/Twig1x/symfony/polyfill-ctype/Ctype.php
rename to system/templateEngines/Twig/Twig1x/vendor/symfony/polyfill-ctype/Ctype.php
diff --git a/system/templateEngines/Twig/Twig1x/symfony/polyfill-ctype/LICENSE b/system/templateEngines/Twig/Twig1x/vendor/symfony/polyfill-ctype/LICENSE
similarity index 100%
rename from system/templateEngines/Twig/Twig1x/symfony/polyfill-ctype/LICENSE
rename to system/templateEngines/Twig/Twig1x/vendor/symfony/polyfill-ctype/LICENSE
diff --git a/system/templateEngines/Twig/Twig1x/symfony/polyfill-ctype/README.md b/system/templateEngines/Twig/Twig1x/vendor/symfony/polyfill-ctype/README.md
similarity index 100%
rename from system/templateEngines/Twig/Twig1x/symfony/polyfill-ctype/README.md
rename to system/templateEngines/Twig/Twig1x/vendor/symfony/polyfill-ctype/README.md
diff --git a/system/templateEngines/Twig/Twig1x/vendor/symfony/polyfill-ctype/bootstrap.php b/system/templateEngines/Twig/Twig1x/vendor/symfony/polyfill-ctype/bootstrap.php
new file mode 100644
index 0000000..0bc45cf
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/symfony/polyfill-ctype/bootstrap.php
@@ -0,0 +1,46 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use Symfony\Polyfill\Ctype as p;
+
+if (!function_exists('ctype_alnum')) {
+ function ctype_alnum($input) { return p\Ctype::ctype_alnum($input); }
+}
+if (!function_exists('ctype_alpha')) {
+ function ctype_alpha($input) { return p\Ctype::ctype_alpha($input); }
+}
+if (!function_exists('ctype_cntrl')) {
+ function ctype_cntrl($input) { return p\Ctype::ctype_cntrl($input); }
+}
+if (!function_exists('ctype_digit')) {
+ function ctype_digit($input) { return p\Ctype::ctype_digit($input); }
+}
+if (!function_exists('ctype_graph')) {
+ function ctype_graph($input) { return p\Ctype::ctype_graph($input); }
+}
+if (!function_exists('ctype_lower')) {
+ function ctype_lower($input) { return p\Ctype::ctype_lower($input); }
+}
+if (!function_exists('ctype_print')) {
+ function ctype_print($input) { return p\Ctype::ctype_print($input); }
+}
+if (!function_exists('ctype_punct')) {
+ function ctype_punct($input) { return p\Ctype::ctype_punct($input); }
+}
+if (!function_exists('ctype_space')) {
+ function ctype_space($input) { return p\Ctype::ctype_space($input); }
+}
+if (!function_exists('ctype_upper')) {
+ function ctype_upper($input) { return p\Ctype::ctype_upper($input); }
+}
+if (!function_exists('ctype_xdigit')) {
+ function ctype_xdigit($input) { return p\Ctype::ctype_xdigit($input); }
+}
diff --git a/system/templateEngines/Twig/Twig1x/vendor/symfony/polyfill-ctype/composer.json b/system/templateEngines/Twig/Twig1x/vendor/symfony/polyfill-ctype/composer.json
new file mode 100644
index 0000000..d7c9abb
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/symfony/polyfill-ctype/composer.json
@@ -0,0 +1,38 @@
+{
+ "name": "symfony/polyfill-ctype",
+ "type": "library",
+ "description": "Symfony polyfill for ctype functions",
+ "keywords": ["polyfill", "compatibility", "portable", "ctype"],
+ "homepage": "https://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Gert de Pagter",
+ "email": "BackEndTea@gmail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "autoload": {
+ "psr-4": { "Symfony\\Polyfill\\Ctype\\": "" },
+ "files": [ "bootstrap.php" ]
+ },
+ "suggest": {
+ "ext-ctype": "For best performance"
+ },
+ "minimum-stability": "dev",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.19-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ }
+}
diff --git a/system/templateEngines/Twig/Twig1x/twig/twig/.editorconfig b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/.editorconfig
similarity index 100%
rename from system/templateEngines/Twig/Twig1x/twig/twig/.editorconfig
rename to system/templateEngines/Twig/Twig1x/vendor/twig/twig/.editorconfig
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/.gitignore b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/.gitignore
new file mode 100644
index 0000000..3110362
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/.gitignore
@@ -0,0 +1,5 @@
+/build
+/composer.lock
+/ext/twig/autom4te.cache/
+/phpunit.xml
+/vendor
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/.php_cs.dist b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/.php_cs.dist
new file mode 100644
index 0000000..1b31c0a
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/.php_cs.dist
@@ -0,0 +1,18 @@
+setRules([
+ '@Symfony' => true,
+ '@Symfony:risky' => true,
+ 'array_syntax' => ['syntax' => 'short'],
+ 'php_unit_fqcn_annotation' => true,
+ 'no_unreachable_default_argument_value' => false,
+ 'braces' => ['allow_single_line_closure' => true],
+ 'heredoc_to_nowdoc' => false,
+ 'ordered_imports' => true,
+ 'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'],
+ 'native_function_invocation' => ['include' => ['@compiler_optimized'], 'scope' => 'all'],
+ ])
+ ->setRiskyAllowed(true)
+ ->setFinder(PhpCsFixer\Finder::create()->in(__DIR__))
+;
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/.travis.yml b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/.travis.yml
new file mode 100644
index 0000000..291b4a9
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/.travis.yml
@@ -0,0 +1,44 @@
+language: php
+
+sudo: false
+
+cache:
+ directories:
+ - vendor
+ - $HOME/.composer/cache/files
+
+env:
+ - TWIG_EXT=no
+
+before_install:
+ - phpenv config-rm xdebug.ini || return 0
+
+install:
+ - travis_retry composer install
+
+before_script:
+ - if [ "$TWIG_EXT" == "yes" ]; then sh -c "cd ext/twig && phpize && ./configure --enable-twig && make && make install"; fi
+ - if [ "$TWIG_EXT" == "yes" ]; then echo "extension=twig.so" >> `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"`; fi
+
+script: ./vendor/bin/simple-phpunit
+
+jobs:
+ fast_finish: true
+ include:
+ - php: 5.4
+ - php: 5.4
+ env: TWIG_EXT=yes
+ - php: 5.5
+ - php: 5.5
+ env: TWIG_EXT=yes
+ - php: 5.6
+ - php: 5.6
+ env: TWIG_EXT=yes
+ - php: 7.0
+ - php: 7.1
+ - php: 7.2
+ - php: 7.3
+ - php: 7.4snapshot
+ - stage: integration tests
+ php: 7.3
+ script: ./drupal_test.sh
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/CHANGELOG b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/CHANGELOG
new file mode 100644
index 0000000..72948e5
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/CHANGELOG
@@ -0,0 +1,1105 @@
+* 1.41.0 (2019-05-14)
+
+ * fixed support for PHP 7.4
+ * added "filter", "map", and "reduce" filters (and support for arrow functions)
+ * fixed partial output leak when a PHP fatal error occurs
+ * optimized context access on PHP 7.4
+
+* 1.40.1 (2019-04-29)
+
+* fixed regression in NodeTraverser
+
+* 1.40.0 (2019-04-28)
+
+ * allowed Twig\NodeVisitor\NodeVisitorInterface::leaveNode() to return "null" instead of "false" (same meaning)
+ * added the "apply" tag as a replacement for the "filter" tag
+ * allowed Twig\Loader\FilesystemLoader::findTemplate() to return "null" instead of "false" (same meaning)
+ * added support for "Twig\Markup" instances in the "in" test
+ * fixed Lexer when using custom options containing the # char
+ * fixed "import" when macros are stored in a template string
+
+* 1.39.1 (2019-04-16)
+
+ * fixed EscaperNodeVisitor
+
+* 1.39.0 (2019-04-16)
+
+ * added Traversable support for the length filter
+ * fixed some wrong location in error messages
+ * made exception creation faster
+ * made escaping on ternary expressions (?: and ??) more fine-grained
+ * added the possibility to give a nice name to string templates (template_from_string function)
+ * fixed the "with" behavior to always include the globals (for consistency with the "include" and "embed" tags)
+ * fixed "include" with "ignore missing" when an error loading occurs in the included template
+ * added support for a new whitespace trimming option ({%~ ~%}, {{~ ~}}, {#~ ~#})
+
+* 1.38.4 (2019-03-23)
+
+ * fixed CheckToStringNode implementation (broken when a function/filter is variadic)
+
+* 1.38.3 (2019-03-21)
+
+ * fixed the spaceless filter so that it behaves like the spaceless tag
+ * fixed BC break on Environment::resolveTemplate()
+ * fixed the bundled Autoloader to also load namespaced classes
+ * allowed Traversable objects to be used in the "with" tag
+ * allowed Traversable objects to be used in the "with" argument of the "include" and "embed" tags
+
+* 1.38.2 (2019-03-12)
+
+ * added TemplateWrapper::getTemplateName()
+
+* 1.38.1 (2019-03-12)
+
+ * fixed class aliases
+
+* 1.38.0 (2019-03-12)
+
+ * fixed sandbox security issue (under some circumstances, calling the
+ __toString() method on an object was possible even if not allowed by the
+ security policy)
+ * fixed batch filter clobbers array keys when fill parameter is used
+ * added preserveKeys support for the batch filter
+ * fixed "embed" support when used from "template_from_string"
+ * added the possibility to pass a TemplateWrapper to Twig\Environment::load()
+ * improved the performance of the sandbox
+ * added a spaceless filter
+ * added max value to the "random" function
+ * made namespace classes the default classes (PSR-0 ones are aliases now)
+ * removed duplicated directory separator in FilesystemLoader
+ * added Twig\Loader\ChainLoader::getLoaders()
+ * changed internal code to use the namespaced classes as much as possible
+
+* 1.37.1 (2019-01-14)
+
+ * fixed regression (key exists check for non ArrayObject objects)
+ * fixed logic in TemplateWrapper
+
+* 1.37.0 (2019-01-14)
+
+ * fixed ArrayObject access with a null value
+ * fixed embedded templates starting with a BOM
+ * fixed using a Twig_TemplateWrapper instance as an argument to extends
+ * switched generated code to use the PHP short array notation
+ * dropped PHP 5.3 support
+ * fixed float representation in compiled templates
+ * added a second argument to the join filter (last separator configuration)
+
+* 1.36.0 (2018-12-16)
+
+ * made sure twig_include returns a string
+ * fixed multi-byte UFT-8 in escape('html_attr')
+ * added the "deprecated" tag
+ * added support for dynamically named tests
+ * fixed GlobalsInterface extended class
+ * fixed filesystem loader throwing an exception instead of returning false
+
+* 1.35.4 (2018-07-13)
+
+ * ensured that syntax errors are triggered with the right line
+ * added the Symfony ctype polyfill as a dependency
+ * "js" filter now produces valid JSON
+
+* 1.35.3 (2018-03-20)
+
+ * fixed block names unicity
+ * fixed counting children of SimpleXMLElement objects
+ * added missing else clause to avoid infinite loops
+ * fixed .. (range operator) in sandbox policy
+
+* 1.35.2 (2018-03-03)
+
+ * fixed a regression in the way the profiler is registered in templates
+
+* 1.35.1 (2018-03-02)
+
+ * added an exception when using "===" instead of "same as"
+ * fixed possible array to string conversion concealing actual error
+ * made variable names deterministic in compiled templates
+ * fixed length filter when passing an instance of IteratorAggregate
+ * fixed Environment::resolveTemplate to accept instances of TemplateWrapper
+
+* 1.35.0 (2017-09-27)
+
+ * added Twig_Profiler_Profile::reset()
+ * fixed use TokenParser to return an empty Node
+ * added RuntimeExtensionInterface
+ * added circular reference detection when loading templates
+
+* 1.34.4 (2017-07-04)
+
+ * added support for runtime loaders in IntegrationTestCase
+ * fixed deprecation when using Twig_Profiler_Dumper_Html
+
+* 1.34.3 (2017-06-07)
+
+ * fixed namespaces introduction
+
+* 1.34.2 (2017-06-05)
+
+ * fixed namespaces introduction
+
+* 1.34.1 (2017-06-05)
+
+ * fixed namespaces introduction
+
+* 1.34.0 (2017-06-05)
+
+ * added support for PHPUnit 6 when testing extensions
+ * fixed PHP 7.2 compatibility
+ * fixed template name generation in Twig_Environment::createTemplate()
+ * removed final tag on Twig_TokenParser_Include
+ * added namespaced aliases for all (non-deprecated) classes and interfaces
+ * dropped HHVM support
+ * dropped PHP 5.2 support
+
+* 1.33.2 (2017-04-20)
+
+ * fixed edge case in the method cache for Twig attributes
+
+* 1.33.1 (2017-04-18)
+
+ * fixed the empty() test
+
+* 1.33.0 (2017-03-22)
+
+ * fixed a race condition handling when writing cache files
+ * "length" filter now returns string length when applied to an object that does
+ not implement \Countable but provides __toString()
+ * "empty" test will now consider the return value of the __toString() method for
+ objects implement __toString() but not \Countable
+ * fixed JS escaping for unicode characters with higher code points
+
+* 1.32.0 (2017-02-26)
+
+ * fixed deprecation notice in Twig_Util_DeprecationCollector
+ * added a PSR-11 compatible runtime loader
+ * added `side` argument to `trim` to allow left or right trimming only.
+
+* 1.31.0 (2017-01-11)
+
+ * added Twig_NodeCaptureInterface for nodes that capture all output
+ * fixed marking the environment as initialized too early
+ * fixed C89 compat for the C extension
+ * turned fatal error into exception when a previously generated cache is corrupted
+ * fixed offline cache warm-ups for embedded templates
+
+* 1.30.0 (2016-12-23)
+
+ * added Twig_FactoryRuntimeLoader
+ * deprecated function/test/filter/tag overriding
+ * deprecated the "disable_c_ext" attribute on Twig_Node_Expression_GetAttr
+
+* 1.29.0 (2016-12-13)
+
+ * fixed sandbox being left enabled if an exception is thrown while rendering
+ * marked some classes as being final (via @final)
+ * made Twig_Error report real source path when possible
+ * added support for {{ _self }} to provide an upgrade path from 1.x to 2.0 (replaces {{ _self.templateName }})
+ * deprecated silent display of undefined blocks
+ * deprecated support for mbstring.func_overload != 0
+
+* 1.28.2 (2016-11-23)
+
+ * fixed precedence between getFoo() and isFoo() in Twig_Template::getAttribute()
+ * improved a deprecation message
+
+* 1.28.1 (2016-11-18)
+
+ * fixed block() function when used with a template argument
+
+* 1.28.0 (2016-11-17)
+
+ * added support for the PHP 7 null coalescing operator for the ?? Twig implementation
+ * exposed a way to access template data and methods in a portable way
+ * changed context access to use the PHP 7 null coalescing operator when available
+ * added the "with" tag
+ * added support for a custom template on the block() function
+ * added "is defined" support for block() and constant()
+ * optimized the way attributes are fetched
+
+* 1.27.0 (2016-10-25)
+
+ * deprecated Twig_Parser::getEnvironment()
+ * deprecated Twig_Parser::addHandler() and Twig_Parser::addNodeVisitor()
+ * deprecated Twig_Compiler::addIndentation()
+ * fixed regression when registering two extensions having the same class name
+ * deprecated Twig_LoaderInterface::getSource() (implement Twig_SourceContextLoaderInterface instead)
+ * fixed the filesystem loader with relative paths
+ * deprecated Twig_Node::getLine() in favor of Twig_Node::getTemplateLine()
+ * deprecated Twig_Template::getSource() in favor of Twig_Template::getSourceContext()
+ * deprecated Twig_Node::getFilename() in favor of Twig_Node::getTemplateName()
+ * deprecated the "filename" escaping strategy (use "name" instead)
+ * added Twig_Source to hold information about the original template
+ * deprecated Twig_Error::getTemplateFile() and Twig_Error::setTemplateFile() in favor of Twig_Error::getTemplateName() and Twig_Error::setTemplateName()
+ * deprecated Parser::getFilename()
+ * fixed template paths when a template name contains a protocol like vfs://
+ * improved debugging with Twig_Sandbox_SecurityError exceptions for disallowed methods and properties
+
+* 1.26.1 (2016-10-05)
+
+ * removed template source code from generated template classes when debug is disabled
+ * fixed default implementation of Twig_Template::getDebugInfo() for better BC
+ * fixed regression on static calls for functions/filters/tests
+
+* 1.26.0 (2016-10-02)
+
+ * added template cache invalidation based on more environment options
+ * added a missing deprecation notice
+ * fixed template paths when a template is stored in a PHAR file
+ * allowed filters/functions/tests implementation to use a different class than the extension they belong to
+ * deprecated Twig_ExtensionInterface::getName()
+
+* 1.25.0 (2016-09-21)
+
+ * changed the way we store template source in template classes
+ * removed usage of realpath in cache keys
+ * fixed Twig cache sharing when used with different versions of PHP
+ * removed embed parent workaround for simple use cases
+ * deprecated the ability to store non Node instances in Node::$nodes
+ * deprecated Twig_Environment::getLexer(), Twig_Environment::getParser(), Twig_Environment::getCompiler()
+ * deprecated Twig_Compiler::getFilename()
+
+* 1.24.2 (2016-09-01)
+
+ * fixed static callables
+ * fixed a potential PHP warning when loading the cache
+ * fixed a case where the autoescaping does not work as expected
+
+* 1.24.1 (2016-05-30)
+
+ * fixed reserved keywords (forbids true, false, null and none keywords for variables names)
+ * fixed support for PHP7 (Throwable support)
+ * marked the following methods as being internals on Twig_Environment:
+ getFunctions(), getFilters(), getTests(), getFunction(), getFilter(), getTest(),
+ getTokenParsers(), getTags(), getNodeVisitors(), getUnaryOperators(), getBinaryOperators(),
+ getFunctions(), getFilters(), getGlobals(), initGlobals(), initExtensions(), and initExtension()
+
+* 1.24.0 (2016-01-25)
+
+ * adding support for the ?? operator
+ * fixed the defined test when used on a constant, a map, or a sequence
+ * undeprecated _self (should only be used to get the template name, not the template instance)
+ * fixed parsing on PHP7
+
+* 1.23.3 (2016-01-11)
+
+ * fixed typo
+
+* 1.23.2 (2015-01-11)
+
+ * added versions in deprecated messages
+ * made file cache tolerant for trailing (back)slashes on directory configuration
+ * deprecated unused Twig_Node_Expression_ExtensionReference class
+
+* 1.23.1 (2015-11-05)
+
+ * fixed some exception messages which triggered PHP warnings
+ * fixed BC on Twig_Test_NodeTestCase
+
+* 1.23.0 (2015-10-29)
+
+ * deprecated the possibility to override an extension by registering another one with the same name
+ * deprecated Twig_ExtensionInterface::getGlobals() (added Twig_Extension_GlobalsInterface for BC)
+ * deprecated Twig_ExtensionInterface::initRuntime() (added Twig_Extension_InitRuntimeInterface for BC)
+ * deprecated Twig_Environment::computeAlternatives()
+
+* 1.22.3 (2015-10-13)
+
+ * fixed regression when using null as a cache strategy
+ * improved performance when checking template freshness
+ * fixed warnings when loaded templates do not exist
+ * fixed template class name generation to prevent possible collisions
+ * fixed logic for custom escapers to call them even on integers and null values
+ * changed template cache names to take into account the Twig C extension
+
+* 1.22.2 (2015-09-22)
+
+ * fixed a race condition in template loading
+
+* 1.22.1 (2015-09-15)
+
+ * fixed regression in template_from_string
+
+* 1.22.0 (2015-09-13)
+
+ * made Twig_Test_IntegrationTestCase more flexible
+ * added an option to force PHP bytecode invalidation when writing a compiled template into the cache
+ * fixed the profiler duration for the root node
+ * changed template cache names to take into account enabled extensions
+ * deprecated Twig_Environment::clearCacheFiles(), Twig_Environment::getCacheFilename(),
+ Twig_Environment::writeCacheFile(), and Twig_Environment::getTemplateClassPrefix()
+ * added a way to override the filesystem template cache system
+ * added a way to get the original template source from Twig_Template
+
+* 1.21.2 (2015-09-09)
+
+ * fixed variable names for the deprecation triggering code
+ * fixed escaping strategy detection based on filename
+ * added Traversable support for replace, merge, and sort
+ * deprecated support for character by character replacement for the "replace" filter
+
+* 1.21.1 (2015-08-26)
+
+ * fixed regression when using the deprecated Twig_Test_* classes
+
+* 1.21.0 (2015-08-24)
+
+ * added deprecation notices for deprecated features
+ * added a deprecation "framework" for filters/functions/tests and test fixtures
+
+* 1.20.0 (2015-08-12)
+
+ * forbid access to the Twig environment from templates and internal parts of Twig_Template
+ * fixed limited RCEs when in sandbox mode
+ * deprecated Twig_Template::getEnvironment()
+ * deprecated the _self variable for usage outside of the from and import tags
+ * added Twig_BaseNodeVisitor to ease the compatibility of node visitors
+ between 1.x and 2.x
+
+* 1.19.0 (2015-07-31)
+
+ * fixed wrong error message when including an undefined template in a child template
+ * added support for variadic filters, functions, and tests
+ * added support for extra positional arguments in macros
+ * added ignore_missing flag to the source function
+ * fixed batch filter with zero items
+ * deprecated Twig_Environment::clearTemplateCache()
+ * fixed sandbox disabling when using the include function
+
+* 1.18.2 (2015-06-06)
+
+ * fixed template/line guessing in exceptions for nested templates
+ * optimized the number of inodes and the size of realpath cache when using the cache
+
+* 1.18.1 (2015-04-19)
+
+ * fixed memory leaks in the C extension
+ * deprecated Twig_Loader_String
+ * fixed the slice filter when used with a SimpleXMLElement object
+ * fixed filesystem loader when trying to load non-files (like directories)
+
+* 1.18.0 (2015-01-25)
+
+ * fixed some error messages where the line was wrong (unknown variables or argument names)
+ * added a new way to customize the main Module node (via empty nodes)
+ * added Twig_Environment::createTemplate() to create a template from a string
+ * added a profiler
+ * fixed filesystem loader cache when different file paths are used for the same template
+
+* 1.17.0 (2015-01-14)
+
+ * added a 'filename' autoescaping strategy, which dynamically chooses the
+ autoescaping strategy for a template based on template file extension.
+
+* 1.16.3 (2014-12-25)
+
+ * fixed regression for dynamic parent templates
+ * fixed cache management with statcache
+ * fixed a regression in the slice filter
+
+* 1.16.2 (2014-10-17)
+
+ * fixed timezone on dates as strings
+ * fixed 2-words test names when a custom node class is not used
+ * fixed macros when using an argument named like a PHP super global (like GET or POST)
+ * fixed date_modify when working with DateTimeImmutable
+ * optimized for loops
+ * fixed multi-byte characters handling in the split filter
+ * fixed a regression in the in operator
+ * fixed a regression in the slice filter
+
+* 1.16.1 (2014-10-10)
+
+ * improved error reporting in a sandboxed template
+ * fixed missing error file/line information under certain circumstances
+ * fixed wrong error line number in some error messages
+ * fixed the in operator to use strict comparisons
+ * sped up the slice filter
+ * fixed for mb function overload mb_substr acting different
+ * fixed the attribute() function when passing a variable for the arguments
+
+* 1.16.0 (2014-07-05)
+
+ * changed url_encode to always encode according to RFC 3986
+ * fixed inheritance in a 'use'-hierarchy
+ * removed the __toString policy check when the sandbox is disabled
+ * fixed recursively calling blocks in templates with inheritance
+
+* 1.15.1 (2014-02-13)
+
+ * fixed the conversion of the special '0000-00-00 00:00' date
+ * added an error message when trying to import an undefined block from a trait
+ * fixed a C extension crash when accessing defined but uninitialized property.
+
+* 1.15.0 (2013-12-06)
+
+ * made ignoreStrictCheck in Template::getAttribute() works with __call() methods throwing BadMethodCallException
+ * added min and max functions
+ * added the round filter
+ * fixed a bug that prevented the optimizers to be enabled/disabled selectively
+ * fixed first and last filters for UTF-8 strings
+ * added a source function to include the content of a template without rendering it
+ * fixed the C extension sandbox behavior when get or set is prepend to method name
+
+* 1.14.2 (2013-10-30)
+
+ * fixed error filename/line when an error occurs in an included file
+ * allowed operators that contain whitespaces to have more than one whitespace
+ * allowed tests to be made of 1 or 2 words (like "same as" or "divisible by")
+
+* 1.14.1 (2013-10-15)
+
+ * made it possible to use named operators as variables
+ * fixed the possibility to have a variable named 'matches'
+ * added support for PHP 5.5 DateTimeInterface
+
+* 1.14.0 (2013-10-03)
+
+ * fixed usage of the html_attr escaping strategy to avoid double-escaping with the html strategy
+ * added new operators: ends with, starts with, and matches
+ * fixed some compatibility issues with HHVM
+ * added a way to add custom escaping strategies
+ * fixed the C extension compilation on Windows
+ * fixed the batch filter when using a fill argument with an exact match of elements to batch
+ * fixed the filesystem loader cache when a template name exists in several namespaces
+ * fixed template_from_string when the template includes or extends other ones
+ * fixed a crash of the C extension on an edge case
+
+* 1.13.2 (2013-08-03)
+
+ * fixed the error line number for an error occurs in and embedded template
+ * fixed crashes of the C extension on some edge cases
+
+* 1.13.1 (2013-06-06)
+
+ * added the possibility to ignore the filesystem constructor argument in Twig_Loader_Filesystem
+ * fixed Twig_Loader_Chain::exists() for a loader which implements Twig_ExistsLoaderInterface
+ * adjusted backtrace call to reduce memory usage when an error occurs
+ * added support for object instances as the second argument of the constant test
+ * fixed the include function when used in an assignment
+
+* 1.13.0 (2013-05-10)
+
+ * fixed getting a numeric-like item on a variable ('09' for instance)
+ * fixed getting a boolean or float key on an array, so it is consistent with PHP's array access:
+ `{{ array[false] }}` behaves the same as `echo $array[false];` (equals `$array[0]`)
+ * made the escape filter 20% faster for happy path (escaping string for html with UTF-8)
+ * changed ☃ to § in tests
+ * enforced usage of named arguments after positional ones
+
+* 1.12.3 (2013-04-08)
+
+ * fixed a security issue in the filesystem loader where it was possible to include a template one
+ level above the configured path
+ * fixed fatal error that should be an exception when adding a filter/function/test too late
+ * added a batch filter
+ * added support for encoding an array as query string in the url_encode filter
+
+* 1.12.2 (2013-02-09)
+
+ * fixed the timezone used by the date filter and function when the given date contains a timezone (like 2010-01-28T15:00:00+02:00)
+ * fixed globals when getGlobals is called early on
+ * added the first and last filter
+
+* 1.12.1 (2013-01-15)
+
+ * added support for object instances as the second argument of the constant function
+ * relaxed globals management to avoid a BC break
+ * added support for {{ some_string[:2] }}
+
+* 1.12.0 (2013-01-08)
+
+ * added verbatim as an alias for the raw tag to avoid confusion with the raw filter
+ * fixed registration of tests and functions as anonymous functions
+ * fixed globals management
+
+* 1.12.0-RC1 (2012-12-29)
+
+ * added an include function (does the same as the include tag but in a more flexible way)
+ * added the ability to use any PHP callable to define filters, functions, and tests
+ * added a syntax error when using a loop variable that is not defined
+ * added the ability to set default values for macro arguments
+ * added support for named arguments for filters, tests, and functions
+ * moved filters/functions/tests syntax errors to the parser
+ * added support for extended ternary operator syntaxes
+
+* 1.11.1 (2012-11-11)
+
+ * fixed debug info line numbering (was off by 2)
+ * fixed escaping when calling a macro inside another one (regression introduced in 1.9.1)
+ * optimized variable access on PHP 5.4
+ * fixed a crash of the C extension when an exception was thrown from a macro called without being imported (using _self.XXX)
+
+* 1.11.0 (2012-11-07)
+
+ * fixed macro compilation when a variable name is a PHP reserved keyword
+ * changed the date filter behavior to always apply the default timezone, except if false is passed as the timezone
+ * fixed bitwise operator precedences
+ * added the template_from_string function
+ * fixed default timezone usage for the date function
+ * optimized the way Twig exceptions are managed (to make them faster)
+ * added Twig_ExistsLoaderInterface (implementing this interface in your loader make the chain loader much faster)
+
+* 1.10.3 (2012-10-19)
+
+ * fixed wrong template location in some error messages
+ * reverted a BC break introduced in 1.10.2
+ * added a split filter
+
+* 1.10.2 (2012-10-15)
+
+ * fixed macro calls on PHP 5.4
+
+* 1.10.1 (2012-10-15)
+
+ * made a speed optimization to macro calls when imported via the "import" tag
+ * fixed C extension compilation on Windows
+ * fixed a segfault in the C extension when using DateTime objects
+
+* 1.10.0 (2012-09-28)
+
+ * extracted functional tests framework to make it reusable for third-party extensions
+ * added namespaced templates support in Twig_Loader_Filesystem
+ * added Twig_Loader_Filesystem::prependPath()
+ * fixed an error when a token parser pass a closure as a test to the subparse() method
+
+* 1.9.2 (2012-08-25)
+
+ * fixed the in operator for objects that contain circular references
+ * fixed the C extension when accessing a public property of an object implementing the \ArrayAccess interface
+
+* 1.9.1 (2012-07-22)
+
+ * optimized macro calls when auto-escaping is on
+ * fixed wrong parent class for Twig_Function_Node
+ * made Twig_Loader_Chain more explicit about problems
+
+* 1.9.0 (2012-07-13)
+
+ * made the parsing independent of the template loaders
+ * fixed exception trace when an error occurs when rendering a child template
+ * added escaping strategies for CSS, URL, and HTML attributes
+ * fixed nested embed tag calls
+ * added the date_modify filter
+
+* 1.8.3 (2012-06-17)
+
+ * fixed paths in the filesystem loader when passing a path that ends with a slash or a backslash
+ * fixed escaping when a project defines a function named html or js
+ * fixed chmod mode to apply the umask correctly
+
+* 1.8.2 (2012-05-30)
+
+ * added the abs filter
+ * fixed a regression when using a number in template attributes
+ * fixed compiler when mbstring.func_overload is set to 2
+ * fixed DateTimeZone support in date filter
+
+* 1.8.1 (2012-05-17)
+
+ * fixed a regression when dealing with SimpleXMLElement instances in templates
+ * fixed "is_safe" value for the "dump" function when "html_errors" is not defined in php.ini
+ * switched to use mbstring whenever possible instead of iconv (you might need to update your encoding as mbstring and iconv encoding names sometimes differ)
+
+* 1.8.0 (2012-05-08)
+
+ * enforced interface when adding tests, filters, functions, and node visitors from extensions
+ * fixed a side-effect of the date filter where the timezone might be changed
+ * simplified usage of the autoescape tag; the only (optional) argument is now the escaping strategy or false (with a BC layer)
+ * added a way to dynamically change the auto-escaping strategy according to the template "filename"
+ * changed the autoescape option to also accept a supported escaping strategy (for BC, true is equivalent to html)
+ * added an embed tag
+
+* 1.7.0 (2012-04-24)
+
+ * fixed a PHP warning when using CIFS
+ * fixed template line number in some exceptions
+ * added an iterable test
+ * added an error when defining two blocks with the same name in a template
+ * added the preserves_safety option for filters
+ * fixed a PHP notice when trying to access a key on a non-object/array variable
+ * enhanced error reporting when the template file is an instance of SplFileInfo
+ * added Twig_Environment::mergeGlobals()
+ * added compilation checks to avoid misuses of the sandbox tag
+ * fixed filesystem loader freshness logic for high traffic websites
+ * fixed random function when charset is null
+
+* 1.6.5 (2012-04-11)
+
+ * fixed a regression when a template only extends another one without defining any blocks
+
+* 1.6.4 (2012-04-02)
+
+ * fixed PHP notice in Twig_Error::guessTemplateLine() introduced in 1.6.3
+ * fixed performance when compiling large files
+ * optimized parent template creation when the template does not use dynamic inheritance
+
+* 1.6.3 (2012-03-22)
+
+ * fixed usage of Z_ADDREF_P for PHP 5.2 in the C extension
+ * fixed compilation of numeric values used in templates when using a locale where the decimal separator is not a dot
+ * made the strategy used to guess the real template file name and line number in exception messages much faster and more accurate
+
+* 1.6.2 (2012-03-18)
+
+ * fixed sandbox mode when used with inheritance
+ * added preserveKeys support for the slice filter
+ * fixed the date filter when a DateTime instance is passed with a specific timezone
+ * added a trim filter
+
+* 1.6.1 (2012-02-29)
+
+ * fixed Twig C extension
+ * removed the creation of Twig_Markup instances when not needed
+ * added a way to set the default global timezone for dates
+ * fixed the slice filter on strings when the length is not specified
+ * fixed the creation of the cache directory in case of a race condition
+
+* 1.6.0 (2012-02-04)
+
+ * fixed raw blocks when used with the whitespace trim option
+ * made a speed optimization to macro calls when imported via the "from" tag
+ * fixed globals, parsers, visitors, filters, tests, and functions management in Twig_Environment when a new one or new extension is added
+ * fixed the attribute function when passing arguments
+ * added slice notation support for the [] operator (syntactic sugar for the slice operator)
+ * added a slice filter
+ * added string support for the reverse filter
+ * fixed the empty test and the length filter for Twig_Markup instances
+ * added a date function to ease date comparison
+ * fixed unary operators precedence
+ * added recursive parsing support in the parser
+ * added string and integer handling for the random function
+
+* 1.5.1 (2012-01-05)
+
+ * fixed a regression when parsing strings
+
+* 1.5.0 (2012-01-04)
+
+ * added Traversable objects support for the join filter
+
+* 1.5.0-RC2 (2011-12-30)
+
+ * added a way to set the default global date interval format
+ * fixed the date filter for DateInterval instances (setTimezone() does not exist for them)
+ * refactored Twig_Template::display() to ease its extension
+ * added a number_format filter
+
+* 1.5.0-RC1 (2011-12-26)
+
+ * removed the need to quote hash keys
+ * allowed hash keys to be any expression
+ * added a do tag
+ * added a flush tag
+ * added support for dynamically named filters and functions
+ * added a dump function to help debugging templates
+ * added a nl2br filter
+ * added a random function
+ * added a way to change the default format for the date filter
+ * fixed the lexer when an operator ending with a letter ends a line
+ * added string interpolation support
+ * enhanced exceptions for unknown filters, functions, tests, and tags
+
+* 1.4.0 (2011-12-07)
+
+ * fixed lexer when using big numbers (> PHP_INT_MAX)
+ * added missing preserveKeys argument to the reverse filter
+ * fixed macros containing filter tag calls
+
+* 1.4.0-RC2 (2011-11-27)
+
+ * removed usage of Reflection in Twig_Template::getAttribute()
+ * added a C extension that can optionally replace Twig_Template::getAttribute()
+ * added negative timestamp support to the date filter
+
+* 1.4.0-RC1 (2011-11-20)
+
+ * optimized variable access when using PHP 5.4
+ * changed the precedence of the .. operator to be more consistent with languages that implements such a feature like Ruby
+ * added an Exception to Twig_Loader_Array::isFresh() method when the template does not exist to be consistent with other loaders
+ * added Twig_Function_Node to allow more complex functions to have their own Node class
+ * added Twig_Filter_Node to allow more complex filters to have their own Node class
+ * added Twig_Test_Node to allow more complex tests to have their own Node class
+ * added a better error message when a template is empty but contain a BOM
+ * fixed "in" operator for empty strings
+ * fixed the "defined" test and the "default" filter (now works with more than one call (foo.bar.foo) and for both values of the strict_variables option)
+ * changed the way extensions are loaded (addFilter/addFunction/addGlobal/addTest/addNodeVisitor/addTokenParser/addExtension can now be called in any order)
+ * added Twig_Environment::display()
+ * made the escape filter smarter when the encoding is not supported by PHP
+ * added a convert_encoding filter
+ * moved all node manipulations outside the compile() Node method
+ * made several speed optimizations
+
+* 1.3.0 (2011-10-08)
+
+no changes
+
+* 1.3.0-RC1 (2011-10-04)
+
+ * added an optimization for the parent() function
+ * added cache reloading when auto_reload is true and an extension has been modified
+ * added the possibility to force the escaping of a string already marked as safe (instance of Twig_Markup)
+ * allowed empty templates to be used as traits
+ * added traits support for the "parent" function
+
+* 1.2.0 (2011-09-13)
+
+no changes
+
+* 1.2.0-RC1 (2011-09-10)
+
+ * enhanced the exception when a tag remains unclosed
+ * added support for empty Countable objects for the "empty" test
+ * fixed algorithm that determines if a template using inheritance is valid (no output between block definitions)
+ * added better support for encoding problems when escaping a string (available as of PHP 5.4)
+ * added a way to ignore a missing template when using the "include" tag ({% include "foo" ignore missing %})
+ * added support for an array of templates to the "include" and "extends" tags ({% include ['foo', 'bar'] %})
+ * added support for bitwise operators in expressions
+ * added the "attribute" function to allow getting dynamic attributes on variables
+ * added Twig_Loader_Chain
+ * added Twig_Loader_Array::setTemplate()
+ * added an optimization for the set tag when used to capture a large chunk of static text
+ * changed name regex to match PHP one "[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*" (works for blocks, tags, functions, filters, and macros)
+ * removed the possibility to use the "extends" tag from a block
+ * added "if" modifier support to "for" loops
+
+* 1.1.2 (2011-07-30)
+
+ * fixed json_encode filter on PHP 5.2
+ * fixed regression introduced in 1.1.1 ({{ block(foo|lower) }})
+ * fixed inheritance when using conditional parents
+ * fixed compilation of templates when the body of a child template is not empty
+ * fixed output when a macro throws an exception
+ * fixed a parsing problem when a large chunk of text is enclosed in a comment tag
+ * added PHPDoc for all Token parsers and Core extension functions
+
+* 1.1.1 (2011-07-17)
+
+ * added a performance optimization in the Optimizer (also helps to lower the number of nested level calls)
+ * made some performance improvement for some edge cases
+
+* 1.1.0 (2011-06-28)
+
+ * fixed json_encode filter
+
+* 1.1.0-RC3 (2011-06-24)
+
+ * fixed method case-sensitivity when using the sandbox mode
+ * added timezone support for the date filter
+ * fixed possible security problems with NUL bytes
+
+* 1.1.0-RC2 (2011-06-16)
+
+ * added an exception when the template passed to "use" is not a string
+ * made 'a.b is defined' not throw an exception if a is not defined (in strict mode)
+ * added {% line \d+ %} directive
+
+* 1.1.0-RC1 (2011-05-28)
+
+Flush your cache after upgrading.
+
+ * fixed date filter when using a timestamp
+ * fixed the defined test for some cases
+ * fixed a parsing problem when a large chunk of text is enclosed in a raw tag
+ * added support for horizontal reuse of template blocks (see docs for more information)
+ * added whitespace control modifier to all tags (see docs for more information)
+ * added null as an alias for none (the null test is also an alias for the none test now)
+ * made TRUE, FALSE, NONE equivalent to their lowercase counterparts
+ * wrapped all compilation and runtime exceptions with Twig_Error_Runtime and added logic to guess the template name and line
+ * moved display() method to Twig_Template (generated templates should now use doDisplay() instead)
+
+* 1.0.0 (2011-03-27)
+
+ * fixed output when using mbstring
+ * fixed duplicate call of methods when using the sandbox
+ * made the charset configurable for the escape filter
+
+* 1.0.0-RC2 (2011-02-21)
+
+ * changed the way {% set %} works when capturing (the content is now marked as safe)
+ * added support for macro name in the endmacro tag
+ * make Twig_Error compatible with PHP 5.3.0 >
+ * fixed an infinite loop on some Windows configurations
+ * fixed the "length" filter for numbers
+ * fixed Template::getAttribute() as properties in PHP are case sensitive
+ * removed coupling between Twig_Node and Twig_Template
+ * fixed the ternary operator precedence rule
+
+* 1.0.0-RC1 (2011-01-09)
+
+Backward incompatibilities:
+
+ * the "items" filter, which has been deprecated for quite a long time now, has been removed
+ * the "range" filter has been converted to a function: 0|range(10) -> range(0, 10)
+ * the "constant" filter has been converted to a function: {{ some_date|date('DATE_W3C'|constant) }} -> {{ some_date|date(constant('DATE_W3C')) }}
+ * the "cycle" filter has been converted to a function: {{ ['odd', 'even']|cycle(i) }} -> {{ cycle(['odd', 'even'], i) }}
+ * the "for" tag does not support "joined by" anymore
+ * the "autoescape" first argument is now "true"/"false" (instead of "on"/"off")
+ * the "parent" tag has been replaced by a "parent" function ({{ parent() }} instead of {% parent %})
+ * the "display" tag has been replaced by a "block" function ({{ block('title') }} instead of {% display title %})
+ * removed the grammar and simple token parser (moved to the Twig Extensions repository)
+
+Changes:
+
+ * added "needs_context" option for filters and functions (the context is then passed as a first argument)
+ * added global variables support
+ * made macros return their value instead of echoing directly (fixes calling a macro in sandbox mode)
+ * added the "from" tag to import macros as functions
+ * added support for functions (a function is just syntactic sugar for a getAttribute() call)
+ * made macros callable when sandbox mode is enabled
+ * added an exception when a macro uses a reserved name
+ * the "default" filter now uses the "empty" test instead of just checking for null
+ * added the "empty" test
+
+* 0.9.10 (2010-12-16)
+
+Backward incompatibilities:
+
+ * The Escaper extension is enabled by default, which means that all displayed
+ variables are now automatically escaped. You can revert to the previous
+ behavior by removing the extension via $env->removeExtension('escaper')
+ or just set the 'autoescape' option to 'false'.
+ * removed the "without loop" attribute for the "for" tag (not needed anymore
+ as the Optimizer take care of that for most cases)
+ * arrays and hashes have now a different syntax
+ * arrays keep the same syntax with square brackets: [1, 2]
+ * hashes now use curly braces (["a": "b"] should now be written as {"a": "b"})
+ * support for "arrays with keys" and "hashes without keys" is not supported anymore ([1, "foo": "bar"] or {"foo": "bar", 1})
+ * the i18n extension is now part of the Twig Extensions repository
+
+Changes:
+
+ * added the merge filter
+ * removed 'is_escaper' option for filters (a left over from the previous version) -- you must use 'is_safe' now instead
+ * fixed usage of operators as method names (like is, in, and not)
+ * changed the order of execution for node visitors
+ * fixed default() filter behavior when used with strict_variables set to on
+ * fixed filesystem loader compatibility with PHAR files
+ * enhanced error messages when an unexpected token is parsed in an expression
+ * fixed filename not being added to syntax error messages
+ * added the autoescape option to enable/disable autoescaping
+ * removed the newline after a comment (mimics PHP behavior)
+ * added a syntax error exception when parent block is used on a template that does not extend another one
+ * made the Escaper extension enabled by default
+ * fixed sandbox extension when used with auto output escaping
+ * fixed escaper when wrapping a Twig_Node_Print (the original class must be preserved)
+ * added an Optimizer extension (enabled by default; optimizes "for" loops and "raw" filters)
+ * added priority to node visitors
+
+* 0.9.9 (2010-11-28)
+
+Backward incompatibilities:
+ * the self special variable has been renamed to _self
+ * the odd and even filters are now tests:
+ {{ foo|odd }} must now be written {{ foo is odd }}
+ * the "safe" filter has been renamed to "raw"
+ * in Node classes,
+ sub-nodes are now accessed via getNode() (instead of property access)
+ attributes via getAttribute() (instead of array access)
+ * the urlencode filter had been renamed to url_encode
+ * the include tag now merges the passed variables with the current context by default
+ (the old behavior is still possible by adding the "only" keyword)
+ * moved Exceptions to Twig_Error_* (Twig_SyntaxError/Twig_RuntimeError are now Twig_Error_Syntax/Twig_Error_Runtime)
+ * removed support for {{ 1 < i < 3 }} (use {{ i > 1 and i < 3 }} instead)
+ * the "in" filter has been removed ({{ a|in(b) }} should now be written {{ a in b }})
+
+Changes:
+ * added file and line to Twig_Error_Runtime exceptions thrown from Twig_Template
+ * changed trans tag to accept any variable for the plural count
+ * fixed sandbox mode (__toString() method check was not enforced if called implicitly from complex statements)
+ * added the ** (power) operator
+ * changed the algorithm used for parsing expressions
+ * added the spaceless tag
+ * removed trim_blocks option
+ * added support for is*() methods for attributes (foo.bar now looks for foo->getBar() or foo->isBar())
+ * changed all exceptions to extend Twig_Error
+ * fixed unary expressions ({{ not(1 or 0) }})
+ * fixed child templates (with an extend tag) that uses one or more imports
+ * added support for {{ 1 not in [2, 3] }} (more readable than the current {{ not (1 in [2, 3]) }})
+ * escaping has been rewritten
+ * the implementation of template inheritance has been rewritten
+ (blocks can now be called individually and still work with inheritance)
+ * fixed error handling for if tag when a syntax error occurs within a subparse process
+ * added a way to implement custom logic for resolving token parsers given a tag name
+ * fixed js escaper to be stricter (now uses a whilelist-based js escaper)
+ * added the following filers: "constant", "trans", "replace", "json_encode"
+ * added a "constant" test
+ * fixed objects with __toString() not being autoescaped
+ * fixed subscript expressions when calling __call() (methods now keep the case)
+ * added "test" feature (accessible via the "is" operator)
+ * removed the debug tag (should be done in an extension)
+ * fixed trans tag when no vars are used in plural form
+ * fixed race condition when writing template cache
+ * added the special _charset variable to reference the current charset
+ * added the special _context variable to reference the current context
+ * renamed self to _self (to avoid conflict)
+ * fixed Twig_Template::getAttribute() for protected properties
+
+* 0.9.8 (2010-06-28)
+
+Backward incompatibilities:
+ * the trans tag plural count is now attached to the plural tag:
+ old: `{% trans count %}...{% plural %}...{% endtrans %}`
+ new: `{% trans %}...{% plural count %}...{% endtrans %}`
+
+ * added a way to translate strings coming from a variable ({% trans var %})
+ * fixed trans tag when used with the Escaper extension
+ * fixed default cache umask
+ * removed Twig_Template instances from the debug tag output
+ * fixed objects with __isset() defined
+ * fixed set tag when used with a capture
+ * fixed type hinting for Twig_Environment::addFilter() method
+
+* 0.9.7 (2010-06-12)
+
+Backward incompatibilities:
+ * changed 'as' to '=' for the set tag ({% set title as "Title" %} must now be {% set title = "Title" %})
+ * removed the sandboxed attribute of the include tag (use the new sandbox tag instead)
+ * refactored the Node system (if you have custom nodes, you will have to update them to use the new API)
+
+ * added self as a special variable that refers to the current template (useful for importing macros from the current template)
+ * added Twig_Template instance support to the include tag
+ * added support for dynamic and conditional inheritance ({% extends some_var %} and {% extends standalone ? "minimum" : "base" %})
+ * added a grammar sub-framework to ease the creation of custom tags
+ * fixed the for tag for large arrays (some loop variables are now only available for arrays and objects that implement the Countable interface)
+ * removed the Twig_Resource::resolveMissingFilter() method
+ * fixed the filter tag which did not apply filtering to included files
+ * added a bunch of unit tests
+ * added a bunch of phpdoc
+ * added a sandbox tag in the sandbox extension
+ * changed the date filter to support any date format supported by DateTime
+ * added strict_variable setting to throw an exception when an invalid variable is used in a template (disabled by default)
+ * added the lexer, parser, and compiler as arguments to the Twig_Environment constructor
+ * changed the cache option to only accepts an explicit path to a cache directory or false
+ * added a way to add token parsers, filters, and visitors without creating an extension
+ * added three interfaces: Twig_NodeInterface, Twig_TokenParserInterface, and Twig_FilterInterface
+ * changed the generated code to match the new coding standards
+ * fixed sandbox mode (__toString() method check was not enforced if called implicitly from a simple statement like {{ article }})
+ * added an exception when a child template has a non-empty body (as it is always ignored when rendering)
+
+* 0.9.6 (2010-05-12)
+
+ * fixed variables defined outside a loop and for which the value changes in a for loop
+ * fixed the test suite for PHP 5.2 and older versions of PHPUnit
+ * added support for __call() in expression resolution
+ * fixed node visiting for macros (macros are now visited by visitors as any other node)
+ * fixed nested block definitions with a parent call (rarely useful but nonetheless supported now)
+ * added the cycle filter
+ * fixed the Lexer when mbstring.func_overload is used with an mbstring.internal_encoding different from ASCII
+ * added a long-syntax for the set tag ({% set foo %}...{% endset %})
+ * unit tests are now powered by PHPUnit
+ * added support for gettext via the `i18n` extension
+ * fixed twig_capitalize_string_filter() and fixed twig_length_filter() when used with UTF-8 values
+ * added a more useful exception if an if tag is not closed properly
+ * added support for escaping strategy in the autoescape tag
+ * fixed lexer when a template has a big chunk of text between/in a block
+
+* 0.9.5 (2010-01-20)
+
+As for any new release, don't forget to remove all cached templates after
+upgrading.
+
+If you have defined custom filters, you MUST upgrade them for this release. To
+upgrade, replace "array" with "new Twig_Filter_Function", and replace the
+environment constant by the "needs_environment" option:
+
+ // before
+ 'even' => array('twig_is_even_filter', false),
+ 'escape' => array('twig_escape_filter', true),
+
+ // after
+ 'even' => new Twig_Filter_Function('twig_is_even_filter'),
+ 'escape' => new Twig_Filter_Function('twig_escape_filter', array('needs_environment' => true)),
+
+If you have created NodeTransformer classes, you will need to upgrade them to
+the new interface (please note that the interface is not yet considered
+stable).
+
+ * fixed list nodes that did not extend the Twig_NodeListInterface
+ * added the "without loop" option to the for tag (it disables the generation of the loop variable)
+ * refactored node transformers to node visitors
+ * fixed automatic-escaping for blocks
+ * added a way to specify variables to pass to an included template
+ * changed the automatic-escaping rules to be more sensible and more configurable in custom filters (the documentation lists all the rules)
+ * improved the filter system to allow object methods to be used as filters
+ * changed the Array and String loaders to actually make use of the cache mechanism
+ * included the default filter function definitions in the extension class files directly (Core, Escaper)
+ * added the // operator (like the floor() PHP function)
+ * added the .. operator (as a syntactic sugar for the range filter when the step is 1)
+ * added the in operator (as a syntactic sugar for the in filter)
+ * added the following filters in the Core extension: in, range
+ * added support for arrays (same behavior as in PHP, a mix between lists and dictionaries, arrays and hashes)
+ * enhanced some error messages to provide better feedback in case of parsing errors
+
+* 0.9.4 (2009-12-02)
+
+If you have custom loaders, you MUST upgrade them for this release: The
+Twig_Loader base class has been removed, and the Twig_LoaderInterface has also
+been changed (see the source code for more information or the documentation).
+
+ * added support for DateTime instances for the date filter
+ * fixed loop.last when the array only has one item
+ * made it possible to insert newlines in tag and variable blocks
+ * fixed a bug when a literal '\n' were present in a template text
+ * fixed bug when the filename of a template contains */
+ * refactored loaders
+
+* 0.9.3 (2009-11-11)
+
+This release is NOT backward compatible with the previous releases.
+
+ The loaders do not take the cache and autoReload arguments anymore. Instead,
+ the Twig_Environment class has two new options: cache and auto_reload.
+ Upgrading your code means changing this kind of code:
+
+ $loader = new Twig_Loader_Filesystem('/path/to/templates', '/path/to/compilation_cache', true);
+ $twig = new Twig_Environment($loader);
+
+ to something like this:
+
+ $loader = new Twig_Loader_Filesystem('/path/to/templates');
+ $twig = new Twig_Environment($loader, array(
+ 'cache' => '/path/to/compilation_cache',
+ 'auto_reload' => true,
+ ));
+
+ * deprecated the "items" filter as it is not needed anymore
+ * made cache and auto_reload options of Twig_Environment instead of arguments of Twig_Loader
+ * optimized template loading speed
+ * removed output when an error occurs in a template and render() is used
+ * made major speed improvements for loops (up to 300% on even the smallest loops)
+ * added properties as part of the sandbox mode
+ * added public properties support (obj.item can now be the item property on the obj object)
+ * extended set tag to support expression as value ({% set foo as 'foo' ~ 'bar' %} )
+ * fixed bug when \ was used in HTML
+
+* 0.9.2 (2009-10-29)
+
+ * made some speed optimizations
+ * changed the cache extension to .php
+ * added a js escaping strategy
+ * added support for short block tag
+ * changed the filter tag to allow chained filters
+ * made lexer more flexible as you can now change the default delimiters
+ * added set tag
+ * changed default directory permission when cache dir does not exist (more secure)
+ * added macro support
+ * changed filters first optional argument to be a Twig_Environment instance instead of a Twig_Template instance
+ * made Twig_Autoloader::autoload() a static method
+ * avoid writing template file if an error occurs
+ * added $ escaping when outputting raw strings
+ * enhanced some error messages to ease debugging
+ * fixed empty cache files when the template contains an error
+
+* 0.9.1 (2009-10-14)
+
+ * fixed a bug in PHP 5.2.6
+ * fixed numbers with one than one decimal
+ * added support for method calls with arguments ({{ foo.bar('a', 43) }})
+ * made small speed optimizations
+ * made minor tweaks to allow better extensibility and flexibility
+
+* 0.9.0 (2009-10-12)
+
+ * Initial release
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/LICENSE b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/LICENSE
new file mode 100644
index 0000000..d06ced2
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/LICENSE
@@ -0,0 +1,31 @@
+Copyright (c) 2009-2019 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/system/templateEngines/Twig/Twig1x/vendor/twig/twig/README.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/README.rst
new file mode 100644
index 0000000..f33ea33
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/README.rst
@@ -0,0 +1,15 @@
+Twig, the flexible, fast, and secure template language for PHP
+==============================================================
+
+Twig is a template language for PHP, released under the new BSD license (code
+and documentation).
+
+Twig uses a syntax similar to the Django and Jinja template languages which
+inspired the Twig runtime environment.
+
+More Information
+----------------
+
+Read the `documentation`_ for more information.
+
+.. _documentation: https://twig.symfony.com/documentation
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/composer.json b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/composer.json
new file mode 100644
index 0000000..4b99372
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/composer.json
@@ -0,0 +1,48 @@
+{
+ "name": "twig/twig",
+ "type": "library",
+ "description": "Twig, the flexible, fast, and secure template language for PHP",
+ "keywords": ["templating"],
+ "homepage": "https://twig.symfony.com",
+ "license": "BSD-3-Clause",
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
+ },
+ {
+ "name": "Twig Team",
+ "homepage": "https://twig.symfony.com/contributors",
+ "role": "Contributors"
+ },
+ {
+ "name": "Armin Ronacher",
+ "email": "armin.ronacher@active-4.com",
+ "role": "Project Founder"
+ }
+ ],
+ "require": {
+ "php": ">=5.4.0",
+ "symfony/polyfill-ctype": "^1.8"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "^3.4.19|^4.1.8",
+ "symfony/debug": "^2.7",
+ "psr/container": "^1.0"
+ },
+ "autoload": {
+ "psr-0" : {
+ "Twig_" : "lib/"
+ },
+ "psr-4" : {
+ "Twig\\" : "src/"
+ }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.41-dev"
+ }
+ }
+}
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/advanced.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/advanced.rst
new file mode 100644
index 0000000..fd95883
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/advanced.rst
@@ -0,0 +1,1005 @@
+Extending Twig
+==============
+
+.. caution::
+
+ This section describes how to extend Twig as of **Twig 1.12**. If you are
+ using an older version, read the :doc:`legacy` chapter
+ instead.
+
+Twig can be extended in many ways; you can add extra tags, filters, tests,
+operators, global variables, and functions. You can even extend the parser
+itself with node visitors.
+
+.. note::
+
+ The first section of this chapter describes how to extend Twig. If you want
+ to reuse your changes in different projects or if you want to share them
+ with others, you should then create an extension as described in the
+ following section.
+
+.. caution::
+
+ When extending Twig without creating an extension, Twig won't be able to
+ recompile your templates when the PHP code is updated. To see your changes
+ in real-time, either disable template caching or package your code into an
+ extension (see the next section of this chapter).
+
+Before extending Twig, you must understand the differences between all the
+different possible extension points and when to use them.
+
+First, remember that Twig has two main language constructs:
+
+* ``{{ }}``: used to print the result of an expression evaluation;
+
+* ``{% %}``: used to execute statements.
+
+To understand why Twig exposes so many extension points, let's see how to
+implement a *Lorem ipsum* generator (it needs to know the number of words to
+generate).
+
+You can use a ``lipsum`` *tag*:
+
+.. code-block:: twig
+
+ {% lipsum 40 %}
+
+That works, but using a tag for ``lipsum`` is not a good idea for at least
+three main reasons:
+
+* ``lipsum`` is not a language construct;
+* The tag outputs something;
+* The tag is not flexible as you cannot use it in an expression:
+
+ .. code-block:: twig
+
+ {{ 'some text' ~ {% lipsum 40 %} ~ 'some more text' }}
+
+In fact, you rarely need to create tags; and that's good news because tags are
+the most complex extension point.
+
+Now, let's use a ``lipsum`` *filter*:
+
+.. code-block:: twig
+
+ {{ 40|lipsum }}
+
+Again, it works. But a filter should transform the passed value to something
+else. Here, we use the value to indicate the number of words to generate (so,
+``40`` is an argument of the filter, not the value we want to transform).
+
+Next, let's use a ``lipsum`` *function*:
+
+.. code-block:: twig
+
+ {{ lipsum(40) }}
+
+Here we go. For this specific example, the creation of a function is the
+extension point to use. And you can use it anywhere an expression is accepted:
+
+.. code-block:: twig
+
+ {{ 'some text' ~ lipsum(40) ~ 'some more text' }}
+
+ {% set lipsum = lipsum(40) %}
+
+Lastly, you can also use a *global* object with a method able to generate lorem
+ipsum text:
+
+.. code-block:: twig
+
+ {{ text.lipsum(40) }}
+
+As a rule of thumb, use functions for frequently used features and global
+objects for everything else.
+
+Keep in mind the following when you want to extend Twig:
+
+========== ========================== ========== =========================
+What? Implementation difficulty? How often? When?
+========== ========================== ========== =========================
+*macro* simple frequent Content generation
+*global* simple frequent Helper object
+*function* simple frequent Content generation
+*filter* simple frequent Value transformation
+*tag* complex rare DSL language construct
+*test* simple rare Boolean decision
+*operator* simple rare Values transformation
+========== ========================== ========== =========================
+
+Globals
+-------
+
+A global variable is like any other template variable, except that it's
+available in all templates and macros::
+
+ $twig = new \Twig\Environment($loader);
+ $twig->addGlobal('text', new Text());
+
+You can then use the ``text`` variable anywhere in a template:
+
+.. code-block:: twig
+
+ {{ text.lipsum(40) }}
+
+Filters
+-------
+
+Creating a filter consists of associating a name with a PHP callable::
+
+ // an anonymous function
+ $filter = new \Twig\TwigFilter('rot13', function ($string) {
+ return str_rot13($string);
+ });
+
+ // or a simple PHP function
+ $filter = new \Twig\TwigFilter('rot13', 'str_rot13');
+
+ // or a class static method
+ $filter = new \Twig\TwigFilter('rot13', ['SomeClass', 'rot13Filter']);
+ $filter = new \Twig\TwigFilter('rot13', 'SomeClass::rot13Filter');
+
+ // or a class method
+ $filter = new \Twig\TwigFilter('rot13', [$this, 'rot13Filter']);
+ // the one below needs a runtime implementation (see below for more information)
+ $filter = new \Twig\TwigFilter('rot13', ['SomeClass', 'rot13Filter']);
+
+The first argument passed to the ``\Twig\TwigFilter`` constructor is the name
+of the filter you will use in templates and the second one is the PHP callable
+to associate with it.
+
+Then, add the filter to the Twig environment::
+
+ $twig = new \Twig\Environment($loader);
+ $twig->addFilter($filter);
+
+And here is how to use it in a template:
+
+.. code-block:: twig
+
+ {{ 'Twig'|rot13 }}
+
+ {# will output Gjvt #}
+
+When called by Twig, the PHP callable receives the left side of the filter
+(before the pipe ``|``) as the first argument and the extra arguments passed
+to the filter (within parentheses ``()``) as extra arguments.
+
+For instance, the following code:
+
+.. code-block:: twig
+
+ {{ 'TWIG'|lower }}
+ {{ now|date('d/m/Y') }}
+
+is compiled to something like the following::
+
+
+
+
+The ``\Twig\TwigFilter`` class takes an array of options as its last
+argument::
+
+ $filter = new \Twig\TwigFilter('rot13', 'str_rot13', $options);
+
+Environment-aware Filters
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you want to access the current environment instance in your filter, set the
+``needs_environment`` option to ``true``; Twig will pass the current
+environment as the first argument to the filter call::
+
+ $filter = new \Twig\TwigFilter('rot13', function (Twig_Environment $env, $string) {
+ // get the current charset for instance
+ $charset = $env->getCharset();
+
+ return str_rot13($string);
+ }, ['needs_environment' => true]);
+
+Context-aware Filters
+~~~~~~~~~~~~~~~~~~~~~
+
+If you want to access the current context in your filter, set the
+``needs_context`` option to ``true``; Twig will pass the current context as
+the first argument to the filter call (or the second one if
+``needs_environment`` is also set to ``true``)::
+
+ $filter = new \Twig\TwigFilter('rot13', function ($context, $string) {
+ // ...
+ }, ['needs_context' => true]);
+
+ $filter = new \Twig\TwigFilter('rot13', function (Twig_Environment $env, $context, $string) {
+ // ...
+ }, ['needs_context' => true, 'needs_environment' => true]);
+
+Automatic Escaping
+~~~~~~~~~~~~~~~~~~
+
+If automatic escaping is enabled, the output of the filter may be escaped
+before printing. If your filter acts as an escaper (or explicitly outputs HTML
+or JavaScript code), you will want the raw output to be printed. In such a
+case, set the ``is_safe`` option::
+
+ $filter = new \Twig\TwigFilter('nl2br', 'nl2br', ['is_safe' => ['html']]);
+
+Some filters may need to work on input that is already escaped or safe, for
+example when adding (safe) HTML tags to originally unsafe output. In such a
+case, set the ``pre_escape`` option to escape the input data before it is run
+through your filter::
+
+ $filter = new \Twig\TwigFilter('somefilter', 'somefilter', ['pre_escape' => 'html', 'is_safe' => ['html']]);
+
+Variadic Filters
+~~~~~~~~~~~~~~~~
+
+.. versionadded:: 1.19
+ Support for variadic filters was added in Twig 1.19.
+
+When a filter should accept an arbitrary number of arguments, set the
+``is_variadic`` option to ``true``; Twig will pass the extra arguments as the
+last argument to the filter call as an array::
+
+ $filter = new \Twig\TwigFilter('thumbnail', function ($file, array $options = []) {
+ // ...
+ }, ['is_variadic' => true]);
+
+Be warned that :ref:`named arguments ` passed to a variadic
+filter cannot be checked for validity as they will automatically end up in the
+option array.
+
+Dynamic Filters
+~~~~~~~~~~~~~~~
+
+A filter name containing the special ``*`` character is a dynamic filter and
+the ``*`` part will match any string::
+
+ $filter = new \Twig\TwigFilter('*_path', function ($name, $arguments) {
+ // ...
+ });
+
+The following filters are matched by the above defined dynamic filter:
+
+* ``product_path``
+* ``category_path``
+
+A dynamic filter can define more than one dynamic parts::
+
+ $filter = new \Twig\TwigFilter('*_path_*', function ($name, $suffix, $arguments) {
+ // ...
+ });
+
+The filter receives all dynamic part values before the normal filter arguments,
+but after the environment and the context. For instance, a call to
+``'foo'|a_path_b()`` will result in the following arguments to be passed to the
+filter: ``('a', 'b', 'foo')``.
+
+Deprecated Filters
+~~~~~~~~~~~~~~~~~~
+
+.. versionadded:: 1.21
+ Support for deprecated filters was added in Twig 1.21.
+
+You can mark a filter as being deprecated by setting the ``deprecated`` option
+to ``true``. You can also give an alternative filter that replaces the
+deprecated one when that makes sense::
+
+ $filter = new \Twig\TwigFilter('obsolete', function () {
+ // ...
+ }, ['deprecated' => true, 'alternative' => 'new_one']);
+
+When a filter is deprecated, Twig emits a deprecation notice when compiling a
+template using it. See :ref:`deprecation-notices` for more information.
+
+Functions
+---------
+
+Functions are defined in the exact same way as filters, but you need to create
+an instance of ``\Twig\TwigFunction``::
+
+ $twig = new \Twig\Environment($loader);
+ $function = new \Twig\TwigFunction('function_name', function () {
+ // ...
+ });
+ $twig->addFunction($function);
+
+Functions support the same features as filters, except for the ``pre_escape``
+and ``preserves_safety`` options.
+
+Tests
+-----
+
+Tests are defined in the exact same way as filters and functions, but you need
+to create an instance of ``\Twig\TwigTest``::
+
+ $twig = new \Twig\Environment($loader);
+ $test = new \Twig\TwigTest('test_name', function () {
+ // ...
+ });
+ $twig->addTest($test);
+
+Tests allow you to create custom application specific logic for evaluating
+boolean conditions. As a simple example, let's create a Twig test that checks if
+objects are 'red'::
+
+ $twig = new \Twig\Environment($loader);
+ $test = new \Twig\TwigTest('red', function ($value) {
+ if (isset($value->color) && $value->color == 'red') {
+ return true;
+ }
+ if (isset($value->paint) && $value->paint == 'red') {
+ return true;
+ }
+ return false;
+ });
+ $twig->addTest($test);
+
+Test functions must always return ``true``/``false``.
+
+When creating tests you can use the ``node_class`` option to provide custom test
+compilation. This is useful if your test can be compiled into PHP primitives.
+This is used by many of the tests built into Twig::
+
+ $twig = new \Twig\Environment($loader);
+ $test = new \Twig\TwigTest(
+ 'odd',
+ null,
+ ['node_class' => '\Twig\Node\Expression\Test\OddTest']);
+ $twig->addTest($test);
+
+ class Twig_Node_Expression_Test_Odd extends \Twig\Node\Expression\TestExpression
+ {
+ public function compile(\Twig\Compiler $compiler)
+ {
+ $compiler
+ ->raw('(')
+ ->subcompile($this->getNode('node'))
+ ->raw(' % 2 == 1')
+ ->raw(')')
+ ;
+ }
+ }
+
+The above example shows how you can create tests that use a node class. The node
+class has access to one sub-node called ``node``. This sub-node contains the
+value that is being tested. When the ``odd`` filter is used in code such as:
+
+.. code-block:: twig
+
+ {% if my_value is odd %}
+
+The ``node`` sub-node will contain an expression of ``my_value``. Node-based
+tests also have access to the ``arguments`` node. This node will contain the
+various other arguments that have been provided to your test.
+
+.. versionadded:: 1.36
+ Dynamic tests support was added in Twig 1.36.
+
+If you want to pass a variable number of positional or named arguments to the
+test, set the ``is_variadic`` option to ``true``. Tests support dynamic
+names (see dynamic filters for the syntax).
+
+Tags
+----
+
+One of the most exciting features of a template engine like Twig is the
+possibility to define new **language constructs**. This is also the most complex
+feature as you need to understand how Twig's internals work.
+
+Most of the time though, a tag is not needed:
+
+* If your tag generates some output, use a **function** instead.
+
+* If your tag modifies some content and returns it, use a **filter** instead.
+
+ For instance, if you want to create a tag that converts a Markdown formatted
+ text to HTML, create a ``markdown`` filter instead:
+
+ .. code-block:: twig
+
+ {{ '**markdown** text'|markdown }}
+
+ If you want use this filter on large amounts of text, wrap it with the
+ :doc:`apply ` tag:
+
+ .. code-block:: twig
+
+ {% apply markdown %}
+ Title
+ =====
+
+ Much better than creating a tag as you can **compose** filters.
+ {% endapply %}
+
+ .. note::
+
+ The ``apply`` tag was introduced in Twig 1.40; use the ``filter`` tag with
+ previous versions.
+
+* If your tag does not output anything, but only exists because of a side
+ effect, create a **function** that returns nothing and call it via the
+ :doc:`filter ` tag.
+
+ For instance, if you want to create a tag that logs text, create a ``log``
+ function instead and call it via the :doc:`do ` tag:
+
+ .. code-block:: twig
+
+ {% do log('Log some things') %}
+
+If you still want to create a tag for a new language construct, great!
+
+Let's create a ``set`` tag that allows the definition of simple variables from
+within a template. The tag can be used like follows:
+
+.. code-block:: twig
+
+ {% set name = "value" %}
+
+ {{ name }}
+
+ {# should output value #}
+
+.. note::
+
+ The ``set`` tag is part of the Core extension and as such is always
+ available. The built-in version is slightly more powerful and supports
+ multiple assignments by default.
+
+Three steps are needed to define a new tag:
+
+* Defining a Token Parser class (responsible for parsing the template code);
+
+* Defining a Node class (responsible for converting the parsed code to PHP);
+
+* Registering the tag.
+
+Registering a new tag
+~~~~~~~~~~~~~~~~~~~~~
+
+Add a tag by calling the ``addTokenParser`` method on the ``\Twig\Environment``
+instance::
+
+ $twig = new \Twig\Environment($loader);
+ $twig->addTokenParser(new Project_Set_TokenParser());
+
+Defining a Token Parser
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Now, let's see the actual code of this class::
+
+ class Project_Set_TokenParser extends \Twig\TokenParser\AbstractTokenParser
+ {
+ public function parse(\Twig\Token $token)
+ {
+ $parser = $this->parser;
+ $stream = $parser->getStream();
+
+ $name = $stream->expect(\Twig\Token::NAME_TYPE)->getValue();
+ $stream->expect(\Twig\Token::OPERATOR_TYPE, '=');
+ $value = $parser->getExpressionParser()->parseExpression();
+ $stream->expect(\Twig\Token::BLOCK_END_TYPE);
+
+ return new Project_Set_Node($name, $value, $token->getLine(), $this->getTag());
+ }
+
+ public function getTag()
+ {
+ return 'set';
+ }
+ }
+
+The ``getTag()`` method must return the tag we want to parse, here ``set``.
+
+The ``parse()`` method is invoked whenever the parser encounters a ``set``
+tag. It should return a ``\Twig\Node\Node`` instance that represents the node (the
+``Project_Set_Node`` calls creating is explained in the next section).
+
+The parsing process is simplified thanks to a bunch of methods you can call
+from the token stream (``$this->parser->getStream()``):
+
+* ``getCurrent()``: Gets the current token in the stream.
+
+* ``next()``: Moves to the next token in the stream, *but returns the old one*.
+
+* ``test($type)``, ``test($value)`` or ``test($type, $value)``: Determines whether
+ the current token is of a particular type or value (or both). The value may be an
+ array of several possible values.
+
+* ``expect($type[, $value[, $message]])``: If the current token isn't of the given
+ type/value a syntax error is thrown. Otherwise, if the type and value are correct,
+ the token is returned and the stream moves to the next token.
+
+* ``look()``: Looks at the next token without consuming it.
+
+Parsing expressions is done by calling the ``parseExpression()`` like we did for
+the ``set`` tag.
+
+.. tip::
+
+ Reading the existing ``TokenParser`` classes is the best way to learn all
+ the nitty-gritty details of the parsing process.
+
+Defining a Node
+~~~~~~~~~~~~~~~
+
+The ``Project_Set_Node`` class itself is quite short::
+
+ class Project_Set_Node extends \Twig\Node\Node
+ {
+ public function __construct($name, \Twig\Node\Expression\AbstractExpression $value, $line, $tag = null)
+ {
+ parent::__construct(['value' => $value], ['name' => $name], $line, $tag);
+ }
+
+ public function compile(\Twig\Compiler $compiler)
+ {
+ $compiler
+ ->addDebugInfo($this)
+ ->write('$context[\''.$this->getAttribute('name').'\'] = ')
+ ->subcompile($this->getNode('value'))
+ ->raw(";\n")
+ ;
+ }
+ }
+
+The compiler implements a fluid interface and provides methods that helps the
+developer generate beautiful and readable PHP code:
+
+* ``subcompile()``: Compiles a node.
+
+* ``raw()``: Writes the given string as is.
+
+* ``write()``: Writes the given string by adding indentation at the beginning
+ of each line.
+
+* ``string()``: Writes a quoted string.
+
+* ``repr()``: Writes a PHP representation of a given value (see
+ ``\Twig\Node\ForNode`` for a usage example).
+
+* ``addDebugInfo()``: Adds the line of the original template file related to
+ the current node as a comment.
+
+* ``indent()``: Indents the generated code (see ``\Twig\Node\BlockNode`` for a
+ usage example).
+
+* ``outdent()``: Outdents the generated code (see ``\Twig\Node\BlockNode`` for a
+ usage example).
+
+.. _creating_extensions:
+
+Creating an Extension
+---------------------
+
+The main motivation for writing an extension is to move often used code into a
+reusable class like adding support for internationalization. An extension can
+define tags, filters, tests, operators, functions, and node visitors.
+
+Most of the time, it is useful to create a single extension for your project,
+to host all the specific tags and filters you want to add to Twig.
+
+.. tip::
+
+ When packaging your code into an extension, Twig is smart enough to
+ recompile your templates whenever you make a change to it (when
+ ``auto_reload`` is enabled).
+
+.. note::
+
+ Before writing your own extensions, have a look at the Twig official
+ extension repository: https://github.com/twigphp/Twig-extensions.
+
+An extension is a class that implements the following interface::
+
+ interface Twig_ExtensionInterface
+ {
+ /**
+ * Initializes the runtime environment.
+ *
+ * This is where you can load some file that contains filter functions for instance.
+ *
+ * @deprecated since 1.23 (to be removed in 2.0), implement \Twig\Extension\InitRuntimeInterface instead
+ */
+ function initRuntime(\Twig\Environment $environment);
+
+ /**
+ * Returns the token parser instances to add to the existing list.
+ *
+ * @return (Twig_TokenParserInterface|Twig_TokenParserBrokerInterface)[]
+ */
+ function getTokenParsers();
+
+ /**
+ * Returns the node visitor instances to add to the existing list.
+ *
+ * @return \Twig\NodeVisitor\NodeVisitorInterface[]
+ */
+ function getNodeVisitors();
+
+ /**
+ * Returns a list of filters to add to the existing list.
+ *
+ * @return \Twig\TwigFilter[]
+ */
+ function getFilters();
+
+ /**
+ * Returns a list of tests to add to the existing list.
+ *
+ * @return \Twig\TwigTest[]
+ */
+ function getTests();
+
+ /**
+ * Returns a list of functions to add to the existing list.
+ *
+ * @return \Twig\TwigFunction[]
+ */
+ function getFunctions();
+
+ /**
+ * Returns a list of operators to add to the existing list.
+ *
+ * @return array First array of unary operators, second array of binary operators
+ */
+ function getOperators();
+
+ /**
+ * Returns a list of global variables to add to the existing list.
+ *
+ * @return array An array of global variables
+ *
+ * @deprecated since 1.23 (to be removed in 2.0), implement \Twig\Extension\GlobalsInterface instead
+ */
+ function getGlobals();
+
+ /**
+ * Returns the name of the extension.
+ *
+ * @return string The extension name
+ *
+ * @deprecated since 1.26 (to be removed in 2.0), not used anymore internally
+ */
+ function getName();
+ }
+
+To keep your extension class clean and lean, inherit from the built-in
+``\Twig\Extension\AbstractExtension`` class instead of implementing the interface as it provides
+empty implementations for all methods:
+
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
+ {
+ }
+
+This extension does nothing for now. We will customize it in the next sections.
+
+.. note::
+
+ Prior to Twig 1.26, you must implement the ``getName()`` method which must
+ return a unique identifier for the extension.
+
+You can save your extension anywhere on the filesystem, as all extensions must
+be registered explicitly to be available in your templates.
+
+You can register an extension by using the ``addExtension()`` method on your
+main ``Environment`` object::
+
+ $twig = new \Twig\Environment($loader);
+ $twig->addExtension(new Project_Twig_Extension());
+
+.. tip::
+
+ The Twig core extensions are great examples of how extensions work.
+
+Globals
+~~~~~~~
+
+Global variables can be registered in an extension via the ``getGlobals()``
+method::
+
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension implements \Twig\Extension\GlobalsInterface
+ {
+ public function getGlobals()
+ {
+ return [
+ 'text' => new Text(),
+ ];
+ }
+
+ // ...
+ }
+
+Functions
+~~~~~~~~~
+
+Functions can be registered in an extension via the ``getFunctions()``
+method::
+
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
+ {
+ public function getFunctions()
+ {
+ return [
+ new \Twig\TwigFunction('lipsum', 'generate_lipsum'),
+ ];
+ }
+
+ // ...
+ }
+
+Filters
+~~~~~~~
+
+To add a filter to an extension, you need to override the ``getFilters()``
+method. This method must return an array of filters to add to the Twig
+environment::
+
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
+ {
+ public function getFilters()
+ {
+ return [
+ new \Twig\TwigFilter('rot13', 'str_rot13'),
+ ];
+ }
+
+ // ...
+ }
+
+Tags
+~~~~
+
+Adding a tag in an extension can be done by overriding the
+``getTokenParsers()`` method. This method must return an array of tags to add
+to the Twig environment::
+
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
+ {
+ public function getTokenParsers()
+ {
+ return [new Project_Set_TokenParser()];
+ }
+
+ // ...
+ }
+
+In the above code, we have added a single new tag, defined by the
+``Project_Set_TokenParser`` class. The ``Project_Set_TokenParser`` class is
+responsible for parsing the tag and compiling it to PHP.
+
+Operators
+~~~~~~~~~
+
+The ``getOperators()`` methods lets you add new operators. Here is how to add
+the ``!``, ``||``, and ``&&`` operators::
+
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
+ {
+ public function getOperators()
+ {
+ return [
+ [
+ '!' => ['precedence' => 50, 'class' => '\Twig\Node\Expression\Unary\NotUnary'],
+ ],
+ [
+ '||' => ['precedence' => 10, 'class' => '\Twig\Node\Expression\Binary\OrBinary', 'associativity' => \Twig\ExpressionParser::OPERATOR_LEFT],
+ '&&' => ['precedence' => 15, 'class' => '\Twig\Node\Expression\Binary\AndBinary', 'associativity' => \Twig\ExpressionParser::OPERATOR_LEFT],
+ ],
+ ];
+ }
+
+ // ...
+ }
+
+Tests
+~~~~~
+
+The ``getTests()`` method lets you add new test functions::
+
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
+ {
+ public function getTests()
+ {
+ return [
+ new \Twig\TwigTest('even', 'twig_test_even'),
+ ];
+ }
+
+ // ...
+ }
+
+Definition vs Runtime
+~~~~~~~~~~~~~~~~~~~~~
+
+Twig filters, functions, and tests runtime implementations can be defined as
+any valid PHP callable:
+
+* **functions/static methods**: Simple to implement and fast (used by all Twig
+ core extensions); but it is hard for the runtime to depend on external
+ objects;
+
+* **closures**: Simple to implement;
+
+* **object methods**: More flexible and required if your runtime code depends
+ on external objects.
+
+The simplest way to use methods is to define them on the extension itself::
+
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
+ {
+ private $rot13Provider;
+
+ public function __construct($rot13Provider)
+ {
+ $this->rot13Provider = $rot13Provider;
+ }
+
+ public function getFunctions()
+ {
+ return [
+ new \Twig\TwigFunction('rot13', [$this, 'rot13']),
+ ];
+ }
+
+ public function rot13($value)
+ {
+ return $this->rot13Provider->rot13($value);
+ }
+ }
+
+This is very convenient but not recommended as it makes template compilation
+depend on runtime dependencies even if they are not needed (think for instance
+as a dependency that connects to a database engine).
+
+As of Twig 1.26, you can easily decouple the extension definitions from their
+runtime implementations by registering a ``\Twig\RuntimeLoader\RuntimeLoaderInterface``
+instance on the environment that knows how to instantiate such runtime classes
+(runtime classes must be autoload-able)::
+
+ class RuntimeLoader implements \Twig\RuntimeLoader\RuntimeLoaderInterface
+ {
+ public function load($class)
+ {
+ // implement the logic to create an instance of $class
+ // and inject its dependencies
+ // most of the time, it means using your dependency injection container
+ if ('Project_Twig_RuntimeExtension' === $class) {
+ return new $class(new Rot13Provider());
+ } else {
+ // ...
+ }
+ }
+ }
+
+ $twig->addRuntimeLoader(new RuntimeLoader());
+
+.. note::
+
+ As of Twig 1.32, Twig comes with a PSR-11 compatible runtime loader
+ (``\Twig\RuntimeLoader\ContainerRuntimeLoader``).
+
+It is now possible to move the runtime logic to a new
+``Project_Twig_RuntimeExtension`` class and use it directly in the extension::
+
+ class Project_Twig_RuntimeExtension
+ {
+ private $rot13Provider;
+
+ public function __construct($rot13Provider)
+ {
+ $this->rot13Provider = $rot13Provider;
+ }
+
+ public function rot13($value)
+ {
+ return $this->rot13Provider->rot13($value);
+ }
+ }
+
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
+ {
+ public function getFunctions()
+ {
+ return [
+ new \Twig\TwigFunction('rot13', ['Project_Twig_RuntimeExtension', 'rot13']),
+ // or
+ new \Twig\TwigFunction('rot13', 'Project_Twig_RuntimeExtension::rot13'),
+ ];
+ }
+ }
+
+Overloading
+-----------
+
+To overload an already defined filter, test, operator, global variable, or
+function, re-define it in an extension and register it **as late as
+possible** (order matters)::
+
+ class MyCoreExtension extends \Twig\Extension\AbstractExtension
+ {
+ public function getFilters()
+ {
+ return [
+ new \Twig\TwigFilter('date', [$this, 'dateFilter']),
+ ];
+ }
+
+ public function dateFilter($timestamp, $format = 'F j, Y H:i')
+ {
+ // do something different from the built-in date filter
+ }
+ }
+
+ $twig = new \Twig\Environment($loader);
+ $twig->addExtension(new MyCoreExtension());
+
+Here, we have overloaded the built-in ``date`` filter with a custom one.
+
+If you do the same on the ``\Twig\Environment`` itself, beware that it takes
+precedence over any other registered extensions::
+
+ $twig = new \Twig\Environment($loader);
+ $twig->addFilter(new \Twig\TwigFilter('date', function ($timestamp, $format = 'F j, Y H:i') {
+ // do something different from the built-in date filter
+ }));
+ // the date filter will come from the above registration, not
+ // from the registered extension below
+ $twig->addExtension(new MyCoreExtension());
+
+.. caution::
+
+ Note that overloading the built-in Twig elements is not recommended as it
+ might be confusing.
+
+Testing an Extension
+--------------------
+
+Functional Tests
+~~~~~~~~~~~~~~~~
+
+You can create functional tests for extensions by creating the following file
+structure in your test directory::
+
+ Fixtures/
+ filters/
+ foo.test
+ bar.test
+ functions/
+ foo.test
+ bar.test
+ tags/
+ foo.test
+ bar.test
+ IntegrationTest.php
+
+The ``IntegrationTest.php`` file should look like this::
+
+ class Project_Tests_IntegrationTest extends \Twig\Test\IntegrationTestCase
+ {
+ public function getExtensions()
+ {
+ return [
+ new Project_Twig_Extension1(),
+ new Project_Twig_Extension2(),
+ ];
+ }
+
+ public function getFixturesDir()
+ {
+ return dirname(__FILE__).'/Fixtures/';
+ }
+ }
+
+Fixtures examples can be found within the Twig repository
+`tests/Twig/Fixtures`_ directory.
+
+Node Tests
+~~~~~~~~~~
+
+Testing the node visitors can be complex, so extend your test cases from
+``\Twig\Test\NodeTestCase``. Examples can be found in the Twig repository
+`tests/Twig/Node`_ directory.
+
+.. _`rot13`: https://secure.php.net/manual/en/function.str-rot13.php
+.. _`tests/Twig/Fixtures`: https://github.com/twigphp/Twig/tree/master/test/Twig/Tests/Fixtures
+.. _`tests/Twig/Node`: https://github.com/twigphp/Twig/tree/master/test/Twig/Tests/Node
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/advanced_legacy.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/advanced_legacy.rst
new file mode 100644
index 0000000..9abfee0
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/advanced_legacy.rst
@@ -0,0 +1,883 @@
+Extending Twig
+==============
+
+.. caution::
+
+ This section describes how to extends Twig for versions **older than
+ 1.12**. If you are using a newer version, read the :doc:`newer`
+ chapter instead.
+
+Twig can be extended in many ways; you can add extra tags, filters, tests,
+operators, global variables, and functions. You can even extend the parser
+itself with node visitors.
+
+.. note::
+
+ The first section of this chapter describes how to extend Twig easily. If
+ you want to reuse your changes in different projects or if you want to
+ share them with others, you should then create an extension as described
+ in the following section.
+
+.. caution::
+
+ When extending Twig by calling methods on the Twig environment instance,
+ Twig won't be able to recompile your templates when the PHP code is
+ updated. To see your changes in real-time, either disable template caching
+ or package your code into an extension (see the next section of this
+ chapter).
+
+Before extending Twig, you must understand the differences between all the
+different possible extension points and when to use them.
+
+First, remember that Twig has two main language constructs:
+
+* ``{{ }}``: used to print the result of an expression evaluation;
+
+* ``{% %}``: used to execute statements.
+
+To understand why Twig exposes so many extension points, let's see how to
+implement a *Lorem ipsum* generator (it needs to know the number of words to
+generate).
+
+You can use a ``lipsum`` *tag*:
+
+.. code-block:: twig
+
+ {% lipsum 40 %}
+
+That works, but using a tag for ``lipsum`` is not a good idea for at least
+three main reasons:
+
+* ``lipsum`` is not a language construct;
+* The tag outputs something;
+* The tag is not flexible as you cannot use it in an expression:
+
+ .. code-block:: twig
+
+ {{ 'some text' ~ {% lipsum 40 %} ~ 'some more text' }}
+
+In fact, you rarely need to create tags; and that's good news because tags are
+the most complex extension point of Twig.
+
+Now, let's use a ``lipsum`` *filter*:
+
+.. code-block:: twig
+
+ {{ 40|lipsum }}
+
+Again, it works, but it looks weird. A filter transforms the passed value to
+something else but here we use the value to indicate the number of words to
+generate (so, ``40`` is an argument of the filter, not the value we want to
+transform).
+
+Next, let's use a ``lipsum`` *function*:
+
+.. code-block:: twig
+
+ {{ lipsum(40) }}
+
+Here we go. For this specific example, the creation of a function is the
+extension point to use. And you can use it anywhere an expression is accepted:
+
+.. code-block:: twig
+
+ {{ 'some text' ~ ipsum(40) ~ 'some more text' }}
+
+ {% set ipsum = ipsum(40) %}
+
+Last but not the least, you can also use a *global* object with a method able
+to generate lorem ipsum text:
+
+.. code-block:: twig
+
+ {{ text.lipsum(40) }}
+
+As a rule of thumb, use functions for frequently used features and global
+objects for everything else.
+
+Keep in mind the following when you want to extend Twig:
+
+========== ========================== ========== =========================
+What? Implementation difficulty? How often? When?
+========== ========================== ========== =========================
+*macro* trivial frequent Content generation
+*global* trivial frequent Helper object
+*function* trivial frequent Content generation
+*filter* trivial frequent Value transformation
+*tag* complex rare DSL language construct
+*test* trivial rare Boolean decision
+*operator* trivial rare Values transformation
+========== ========================== ========== =========================
+
+Globals
+-------
+
+A global variable is like any other template variable, except that it's
+available in all templates and macros::
+
+ $twig = new \Twig\Environment($loader);
+ $twig->addGlobal('text', new Text());
+
+You can then use the ``text`` variable anywhere in a template:
+
+.. code-block:: twig
+
+ {{ text.lipsum(40) }}
+
+Filters
+-------
+
+A filter is a regular PHP function or an object method that takes the left
+side of the filter (before the pipe ``|``) as first argument and the extra
+arguments passed to the filter (within parentheses ``()``) as extra arguments.
+
+Defining a filter is as easy as associating the filter name with a PHP
+callable. For instance, let's say you have the following code in a template:
+
+.. code-block:: twig
+
+ {{ 'TWIG'|lower }}
+
+When compiling this template to PHP, Twig looks for the PHP callable
+associated with the ``lower`` filter. The ``lower`` filter is a built-in Twig
+filter, and it is simply mapped to the PHP ``strtolower()`` function. After
+compilation, the generated PHP code is roughly equivalent to:
+
+.. code-block:: html+php
+
+
+
+As you can see, the ``'TWIG'`` string is passed as a first argument to the PHP
+function.
+
+A filter can also take extra arguments like in the following example:
+
+.. code-block:: twig
+
+ {{ now|date('d/m/Y') }}
+
+In this case, the extra arguments are passed to the function after the main
+argument, and the compiled code is equivalent to:
+
+.. code-block:: html+php
+
+
+
+Let's see how to create a new filter.
+
+In this section, we will create a ``rot13`` filter, which should return the
+`rot13`_ transformation of a string. Here is an example of its usage and the
+expected output:
+
+.. code-block:: twig
+
+ {{ "Twig"|rot13 }}
+
+ {# should displays Gjvt #}
+
+Adding a filter is as simple as calling the ``addFilter()`` method on the
+``\Twig\Environment`` instance::
+
+ $twig = new \Twig\Environment($loader);
+ $twig->addFilter('rot13', new Twig_Filter_Function('str_rot13'));
+
+The second argument of ``addFilter()`` is an instance of ``Twig_Filter``.
+Here, we use ``Twig_Filter_Function`` as the filter is a PHP function. The
+first argument passed to the ``Twig_Filter_Function`` constructor is the name
+of the PHP function to call, here ``str_rot13``, a native PHP function.
+
+Let's say I now want to be able to add a prefix before the converted string:
+
+.. code-block:: twig
+
+ {{ "Twig"|rot13('prefix_') }}
+
+ {# should displays prefix_Gjvt #}
+
+As the PHP ``str_rot13()`` function does not support this requirement, let's
+create a new PHP function::
+
+ function project_compute_rot13($string, $prefix = '')
+ {
+ return $prefix.str_rot13($string);
+ }
+
+As you can see, the ``prefix`` argument of the filter is passed as an extra
+argument to the ``project_compute_rot13()`` function.
+
+Adding this filter is as easy as before::
+
+ $twig->addFilter('rot13', new Twig_Filter_Function('project_compute_rot13'));
+
+For better encapsulation, a filter can also be defined as a static method of a
+class. The ``Twig_Filter_Function`` class can also be used to register such
+static methods as filters::
+
+ $twig->addFilter('rot13', new Twig_Filter_Function('SomeClass::rot13Filter'));
+
+.. tip::
+
+ In an extension, you can also define a filter as a static method of the
+ extension class.
+
+Environment aware Filters
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``Twig_Filter`` classes take options as their last argument. For instance,
+if you want access to the current environment instance in your filter, set the
+``needs_environment`` option to ``true``::
+
+ $filter = new Twig_Filter_Function('str_rot13', ['needs_environment' => true]);
+
+Twig will then pass the current environment as the first argument to the
+filter call::
+
+ function twig_compute_rot13(\Twig\Environment $env, $string)
+ {
+ // get the current charset for instance
+ $charset = $env->getCharset();
+
+ return str_rot13($string);
+ }
+
+Automatic Escaping
+~~~~~~~~~~~~~~~~~~
+
+If automatic escaping is enabled, the output of the filter may be escaped
+before printing. If your filter acts as an escaper (or explicitly outputs HTML
+or JavaScript code), you will want the raw output to be printed. In such a
+case, set the ``is_safe`` option::
+
+ $filter = new Twig_Filter_Function('nl2br', ['is_safe' => ['html']]);
+
+Some filters may need to work on input that is already escaped or safe, for
+example when adding (safe) HTML tags to originally unsafe output. In such a
+case, set the ``pre_escape`` option to escape the input data before it is run
+through your filter::
+
+ $filter = new Twig_Filter_Function('somefilter', ['pre_escape' => 'html', 'is_safe' => ['html']]);
+
+Dynamic Filters
+~~~~~~~~~~~~~~~
+
+.. versionadded:: 1.5
+ Dynamic filters support was added in Twig 1.5.
+
+A filter name containing the special ``*`` character is a dynamic filter as
+the ``*`` can be any string::
+
+ $twig->addFilter('*_path_*', new Twig_Filter_Function('twig_path'));
+
+ function twig_path($name, $arguments)
+ {
+ // ...
+ }
+
+The following filters will be matched by the above defined dynamic filter:
+
+* ``product_path``
+* ``category_path``
+
+A dynamic filter can define more than one dynamic parts::
+
+ $twig->addFilter('*_path_*', new Twig_Filter_Function('twig_path'));
+
+ function twig_path($name, $suffix, $arguments)
+ {
+ // ...
+ }
+
+The filter will receive all dynamic part values before the normal filters
+arguments. For instance, a call to ``'foo'|a_path_b()`` will result in the
+following PHP call: ``twig_path('a', 'b', 'foo')``.
+
+Functions
+---------
+
+A function is a regular PHP function or an object method that can be called from
+templates.
+
+.. code-block:: twig
+
+ {{ constant("DATE_W3C") }}
+
+When compiling this template to PHP, Twig looks for the PHP callable
+associated with the ``constant`` function. The ``constant`` function is a built-in Twig
+function, and it is simply mapped to the PHP ``constant()`` function. After
+compilation, the generated PHP code is roughly equivalent to:
+
+.. code-block:: html+php
+
+
+
+Adding a function is similar to adding a filter. This can be done by calling the
+``addFunction()`` method on the ``\Twig\Environment`` instance::
+
+ $twig = new \Twig\Environment($loader);
+ $twig->addFunction('functionName', new Twig_Function_Function('someFunction'));
+
+You can also expose extension methods as functions in your templates::
+
+ // $this is an object that implements \Twig\Extension\ExtensionInterface.
+ $twig = new \Twig\Environment($loader);
+ $twig->addFunction('otherFunction', new Twig_Function_Method($this, 'someMethod'));
+
+Functions also support ``needs_environment`` and ``is_safe`` parameters.
+
+Dynamic Functions
+~~~~~~~~~~~~~~~~~
+
+.. versionadded:: 1.5
+ Dynamic functions support was added in Twig 1.5.
+
+A function name containing the special ``*`` character is a dynamic function
+as the ``*`` can be any string::
+
+ $twig->addFunction('*_path', new Twig_Function_Function('twig_path'));
+
+ function twig_path($name, $arguments)
+ {
+ // ...
+ }
+
+The following functions will be matched by the above defined dynamic function:
+
+* ``product_path``
+* ``category_path``
+
+A dynamic function can define more than one dynamic parts::
+
+ $twig->addFilter('*_path_*', new Twig_Filter_Function('twig_path'));
+
+ function twig_path($name, $suffix, $arguments)
+ {
+ // ...
+ }
+
+The function will receive all dynamic part values before the normal functions
+arguments. For instance, a call to ``a_path_b('foo')`` will result in the
+following PHP call: ``twig_path('a', 'b', 'foo')``.
+
+Tags
+----
+
+One of the most exciting feature of a template engine like Twig is the
+possibility to define new language constructs. This is also the most complex
+feature as you need to understand how Twig's internals work.
+
+Let's create a simple ``set`` tag that allows the definition of simple
+variables from within a template. The tag can be used like follows:
+
+.. code-block:: twig
+
+ {% set name = "value" %}
+
+ {{ name }}
+
+ {# should output value #}
+
+.. note::
+
+ The ``set`` tag is part of the Core extension and as such is always
+ available. The built-in version is slightly more powerful and supports
+ multiple assignments by default (cf. the template designers chapter for
+ more information).
+
+Three steps are needed to define a new tag:
+
+* Defining a Token Parser class (responsible for parsing the template code);
+
+* Defining a Node class (responsible for converting the parsed code to PHP);
+
+* Registering the tag.
+
+Registering a new tag
+~~~~~~~~~~~~~~~~~~~~~
+
+Adding a tag is as simple as calling the ``addTokenParser`` method on the
+``\Twig\Environment`` instance::
+
+ $twig = new \Twig\Environment($loader);
+ $twig->addTokenParser(new Project_Set_TokenParser());
+
+Defining a Token Parser
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Now, let's see the actual code of this class::
+
+ class Project_Set_TokenParser extends \Twig\TokenParser\AbstractTokenParser
+ {
+ public function parse(\Twig\Token $token)
+ {
+ $lineno = $token->getLine();
+ $name = $this->parser->getStream()->expect(\Twig\Token::NAME_TYPE)->getValue();
+ $this->parser->getStream()->expect(\Twig\Token::OPERATOR_TYPE, '=');
+ $value = $this->parser->getExpressionParser()->parseExpression();
+
+ $this->parser->getStream()->expect(\Twig\Token::BLOCK_END_TYPE);
+
+ return new Project_Set_Node($name, $value, $lineno, $this->getTag());
+ }
+
+ public function getTag()
+ {
+ return 'set';
+ }
+ }
+
+The ``getTag()`` method must return the tag we want to parse, here ``set``.
+
+The ``parse()`` method is invoked whenever the parser encounters a ``set``
+tag. It should return a ``\Twig\Node\Node`` instance that represents the node (the
+``Project_Set_Node`` calls creating is explained in the next section).
+
+The parsing process is simplified thanks to a bunch of methods you can call
+from the token stream (``$this->parser->getStream()``):
+
+* ``getCurrent()``: Gets the current token in the stream.
+
+* ``next()``: Moves to the next token in the stream, *but returns the old one*.
+
+* ``test($type)``, ``test($value)`` or ``test($type, $value)``: Determines whether
+ the current token is of a particular type or value (or both). The value may be an
+ array of several possible values.
+
+* ``expect($type[, $value[, $message]])``: If the current token isn't of the given
+ type/value a syntax error is thrown. Otherwise, if the type and value are correct,
+ the token is returned and the stream moves to the next token.
+
+* ``look()``: Looks a the next token without consuming it.
+
+Parsing expressions is done by calling the ``parseExpression()`` like we did for
+the ``set`` tag.
+
+.. tip::
+
+ Reading the existing ``TokenParser`` classes is the best way to learn all
+ the nitty-gritty details of the parsing process.
+
+Defining a Node
+~~~~~~~~~~~~~~~
+
+The ``Project_Set_Node`` class itself is rather simple::
+
+ class Project_Set_Node extends \Twig\Node\Node
+ {
+ public function __construct($name, \Twig\Node\Expression\AbstractExpression $value, $lineno, $tag = null)
+ {
+ parent::__construct(['value' => $value], ['name' => $name], $lineno, $tag);
+ }
+
+ public function compile(\Twig\Compiler $compiler)
+ {
+ $compiler
+ ->addDebugInfo($this)
+ ->write('$context[\''.$this->getAttribute('name').'\'] = ')
+ ->subcompile($this->getNode('value'))
+ ->raw(";\n")
+ ;
+ }
+ }
+
+The compiler implements a fluid interface and provides methods that helps the
+developer generate beautiful and readable PHP code:
+
+* ``subcompile()``: Compiles a node.
+
+* ``raw()``: Writes the given string as is.
+
+* ``write()``: Writes the given string by adding indentation at the beginning
+ of each line.
+
+* ``string()``: Writes a quoted string.
+
+* ``repr()``: Writes a PHP representation of a given value (see
+ ``\Twig\Node\ForNode`` for a usage example).
+
+* ``addDebugInfo()``: Adds the line of the original template file related to
+ the current node as a comment.
+
+* ``indent()``: Indents the generated code (see ``\Twig\Node\BlockNode`` for a
+ usage example).
+
+* ``outdent()``: Outdents the generated code (see ``\Twig\Node\BlockNode`` for a
+ usage example).
+
+Creating an Extension
+---------------------
+
+The main motivation for writing an extension is to move often used code into a
+reusable class like adding support for internationalization. An extension can
+define tags, filters, tests, operators, global variables, functions, and node
+visitors.
+
+Creating an extension also makes for a better separation of code that is
+executed at compilation time and code needed at runtime. As such, it makes
+your code faster.
+
+Most of the time, it is useful to create a single extension for your project,
+to host all the specific tags and filters you want to add to Twig.
+
+.. tip::
+
+ When packaging your code into an extension, Twig is smart enough to
+ recompile your templates whenever you make a change to it (when the
+ ``auto_reload`` is enabled).
+
+.. note::
+
+ Before writing your own extensions, have a look at the Twig official
+ extension repository: https://github.com/twigphp/Twig-extensions.
+
+An extension is a class that implements the following interface::
+
+ interface Twig_ExtensionInterface
+ {
+ /**
+ * Initializes the runtime environment.
+ *
+ * This is where you can load some file that contains filter functions for instance.
+ */
+ function initRuntime(\Twig\Environment $environment);
+
+ /**
+ * Returns the token parser instances to add to the existing list.
+ *
+ * @return (Twig_TokenParserInterface|Twig_TokenParserBrokerInterface)[]
+ */
+ function getTokenParsers();
+
+ /**
+ * Returns the node visitor instances to add to the existing list.
+ *
+ * @return \Twig\NodeVisitor\NodeVisitorInterface[]
+ */
+ function getNodeVisitors();
+
+ /**
+ * Returns a list of filters to add to the existing list.
+ *
+ * @return \Twig\TwigFilter[]
+ */
+ function getFilters();
+
+ /**
+ * Returns a list of tests to add to the existing list.
+ *
+ * @return \Twig\TwigTest[]
+ */
+ function getTests();
+
+ /**
+ * Returns a list of functions to add to the existing list.
+ *
+ * @return \Twig\TwigFunction[]
+ */
+ function getFunctions();
+
+ /**
+ * Returns a list of operators to add to the existing list.
+ *
+ * @return array First array of unary operators, second array of binary operators
+ */
+ function getOperators();
+
+ /**
+ * Returns a list of global variables to add to the existing list.
+ *
+ * @return array An array of global variables
+ */
+ function getGlobals();
+
+ /**
+ * Returns the name of the extension.
+ *
+ * @return string The extension name
+ */
+ function getName();
+ }
+
+To keep your extension class clean and lean, it can inherit from the built-in
+``\Twig\Extension\AbstractExtension`` class instead of implementing the whole interface. That
+way, you just need to implement the ``getName()`` method as the
+``\Twig\Extension\AbstractExtension`` provides empty implementations for all other methods.
+
+The ``getName()`` method must return a unique identifier for your extension.
+
+Now, with this information in mind, let's create the most basic extension
+possible::
+
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
+ {
+ public function getName()
+ {
+ return 'project';
+ }
+ }
+
+.. note::
+
+ Of course, this extension does nothing for now. We will customize it in
+ the next sections.
+
+Twig does not care where you save your extension on the filesystem, as all
+extensions must be registered explicitly to be available in your templates.
+
+You can register an extension by using the ``addExtension()`` method on your
+main ``Environment`` object::
+
+ $twig = new \Twig\Environment($loader);
+ $twig->addExtension(new Project_Twig_Extension());
+
+Of course, you need to first load the extension file by either using
+``require_once()`` or by using an autoloader (see `spl_autoload_register()`_).
+
+.. tip::
+
+ The bundled extensions are great examples of how extensions work.
+
+Globals
+~~~~~~~
+
+Global variables can be registered in an extension via the ``getGlobals()``
+method::
+
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
+ {
+ public function getGlobals()
+ {
+ return [
+ 'text' => new Text(),
+ ];
+ }
+
+ // ...
+ }
+
+Functions
+~~~~~~~~~
+
+Functions can be registered in an extension via the ``getFunctions()``
+method::
+
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
+ {
+ public function getFunctions()
+ {
+ return [
+ 'lipsum' => new Twig_Function_Function('generate_lipsum'),
+ ];
+ }
+
+ // ...
+ }
+
+Filters
+~~~~~~~
+
+To add a filter to an extension, you need to override the ``getFilters()``
+method. This method must return an array of filters to add to the Twig
+environment::
+
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
+ {
+ public function getFilters()
+ {
+ return [
+ 'rot13' => new Twig_Filter_Function('str_rot13'),
+ ];
+ }
+
+ // ...
+ }
+
+As you can see in the above code, the ``getFilters()`` method returns an array
+where keys are the name of the filters (``rot13``) and the values the
+definition of the filter (``new Twig_Filter_Function('str_rot13')``).
+
+As seen in the previous chapter, you can also define filters as static methods
+on the extension class::
+
+$twig->addFilter('rot13', new Twig_Filter_Function('Project_Twig_Extension::rot13Filter'));
+
+You can also use ``Twig_Filter_Method`` instead of ``Twig_Filter_Function``
+when defining a filter to use a method::
+
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
+ {
+ public function getFilters()
+ {
+ return [
+ 'rot13' => new Twig_Filter_Method($this, 'rot13Filter'),
+ ];
+ }
+
+ public function rot13Filter($string)
+ {
+ return str_rot13($string);
+ }
+
+ // ...
+ }
+
+The first argument of the ``Twig_Filter_Method`` constructor is always
+``$this``, the current extension object. The second one is the name of the
+method to call.
+
+Using methods for filters is a great way to package your filter without
+polluting the global namespace. This also gives the developer more flexibility
+at the cost of a small overhead.
+
+Overriding default Filters
+..........................
+
+If some default core filters do not suit your needs, you can easily override
+them by creating your own extension. Just use the same names as the one you
+want to override::
+
+ class MyCoreExtension extends \Twig\Extension\AbstractExtension
+ {
+ public function getFilters()
+ {
+ return [
+ 'date' => new Twig_Filter_Method($this, 'dateFilter'),
+ // ...
+ ];
+ }
+
+ public function dateFilter($timestamp, $format = 'F j, Y H:i')
+ {
+ return '...'.twig_date_format_filter($timestamp, $format);
+ }
+
+ public function getName()
+ {
+ return 'project';
+ }
+ }
+
+Here, we override the ``date`` filter with a custom one. Using this extension
+is as simple as registering the ``MyCoreExtension`` extension by calling the
+``addExtension()`` method on the environment instance::
+
+ $twig = new \Twig\Environment($loader);
+ $twig->addExtension(new MyCoreExtension());
+
+Tags
+~~~~
+
+Adding a tag in an extension can be done by overriding the
+``getTokenParsers()`` method. This method must return an array of tags to add
+to the Twig environment::
+
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
+ {
+ public function getTokenParsers()
+ {
+ return [new Project_Set_TokenParser()];
+ }
+
+ // ...
+ }
+
+In the above code, we have added a single new tag, defined by the
+``Project_Set_TokenParser`` class. The ``Project_Set_TokenParser`` class is
+responsible for parsing the tag and compiling it to PHP.
+
+Operators
+~~~~~~~~~
+
+The ``getOperators()`` methods allows to add new operators. Here is how to add
+``!``, ``||``, and ``&&`` operators::
+
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
+ {
+ public function getOperators()
+ {
+ return [
+ [
+ '!' => ['precedence' => 50, 'class' => '\Twig\Node\Expression\Unary\NotUnary'],
+ ),
+ [
+ '||' => ['precedence' => 10, 'class' => '\Twig\Node\Expression\Binary\OrBinary', 'associativity' => \Twig\ExpressionParser::OPERATOR_LEFT],
+ '&&' => ['precedence' => 15, 'class' => '\Twig\Node\Expression\Binary\AndBinary', 'associativity' => \Twig\ExpressionParser::OPERATOR_LEFT],
+ ],
+ ];
+ }
+
+ // ...
+ }
+
+Tests
+~~~~~
+
+The ``getTests()`` methods allows to add new test functions::
+
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
+ {
+ public function getTests()
+ {
+ return [
+ 'even' => new Twig_Test_Function('twig_test_even'),
+ ];
+ }
+
+ // ...
+ }
+
+Testing an Extension
+--------------------
+
+.. versionadded:: 1.10
+ Support for functional tests was added in Twig 1.10.
+
+Functional Tests
+~~~~~~~~~~~~~~~~
+
+You can create functional tests for extensions simply by creating the
+following file structure in your test directory::
+
+ Fixtures/
+ filters/
+ foo.test
+ bar.test
+ functions/
+ foo.test
+ bar.test
+ tags/
+ foo.test
+ bar.test
+ IntegrationTest.php
+
+The ``IntegrationTest.php`` file should look like this::
+
+ class Project_Tests_IntegrationTest extends \Twig\Test\IntegrationTestCase
+ {
+ public function getExtensions()
+ {
+ return [
+ new Project_Twig_Extension1(),
+ new Project_Twig_Extension2(),
+ ];
+ }
+
+ public function getFixturesDir()
+ {
+ return dirname(__FILE__).'/Fixtures/';
+ }
+ }
+
+Fixtures examples can be found within the Twig repository
+`tests/Twig/Fixtures`_ directory.
+
+Node Tests
+~~~~~~~~~~
+
+Testing the node visitors can be complex, so extend your test cases from
+``\Twig\Test\NodeTestCase``. Examples can be found in the Twig repository
+`tests/Twig/Node`_ directory.
+
+.. _`spl_autoload_register()`: https://secure.php.net/spl_autoload_register
+.. _`rot13`: https://secure.php.net/manual/en/function.str-rot13.php
+.. _`tests/Twig/Fixtures`: https://github.com/twigphp/Twig/tree/master/test/Twig/Tests/Fixtures
+.. _`tests/Twig/Node`: https://github.com/twigphp/Twig/tree/master/test/Twig/Tests/Node
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/api.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/api.rst
new file mode 100644
index 0000000..b96b0d4
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/api.rst
@@ -0,0 +1,596 @@
+Twig for Developers
+===================
+
+This chapter describes the API to Twig and not the template language. It will
+be most useful as reference to those implementing the template interface to
+the application and not those who are creating Twig templates.
+
+Basics
+------
+
+Twig uses a central object called the **environment** (of class
+``\Twig\Environment``). Instances of this class are used to store the
+configuration and extensions, and are used to load templates.
+
+Most applications create one ``\Twig\Environment`` object on application
+initialization and use that to load templates. In some cases, it might be useful
+to have multiple environments side by side, with different configurations.
+
+The typical way to configure Twig to load templates for an application looks
+roughly like this::
+
+ require_once '/path/to/lib/Twig/Autoloader.php';
+ Twig_Autoloader::register();
+
+ $loader = new \Twig\Loader\FilesystemLoader('/path/to/templates');
+ $twig = new \Twig\Environment($loader, [
+ 'cache' => '/path/to/compilation_cache',
+ ]);
+
+This creates a template environment with a default configuration and a loader
+that looks up templates in the ``/path/to/templates/`` directory. Different
+loaders are available and you can also write your own if you want to load
+templates from a database or other resources.
+
+.. note::
+
+ Notice that the second argument of the environment is an array of options.
+ The ``cache`` option is a compilation cache directory, where Twig caches
+ the compiled templates to avoid the parsing phase for sub-sequent
+ requests. It is very different from the cache you might want to add for
+ the evaluated templates. For such a need, you can use any available PHP
+ cache library.
+
+Rendering Templates
+-------------------
+
+To load a template from a Twig environment, call the ``load()`` method which
+returns a ``\Twig\TemplateWrapper`` instance::
+
+ $template = $twig->load('index.html');
+
+.. note::
+
+ Before Twig 1.28, use ``loadTemplate()`` instead which returns a
+ ``\Twig\Template`` instance.
+
+To render the template with some variables, call the ``render()`` method::
+
+ echo $template->render(['the' => 'variables', 'go' => 'here']);
+
+.. note::
+
+ The ``display()`` method is a shortcut to output the rendered template.
+
+You can also load and render the template in one fell swoop::
+
+ echo $twig->render('index.html', ['the' => 'variables', 'go' => 'here']);
+
+.. versionadded:: 1.28
+ The possibility to render blocks from the API was added in Twig 1.28.
+
+If a template defines blocks, they can be rendered individually via the
+``renderBlock()`` call::
+
+ echo $template->renderBlock('block_name', ['the' => 'variables', 'go' => 'here']);
+
+.. _environment_options:
+
+Environment Options
+-------------------
+
+When creating a new ``\Twig\Environment`` instance, you can pass an array of
+options as the constructor second argument::
+
+ $twig = new \Twig\Environment($loader, ['debug' => true]);
+
+The following options are available:
+
+* ``debug`` *boolean*
+
+ When set to ``true``, the generated templates have a
+ ``__toString()`` method that you can use to display the generated nodes
+ (default to ``false``).
+
+* ``charset`` *string* (defaults to ``utf-8``)
+
+ The charset used by the templates.
+
+* ``base_template_class`` *string* (defaults to ``\Twig\Template``)
+
+ The base template class to use for generated
+ templates.
+
+* ``cache`` *string* or ``false``
+
+ An absolute path where to store the compiled templates, or
+ ``false`` to disable caching (which is the default).
+
+* ``auto_reload`` *boolean*
+
+ When developing with Twig, it's useful to recompile the
+ template whenever the source code changes. If you don't provide a value for
+ the ``auto_reload`` option, it will be determined automatically based on the
+ ``debug`` value.
+
+* ``strict_variables`` *boolean*
+
+ If set to ``false``, Twig will silently ignore invalid
+ variables (variables and or attributes/methods that do not exist) and
+ replace them with a ``null`` value. When set to ``true``, Twig throws an
+ exception instead (default to ``false``).
+
+* ``autoescape`` *string* or *boolean*
+
+ If set to ``true``, HTML auto-escaping will be enabled by
+ default for all templates (default to ``true``).
+
+ As of Twig 1.8, you can set the escaping strategy to use (``html``, ``js``,
+ ``false`` to disable).
+
+ As of Twig 1.9, you can set the escaping strategy to use (``css``, ``url``,
+ ``html_attr``, or a PHP callback that takes the template name and must
+ return the escaping strategy to use -- the callback cannot be a function name
+ to avoid collision with built-in escaping strategies).
+
+ As of Twig 1.17, the ``filename`` escaping strategy (renamed to ``name`` as
+ of Twig 1.27) determines the escaping strategy to use for a template based on
+ the template filename extension (this strategy does not incur any overhead at
+ runtime as auto-escaping is done at compilation time.)
+
+* ``optimizations`` *integer*
+
+ A flag that indicates which optimizations to apply
+ (default to ``-1`` -- all optimizations are enabled; set it to ``0`` to
+ disable).
+
+Loaders
+-------
+
+Loaders are responsible for loading templates from a resource such as the file
+system.
+
+Compilation Cache
+~~~~~~~~~~~~~~~~~
+
+All template loaders can cache the compiled templates on the filesystem for
+future reuse. It speeds up Twig a lot as templates are only compiled once; and
+the performance boost is even larger if you use a PHP accelerator such as
+OPCache. See the ``cache`` and ``auto_reload`` options of ``\Twig\Environment``
+above for more information.
+
+Built-in Loaders
+~~~~~~~~~~~~~~~~
+
+Here is a list of the built-in loaders:
+
+``\Twig\Loader\FilesystemLoader``
+.................................
+
+.. versionadded:: 1.10
+ The ``prependPath()`` and support for namespaces were added in Twig 1.10.
+
+.. versionadded:: 1.27
+ Relative paths support was added in Twig 1.27.
+
+``\Twig\Loader\FilesystemLoader`` loads templates from the file system. This loader
+can find templates in folders on the file system and is the preferred way to
+load them::
+
+ $loader = new \Twig\Loader\FilesystemLoader($templateDir);
+
+It can also look for templates in an array of directories::
+
+ $loader = new \Twig\Loader\FilesystemLoader([$templateDir1, $templateDir2]);
+
+With such a configuration, Twig will first look for templates in
+``$templateDir1`` and if they do not exist, it will fallback to look for them
+in the ``$templateDir2``.
+
+You can add or prepend paths via the ``addPath()`` and ``prependPath()``
+methods::
+
+ $loader->addPath($templateDir3);
+ $loader->prependPath($templateDir4);
+
+The filesystem loader also supports namespaced templates. This allows to group
+your templates under different namespaces which have their own template paths.
+
+When using the ``setPaths()``, ``addPath()``, and ``prependPath()`` methods,
+specify the namespace as the second argument (when not specified, these
+methods act on the "main" namespace)::
+
+ $loader->addPath($templateDir, 'admin');
+
+Namespaced templates can be accessed via the special
+``@namespace_name/template_path`` notation::
+
+ $twig->render('@admin/index.html', []);
+
+``\Twig\Loader\FilesystemLoader`` support absolute and relative paths. Using relative
+paths is preferred as it makes the cache keys independent of the project root
+directory (for instance, it allows warming the cache from a build server where
+the directory might be different from the one used on production servers)::
+
+ $loader = new \Twig\Loader\FilesystemLoader('templates', getcwd().'/..');
+
+.. note::
+
+ When not passing the root path as a second argument, Twig uses ``getcwd()``
+ for relative paths.
+
+``\Twig\Loader\ArrayLoader``
+............................
+
+``\Twig\Loader\ArrayLoader`` loads a template from a PHP array. It is passed an
+array of strings bound to template names::
+
+ $loader = new \Twig\Loader\ArrayLoader([
+ 'index.html' => 'Hello {{ name }}!',
+ ]);
+ $twig = new \Twig\Environment($loader);
+
+ echo $twig->render('index.html', ['name' => 'Fabien']);
+
+This loader is very useful for unit testing. It can also be used for small
+projects where storing all templates in a single PHP file might make sense.
+
+.. tip::
+
+ When using the ``Array`` loaders 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.
+
+``\Twig\Loader\ChainLoader``
+............................
+
+``\Twig\Loader\ChainLoader`` delegates the loading of templates to other loaders::
+
+ $loader1 = new \Twig\Loader\ArrayLoader([
+ 'base.html' => '{% block content %}{% endblock %}',
+ ]);
+ $loader2 = new \Twig\Loader\ArrayLoader([
+ 'index.html' => '{% extends "base.html" %}{% block content %}Hello {{ name }}{% endblock %}',
+ 'base.html' => 'Will never be loaded',
+ ]);
+
+ $loader = new \Twig\Loader\ChainLoader([$loader1, $loader2]);
+
+ $twig = new \Twig\Environment($loader);
+
+When looking for a template, Twig tries each loader in turn and returns as soon
+as the template is found. When rendering the ``index.html`` template from the
+above example, Twig will load it with ``$loader2`` but the ``base.html``
+template will be loaded from ``$loader1``.
+
+.. note::
+
+ You can also add loaders via the ``addLoader()`` method.
+
+Create your own Loader
+~~~~~~~~~~~~~~~~~~~~~~
+
+All loaders implement the ``\Twig\Loader\LoaderInterface``::
+
+ interface Twig_LoaderInterface
+ {
+ /**
+ * Gets the source code of a template, given its name.
+ *
+ * @param string $name string The name of the template to load
+ *
+ * @return string The template source code
+ *
+ * @deprecated since 1.27 (to be removed in 2.0), implement \Twig\Loader\SourceContextLoaderInterface
+ */
+ function getSource($name);
+
+ /**
+ * Gets the cache key to use for the cache for a given template name.
+ *
+ * @param string $name string The name of the template to load
+ *
+ * @return string The cache key
+ */
+ function getCacheKey($name);
+
+ /**
+ * Returns true if the template is still fresh.
+ *
+ * @param string $name The template name
+ * @param timestamp $time The last modification time of the cached template
+ */
+ function isFresh($name, $time);
+ }
+
+The ``isFresh()`` method must return ``true`` if the current cached template
+is still fresh, given the last modification time, or ``false`` otherwise.
+
+.. note::
+
+ As of Twig 1.27, you should also implement
+ ``\Twig\Loader\SourceContextLoaderInterface`` to avoid deprecation notices.
+
+.. tip::
+
+ As of Twig 1.11.0, you can also implement ``\Twig\Loader\ExistsLoaderInterface``
+ to make your loader faster when used with the chain loader.
+
+Using Extensions
+----------------
+
+Twig extensions are packages that add new features to Twig. Register an
+extension via the ``addExtension()`` method::
+
+ $twig->addExtension(new \Twig\Extension\SandboxExtension());
+
+Twig comes bundled with the following extensions:
+
+* *Twig\Extension\CoreExtension*: Defines all the core features of Twig.
+
+* *Twig\Extension\DebugExtension*: Defines the ``dump`` function to help debug
+ template variables.
+
+* *Twig\Extension\EscaperExtension*: Adds automatic output-escaping and the
+ possibility to escape/unescape blocks of code.
+
+* *Twig\Extension\SandboxExtension*: Adds a sandbox mode to the default Twig
+ environment, making it safe to evaluate untrusted code.
+
+* *Twig\Extension\ProfilerExtension*: Enabled the built-in Twig profiler (as of
+ Twig 1.18).
+
+* *Twig\Extension\OptimizerExtension*: Optimizes the node tree before
+ compilation.
+
+* *Twig\Extension\StringLoaderExtension*: Defined the ``template_from_string``
+ function to allow loading templates from string in a template.
+
+The Core, Escaper, and Optimizer extensions are registered by default.
+
+Built-in Extensions
+-------------------
+
+This section describes the features added by the built-in extensions.
+
+.. tip::
+
+ Read the chapter about extending Twig to learn how to create your own
+ extensions.
+
+Core Extension
+~~~~~~~~~~~~~~
+
+The ``core`` extension defines all the core features of Twig:
+
+* :doc:`Tags `;
+* :doc:`Filters `;
+* :doc:`Functions `;
+* :doc:`Tests `.
+
+Escaper Extension
+~~~~~~~~~~~~~~~~~
+
+The ``escaper`` extension adds automatic output escaping to Twig. It defines a
+tag, ``autoescape``, and a filter, ``raw``.
+
+When creating the escaper extension, you can switch on or off the global
+output escaping strategy::
+
+ $escaper = new \Twig\Extension\EscaperExtension('html');
+ $twig->addExtension($escaper);
+
+If set to ``html``, all variables in templates are escaped (using the ``html``
+escaping strategy), except those using the ``raw`` filter:
+
+.. code-block:: twig
+
+ {{ article.to_html|raw }}
+
+You can also change the escaping mode locally by using the ``autoescape`` tag
+(see the :doc:`autoescape` doc for the syntax used before
+Twig 1.8):
+
+.. code-block:: twig
+
+ {% autoescape 'html' %}
+ {{ var }}
+ {{ var|raw }} {# var won't be escaped #}
+ {{ var|escape }} {# var won't be double-escaped #}
+ {% endautoescape %}
+
+.. warning::
+
+ The ``autoescape`` tag has no effect on included files.
+
+The escaping rules are implemented as follows:
+
+* Literals (integers, booleans, arrays, ...) used in the template directly as
+ variables or filter arguments are never automatically escaped:
+
+ .. code-block:: twig
+
+ {{ "Twig " }} {# won't be escaped #}
+
+ {% set text = "Twig " %}
+ {{ text }} {# will be escaped #}
+
+* Expressions which the result is always a literal or a variable marked safe
+ are never automatically escaped:
+
+ .. code-block:: twig
+
+ {{ foo ? "Twig " : " Twig" }} {# won't be escaped #}
+
+ {% set text = "Twig " %}
+ {{ foo ? text : " Twig" }} {# will be escaped #}
+
+ {% set text = "Twig " %}
+ {{ foo ? text|raw : " Twig" }} {# won't be escaped #}
+
+ {% set text = "Twig " %}
+ {{ foo ? text|escape : " Twig" }} {# the result of the expression won't be escaped #}
+
+* Escaping is applied before printing, after any other filter is applied:
+
+ .. code-block:: twig
+
+ {{ var|upper }} {# is equivalent to {{ var|upper|escape }} #}
+
+* The `raw` filter should only be used at the end of the filter chain:
+
+ .. code-block:: twig
+
+ {{ var|raw|upper }} {# will be escaped #}
+
+ {{ var|upper|raw }} {# won't be escaped #}
+
+* Automatic escaping is not applied if the last filter in the chain is marked
+ safe for the current context (e.g. ``html`` or ``js``). ``escape`` and
+ ``escape('html')`` are marked safe for HTML, ``escape('js')`` is marked
+ safe for JavaScript, ``raw`` is marked safe for everything.
+
+ .. code-block:: twig
+
+ {% autoescape 'js' %}
+ {{ var|escape('html') }} {# will be escaped for HTML and JavaScript #}
+ {{ var }} {# will be escaped for JavaScript #}
+ {{ var|escape('js') }} {# won't be double-escaped #}
+ {% endautoescape %}
+
+.. note::
+
+ Note that autoescaping has some limitations as escaping is applied on
+ expressions after evaluation. For instance, when working with
+ concatenation, ``{{ foo|raw ~ bar }}`` won't give the expected result as
+ escaping is applied on the result of the concatenation, not on the
+ individual variables (so, the ``raw`` filter won't have any effect here).
+
+Sandbox Extension
+~~~~~~~~~~~~~~~~~
+
+The ``sandbox`` extension can be used to evaluate untrusted code. Access to
+unsafe attributes and methods is prohibited. The sandbox security is managed
+by a policy instance. By default, Twig comes with one policy class:
+``\Twig\Sandbox\SecurityPolicy``. This class allows you to white-list some
+tags, filters, properties, and methods::
+
+ $tags = ['if'];
+ $filters = ['upper'];
+ $methods = [
+ 'Article' => ['getTitle', 'getBody'],
+ ];
+ $properties = [
+ 'Article' => ['title', 'body'],
+ ];
+ $functions = ['range'];
+ $policy = new \Twig\Sandbox\SecurityPolicy($tags, $filters, $methods, $properties, $functions);
+
+With the previous configuration, the security policy will only allow usage of
+the ``if`` tag, and the ``upper`` filter. Moreover, the templates will only be
+able to call the ``getTitle()`` and ``getBody()`` methods on ``Article``
+objects, and the ``title`` and ``body`` public properties. Everything else
+won't be allowed and will generate a ``\Twig\Sandbox\SecurityError`` exception.
+
+The policy object is the first argument of the sandbox constructor::
+
+ $sandbox = new \Twig\Extension\SandboxExtension($policy);
+ $twig->addExtension($sandbox);
+
+By default, the sandbox mode is disabled and should be enabled when including
+untrusted template code by using the ``sandbox`` tag:
+
+.. code-block:: twig
+
+ {% sandbox %}
+ {% include 'user.html' %}
+ {% endsandbox %}
+
+You can sandbox all templates by passing ``true`` as the second argument of
+the extension constructor::
+
+ $sandbox = new \Twig\Extension\SandboxExtension($policy, true);
+
+Profiler Extension
+~~~~~~~~~~~~~~~~~~
+
+.. versionadded:: 1.18
+ The Profile extension was added in Twig 1.18.
+
+The ``profiler`` extension enables a profiler for Twig templates; it should
+only be used on your development machines as it adds some overhead::
+
+ $profile = new \Twig\Profiler\Profile();
+ $twig->addExtension(new \Twig\Extension\ProfilerExtension($profile));
+
+ $dumper = new \Twig\Profiler\Dumper\TextDumper();
+ echo $dumper->dump($profile);
+
+A profile contains information about time and memory consumption for template,
+block, and macro executions.
+
+You can also dump the data in a `Blackfire.io `_
+compatible format::
+
+ $dumper = new \Twig\Profiler\Dumper\BlackfireDumper();
+ file_put_contents('/path/to/profile.prof', $dumper->dump($profile));
+
+Upload the profile to visualize it (create a `free account
+`_
+first):
+
+.. code-block:: sh
+
+ blackfire --slot=7 upload /path/to/profile.prof
+
+Optimizer Extension
+~~~~~~~~~~~~~~~~~~~
+
+The ``optimizer`` extension optimizes the node tree before compilation::
+
+ $twig->addExtension(new \Twig\Extension\OptimizerExtension());
+
+By default, all optimizations are turned on. You can select the ones you want
+to enable by passing them to the constructor::
+
+ $optimizer = new \Twig\Extension\OptimizerExtension(\Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_FOR);
+
+ $twig->addExtension($optimizer);
+
+Twig supports the following optimizations:
+
+* ``\Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_ALL``, enables all optimizations
+ (this is the default value).
+
+* ``\Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_NONE``, disables all optimizations.
+ This reduces the compilation time, but it can increase the execution time
+ and the consumed memory.
+
+* ``\Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_FOR``, optimizes the ``for`` tag by
+ removing the ``loop`` variable creation whenever possible.
+
+* ``\Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_RAW_FILTER``, removes the ``raw``
+ filter whenever possible.
+
+* ``\Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_VAR_ACCESS``, simplifies the creation
+ and access of variables in the compiled templates whenever possible.
+
+Exceptions
+----------
+
+Twig can throw exceptions:
+
+* ``\Twig\Error\Error``: The base exception for all errors.
+
+* ``\Twig\Error\SyntaxError``: Thrown to tell the user that there is a problem with
+ the template syntax.
+
+* ``\Twig\Error\RuntimeError``: Thrown when an error occurs at runtime (when a filter
+ does not exist for instance).
+
+* ``\Twig\Error\LoaderError``: Thrown when an error occurs during template loading.
+
+* ``\Twig\Sandbox\SecurityError``: Thrown when an unallowed tag, filter, or
+ method is called in a sandboxed template.
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/coding_standards.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/coding_standards.rst
new file mode 100644
index 0000000..721b0f1
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/coding_standards.rst
@@ -0,0 +1,101 @@
+Coding Standards
+================
+
+When writing Twig templates, we recommend you to follow these official coding
+standards:
+
+* Put one (and only one) space after the start of a delimiter (``{{``, ``{%``,
+ and ``{#``) and before the end of a delimiter (``}}``, ``%}``, and ``#}``):
+
+ .. code-block:: twig
+
+ {{ foo }}
+ {# comment #}
+ {% if foo %}{% endif %}
+
+ When using the whitespace control character, do not put any spaces between
+ it and the delimiter:
+
+ .. code-block:: twig
+
+ {{- foo -}}
+ {#- comment -#}
+ {%- if foo -%}{%- endif -%}
+
+* Put one (and only one) space before and after the following operators:
+ comparison operators (``==``, ``!=``, ``<``, ``>``, ``>=``, ``<=``), math
+ operators (``+``, ``-``, ``/``, ``*``, ``%``, ``//``, ``**``), logic
+ operators (``not``, ``and``, ``or``), ``~``, ``is``, ``in``, and the ternary
+ operator (``?:``):
+
+ .. code-block:: twig
+
+ {{ 1 + 2 }}
+ {{ foo ~ bar }}
+ {{ true ? true : false }}
+
+* Put one (and only one) space after the ``:`` sign in hashes and ``,`` in
+ arrays and hashes:
+
+ .. code-block:: twig
+
+ {{ [1, 2, 3] }}
+ {{ {'foo': 'bar'} }}
+
+* Do not put any spaces after an opening parenthesis and before a closing
+ parenthesis in expressions:
+
+ .. code-block:: twig
+
+ {{ 1 + (2 * 3) }}
+
+* Do not put any spaces before and after string delimiters:
+
+ .. code-block:: twig
+
+ {{ 'foo' }}
+ {{ "foo" }}
+
+* Do not put any spaces before and after the following operators: ``|``,
+ ``.``, ``..``, ``[]``:
+
+ .. code-block:: twig
+
+ {{ foo|upper|lower }}
+ {{ user.name }}
+ {{ user[name] }}
+ {% for i in 1..12 %}{% endfor %}
+
+* Do not put any spaces before and after the parenthesis used for filter and
+ function calls:
+
+ .. code-block:: twig
+
+ {{ foo|default('foo') }}
+ {{ range(1..10) }}
+
+* Do not put any spaces before and after the opening and the closing of arrays
+ and hashes:
+
+ .. code-block:: twig
+
+ {{ [1, 2, 3] }}
+ {{ {'foo': 'bar'} }}
+
+* Use lower cased and underscored variable names:
+
+ .. code-block:: twig
+
+ {% set foo = 'foo' %}
+ {% set foo_bar = 'foo' %}
+
+* Indent your code inside tags (use the same indentation as the one used for
+ the target language of the rendered template):
+
+ .. code-block:: twig
+
+ {% block foo %}
+ {% if true %}
+ true
+ {% endif %}
+ {% endblock %}
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/deprecated.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/deprecated.rst
new file mode 100644
index 0000000..1d01fcc
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/deprecated.rst
@@ -0,0 +1,224 @@
+Deprecated Features
+===================
+
+This document lists all deprecated features in Twig. Deprecated features are
+kept for backward compatibility and removed in the next major release (a
+feature that was deprecated in Twig 1.x is removed in Twig 2.0).
+
+Deprecation Notices
+-------------------
+
+As of Twig 1.21, Twig generates deprecation notices when a template uses
+deprecated features. See :ref:`deprecation-notices` for more information.
+
+Macros
+------
+
+As of Twig 2.0, macros imported in a file are not available in child templates
+anymore (via an ``include`` call for instance). You need to import macros
+explicitly in each file where you are using them.
+
+Token Parsers
+-------------
+
+* As of Twig 1.x, the token parser broker sub-system is deprecated. The
+ following class and interface will be removed in 2.0:
+
+ * ``Twig_TokenParserBrokerInterface``
+ * ``Twig_TokenParserBroker``
+
+* As of Twig 1.27, ``\Twig\Parser::getFilename()`` is deprecated. From a token
+ parser, use ``$this->parser->getStream()->getSourceContext()->getPath()`` instead.
+
+* As of Twig 1.27, ``\Twig\Parser::getEnvironment()`` is deprecated.
+
+Extensions
+----------
+
+* As of Twig 1.x, the ability to remove an extension is deprecated and the
+ ``\Twig\Environment::removeExtension()`` method will be removed in 2.0.
+
+* As of Twig 1.23, the ``\Twig\Extension\ExtensionInterface::initRuntime()`` method is
+ deprecated. You have two options to avoid the deprecation notice: if you
+ implement this method to store the environment for your custom filters,
+ functions, or tests, use the ``needs_environment`` option instead; if you
+ have more complex needs, explicitly implement
+ ``\Twig\Extension\InitRuntimeInterface`` (not recommended).
+
+* As of Twig 1.23, the ``\Twig\Extension\ExtensionInterface::getGlobals()`` method is
+ deprecated. Implement ``\Twig\Extension\GlobalsInterface`` to avoid
+ deprecation notices.
+
+* As of Twig 1.26, the ``\Twig\Extension\ExtensionInterface::getName()`` method is
+ deprecated and it is not used internally anymore.
+
+PEAR
+----
+
+PEAR support has been discontinued in Twig 1.15.1, and no PEAR packages are
+provided anymore. Use Composer instead.
+
+Filters
+-------
+
+* As of Twig 1.x, use ``\Twig\TwigFilter`` to add a filter. The following
+ classes and interfaces will be removed in 2.0:
+
+ * ``Twig_FilterInterface``
+ * ``Twig_FilterCallableInterface``
+ * ``Twig_Filter``
+ * ``Twig_Filter_Function``
+ * ``Twig_Filter_Method``
+ * ``Twig_Filter_Node``
+
+* As of Twig 2.x, the ``Twig_SimpleFilter`` class is deprecated and will be
+ removed in Twig 3.x (use ``\Twig\TwigFilter`` instead). In Twig 2.x,
+ ``Twig_SimpleFilter`` is just an alias for ``\Twig\TwigFilter``.
+
+Functions
+---------
+
+* As of Twig 1.x, use ``\Twig\TwigFunction`` to add a function. The following
+ classes and interfaces will be removed in 2.0:
+
+ * ``Twig_FunctionInterface``
+ * ``Twig_FunctionCallableInterface``
+ * ``Twig_Function``
+ * ``Twig_Function_Function``
+ * ``Twig_Function_Method``
+ * ``Twig_Function_Node``
+
+* As of Twig 2.x, the ``Twig_SimpleFunction`` class is deprecated and will be
+ removed in Twig 3.x (use ``\Twig\TwigFunction`` instead). In Twig 2.x,
+ ``Twig_SimpleFunction`` is just an alias for ``\Twig\TwigFunction``.
+
+Tests
+-----
+
+* As of Twig 1.x, use ``\Twig\TwigTest`` to add a test. The following classes
+ and interfaces will be removed in 2.0:
+
+ * ``Twig_TestInterface``
+ * ``Twig_TestCallableInterface``
+ * ``Twig_Test``
+ * ``Twig_Test_Function``
+ * ``Twig_Test_Method``
+ * ``Twig_Test_Node``
+
+* As of Twig 2.x, the ``Twig_SimpleTest`` class is deprecated and will be
+ removed in Twig 3.x (use ``\Twig\TwigTest`` instead). In Twig 2.x,
+ ``Twig_SimpleTest`` is just an alias for ``\Twig\TwigTest``.
+
+* The ``sameas`` and ``divisibleby`` tests are deprecated in favor of ``same
+ as`` and ``divisible by`` respectively.
+
+Tags
+----
+
+* As of Twig 1.x, the ``raw`` tag is deprecated. You should use ``verbatim``
+ instead.
+
+Nodes
+-----
+
+* As of Twig 1.x, ``Node::toXml()`` is deprecated and will be removed in Twig
+ 2.0.
+
+* As of Twig 1.26, ``Node::$nodes`` should only contains ``\Twig\Node\Node``
+ instances, storing a ``null`` value is deprecated and won't be possible in
+ Twig 2.x.
+
+* As of Twig 1.27, the ``filename`` attribute on ``\Twig\Node\ModuleNode`` is
+ deprecated. Use ``getName()`` instead.
+
+* As of Twig 1.27, the ``\Twig\Node\Node::getFilename()/\Twig\Node\Node::getLine()``
+ methods are deprecated, use
+ ``\Twig\Node\Node::getTemplateName()/\Twig\Node\Node::getTemplateLine()`` instead.
+
+Interfaces
+----------
+
+* As of Twig 2.x, the following interfaces are deprecated and empty (they will
+ be removed in Twig 3.0):
+
+* ``Twig_CompilerInterface`` (use ``\Twig\Compiler`` instead)
+* ``Twig_LexerInterface`` (use ``\Twig\Lexer`` instead)
+* ``Twig_NodeInterface`` (use ``\Twig\Node\Node`` instead)
+* ``Twig_ParserInterface`` (use ``\Twig\Parser`` instead)
+* ``\Twig\Loader\ExistsLoaderInterface`` (merged with ``\Twig\Loader\LoaderInterface``)
+* ``\Twig\Loader\SourceContextLoaderInterface`` (merged with ``\Twig\Loader\LoaderInterface``)
+* ``Twig_TemplateInterface`` (use ``\Twig\Template`` instead, and use
+ those constants \Twig\Template::ANY_CALL, \Twig\Template::ARRAY_CALL,
+ \Twig\Template::METHOD_CALL)
+
+Compiler
+--------
+
+* As of Twig 1.26, the ``\Twig\Compiler::getFilename()`` has been deprecated.
+ You should not use it anyway as its values is not reliable.
+
+* As of Twig 1.27, the ``\Twig\Compiler::addIndentation()`` has been deprecated.
+ Use ``\Twig\Compiler::write('')`` instead.
+
+Loaders
+-------
+
+* As of Twig 1.x, ``Twig_Loader_String`` is deprecated and will be removed in
+ 2.0. You can render a string via ``\Twig\Environment::createTemplate()``.
+
+* As of Twig 1.27, ``\Twig\Loader\LoaderInterface::getSource()`` is deprecated.
+ Implement ``\Twig\Loader\SourceContextLoaderInterface`` instead and use
+ ``getSourceContext()``.
+
+Node Visitors
+-------------
+
+* Because of the removal of ``Twig_NodeInterface`` in 2.0, you need to extend
+ ``\Twig\NodeVisitor\AbstractNodeVisitor`` instead of implementing ``\Twig\NodeVisitor\NodeVisitorInterface``
+ directly to make your node visitors compatible with both Twig 1.x and 2.x.
+
+Globals
+-------
+
+* As of Twig 2.x, the ability to register a global variable after the runtime
+ or the extensions have been initialized is not possible anymore (but
+ changing the value of an already registered global is possible).
+
+* As of Twig 1.x, using the ``_self`` global variable to get access to the
+ current ``\Twig\Template`` instance is deprecated; most usages only need the
+ current template name, which will continue to work in Twig 2.0. In Twig 2.0,
+ ``_self`` returns the current template name instead of the current
+ ``\Twig\Template`` instance. If you are using ``{{ _self.templateName }}``,
+ just replace it with ``{{ _self }}``.
+
+Miscellaneous
+-------------
+
+* As of Twig 1.x, ``\Twig\Environment::clearTemplateCache()``,
+ ``\Twig\Environment::writeCacheFile()``,
+ ``\Twig\Environment::clearCacheFiles()``,
+ ``\Twig\Environment::getCacheFilename()``,
+ ``\Twig\Environment::getTemplateClassPrefix()``,
+ ``\Twig\Environment::getLexer()``, ``\Twig\Environment::getParser()``, and
+ ``\Twig\Environment::getCompiler()`` are deprecated and will be removed in 2.0.
+
+* As of Twig 1.x, ``\Twig\Template::getEnvironment()`` and
+ ``Twig_TemplateInterface::getEnvironment()`` are deprecated and will be
+ removed in 2.0.
+
+* As of Twig 1.21, setting the environment option ``autoescape`` to ``true`` is
+ deprecated and will be removed in 2.0. Use ``"html"`` instead.
+
+* As of Twig 1.27, ``\Twig\Error\Error::getTemplateFile()`` and
+ ``\Twig\Error\Error::setTemplateFile()`` are deprecated. Use
+ ``\Twig\Error\Error::getTemplateName()`` and ``\Twig\Error\Error::setTemplateName()``
+ instead.
+
+* As of Twig 1.27, ``\Twig\Template::getSource()`` is deprecated. Use
+ ``\Twig\Template::getSourceContext()`` instead.
+
+* As of Twig 1.27, ``\Twig\Parser::addHandler()`` and
+ ``\Twig\Parser::addNodeVisitor()`` are deprecated and will be removed in 2.0.
+
+* As of Twig 1.29, some classes are marked as being final via the `@final`
+ annotation. Those classes will be marked as final in 2.0.
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/abs.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/abs.rst
new file mode 100644
index 0000000..77d5cf0
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/abs.rst
@@ -0,0 +1,18 @@
+``abs``
+=======
+
+The ``abs`` filter returns the absolute value.
+
+.. code-block:: twig
+
+ {# number = -5 #}
+
+ {{ number|abs }}
+
+ {# outputs 5 #}
+
+.. note::
+
+ Internally, Twig uses the PHP `abs`_ function.
+
+.. _`abs`: https://secure.php.net/abs
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/batch.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/batch.rst
new file mode 100644
index 0000000..cc50ec8
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/batch.rst
@@ -0,0 +1,51 @@
+``batch``
+=========
+
+.. versionadded:: 1.12.3
+ The ``batch`` filter was added in Twig 1.12.3.
+
+The ``batch`` filter "batches" items by returning a list of lists with the
+given number of items. A second parameter can be provided and used to fill in
+missing items:
+
+.. code-block:: twig
+
+ {% set items = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] %}
+
+
+ {% for row in items|batch(3, 'No item') %}
+
+ {% for column in row %}
+
{{ column }}
+ {% endfor %}
+
+ {% endfor %}
+
+
+The above example will be rendered as:
+
+.. code-block:: twig
+
+
+
+
a
+
b
+
c
+
+
+
d
+
e
+
f
+
+
+
g
+
No item
+
No item
+
+
+
+Arguments
+---------
+
+* ``size``: The size of the batch; fractional numbers will be rounded up
+* ``fill``: Used to fill in missing items
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/capitalize.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/capitalize.rst
new file mode 100644
index 0000000..2353658
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/capitalize.rst
@@ -0,0 +1,11 @@
+``capitalize``
+==============
+
+The ``capitalize`` filter capitalizes a value. The first character will be
+uppercase, all others lowercase:
+
+.. code-block:: twig
+
+ {{ 'my first car'|capitalize }}
+
+ {# outputs 'My first car' #}
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/convert_encoding.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/convert_encoding.rst
new file mode 100644
index 0000000..28fde82
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/convert_encoding.rst
@@ -0,0 +1,28 @@
+``convert_encoding``
+====================
+
+.. versionadded:: 1.4
+ The ``convert_encoding`` filter was added in Twig 1.4.
+
+The ``convert_encoding`` filter converts a string from one encoding to
+another. The first argument is the expected output charset and the second one
+is the input charset:
+
+.. code-block:: twig
+
+ {{ data|convert_encoding('UTF-8', 'iso-2022-jp') }}
+
+.. note::
+
+ This filter relies on the `iconv`_ or `mbstring`_ extension, so one of
+ them must be installed. In case both are installed, `mbstring`_ is used by
+ default (Twig before 1.8.1 uses `iconv`_ by default).
+
+Arguments
+---------
+
+* ``to``: The output charset
+* ``from``: The input charset
+
+.. _`iconv`: https://secure.php.net/iconv
+.. _`mbstring`: https://secure.php.net/mbstring
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/date.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/date.rst
new file mode 100644
index 0000000..b8f00bf
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/date.rst
@@ -0,0 +1,100 @@
+``date``
+========
+
+.. versionadded:: 1.1
+ The timezone support has been added in Twig 1.1.
+
+.. versionadded:: 1.5
+ The default date format support has been added in Twig 1.5.
+
+.. versionadded:: 1.6.1
+ The default timezone support has been added in Twig 1.6.1.
+
+.. versionadded:: 1.11.0
+ The introduction of the false value for the timezone was introduced in Twig 1.11.0
+
+The ``date`` filter formats a date to a given format:
+
+.. code-block:: twig
+
+ {{ post.published_at|date("m/d/Y") }}
+
+The format specifier is the same as supported by `date`_,
+except when the filtered data is of type `DateInterval`_, when the format must conform to
+`DateInterval::format`_ instead.
+
+The ``date`` filter accepts strings (it must be in a format supported by the
+`strtotime`_ function), `DateTime`_ instances, or `DateInterval`_ instances. For
+instance, to display the current date, filter the word "now":
+
+.. code-block:: twig
+
+ {{ "now"|date("m/d/Y") }}
+
+To escape words and characters in the date format use ``\\`` in front of each
+character:
+
+.. code-block:: twig
+
+ {{ post.published_at|date("F jS \\a\\t g:ia") }}
+
+If the value passed to the ``date`` filter is ``null``, it will return the
+current date by default. If an empty string is desired instead of the current
+date, use a ternary operator:
+
+.. code-block:: twig
+
+ {{ post.published_at is empty ? "" : post.published_at|date("m/d/Y") }}
+
+If no format is provided, Twig will use the default one: ``F j, Y H:i``. This
+default can be easily changed by calling the ``setDateFormat()`` method on the
+``core`` extension instance. The first argument is the default format for
+dates and the second one is the default format for date intervals:
+
+.. code-block:: php
+
+ $twig = new \Twig\Environment($loader);
+ $twig->getExtension('\Twig\Extension\CoreExtension')->setDateFormat('d/m/Y', '%d days');
+
+ // before Twig 1.26
+ $twig->getExtension('core')->setDateFormat('d/m/Y', '%d days');
+
+Timezone
+--------
+
+By default, the date is displayed by applying the default timezone (the one
+specified in php.ini or declared in Twig -- see below), but you can override
+it by explicitly specifying a timezone:
+
+.. code-block:: twig
+
+ {{ post.published_at|date("m/d/Y", "Europe/Paris") }}
+
+If the date is already a DateTime object, and if you want to keep its current
+timezone, pass ``false`` as the timezone value:
+
+.. code-block:: twig
+
+ {{ post.published_at|date("m/d/Y", false) }}
+
+The default timezone can also be set globally by calling ``setTimezone()``:
+
+.. code-block:: php
+
+ $twig = new \Twig\Environment($loader);
+ $twig->getExtension('\Twig\Extension\CoreExtension')->setTimezone('Europe/Paris');
+
+ // before Twig 1.26
+ $twig->getExtension('core')->setTimezone('Europe/Paris');
+
+Arguments
+---------
+
+* ``format``: The date format
+* ``timezone``: The date timezone
+
+.. _`strtotime`: https://secure.php.net/strtotime
+.. _`DateTime`: https://secure.php.net/DateTime
+.. _`DateInterval`: https://secure.php.net/DateInterval
+.. _`date`: https://secure.php.net/date
+.. _`DateInterval::format`: https://secure.php.net/DateInterval.format
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/date_modify.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/date_modify.rst
new file mode 100644
index 0000000..562cb63
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/date_modify.rst
@@ -0,0 +1,23 @@
+``date_modify``
+===============
+
+.. versionadded:: 1.9.0
+ The date_modify filter has been added in Twig 1.9.0.
+
+The ``date_modify`` filter modifies a date with a given modifier string:
+
+.. code-block:: twig
+
+ {{ post.published_at|date_modify("+1 day")|date("m/d/Y") }}
+
+The ``date_modify`` filter accepts strings (it must be in a format supported
+by the `strtotime`_ function) or `DateTime`_ instances. You can easily combine
+it with the :doc:`date` filter for formatting.
+
+Arguments
+---------
+
+* ``modifier``: The modifier
+
+.. _`strtotime`: https://secure.php.net/strtotime
+.. _`DateTime`: https://secure.php.net/DateTime
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/default.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/default.rst
new file mode 100644
index 0000000..c4ccb56
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/default.rst
@@ -0,0 +1,33 @@
+``default``
+===========
+
+The ``default`` filter returns the passed default value if the value is
+undefined or empty, otherwise the value of the variable:
+
+.. code-block:: twig
+
+ {{ var|default('var is not defined') }}
+
+ {{ var.foo|default('foo item on var is not defined') }}
+
+ {{ var['foo']|default('foo item on var is not defined') }}
+
+ {{ ''|default('passed var is empty') }}
+
+When using the ``default`` filter on an expression that uses variables in some
+method calls, be sure to use the ``default`` filter whenever a variable can be
+undefined:
+
+.. code-block:: twig
+
+ {{ var.method(foo|default('foo'))|default('foo') }}
+
+.. note::
+
+ Read the documentation for the :doc:`defined<../tests/defined>` and
+ :doc:`empty<../tests/empty>` tests to learn more about their semantics.
+
+Arguments
+---------
+
+* ``default``: The default value
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/escape.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/escape.rst
new file mode 100644
index 0000000..8ae95b9
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/escape.rst
@@ -0,0 +1,129 @@
+``escape``
+==========
+
+.. versionadded:: 1.9.0
+ The ``css``, ``url``, and ``html_attr`` strategies were added in Twig
+ 1.9.0.
+
+.. versionadded:: 1.14.0
+ The ability to define custom escapers was added in Twig 1.14.0.
+
+The ``escape`` filter escapes a string using strategies that depend on the
+context.
+
+By default, it uses the HTML escaping strategy:
+
+.. code-block:: html+twig
+
+
+ {{ user.username|escape }}
+
+
+For convenience, the ``e`` filter is defined as an alias:
+
+.. code-block:: html+twig
+
+
+ {{ user.username|e }}
+
+
+The ``escape`` filter can also be used in other contexts than HTML thanks to
+an optional argument which defines the escaping strategy to use:
+
+.. code-block:: twig
+
+ {{ user.username|e }}
+ {# is equivalent to #}
+ {{ user.username|e('html') }}
+
+And here is how to escape variables included in JavaScript code:
+
+.. code-block:: twig
+
+ {{ user.username|escape('js') }}
+ {{ user.username|e('js') }}
+
+The ``escape`` filter supports the following escaping strategies for HTML
+documents:
+
+* ``html``: escapes a string for the **HTML body** context.
+
+* ``js``: escapes a string for the **JavaScript** context.
+
+* ``css``: escapes a string for the **CSS** context. CSS escaping can be
+ applied to any string being inserted into CSS and escapes everything except
+ alphanumerics.
+
+* ``url``: escapes a string for the **URI or parameter** contexts. This should
+ not be used to escape an entire URI; only a subcomponent being inserted.
+
+* ``html_attr``: escapes a string for the **HTML attribute** context.
+
+Note that doing contextual escaping in HTML documents is hard and choosing the
+right escaping strategy depends on a lot of factors. Please, read related
+documentation like `the OWASP prevention cheat sheet
+`_
+to learn more about this topic.
+
+.. note::
+
+ Internally, ``escape`` uses the PHP native `htmlspecialchars`_ function
+ for the HTML escaping strategy.
+
+.. caution::
+
+ When using automatic escaping, Twig tries to not double-escape a variable
+ when the automatic escaping strategy is the same as the one applied by the
+ escape filter; but that does not work when using a variable as the
+ escaping strategy:
+
+ .. code-block:: twig
+
+ {% set strategy = 'html' %}
+
+ {% autoescape 'html' %}
+ {{ var|escape('html') }} {# won't be double-escaped #}
+ {{ var|escape(strategy) }} {# will be double-escaped #}
+ {% endautoescape %}
+
+ When using a variable as the escaping strategy, you should disable
+ automatic escaping:
+
+ .. code-block:: twig
+
+ {% set strategy = 'html' %}
+
+ {% autoescape 'html' %}
+ {{ var|escape(strategy)|raw }} {# won't be double-escaped #}
+ {% endautoescape %}
+
+Custom Escapers
+---------------
+
+You can define custom escapers by calling the ``setEscaper()`` method on the
+``core`` extension instance. The first argument is the escaper name (to be
+used in the ``escape`` call) and the second one must be a valid PHP callable:
+
+.. code-block:: php
+
+ $twig = new \Twig\Environment($loader);
+ $twig->getExtension('\Twig\Extension\CoreExtension')->setEscaper('csv', 'csv_escaper');
+
+ // before Twig 1.26
+ $twig->getExtension('core')->setEscaper('csv', 'csv_escaper');
+
+When called by Twig, the callable receives the Twig environment instance, the
+string to escape, and the charset.
+
+.. note::
+
+ Built-in escapers cannot be overridden mainly because they should be
+ considered as the final implementation and also for better performance.
+
+Arguments
+---------
+
+* ``strategy``: The escaping strategy
+* ``charset``: The string charset
+
+.. _`htmlspecialchars`: https://secure.php.net/htmlspecialchars
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/filter.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/filter.rst
new file mode 100644
index 0000000..a6c1c13
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/filter.rst
@@ -0,0 +1,47 @@
+``filter``
+=========
+
+.. versionadded:: 1.41
+ The ``filter`` filter was added in Twig 1.41.
+
+The ``filter`` filter filters elements of a sequence or a mapping using an arrow
+function. The arrow function receives the value of the sequence or mapping:
+
+.. code-block:: twig
+
+ {% set sizes = [34, 36, 38, 40, 42] %}
+
+ {% for v in sizes|filter(v => v > 38) -%}
+ {{ v }}
+ {% endfor %}
+ {# output 40 42 #}
+
+ {% set sizes = {
+ xs: 34,
+ s: 36,
+ m: 38,
+ l: 40,
+ xl: 42,
+ } %}
+
+ {% for k, v in sizes|filter(v => v > 38) -%}
+ {{ k }} = {{ v }}
+ {% endfor %}
+ {# output l = 40 xl = 42 #}
+
+The arrow function also receives the key as a second argument:
+
+.. code-block:: twig
+
+ {% for k, v in sizes|filter((v, k) => v > 38 and k != "xl") -%}
+ {{ k }} = {{ v }}
+ {% endfor %}
+ {# output l = 40 #}
+
+Note that the arrow function has access to the current context.
+
+Arguments
+---------
+
+* ``array``: The sequence or mapping
+* ``arrow``: The arrow function
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/first.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/first.rst
new file mode 100644
index 0000000..f87fe59
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/first.rst
@@ -0,0 +1,25 @@
+``first``
+=========
+
+.. versionadded:: 1.12.2
+ The ``first`` filter was added in Twig 1.12.2.
+
+The ``first`` filter returns the first "element" of a sequence, a mapping, or
+a string:
+
+.. code-block:: twig
+
+ {{ [1, 2, 3, 4]|first }}
+ {# outputs 1 #}
+
+ {{ { a: 1, b: 2, c: 3, d: 4 }|first }}
+ {# outputs 1 #}
+
+ {{ '1234'|first }}
+ {# outputs 1 #}
+
+.. note::
+
+ It also works with objects implementing the `Traversable`_ interface.
+
+.. _`Traversable`: https://secure.php.net/manual/en/class.traversable.php
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/format.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/format.rst
new file mode 100644
index 0000000..c0c96ee
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/format.rst
@@ -0,0 +1,16 @@
+``format``
+==========
+
+The ``format`` filter formats a given string by replacing the placeholders
+(placeholders follows the `sprintf`_ notation):
+
+.. code-block:: twig
+
+ {{ "I like %s and %s."|format(foo, "bar") }}
+
+ {# outputs I like foo and bar
+ if the foo parameter equals to the foo string. #}
+
+.. _`sprintf`: https://secure.php.net/sprintf
+
+.. seealso:: :doc:`replace`
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/index.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/index.rst
new file mode 100644
index 0000000..8524fc0
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/index.rst
@@ -0,0 +1,41 @@
+Filters
+=======
+
+.. toctree::
+ :maxdepth: 1
+
+ abs
+ batch
+ capitalize
+ convert_encoding
+ date
+ date_modify
+ default
+ escape
+ filter
+ first
+ format
+ join
+ json_encode
+ keys
+ last
+ length
+ lower
+ map
+ merge
+ nl2br
+ number_format
+ raw
+ reduce
+ replace
+ reverse
+ round
+ slice
+ sort
+ spaceless
+ split
+ striptags
+ title
+ trim
+ upper
+ url_encode
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/join.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/join.rst
new file mode 100644
index 0000000..3f9079e
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/join.rst
@@ -0,0 +1,35 @@
+``join``
+========
+
+.. versionadded:: 1.37 and 2.6.1
+ The ``and`` argument was added in Twig 1.37 and 2.6.1.
+
+The ``join`` filter returns a string which is the concatenation of the items
+of a sequence:
+
+.. code-block:: twig
+
+ {{ [1, 2, 3]|join }}
+ {# returns 123 #}
+
+The separator between elements is an empty string per default, but you can
+define it with the optional first parameter:
+
+.. code-block:: twig
+
+ {{ [1, 2, 3]|join('|') }}
+ {# outputs 1|2|3 #}
+
+A second parameter can also be provided that will be the separator used between
+the last two items of the sequence:
+
+.. code-block:: twig
+
+ {{ [1, 2, 3]|join(', ', ' and ') }}
+ {# outputs 1, 2 and 3 #}
+
+Arguments
+---------
+
+* ``glue``: The separator
+* ``and``: The separator for the last pair of input items
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/json_encode.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/json_encode.rst
new file mode 100644
index 0000000..434e2f1
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/json_encode.rst
@@ -0,0 +1,23 @@
+``json_encode``
+===============
+
+The ``json_encode`` filter returns the JSON representation of a value:
+
+.. code-block:: twig
+
+ {{ data|json_encode() }}
+
+.. note::
+
+ Internally, Twig uses the PHP `json_encode`_ function.
+
+Arguments
+---------
+
+* ``options``: A bitmask of `json_encode options`_: ``{{
+ data|json_encode(constant('JSON_PRETTY_PRINT')) }}``.
+ Combine constants using :ref:`bitwise operators`:
+ ``{{ data|json_encode(constant('JSON_PRETTY_PRINT') b-or constant('JSON_HEX_QUOT')) }}``
+
+.. _`json_encode`: https://secure.php.net/json_encode
+.. _`json_encode options`: https://secure.php.net/manual/en/json.constants.php
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/keys.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/keys.rst
new file mode 100644
index 0000000..5860947
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/keys.rst
@@ -0,0 +1,11 @@
+``keys``
+========
+
+The ``keys`` filter returns the keys of an array. It is useful when you want to
+iterate over the keys of an array:
+
+.. code-block:: twig
+
+ {% for key in array|keys %}
+ ...
+ {% endfor %}
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/last.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/last.rst
new file mode 100644
index 0000000..0eb2b84
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/last.rst
@@ -0,0 +1,25 @@
+``last``
+========
+
+.. versionadded:: 1.12.2
+ The ``last`` filter was added in Twig 1.12.2.
+
+The ``last`` filter returns the last "element" of a sequence, a mapping, or
+a string:
+
+.. code-block:: twig
+
+ {{ [1, 2, 3, 4]|last }}
+ {# outputs 4 #}
+
+ {{ { a: 1, b: 2, c: 3, d: 4 }|last }}
+ {# outputs 4 #}
+
+ {{ '1234'|last }}
+ {# outputs 4 #}
+
+.. note::
+
+ It also works with objects implementing the `Traversable`_ interface.
+
+.. _`Traversable`: https://secure.php.net/manual/en/class.traversable.php
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/length.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/length.rst
new file mode 100644
index 0000000..8b504ed
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/length.rst
@@ -0,0 +1,23 @@
+``length``
+==========
+
+.. versionadded:: 1.33
+
+ Support for the ``__toString()`` magic method has been added in Twig 1.33.
+
+The ``length`` filter returns the number of items of a sequence or mapping, or
+the length of a string.
+
+For objects that implement the ``Countable`` interface, ``length`` will use the
+return value of the ``count()`` method.
+
+For objects that implement the ``__toString()`` magic method (and not ``Countable``),
+it will return the length of the string provided by that method.
+
+For objects that implement the ``IteratorAggregate`` interface, ``length`` will use the return value of the ``iterator_count()`` method.
+
+.. code-block:: twig
+
+ {% if users|length > 10 %}
+ ...
+ {% endif %}
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/lower.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/lower.rst
new file mode 100644
index 0000000..c0a0e0c
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/lower.rst
@@ -0,0 +1,10 @@
+``lower``
+=========
+
+The ``lower`` filter converts a value to lowercase:
+
+.. code-block:: twig
+
+ {{ 'WELCOME'|lower }}
+
+ {# outputs 'welcome' #}
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/map.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/map.rst
new file mode 100644
index 0000000..b4849a6
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/map.rst
@@ -0,0 +1,38 @@
+``map``
+=======
+
+.. versionadded:: 1.41
+ The ``map`` filter was added in Twig 1.41.
+
+The ``map`` filter applies an arrow function to the elements of a sequence or a
+mapping. The arrow function receives the value of the sequence or mapping:
+
+.. code-block:: twig
+
+ {% set people = [
+ {first: "Bob", last: "Smith"},
+ {first: "Alice", last: "Dupond"},
+ ] %}
+
+ {{ people|map(p => "#{p.first} #{p.last}")|join(', ') }}
+ {# outputs Bob Smith, Alice Dupond #}
+
+The arrow function also receives the key as a second argument:
+
+.. code-block:: twig
+
+ {% set people = {
+ "Bob": "Smith",
+ "Alice": "Dupond",
+ } %}
+
+ {{ people|map((first, last) => "#{first} #{last}")|join(', ') }}
+ {# outputs Bob Smith, Alice Dupond #}
+
+Note that the arrow function has access to the current context.
+
+Arguments
+---------
+
+* ``array``: The sequence or mapping
+* ``arrow``: The arrow function
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/merge.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/merge.rst
new file mode 100644
index 0000000..e26e51c
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/merge.rst
@@ -0,0 +1,48 @@
+``merge``
+=========
+
+The ``merge`` filter merges an array with another array:
+
+.. code-block:: twig
+
+ {% set values = [1, 2] %}
+
+ {% set values = values|merge(['apple', 'orange']) %}
+
+ {# values now contains [1, 2, 'apple', 'orange'] #}
+
+New values are added at the end of the existing ones.
+
+The ``merge`` filter also works on hashes:
+
+.. code-block:: twig
+
+ {% set items = { 'apple': 'fruit', 'orange': 'fruit', 'peugeot': 'unknown' } %}
+
+ {% set items = items|merge({ 'peugeot': 'car', 'renault': 'car' }) %}
+
+ {# items now contains { 'apple': 'fruit', 'orange': 'fruit', 'peugeot': 'car', 'renault': 'car' } #}
+
+For hashes, the merging process occurs on the keys: if the key does not
+already exist, it is added but if the key already exists, its value is
+overridden.
+
+.. tip::
+
+ If you want to ensure that some values are defined in an array (by given
+ default values), reverse the two elements in the call:
+
+ .. code-block:: twig
+
+ {% set items = { 'apple': 'fruit', 'orange': 'fruit' } %}
+
+ {% set items = { 'apple': 'unknown' }|merge(items) %}
+
+ {# items now contains { 'apple': 'fruit', 'orange': 'fruit' } #}
+
+.. note::
+
+ Internally, Twig uses the PHP `array_merge`_ function. It supports
+ Traversable objects by transforming those to arrays.
+
+.. _`array_merge`: https://secure.php.net/array_merge
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/nl2br.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/nl2br.rst
new file mode 100644
index 0000000..3ad8d85
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/nl2br.rst
@@ -0,0 +1,22 @@
+``nl2br``
+=========
+
+.. versionadded:: 1.5
+ The ``nl2br`` filter was added in Twig 1.5.
+
+The ``nl2br`` filter inserts HTML line breaks before all newlines in a string:
+
+.. code-block:: twig
+
+ {{ "I like Twig.\nYou will like it too."|nl2br }}
+ {# outputs
+
+ I like Twig.
+ You will like it too.
+
+ #}
+
+.. note::
+
+ The ``nl2br`` filter pre-escapes the input before applying the
+ transformation.
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/number_format.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/number_format.rst
new file mode 100644
index 0000000..59335e3
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/number_format.rst
@@ -0,0 +1,56 @@
+``number_format``
+=================
+
+.. versionadded:: 1.5
+ The ``number_format`` filter was added in Twig 1.5
+
+The ``number_format`` filter formats numbers. It is a wrapper around PHP's
+`number_format`_ function:
+
+.. code-block:: twig
+
+ {{ 200.35|number_format }}
+
+You can control the number of decimal places, decimal point, and thousands
+separator using the additional arguments:
+
+.. code-block:: twig
+
+ {{ 9800.333|number_format(2, '.', ',') }}
+
+To format negative numbers, wrap the number with parentheses (needed because of
+Twig's :ref:`precedence of operators `:
+
+.. code-block:: twig
+
+ {{ -9800.333|number_format(2, '.', ',') }} {# outputs : -9 #}
+ {{ (-9800.333)|number_format(2, '.', ',') }} {# outputs : -9,800.33 #}
+
+If no formatting options are provided then Twig will use the default formatting
+options of:
+
+* 0 decimal places.
+* ``.`` as the decimal point.
+* ``,`` as the thousands separator.
+
+These defaults can be easily changed through the core extension:
+
+.. code-block:: php
+
+ $twig = new \Twig\Environment($loader);
+ $twig->getExtension('\Twig\Extension\CoreExtension')->setNumberFormat(3, '.', ',');
+
+ // before Twig 1.26
+ $twig->getExtension('core')->setNumberFormat(3, '.', ',');
+
+The defaults set for ``number_format`` can be over-ridden upon each call using the
+additional parameters.
+
+Arguments
+---------
+
+* ``decimal``: The number of decimal points to display
+* ``decimal_point``: The character(s) to use for the decimal point
+* ``thousand_sep``: The character(s) to use for the thousands separator
+
+.. _`number_format`: https://secure.php.net/number_format
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/raw.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/raw.rst
new file mode 100644
index 0000000..ad74a52
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/raw.rst
@@ -0,0 +1,38 @@
+``raw``
+=======
+
+The ``raw`` filter marks the value as being "safe", which means that in an
+environment with automatic escaping enabled this variable will not be escaped
+if ``raw`` is the last filter applied to it:
+
+.. code-block:: twig
+
+ {% autoescape %}
+ {{ var|raw }} {# var won't be escaped #}
+ {% endautoescape %}
+
+.. note::
+
+ **This note only applies to Twig before versions 1.39 and 2.8**.
+
+ Be careful when using the ``raw`` filter inside expressions:
+
+ .. code-block:: twig
+
+ {% autoescape %}
+ {% set hello = 'Hello' %}
+ {% set hola = 'Hola' %}
+
+ {{ false ? 'Hola' : hello|raw }}
+ does not render the same as
+ {{ false ? hola : hello|raw }}
+ but renders the same as
+ {{ (false ? hola : hello)|raw }}
+ {% endautoescape %}
+
+ The first ternary statement is not escaped: ``hello`` is marked as being
+ safe and Twig does not escape static values (see
+ :doc:`escape<../tags/autoescape>`). In the second ternary statement, even
+ if ``hello`` is marked as safe, ``hola`` remains unsafe and so is the whole
+ expression. The third ternary statement is marked as safe and the result is
+ not escaped.
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/reduce.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/reduce.rst
new file mode 100644
index 0000000..10a0d5a
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/reduce.rst
@@ -0,0 +1,33 @@
+``reduce``
+=========
+
+.. versionadded:: 1.41
+ The ``reduce`` filter was added in Twig 1.41.
+
+The ``reduce`` filter iteratively reduces a sequence or a mapping to a single
+value using an arrow function, so as to reduce it to a single value. The arrow
+function receives the return value of the previous iteration and the current
+value of the sequence or mapping:
+
+.. code-block:: twig
+
+ {% set numbers = [1, 2, 3] %}
+
+ {{ numbers|reduce((carry, v) => carry + v) }}
+ {# output 6 #}
+
+The ``reduce`` filter takes an ``initial`` value as a second argument:
+
+.. code-block:: twig
+
+ {{ numbers|reduce((carry, v) => carry + v, 10) }}
+ {# output 16 #}
+
+Note that the arrow function has access to the current context.
+
+Arguments
+---------
+
+* ``array``: The sequence or mapping
+* ``arrow``: The arrow function
+* ``initial``: The initial value
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/replace.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/replace.rst
new file mode 100644
index 0000000..ceb6c00
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/replace.rst
@@ -0,0 +1,25 @@
+``replace``
+===========
+
+The ``replace`` filter formats a given string by replacing the placeholders
+(placeholders are free-form):
+
+.. code-block:: twig
+
+ {{ "I like %this% and %that%."|replace({'%this%': foo, '%that%': "bar"}) }}
+
+ {# outputs I like foo and bar
+ if the foo parameter equals to the foo string. #}
+
+ {# using % as a delimiter is purely conventional and optional #}
+
+ {{ "I like this and --that--."|replace({'this': foo, '--that--': "bar"}) }}
+
+ {# outputs I like foo and bar #}
+
+Arguments
+---------
+
+* ``from``: The placeholder values
+
+.. seealso:: :doc:`format`
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/reverse.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/reverse.rst
new file mode 100644
index 0000000..b2218c9
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/reverse.rst
@@ -0,0 +1,47 @@
+``reverse``
+===========
+
+.. versionadded:: 1.6
+ Support for strings has been added in Twig 1.6.
+
+The ``reverse`` filter reverses a sequence, a mapping, or a string:
+
+.. code-block:: twig
+
+ {% for user in users|reverse %}
+ ...
+ {% endfor %}
+
+ {{ '1234'|reverse }}
+
+ {# outputs 4321 #}
+
+.. tip::
+
+ For sequences and mappings, numeric keys are not preserved. To reverse
+ them as well, pass ``true`` as an argument to the ``reverse`` filter:
+
+ .. code-block:: twig
+
+ {% for key, value in {1: "a", 2: "b", 3: "c"}|reverse %}
+ {{ key }}: {{ value }}
+ {%- endfor %}
+
+ {# output: 0: c 1: b 2: a #}
+
+ {% for key, value in {1: "a", 2: "b", 3: "c"}|reverse(true) %}
+ {{ key }}: {{ value }}
+ {%- endfor %}
+
+ {# output: 3: c 2: b 1: a #}
+
+.. note::
+
+ It also works with objects implementing the `Traversable`_ interface.
+
+Arguments
+---------
+
+* ``preserve_keys``: Preserve keys when reversing a mapping or a sequence.
+
+.. _`Traversable`: https://secure.php.net/Traversable
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/round.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/round.rst
new file mode 100644
index 0000000..590c71f
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/round.rst
@@ -0,0 +1,37 @@
+``round``
+=========
+
+.. versionadded:: 1.15.0
+ The ``round`` filter was added in Twig 1.15.0.
+
+The ``round`` filter rounds a number to a given precision:
+
+.. code-block:: twig
+
+ {{ 42.55|round }}
+ {# outputs 43 #}
+
+ {{ 42.55|round(1, 'floor') }}
+ {# outputs 42.5 #}
+
+The ``round`` filter takes two optional arguments; the first one specifies the
+precision (default is ``0``) and the second the rounding method (default is
+``common``):
+
+* ``common`` rounds either up or down (rounds the value up to precision decimal
+ places away from zero, when it is half way there -- making 1.5 into 2 and
+ -1.5 into -2);
+
+* ``ceil`` always rounds up;
+
+* ``floor`` always rounds down.
+
+.. note::
+
+ The ``//`` operator is equivalent to ``|round(0, 'floor')``.
+
+Arguments
+---------
+
+* ``precision``: The rounding precision
+* ``method``: The rounding method
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/slice.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/slice.rst
new file mode 100644
index 0000000..9a3ca36
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/slice.rst
@@ -0,0 +1,71 @@
+``slice``
+===========
+
+.. versionadded:: 1.6
+ The ``slice`` filter was added in Twig 1.6.
+
+The ``slice`` filter extracts a slice of a sequence, a mapping, or a string:
+
+.. code-block:: twig
+
+ {% for i in [1, 2, 3, 4, 5]|slice(1, 2) %}
+ {# will iterate over 2 and 3 #}
+ {% endfor %}
+
+ {{ '12345'|slice(1, 2) }}
+
+ {# outputs 23 #}
+
+You can use any valid expression for both the start and the length:
+
+.. code-block:: twig
+
+ {% for i in [1, 2, 3, 4, 5]|slice(start, length) %}
+ {# ... #}
+ {% endfor %}
+
+As syntactic sugar, you can also use the ``[]`` notation:
+
+.. code-block:: twig
+
+ {% for i in [1, 2, 3, 4, 5][start:length] %}
+ {# ... #}
+ {% endfor %}
+
+ {{ '12345'[1:2] }} {# will display "23" #}
+
+ {# you can omit the first argument -- which is the same as 0 #}
+ {{ '12345'[:2] }} {# will display "12" #}
+
+ {# you can omit the last argument -- which will select everything till the end #}
+ {{ '12345'[2:] }} {# will display "345" #}
+
+The ``slice`` filter works as the `array_slice`_ PHP function for arrays and
+`mb_substr`_ for strings with a fallback to `substr`_.
+
+If the start is non-negative, the sequence will start at that start in the
+variable. If start is negative, the sequence will start that far from the end
+of the variable.
+
+If length is given and is positive, then the sequence will have up to that
+many elements in it. If the variable is shorter than the length, then only the
+available variable elements will be present. If length is given and is
+negative then the sequence will stop that many elements from the end of the
+variable. If it is omitted, then the sequence will have everything from offset
+up until the end of the variable.
+
+.. note::
+
+ It also works with objects implementing the `Traversable`_ interface.
+
+Arguments
+---------
+
+* ``start``: The start of the slice
+* ``length``: The size of the slice
+* ``preserve_keys``: Whether to preserve key or not (when the input is an array)
+
+.. _`Traversable`: https://secure.php.net/manual/en/class.traversable.php
+.. _`array_slice`: https://secure.php.net/array_slice
+.. _`mb_substr` : https://secure.php.net/mb-substr
+.. _`substr`: https://secure.php.net/substr
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/sort.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/sort.rst
new file mode 100644
index 0000000..f7c0329
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/sort.rst
@@ -0,0 +1,18 @@
+``sort``
+========
+
+The ``sort`` filter sorts an array:
+
+.. code-block:: twig
+
+ {% for user in users|sort %}
+ ...
+ {% endfor %}
+
+.. note::
+
+ Internally, Twig uses the PHP `asort`_ function to maintain index
+ association. It supports Traversable objects by transforming
+ those to arrays.
+
+.. _`asort`: https://secure.php.net/asort
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/spaceless.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/spaceless.rst
new file mode 100644
index 0000000..bfc547e
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/spaceless.rst
@@ -0,0 +1,65 @@
+``spaceless``
+=============
+
+.. versionadded:: 1.38
+
+ The ``spaceless`` filter was added in Twig 1.38.
+
+Use the ``spaceless`` filter to remove whitespace *between HTML tags*, not
+whitespace within HTML tags or whitespace in plain text:
+
+.. code-block:: twig
+
+ {{
+ "
+ foo
+
+ "|spaceless }}
+
+ {# output will be
foo
#}
+
+You can combine ``spaceless`` with the ``apply`` tag to apply the transformation
+on large amounts of HTML:
+
+.. code-block:: twig
+
+ {% apply spaceless %}
+
+ foo
+
+ {% endapply %}
+
+ {# output will be
foo
#}
+
+.. note::
+
+ The ``apply`` tag was introduced in Twig 1.40; use the ``filter`` tag with
+ previous versions.
+
+This tag is not meant to "optimize" the size of the generated HTML content but
+merely to avoid extra whitespace between HTML tags to avoid browser rendering
+quirks under some circumstances.
+
+.. caution::
+
+ As the filter uses a regular expression behind the scenes, its performance
+ is directly related to the text size you are working on (remember that
+ filters are executed at runtime).
+
+.. tip::
+
+ If you want to optimize the size of the generated HTML content, gzip
+ compress the output instead.
+
+.. tip::
+
+ If you want to create a tag that actually removes all extra whitespace in
+ an HTML string, be warned that this is not as easy as it seems to be
+ (think of ``textarea`` or ``pre`` tags for instance). Using a third-party
+ library like Tidy is probably a better idea.
+
+.. tip::
+
+ For more information on whitespace control, read the
+ :ref:`dedicated section ` of the documentation and learn how
+ you can also use the whitespace control modifier on your tags.
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/split.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/split.rst
new file mode 100644
index 0000000..92eedff
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/split.rst
@@ -0,0 +1,53 @@
+``split``
+=========
+
+.. versionadded:: 1.10.3
+ The ``split`` filter was added in Twig 1.10.3.
+
+The ``split`` filter splits a string by the given delimiter and returns a list
+of strings:
+
+.. code-block:: twig
+
+ {% set foo = "one,two,three"|split(',') %}
+ {# foo contains ['one', 'two', 'three'] #}
+
+You can also pass a ``limit`` argument:
+
+* If ``limit`` is positive, the returned array will contain a maximum of
+ limit elements with the last element containing the rest of string;
+
+* If ``limit`` is negative, all components except the last -limit are
+ returned;
+
+* If ``limit`` is zero, then this is treated as 1.
+
+.. code-block:: twig
+
+ {% set foo = "one,two,three,four,five"|split(',', 3) %}
+ {# foo contains ['one', 'two', 'three,four,five'] #}
+
+If the ``delimiter`` is an empty string, then value will be split by equal
+chunks. Length is set by the ``limit`` argument (one character by default).
+
+.. code-block:: twig
+
+ {% set foo = "123"|split('') %}
+ {# foo contains ['1', '2', '3'] #}
+
+ {% set bar = "aabbcc"|split('', 2) %}
+ {# bar contains ['aa', 'bb', 'cc'] #}
+
+.. note::
+
+ Internally, Twig uses the PHP `explode`_ or `str_split`_ (if delimiter is
+ empty) functions for string splitting.
+
+Arguments
+---------
+
+* ``delimiter``: The delimiter
+* ``limit``: The limit argument
+
+.. _`explode`: https://secure.php.net/explode
+.. _`str_split`: https://secure.php.net/str_split
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/striptags.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/striptags.rst
new file mode 100644
index 0000000..62b2a7b
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/striptags.rst
@@ -0,0 +1,29 @@
+``striptags``
+=============
+
+The ``striptags`` filter strips SGML/XML tags and replace adjacent whitespace
+by one space:
+
+.. code-block:: twig
+
+ {{ some_html|striptags }}
+
+You can also provide tags which should not be stripped:
+
+.. code-block:: twig
+
+ {{ some_html|striptags('
') }}
+
+In this example, the `` ``, `` ``, ``
``, and ``
`` tags won't be
+removed from the string.
+
+.. note::
+
+ Internally, Twig uses the PHP `strip_tags`_ function.
+
+Arguments
+---------
+
+* ``allowable_tags``: Tags which should not be stripped
+
+.. _`strip_tags`: https://secure.php.net/strip_tags
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/title.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/title.rst
new file mode 100644
index 0000000..dd0311c
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/title.rst
@@ -0,0 +1,11 @@
+``title``
+=========
+
+The ``title`` filter returns a titlecased version of the value. Words will
+start with uppercase letters, all remaining characters are lowercase:
+
+.. code-block:: twig
+
+ {{ 'my first car'|title }}
+
+ {# outputs 'My First Car' #}
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/trim.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/trim.rst
new file mode 100644
index 0000000..96ce403
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/trim.rst
@@ -0,0 +1,45 @@
+``trim``
+========
+
+.. versionadded:: 1.32
+ The ``side`` argument was added in Twig 1.32.
+
+.. versionadded:: 1.6.2
+ The ``trim`` filter was added in Twig 1.6.2.
+
+The ``trim`` filter strips whitespace (or other characters) from the beginning
+and end of a string:
+
+.. code-block:: twig
+
+ {{ ' I like Twig. '|trim }}
+
+ {# outputs 'I like Twig.' #}
+
+ {{ ' I like Twig.'|trim('.') }}
+
+ {# outputs ' I like Twig' #}
+
+ {{ ' I like Twig. '|trim(side='left') }}
+
+ {# outputs 'I like Twig. ' #}
+
+ {{ ' I like Twig. '|trim(' ', 'right') }}
+
+ {# outputs ' I like Twig.' #}
+
+.. note::
+
+ Internally, Twig uses the PHP `trim`_, `ltrim`_, and `rtrim`_ functions.
+
+Arguments
+---------
+
+* ``character_mask``: The characters to strip
+
+* ``side``: The default is to strip from the left and the right (`both`) sides, but `left`
+ and `right` will strip from either the left side or right side only
+
+.. _`trim`: https://secure.php.net/trim
+.. _`ltrim`: https://secure.php.net/ltrim
+.. _`rtrim`: https://secure.php.net/rtrim
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/upper.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/upper.rst
new file mode 100644
index 0000000..01c9fbb
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/upper.rst
@@ -0,0 +1,10 @@
+``upper``
+=========
+
+The ``upper`` filter converts a value to uppercase:
+
+.. code-block:: twig
+
+ {{ 'welcome'|upper }}
+
+ {# outputs 'WELCOME' #}
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/url_encode.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/url_encode.rst
new file mode 100644
index 0000000..df2c1f0
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/filters/url_encode.rst
@@ -0,0 +1,34 @@
+``url_encode``
+==============
+
+.. versionadded:: 1.12.3
+ Support for encoding an array as query string was added in Twig 1.12.3.
+
+.. versionadded:: 1.16.0
+ The ``raw`` argument was removed in Twig 1.16.0. Twig now always encodes
+ according to RFC 3986.
+
+The ``url_encode`` filter percent encodes a given string as URL segment
+or an array as query string:
+
+.. code-block:: twig
+
+ {{ "path-seg*ment"|url_encode }}
+ {# outputs "path-seg%2Ament" #}
+
+ {{ "string with spaces"|url_encode }}
+ {# outputs "string%20with%20spaces" #}
+
+ {{ {'param': 'value', 'foo': 'bar'}|url_encode }}
+ {# outputs "param=value&foo=bar" #}
+
+.. note::
+
+ Internally, Twig uses the PHP `urlencode`_ (or `rawurlencode`_ if you pass
+ ``true`` as the first parameter) or the `http_build_query`_ function. Note
+ that as of Twig 1.16.0, ``urlencode`` **always** uses ``rawurlencode`` (the
+ ``raw`` argument was removed.)
+
+.. _`urlencode`: https://secure.php.net/urlencode
+.. _`rawurlencode`: https://secure.php.net/rawurlencode
+.. _`http_build_query`: https://secure.php.net/http_build_query
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/attribute.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/attribute.rst
new file mode 100644
index 0000000..99c08d8
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/attribute.rst
@@ -0,0 +1,26 @@
+``attribute``
+=============
+
+.. versionadded:: 1.2
+ The ``attribute`` function was added in Twig 1.2.
+
+The ``attribute`` function can be used to access a "dynamic" attribute of a
+variable:
+
+.. code-block:: twig
+
+ {{ attribute(object, method) }}
+ {{ attribute(object, method, arguments) }}
+ {{ attribute(array, item) }}
+
+In addition, the ``defined`` test can check for the existence of a dynamic
+attribute:
+
+.. code-block:: twig
+
+ {{ attribute(object, method) is defined ? 'Method exists' : 'Method does not exist' }}
+
+.. note::
+
+ The resolution algorithm is the same as the one used for the ``.``
+ notation, except that the item can be any valid expression.
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/block.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/block.rst
new file mode 100644
index 0000000..c626148
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/block.rst
@@ -0,0 +1,41 @@
+``block``
+=========
+
+.. versionadded: 1.28
+ Using ``block`` with the ``defined`` test was added in Twig 1.28.
+
+.. versionadded: 1.28
+ Support for the template argument was added in Twig 1.28.
+
+When a template uses inheritance and if you want to print a block multiple
+times, use the ``block`` function:
+
+.. code-block:: twig
+
+ {% block title %}{% endblock %}
+
+
{{ block('title') }}
+
+ {% block body %}{% endblock %}
+
+The ``block`` function can also be used to display one block from another
+template:
+
+.. code-block:: twig
+
+ {{ block("title", "common_blocks.twig") }}
+
+Use the ``defined`` test to check if a block exists in the context of the
+current template:
+
+.. code-block:: twig
+
+ {% if block("footer") is defined %}
+ ...
+ {% endif %}
+
+ {% if block("footer", "common_blocks.twig") is defined %}
+ ...
+ {% endif %}
+
+.. seealso:: :doc:`extends<../tags/extends>`, :doc:`parent<../functions/parent>`
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/constant.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/constant.rst
new file mode 100644
index 0000000..f9d836c
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/constant.rst
@@ -0,0 +1,29 @@
+``constant``
+============
+
+.. versionadded: 1.12.1
+ constant now accepts object instances as the second argument.
+
+.. versionadded: 1.28
+ Using ``constant`` with the ``defined`` test was added in Twig 1.28.
+
+``constant`` returns the constant value for a given string:
+
+.. code-block:: twig
+
+ {{ some_date|date(constant('DATE_W3C')) }}
+ {{ constant('Namespace\\Classname::CONSTANT_NAME') }}
+
+As of 1.12.1 you can read constants from object instances as well:
+
+.. code-block:: twig
+
+ {{ constant('RSS', date) }}
+
+Use the ``defined`` test to check if a constant is defined:
+
+.. code-block:: twig
+
+ {% if constant('SOME_CONST') is defined %}
+ ...
+ {% endif %}
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/cycle.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/cycle.rst
new file mode 100644
index 0000000..84cff6a
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/cycle.rst
@@ -0,0 +1,28 @@
+``cycle``
+=========
+
+The ``cycle`` function cycles on an array of values:
+
+.. code-block:: twig
+
+ {% set start_year = date() | date('Y') %}
+ {% set end_year = start_year + 5 %}
+
+ {% for year in start_year..end_year %}
+ {{ cycle(['odd', 'even'], loop.index0) }}
+ {% endfor %}
+
+The array can contain any number of values:
+
+.. code-block:: twig
+
+ {% set fruits = ['apple', 'orange', 'citrus'] %}
+
+ {% for i in 0..10 %}
+ {{ cycle(fruits, i) }}
+ {% endfor %}
+
+Arguments
+---------
+
+* ``position``: The cycle position
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/date.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/date.rst
new file mode 100644
index 0000000..b88f669
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/date.rst
@@ -0,0 +1,55 @@
+``date``
+========
+
+.. versionadded:: 1.6
+ The date function has been added in Twig 1.6.
+
+.. versionadded:: 1.6.1
+ The default timezone support has been added in Twig 1.6.1.
+
+Converts an argument to a date to allow date comparison:
+
+.. code-block:: twig
+
+ {% if date(user.created_at) < date('-2days') %}
+ {# do something #}
+ {% endif %}
+
+The argument must be in one of PHP’s supported `date and time formats`_.
+
+You can pass a timezone as the second argument:
+
+.. code-block:: twig
+
+ {% if date(user.created_at) < date('-2days', 'Europe/Paris') %}
+ {# do something #}
+ {% endif %}
+
+If no argument is passed, the function returns the current date:
+
+.. code-block:: twig
+
+ {% if date(user.created_at) < date() %}
+ {# always! #}
+ {% endif %}
+
+.. note::
+
+ You can set the default timezone globally by calling ``setTimezone()`` on
+ the ``core`` extension instance:
+
+ .. code-block:: php
+
+ $twig = new \Twig\Environment($loader);
+ $twig->getExtension('\Twig\Extension\CoreExtension')->setTimezone('Europe/Paris');
+
+ // before Twig 1.26
+ $twig->getExtension('core')->setTimezone('Europe/Paris');
+
+Arguments
+---------
+
+* ``date``: The date
+* ``timezone``: The timezone
+
+.. _`date and time formats`: https://secure.php.net/manual/en/datetime.formats.php
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/dump.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/dump.rst
new file mode 100644
index 0000000..b7c01e7
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/dump.rst
@@ -0,0 +1,69 @@
+``dump``
+========
+
+.. versionadded:: 1.5
+ The ``dump`` function was added in Twig 1.5.
+
+The ``dump`` function dumps information about a template variable. This is
+mostly useful to debug a template that does not behave as expected by
+introspecting its variables:
+
+.. code-block:: twig
+
+ {{ dump(user) }}
+
+.. note::
+
+ The ``dump`` function is not available by default. You must add the
+ ``\Twig\Extension\DebugExtension`` extension explicitly when creating your Twig
+ environment::
+
+ $twig = new \Twig\Environment($loader, [
+ 'debug' => true,
+ // ...
+ ]);
+ $twig->addExtension(new \Twig\Extension\DebugExtension());
+
+ Even when enabled, the ``dump`` function won't display anything if the
+ ``debug`` option on the environment is not enabled (to avoid leaking debug
+ information on a production server).
+
+In an HTML context, wrap the output with a ``pre`` tag to make it easier to
+read:
+
+.. code-block:: twig
+
+
+ {{ dump(user) }}
+
+
+.. tip::
+
+ Using a ``pre`` tag is not needed when `XDebug`_ is enabled and
+ ``html_errors`` is ``on``; as a bonus, the output is also nicer with
+ XDebug enabled.
+
+You can debug several variables by passing them as additional arguments:
+
+.. code-block:: twig
+
+ {{ dump(user, categories) }}
+
+If you don't pass any value, all variables from the current context are
+dumped:
+
+.. code-block:: twig
+
+ {{ dump() }}
+
+.. note::
+
+ Internally, Twig uses the PHP `var_dump`_ function.
+
+Arguments
+---------
+
+* ``context``: The context to dump
+
+.. _`XDebug`: https://xdebug.org/docs/display
+.. _`var_dump`: https://secure.php.net/var_dump
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/include.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/include.rst
new file mode 100644
index 0000000..8af4790
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/include.rst
@@ -0,0 +1,84 @@
+``include``
+===========
+
+.. versionadded:: 1.12
+ The ``include`` function was added in Twig 1.12.
+
+The ``include`` function returns the rendered content of a template:
+
+.. code-block:: twig
+
+ {{ include('template.html') }}
+ {{ include(some_var) }}
+
+Included templates have access to the variables of the active context.
+
+If you are using the filesystem loader, the templates are looked for in the
+paths defined by it.
+
+The context is passed by default to the template but you can also pass
+additional variables:
+
+.. code-block:: twig
+
+ {# template.html will have access to the variables from the current context and the additional ones provided #}
+ {{ include('template.html', {foo: 'bar'}) }}
+
+You can disable access to the context by setting ``with_context`` to
+``false``:
+
+.. code-block:: twig
+
+ {# only the foo variable will be accessible #}
+ {{ include('template.html', {foo: 'bar'}, with_context = false) }}
+
+.. code-block:: twig
+
+ {# no variables will be accessible #}
+ {{ include('template.html', with_context = false) }}
+
+And if the expression evaluates to a ``\Twig\Template`` or a
+``\Twig\TemplateWrapper`` instance, Twig will use it directly::
+
+ // {{ include(template) }}
+
+ // deprecated as of Twig 1.28
+ $template = $twig->loadTemplate('some_template.twig');
+
+ // as of Twig 1.28
+ $template = $twig->load('some_template.twig');
+
+ $twig->display('template.twig', ['template' => $template]);
+
+When you set the ``ignore_missing`` flag, Twig will return an empty string if
+the template does not exist:
+
+.. code-block:: twig
+
+ {{ include('sidebar.html', ignore_missing = true) }}
+
+You can also provide a list of templates that are checked for existence before
+inclusion. The first template that exists will be rendered:
+
+.. code-block:: twig
+
+ {{ include(['page_detailed.html', 'page.html']) }}
+
+If ``ignore_missing`` is set, it will fall back to rendering nothing if none
+of the templates exist, otherwise it will throw an exception.
+
+When including a template created by an end user, you should consider
+sandboxing it:
+
+.. code-block:: twig
+
+ {{ include('page.html', sandboxed = true) }}
+
+Arguments
+---------
+
+* ``template``: The template to render
+* ``variables``: The variables to pass to the template
+* ``with_context``: Whether to pass the current context variables or not
+* ``ignore_missing``: Whether to ignore missing templates or not
+* ``sandboxed``: Whether to sandbox the template or not
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/index.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/index.rst
new file mode 100644
index 0000000..07214a7
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/index.rst
@@ -0,0 +1,20 @@
+Functions
+=========
+
+.. toctree::
+ :maxdepth: 1
+
+ attribute
+ block
+ constant
+ cycle
+ date
+ dump
+ include
+ max
+ min
+ parent
+ random
+ range
+ source
+ template_from_string
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/max.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/max.rst
new file mode 100644
index 0000000..f271e66
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/max.rst
@@ -0,0 +1,20 @@
+``max``
+=======
+
+.. versionadded:: 1.15
+ The ``max`` function was added in Twig 1.15.
+
+``max`` returns the biggest value of a sequence or a set of values:
+
+.. code-block:: twig
+
+ {{ max(1, 3, 2) }}
+ {{ max([1, 3, 2]) }}
+
+When called with a mapping, max ignores keys and only compares values:
+
+.. code-block:: twig
+
+ {{ max({2: "e", 1: "a", 3: "b", 5: "d", 4: "c"}) }}
+ {# returns "e" #}
+
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/min.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/min.rst
new file mode 100644
index 0000000..362b0f9
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/min.rst
@@ -0,0 +1,20 @@
+``min``
+=======
+
+.. versionadded:: 1.15
+ The ``min`` function was added in Twig 1.15.
+
+``min`` returns the lowest value of a sequence or a set of values:
+
+.. code-block:: twig
+
+ {{ min(1, 3, 2) }}
+ {{ min([1, 3, 2]) }}
+
+When called with a mapping, min ignores keys and only compares values:
+
+.. code-block:: twig
+
+ {{ min({2: "e", 3: "a", 1: "b", 5: "d", 4: "c"}) }}
+ {# returns "a" #}
+
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/parent.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/parent.rst
new file mode 100644
index 0000000..9beb5d2
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/parent.rst
@@ -0,0 +1,20 @@
+``parent``
+==========
+
+When a template uses inheritance, it's possible to render the contents of the
+parent block when overriding a block by using the ``parent`` function:
+
+.. code-block:: twig
+
+ {% extends "base.html" %}
+
+ {% block sidebar %}
+
Table Of Contents
+ ...
+ {{ parent() }}
+ {% endblock %}
+
+The ``parent()`` call will return the content of the ``sidebar`` block as
+defined in the ``base.html`` template.
+
+.. seealso:: :doc:`extends<../tags/extends>`, :doc:`block<../functions/block>`, :doc:`block<../tags/block>`
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/random.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/random.rst
new file mode 100644
index 0000000..45e6fa7
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/random.rst
@@ -0,0 +1,36 @@
+``random``
+==========
+
+.. versionadded:: 1.5
+ The ``random`` function was added in Twig 1.5.
+
+.. versionadded:: 1.6
+ String and integer handling was added in Twig 1.6.
+
+.. versionadded:: 1.38
+ The "max" argument was added in Twig 1.38.
+
+The ``random`` function returns a random value depending on the supplied
+parameter type:
+
+* a random item from a sequence;
+* a random character from a string;
+* a random integer between 0 and the integer parameter (inclusive).
+* a random integer between the integer parameter (when negative) and 0 (inclusive).
+* a random integer between the first integer and the second integer parameter (inclusive).
+
+.. code-block:: twig
+
+ {{ random(['apple', 'orange', 'citrus']) }} {# example output: orange #}
+ {{ random('ABC') }} {# example output: C #}
+ {{ random() }} {# example output: 15386094 (works as the native PHP mt_rand function) #}
+ {{ random(5) }} {# example output: 3 #}
+ {{ random(50, 100) }} {# example output: 63 #}
+
+Arguments
+---------
+
+* ``values``: The values
+* ``max``: The max value when values is an integer
+
+.. _`mt_rand`: https://secure.php.net/mt_rand
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/range.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/range.rst
new file mode 100644
index 0000000..a1f0e7c
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/range.rst
@@ -0,0 +1,58 @@
+``range``
+=========
+
+Returns a list containing an arithmetic progression of integers:
+
+.. code-block:: twig
+
+ {% for i in range(0, 3) %}
+ {{ i }},
+ {% endfor %}
+
+ {# outputs 0, 1, 2, 3, #}
+
+When step is given (as the third parameter), it specifies the increment (or
+decrement for negative values):
+
+.. code-block:: twig
+
+ {% for i in range(0, 6, 2) %}
+ {{ i }},
+ {% endfor %}
+
+ {# outputs 0, 2, 4, 6, #}
+
+.. note::
+
+ Note that if the start is greater than the end, ``range`` assumes a step of
+ ``-1``:
+
+ .. code-block:: twig
+
+ {% for i in range(3, 0) %}
+ {{ i }},
+ {% endfor %}
+
+ {# outputs 3, 2, 1, 0, #}
+
+The Twig built-in ``..`` operator is just syntactic sugar for the ``range``
+function (with a step of ``1``, or ``-1`` if the start is greater than the end):
+
+.. code-block:: twig
+
+ {% for i in 0..3 %}
+ {{ i }},
+ {% endfor %}
+
+.. tip::
+
+ The ``range`` function works as the native PHP `range`_ function.
+
+Arguments
+---------
+
+* ``low``: The first value of the sequence.
+* ``high``: The highest possible value of the sequence.
+* ``step``: The increment between elements of the sequence.
+
+.. _`range`: https://secure.php.net/range
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/source.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/source.rst
new file mode 100644
index 0000000..571fea2
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/source.rst
@@ -0,0 +1,32 @@
+``source``
+==========
+
+.. versionadded:: 1.15
+ The ``source`` function was added in Twig 1.15.
+
+.. versionadded:: 1.18.3
+ The ``ignore_missing`` flag was added in Twig 1.18.3.
+
+The ``source`` function returns the content of a template without rendering it:
+
+.. code-block:: twig
+
+ {{ source('template.html') }}
+ {{ source(some_var) }}
+
+When you set the ``ignore_missing`` flag, Twig will return an empty string if
+the template does not exist:
+
+.. code-block:: twig
+
+ {{ source('template.html', ignore_missing = true) }}
+
+The function uses the same template loaders as the ones used to include
+templates. So, if you are using the filesystem loader, the templates are looked
+for in the paths defined by it.
+
+Arguments
+---------
+
+* ``name``: The name of the template to read
+* ``ignore_missing``: Whether to ignore missing templates or not
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/template_from_string.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/template_from_string.rst
new file mode 100644
index 0000000..b26f566
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/functions/template_from_string.rst
@@ -0,0 +1,43 @@
+``template_from_string``
+========================
+
+.. versionadded:: 1.11
+ The ``template_from_string`` function was added in Twig 1.11.
+
+.. versionadded:: 1.39
+ The name argument was added in Twig 1.39.
+
+The ``template_from_string`` function loads a template from a string:
+
+.. code-block:: twig
+
+ {{ include(template_from_string("Hello {{ name }}")) }}
+ {{ include(template_from_string(page.template)) }}
+
+To ease debugging, you can also give the template a name that will be part of
+any related error message:
+
+.. code-block:: twig
+
+ {{ include(template_from_string(page.template, "template for page " ~ page.name)) }}
+
+.. note::
+
+ The ``template_from_string`` function is not available by default. You
+ must add the ``\Twig\Extension\StringLoaderExtension`` extension explicitly when
+ creating your Twig environment::
+
+ $twig = new \Twig\Environment(...);
+ $twig->addExtension(new \Twig\Extension\StringLoaderExtension());
+
+.. note::
+
+ Even if you will probably always use the ``template_from_string`` function
+ with the ``include`` function, you can use it with any tag or function that
+ takes a template as an argument (like the ``embed`` or ``extends`` tags).
+
+Arguments
+---------
+
+* ``template``: The template
+* ``name``: A name for the template
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/index.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/index.rst
new file mode 100644
index 0000000..358bd73
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/index.rst
@@ -0,0 +1,19 @@
+Twig
+====
+
+.. toctree::
+ :maxdepth: 2
+
+ intro
+ installation
+ templates
+ api
+ advanced
+ internals
+ deprecated
+ recipes
+ coding_standards
+ tags/index
+ filters/index
+ functions/index
+ tests/index
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/installation.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/installation.rst
new file mode 100644
index 0000000..362d317
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/installation.rst
@@ -0,0 +1,73 @@
+Installation
+============
+
+You have multiple ways to install Twig.
+
+Installing the Twig PHP package
+-------------------------------
+
+Install `Composer`_ and run the following command:
+
+.. code-block:: bash
+
+ composer require "twig/twig:^1.0"
+
+Installing the C extension
+--------------------------
+
+.. versionadded:: 1.4
+ The C extension was added in Twig 1.4.
+
+Twig comes with an **optional** C extension that improves the performance of the
+Twig runtime engine.
+
+Note that this extension does not replace the PHP code but only provides an
+optimized version of the ``\Twig\Template::getAttribute()`` method; you must
+still install the regular PHP code
+
+The C extension is only compatible and useful for **PHP5**.
+
+Install it like any other PHP extensions:
+
+.. code-block:: bash
+
+ cd ext/twig
+ phpize
+ ./configure
+ make
+ make install
+
+For Windows:
+
+1. Setup the build environment following the `PHP documentation`_
+2. Put Twig's C extension source code into ``C:\php-sdk\phpdev\vcXX\x86\php-source-directory\ext\twig``
+3. Use the ``configure --disable-all --enable-cli --enable-twig=shared`` command instead of step 14
+4. ``nmake``
+5. Copy the ``C:\php-sdk\phpdev\vcXX\x86\php-source-directory\Release_TS\php_twig.dll`` file to your PHP setup.
+
+.. tip::
+
+ For Windows ZendServer, ZTS is not enabled as mentioned in `Zend Server
+ FAQ`_.
+
+ You have to use ``configure --disable-all --disable-zts --enable-cli
+ --enable-twig=shared`` to be able to build the twig C extension for
+ ZendServer.
+
+ The built DLL will be available in
+ ``C:\\php-sdk\\phpdev\\vcXX\\x86\\php-source-directory\\Release``
+
+Finally, enable the extension in your ``php.ini`` configuration file:
+
+.. code-block:: ini
+
+ extension=twig.so # For Unix systems
+ extension=php_twig.dll # For Windows systems
+
+And from now on, Twig will automatically compile your templates to take
+advantage of the C extension.
+
+.. _`download page`: https://github.com/twigphp/Twig/tags
+.. _`Composer`: https://getcomposer.org/download/
+.. _`PHP documentation`: https://wiki.php.net/internals/windows/stepbystepbuild
+.. _`Zend Server FAQ`: https://www.zend.com/en/products/server/faq#faqD6
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/internals.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/internals.rst
new file mode 100644
index 0000000..4b1a1ab
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/internals.rst
@@ -0,0 +1,144 @@
+Twig Internals
+==============
+
+Twig is very extensible and you can easily hack it. Keep in mind that you
+should probably try to create an extension before hacking the core, as most
+features and enhancements can be handled with extensions. This chapter is also
+useful for people who want to understand how Twig works under the hood.
+
+How does Twig work?
+-------------------
+
+The rendering of a Twig template can be summarized into four key steps:
+
+* **Load** the template: If the template is already compiled, load it and go
+ to the *evaluation* step, otherwise:
+
+ * First, the **lexer** tokenizes the template source code into small pieces
+ for easier processing;
+
+ * Then, the **parser** converts the token stream into a meaningful tree
+ of nodes (the Abstract Syntax Tree);
+
+ * Finally, the *compiler* transforms the AST into PHP code.
+
+* **Evaluate** the template: It means calling the ``display()``
+ method of the compiled template and passing it the context.
+
+The Lexer
+---------
+
+The lexer tokenizes a template source code into a token stream (each token is
+an instance of ``\Twig\Token``, and the stream is an instance of
+``\Twig\TokenStream``). The default lexer recognizes 13 different token types:
+
+* ``\Twig\Token::BLOCK_START_TYPE``, ``\Twig\Token::BLOCK_END_TYPE``: Delimiters for blocks (``{% %}``)
+* ``\Twig\Token::VAR_START_TYPE``, ``\Twig\Token::VAR_END_TYPE``: Delimiters for variables (``{{ }}``)
+* ``\Twig\Token::TEXT_TYPE``: A text outside an expression;
+* ``\Twig\Token::NAME_TYPE``: A name in an expression;
+* ``\Twig\Token::NUMBER_TYPE``: A number in an expression;
+* ``\Twig\Token::STRING_TYPE``: A string in an expression;
+* ``\Twig\Token::OPERATOR_TYPE``: An operator;
+* ``\Twig\Token::PUNCTUATION_TYPE``: A punctuation sign;
+* ``\Twig\Token::INTERPOLATION_START_TYPE``, ``\Twig\Token::INTERPOLATION_END_TYPE`` (as of Twig 1.5): Delimiters for string interpolation;
+* ``\Twig\Token::EOF_TYPE``: Ends of template.
+
+You can manually convert a source code into a token stream by calling the
+``tokenize()`` method of an environment::
+
+ $stream = $twig->tokenize(new \Twig\Source($source, $identifier));
+
+.. versionadded:: 1.27
+ ``\Twig\Source`` was introduced in version 1.27, pass the source and the
+ identifier directly on previous versions.
+
+As the stream has a ``__toString()`` method, you can have a textual
+representation of it by echoing the object::
+
+ echo $stream."\n";
+
+Here is the output for the ``Hello {{ name }}`` template:
+
+.. code-block:: text
+
+ TEXT_TYPE(Hello )
+ VAR_START_TYPE()
+ NAME_TYPE(name)
+ VAR_END_TYPE()
+ EOF_TYPE()
+
+.. note::
+
+ The default lexer (``\Twig\Lexer``) can be changed by calling
+ the ``setLexer()`` method::
+
+ $twig->setLexer($lexer);
+
+The Parser
+----------
+
+The parser converts the token stream into an AST (Abstract Syntax Tree), or a
+node tree (an instance of ``\Twig\Node\ModuleNode``). The core extension defines
+the basic nodes like: ``for``, ``if``, ... and the expression nodes.
+
+You can manually convert a token stream into a node tree by calling the
+``parse()`` method of an environment::
+
+ $nodes = $twig->parse($stream);
+
+Echoing the node object gives you a nice representation of the tree::
+
+ echo $nodes."\n";
+
+Here is the output for the ``Hello {{ name }}`` template:
+
+.. code-block:: text
+
+ \Twig\Node\ModuleNode(
+ \Twig\Node\TextNode(Hello )
+ \Twig\Node\PrintNode(
+ \Twig\Node\Expression\NameExpression(name)
+ )
+ )
+
+.. note::
+
+ The default parser (``\Twig\TokenParser\AbstractTokenParser``) can be changed by calling the
+ ``setParser()`` method::
+
+ $twig->setParser($parser);
+
+The Compiler
+------------
+
+The last step is done by the compiler. It takes a node tree as an input and
+generates PHP code usable for runtime execution of the template.
+
+You can manually compile a node tree to PHP code with the ``compile()`` method
+of an environment::
+
+ $php = $twig->compile($nodes);
+
+The generated template for a ``Hello {{ name }}`` template reads as follows
+(the actual output can differ depending on the version of Twig you are
+using)::
+
+ /* Hello {{ name }} */
+ class __TwigTemplate_1121b6f109fe93ebe8c6e22e3712bceb extends \Twig\Template
+ {
+ protected function doDisplay(array $context, array $blocks = [])
+ {
+ // line 1
+ echo "Hello ";
+ echo twig_escape_filter($this->env, (isset($context["name"]) ? $context["name"] : null), "html", null, true);
+ }
+
+ // some more code
+ }
+
+.. note::
+
+ The default compiler (``\Twig\Compiler``) can be changed by calling the
+ ``setCompiler()`` method::
+
+ $twig->setCompiler($compiler);
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/intro.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/intro.rst
new file mode 100644
index 0000000..d1f9c59
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/intro.rst
@@ -0,0 +1,76 @@
+Introduction
+============
+
+Welcome to the documentation for Twig, the flexible, fast, and secure template
+engine for PHP.
+
+Twig is both designer and developer friendly by sticking to PHP's principles and
+adding functionality useful for templating environments.
+
+The key-features are...
+
+* *Fast*: Twig compiles templates down to plain optimized PHP code. The
+ overhead compared to regular PHP code was reduced to the very minimum.
+
+* *Secure*: Twig has a sandbox mode to evaluate untrusted template code. This
+ allows Twig to be used as a template language for applications where users
+ may modify the template design.
+
+* *Flexible*: Twig is powered by a flexible lexer and parser. This allows the
+ developer to define their own custom tags and filters, and to create their own DSL.
+
+Twig is used by many Open-Source projects like Symfony, Drupal8, eZPublish,
+phpBB, Matomo, OroCRM; and many frameworks have support for it as well like
+Slim, Yii, Laravel, and Codeigniter — just to name a few.
+
+Prerequisites
+-------------
+
+Twig needs at least **PHP 5.4.0** to run.
+
+Installation
+------------
+
+The recommended way to install Twig is via Composer:
+
+.. code-block:: bash
+
+ composer require "twig/twig:^1.0"
+
+.. note::
+
+ To learn more about the other installation methods, read the
+ :doc:`installation` chapter; it also explains how to install
+ the Twig C extension.
+
+Basic API Usage
+---------------
+
+This section gives you a brief introduction to the PHP API for Twig.
+
+.. code-block:: php
+
+ require_once '/path/to/vendor/autoload.php';
+
+ $loader = new \Twig\Loader\ArrayLoader([
+ 'index' => 'Hello {{ name }}!',
+ ]);
+ $twig = new \Twig\Environment($loader);
+
+ echo $twig->render('index', ['name' => 'Fabien']);
+
+Twig uses a loader (``\Twig\Loader\ArrayLoader``) to locate templates, and an
+environment (``\Twig\Environment``) to store its configuration.
+
+The ``render()`` method loads the template passed as a first argument and
+renders it with the variables passed as a second argument.
+
+As templates are generally stored on the filesystem, Twig also comes with a
+filesystem loader::
+
+ $loader = new \Twig\Loader\FilesystemLoader('/path/to/templates');
+ $twig = new \Twig\Environment($loader, [
+ 'cache' => '/path/to/compilation_cache',
+ ]);
+
+ echo $twig->render('index.html', ['name' => 'Fabien']);
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/recipes.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/recipes.rst
new file mode 100644
index 0000000..a8238b5
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/recipes.rst
@@ -0,0 +1,568 @@
+Recipes
+=======
+
+.. _deprecation-notices:
+
+Displaying Deprecation Notices
+------------------------------
+
+.. versionadded:: 1.21
+ This works as of Twig 1.21.
+
+Deprecated features generate deprecation notices (via a call to the
+``trigger_error()`` PHP function). By default, they are silenced and never
+displayed nor logged.
+
+To remove all deprecated feature usages from your templates, write and run a
+script along the lines of the following::
+
+ require_once __DIR__.'/vendor/autoload.php';
+
+ $twig = create_your_twig_env();
+
+ $deprecations = new \Twig\Util\DeprecationCollector($twig);
+
+ print_r($deprecations->collectDir(__DIR__.'/templates'));
+
+The ``collectDir()`` method compiles all templates found in a directory,
+catches deprecation notices, and return them.
+
+.. tip::
+
+ If your templates are not stored on the filesystem, use the ``collect()``
+ method instead. ``collect()`` takes a ``Traversable`` which must return
+ template names as keys and template contents as values (as done by
+ ``\Twig\Util\TemplateDirIterator``).
+
+However, this code won't find all deprecations (like using deprecated some Twig
+classes). To catch all notices, register a custom error handler like the one
+below::
+
+ $deprecations = [];
+ set_error_handler(function ($type, $msg) use (&$deprecations) {
+ if (E_USER_DEPRECATED === $type) {
+ $deprecations[] = $msg;
+ }
+ });
+
+ // run your application
+
+ print_r($deprecations);
+
+Note that most deprecation notices are triggered during **compilation**, so
+they won't be generated when templates are already cached.
+
+.. tip::
+
+ If you want to manage the deprecation notices from your PHPUnit tests, have
+ a look at the `symfony/phpunit-bridge
+ `_ package, which eases the
+ process.
+
+Making a Layout conditional
+---------------------------
+
+Working with Ajax means that the same content is sometimes displayed as is,
+and sometimes decorated with a layout. As Twig layout template names can be
+any valid expression, you can pass a variable that evaluates to ``true`` when
+the request is made via Ajax and choose the layout accordingly:
+
+.. code-block:: twig
+
+ {% extends request.ajax ? "base_ajax.html" : "base.html" %}
+
+ {% block content %}
+ This is the content to be displayed.
+ {% endblock %}
+
+Making an Include dynamic
+-------------------------
+
+When including a template, its name does not need to be a string. For
+instance, the name can depend on the value of a variable:
+
+.. code-block:: twig
+
+ {% include var ~ '_foo.html' %}
+
+If ``var`` evaluates to ``index``, the ``index_foo.html`` template will be
+rendered.
+
+As a matter of fact, the template name can be any valid expression, such as
+the following:
+
+.. code-block:: twig
+
+ {% include var|default('index') ~ '_foo.html' %}
+
+Overriding a Template that also extends itself
+----------------------------------------------
+
+A template can be customized in two different ways:
+
+* *Inheritance*: A template *extends* a parent template and overrides some
+ blocks;
+
+* *Replacement*: If you use the filesystem loader, Twig loads the first
+ template it finds in a list of configured directories; a template found in a
+ directory *replaces* another one from a directory further in the list.
+
+But how do you combine both: *replace* a template that also extends itself
+(aka a template in a directory further in the list)?
+
+Let's say that your templates are loaded from both ``.../templates/mysite``
+and ``.../templates/default`` in this order. The ``page.twig`` template,
+stored in ``.../templates/default`` reads as follows:
+
+.. code-block:: twig
+
+ {# page.twig #}
+ {% extends "layout.twig" %}
+
+ {% block content %}
+ {% endblock %}
+
+You can replace this template by putting a file with the same name in
+``.../templates/mysite``. And if you want to extend the original template, you
+might be tempted to write the following:
+
+.. code-block:: twig
+
+ {# page.twig in .../templates/mysite #}
+ {% extends "page.twig" %} {# from .../templates/default #}
+
+Of course, this will not work as Twig will always load the template from
+``.../templates/mysite``.
+
+It turns out it is possible to get this to work, by adding a directory right
+at the end of your template directories, which is the parent of all of the
+other directories: ``.../templates`` in our case. This has the effect of
+making every template file within our system uniquely addressable. Most of the
+time you will use the "normal" paths, but in the special case of wanting to
+extend a template with an overriding version of itself we can reference its
+parent's full, unambiguous template path in the extends tag:
+
+.. code-block:: twig
+
+ {# page.twig in .../templates/mysite #}
+ {% extends "default/page.twig" %} {# from .../templates #}
+
+.. note::
+
+ This recipe was inspired by the following Django wiki page:
+ https://code.djangoproject.com/wiki/ExtendingTemplates
+
+Customizing the Syntax
+----------------------
+
+Twig allows some syntax customization for the block delimiters. It's **not**
+recommended to use this feature as templates will be tied with your custom
+syntax. But for specific projects, it can make sense to change the defaults.
+
+To change the block delimiters, you need to create your own lexer object::
+
+ $twig = new \Twig\Environment();
+
+ $lexer = new \Twig\Lexer($twig, [
+ 'tag_comment' => ['{#', '#}'],
+ 'tag_block' => ['{%', '%}'],
+ 'tag_variable' => ['{{', '}}'],
+ 'interpolation' => ['#{', '}'],
+ ]);
+ $twig->setLexer($lexer);
+
+Here are some configuration example that simulates some other template engines
+syntax::
+
+ // Ruby erb syntax
+ $lexer = new \Twig\Lexer($twig, [
+ 'tag_comment' => ['<%#', '%>'],
+ 'tag_block' => ['<%', '%>'],
+ 'tag_variable' => ['<%=', '%>'],
+ ]);
+
+ // SGML Comment Syntax
+ $lexer = new \Twig\Lexer($twig, [
+ 'tag_comment' => [''],
+ 'tag_block' => [''],
+ 'tag_variable' => ['${', '}'],
+ ]);
+
+ // Smarty like
+ $lexer = new \Twig\Lexer($twig, [
+ 'tag_comment' => ['{*', '*}'],
+ 'tag_block' => ['{', '}'],
+ 'tag_variable' => ['{$', '}'],
+ ]);
+
+Using dynamic Object Properties
+-------------------------------
+
+When Twig encounters a variable like ``article.title``, it tries to find a
+``title`` public property in the ``article`` object.
+
+It also works if the property does not exist but is rather defined dynamically
+thanks to the magic ``__get()`` method; you need to also implement the
+``__isset()`` magic method like shown in the following snippet of code::
+
+ class Article
+ {
+ public function __get($name)
+ {
+ if ('title' == $name) {
+ return 'The title';
+ }
+
+ // throw some kind of error
+ }
+
+ public function __isset($name)
+ {
+ if ('title' == $name) {
+ return true;
+ }
+
+ return false;
+ }
+ }
+
+Accessing the parent Context in Nested Loops
+--------------------------------------------
+
+Sometimes, when using nested loops, you need to access the parent context. The
+parent context is always accessible via the ``loop.parent`` variable. For
+instance, if you have the following template data::
+
+ $data = [
+ 'topics' => [
+ 'topic1' => ['Message 1 of topic 1', 'Message 2 of topic 1'],
+ 'topic2' => ['Message 1 of topic 2', 'Message 2 of topic 2'],
+ ],
+ ];
+
+And the following template to display all messages in all topics:
+
+.. code-block:: twig
+
+ {% for topic, messages in topics %}
+ * {{ loop.index }}: {{ topic }}
+ {% for message in messages %}
+ - {{ loop.parent.loop.index }}.{{ loop.index }}: {{ message }}
+ {% endfor %}
+ {% endfor %}
+
+The output will be similar to:
+
+.. code-block:: text
+
+ * 1: topic1
+ - 1.1: The message 1 of topic 1
+ - 1.2: The message 2 of topic 1
+ * 2: topic2
+ - 2.1: The message 1 of topic 2
+ - 2.2: The message 2 of topic 2
+
+In the inner loop, the ``loop.parent`` variable is used to access the outer
+context. So, the index of the current ``topic`` defined in the outer for loop
+is accessible via the ``loop.parent.loop.index`` variable.
+
+Defining undefined Functions and Filters on the Fly
+---------------------------------------------------
+
+When a function (or a filter) is not defined, Twig defaults to throw a
+``\Twig\Error\SyntaxError`` exception. However, it can also call a `callback`_ (any
+valid PHP callable) which should return a function (or a filter).
+
+For filters, register callbacks with ``registerUndefinedFilterCallback()``.
+For functions, use ``registerUndefinedFunctionCallback()``::
+
+ // auto-register all native PHP functions as Twig functions
+ // don't try this at home as it's not secure at all!
+ $twig->registerUndefinedFunctionCallback(function ($name) {
+ if (function_exists($name)) {
+ return new \Twig\TwigFunction($name, $name);
+ }
+
+ return false;
+ });
+
+If the callable is not able to return a valid function (or filter), it must
+return ``false``.
+
+If you register more than one callback, Twig will call them in turn until one
+does not return ``false``.
+
+.. tip::
+
+ As the resolution of functions and filters is done during compilation,
+ there is no overhead when registering these callbacks.
+
+Validating the Template Syntax
+------------------------------
+
+When template code is provided by a third-party (through a web interface for
+instance), it might be interesting to validate the template syntax before
+saving it. If the template code is stored in a `$template` variable, here is
+how you can do it::
+
+ try {
+ $twig->parse($twig->tokenize(new \Twig\Source($template)));
+
+ // the $template is valid
+ } catch (\Twig\Error\SyntaxError $e) {
+ // $template contains one or more syntax errors
+ }
+
+If you iterate over a set of files, you can pass the filename to the
+``tokenize()`` method to get the filename in the exception message::
+
+ foreach ($files as $file) {
+ try {
+ $twig->parse($twig->tokenize(new \Twig\Source($template, $file->getFilename(), $file)));
+
+ // the $template is valid
+ } catch (\Twig\Error\SyntaxError $e) {
+ // $template contains one or more syntax errors
+ }
+ }
+
+.. versionadded:: 1.27
+ ``\Twig\Source`` was introduced in version 1.27, pass the source and the
+ identifier directly on previous versions.
+
+.. note::
+
+ This method won't catch any sandbox policy violations because the policy
+ is enforced during template rendering (as Twig needs the context for some
+ checks like allowed methods on objects).
+
+Refreshing modified Templates when OPcache or APC is enabled
+------------------------------------------------------------
+
+When using OPcache with ``opcache.validate_timestamps`` set to ``0`` or APC
+with ``apc.stat`` set to ``0`` and Twig cache enabled, clearing the template
+cache won't update the cache.
+
+To get around this, force Twig to invalidate the bytecode cache::
+
+ $twig = new \Twig\Environment($loader, [
+ 'cache' => new \Twig\Cache\FilesystemCache('/some/cache/path', \Twig\Cache\FilesystemCache::FORCE_BYTECODE_INVALIDATION),
+ // ...
+ ]);
+
+.. note::
+
+ Before Twig 1.22, you should extend ``\Twig\Environment`` instead::
+
+ class OpCacheAwareTwigEnvironment extends \Twig\Environment
+ {
+ protected function writeCacheFile($file, $content)
+ {
+ parent::writeCacheFile($file, $content);
+
+ // Compile cached file into bytecode cache
+ if (function_exists('opcache_invalidate')) {
+ opcache_invalidate($file, true);
+ } elseif (function_exists('apc_compile_file')) {
+ apc_compile_file($file);
+ }
+ }
+ }
+
+Reusing a stateful Node Visitor
+-------------------------------
+
+When attaching a visitor to a ``\Twig\Environment`` instance, Twig uses it to
+visit *all* templates it compiles. If you need to keep some state information
+around, you probably want to reset it when visiting a new template.
+
+This can be easily achieved with the following code::
+
+ protected $someTemplateState = [];
+
+ public function enterNode(Twig_NodeInterface $node, \Twig\Environment $env)
+ {
+ if ($node instanceof \Twig\Node\ModuleNode) {
+ // reset the state as we are entering a new template
+ $this->someTemplateState = [];
+ }
+
+ // ...
+
+ return $node;
+ }
+
+Using a Database to store Templates
+-----------------------------------
+
+If you are developing a CMS, templates are usually stored in a database. This
+recipe gives you a simple PDO template loader you can use as a starting point
+for your own.
+
+First, let's create a temporary in-memory SQLite3 database to work with::
+
+ $dbh = new PDO('sqlite::memory:');
+ $dbh->exec('CREATE TABLE templates (name STRING, source STRING, last_modified INTEGER)');
+ $base = '{% block content %}{% endblock %}';
+ $index = '
+ {% extends "base.twig" %}
+ {% block content %}Hello {{ name }}{% endblock %}
+ ';
+ $now = time();
+ $dbh->prepare('INSERT INTO templates (name, source, last_modified) VALUES (?, ?, ?)')->execute(['base.twig', $base, $now]);
+ $dbh->prepare('INSERT INTO templates (name, source, last_modified) VALUES (?, ?, ?)')->execute(['index.twig', $index, $now]);
+
+We have created a simple ``templates`` table that hosts two templates:
+``base.twig`` and ``index.twig``.
+
+Now, let's define a loader able to use this database::
+
+ class DatabaseTwigLoader implements \Twig\Loader\LoaderInterface, \Twig\Loader\ExistsLoaderInterface, \Twig\Loader\SourceContextLoaderInterface
+ {
+ protected $dbh;
+
+ public function __construct(PDO $dbh)
+ {
+ $this->dbh = $dbh;
+ }
+
+ public function getSource($name)
+ {
+ if (false === $source = $this->getValue('source', $name)) {
+ throw new \Twig\Error\LoaderError(sprintf('Template "%s" does not exist.', $name));
+ }
+
+ return $source;
+ }
+
+ // \Twig\Loader\SourceContextLoaderInterface as of Twig 1.27
+ public function getSourceContext($name)
+ {
+ if (false === $source = $this->getValue('source', $name)) {
+ throw new \Twig\Error\LoaderError(sprintf('Template "%s" does not exist.', $name));
+ }
+
+ return new \Twig\Source($source, $name);
+ }
+
+ // \Twig\Loader\ExistsLoaderInterface as of Twig 1.11
+ public function exists($name)
+ {
+ return $name === $this->getValue('name', $name);
+ }
+
+ public function getCacheKey($name)
+ {
+ return $name;
+ }
+
+ public function isFresh($name, $time)
+ {
+ if (false === $lastModified = $this->getValue('last_modified', $name)) {
+ return false;
+ }
+
+ return $lastModified <= $time;
+ }
+
+ protected function getValue($column, $name)
+ {
+ $sth = $this->dbh->prepare('SELECT '.$column.' FROM templates WHERE name = :name');
+ $sth->execute([':name' => (string) $name]);
+
+ return $sth->fetchColumn();
+ }
+ }
+
+Finally, here is an example on how you can use it::
+
+ $loader = new DatabaseTwigLoader($dbh);
+ $twig = new \Twig\Environment($loader);
+
+ echo $twig->render('index.twig', ['name' => 'Fabien']);
+
+Using different Template Sources
+--------------------------------
+
+This recipe is the continuation of the previous one. Even if you store the
+contributed templates in a database, you might want to keep the original/base
+templates on the filesystem. When templates can be loaded from different
+sources, you need to use the ``\Twig\Loader\ChainLoader`` loader.
+
+As you can see in the previous recipe, we reference the template in the exact
+same way as we would have done it with a regular filesystem loader. This is
+the key to be able to mix and match templates coming from the database, the
+filesystem, or any other loader for that matter: the template name should be a
+logical name, and not the path from the filesystem::
+
+ $loader1 = new DatabaseTwigLoader($dbh);
+ $loader2 = new \Twig\Loader\ArrayLoader([
+ 'base.twig' => '{% block content %}{% endblock %}',
+ ]);
+ $loader = new \Twig\Loader\ChainLoader([$loader1, $loader2]);
+
+ $twig = new \Twig\Environment($loader);
+
+ echo $twig->render('index.twig', ['name' => 'Fabien']);
+
+Now that the ``base.twig`` templates is defined in an array loader, you can
+remove it from the database, and everything else will still work as before.
+
+Loading a Template from a String
+--------------------------------
+
+From a template, you can easily load a template stored in a string via the
+``template_from_string`` function (available as of Twig 1.11 via the
+``\Twig\Extension\StringLoaderExtension`` extension):
+
+.. code-block:: twig
+
+ {{ include(template_from_string("Hello {{ name }}")) }}
+
+From PHP, it's also possible to load a template stored in a string via
+``\Twig\Environment::createTemplate()`` (available as of Twig 1.18)::
+
+ $template = $twig->createTemplate('hello {{ name }}');
+ echo $template->render(['name' => 'Fabien']);
+
+.. note::
+
+ Never use the ``Twig_Loader_String`` loader, which has severe limitations.
+
+Using Twig and AngularJS in the same Templates
+----------------------------------------------
+
+Mixing different template syntaxes in the same file is not a recommended
+practice as both AngularJS and Twig use the same delimiters in their syntax:
+``{{`` and ``}}``.
+
+Still, if you want to use AngularJS and Twig in the same template, there are
+two ways to make it work depending on the amount of AngularJS you need to
+include in your templates:
+
+* Escaping the AngularJS delimiters by wrapping AngularJS sections with the
+ ``{% verbatim %}`` tag or by escaping each delimiter via ``{{ '{{' }}`` and
+ ``{{ '}}' }}``;
+
+* Changing the delimiters of one of the template engines (depending on which
+ engine you introduced last):
+
+ * For AngularJS, change the interpolation tags using the
+ ``interpolateProvider`` service, for instance at the module initialization
+ time:
+
+ .. code-block:: javascript
+
+ angular.module('myApp', []).config(function($interpolateProvider) {
+ $interpolateProvider.startSymbol('{[').endSymbol(']}');
+ });
+
+ * For Twig, change the delimiters via the ``tag_variable`` Lexer option:
+
+ .. code-block:: php
+
+ $env->setLexer(new \Twig\Lexer($env, [
+ 'tag_variable' => ['{[', ']}'],
+ ]));
+
+.. _callback: https://secure.php.net/manual/en/function.is-callable.php
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/tags/apply.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/tags/apply.rst
new file mode 100644
index 0000000..09bc036
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/tags/apply.rst
@@ -0,0 +1,23 @@
+``apply``
+=========
+
+.. versionadded:: 1.40
+ The ``apply`` tag was added in Twig 1.40.
+
+The ``apply`` tag allows you to apply Twig filters on a block of template data:
+
+.. code-block:: twig
+
+ {% apply upper %}
+ This text becomes uppercase
+ {% endapply %}
+
+You can also chain filters and pass arguments to them:
+
+.. code-block:: twig
+
+ {% apply lower|escape('html') %}
+ SOME TEXT
+ {% endapply %}
+
+ {# outputs "<strong>some text</strong>" #}
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/tags/autoescape.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/tags/autoescape.rst
new file mode 100644
index 0000000..0fa34bd
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/tags/autoescape.rst
@@ -0,0 +1,81 @@
+``autoescape``
+==============
+
+Whether automatic escaping is enabled or not, you can mark a section of a
+template to be escaped or not by using the ``autoescape`` tag:
+
+.. code-block:: twig
+
+ {% autoescape %}
+ Everything will be automatically escaped in this block
+ using the HTML strategy
+ {% endautoescape %}
+
+ {% autoescape 'html' %}
+ Everything will be automatically escaped in this block
+ using the HTML strategy
+ {% endautoescape %}
+
+ {% autoescape 'js' %}
+ Everything will be automatically escaped in this block
+ using the js escaping strategy
+ {% endautoescape %}
+
+ {% autoescape false %}
+ Everything will be outputted as is in this block
+ {% endautoescape %}
+
+.. note::
+
+ Before Twig 1.8, the syntax was different:
+
+ .. code-block:: twig
+
+ {% autoescape true %}
+ Everything will be automatically escaped in this block
+ using the HTML strategy
+ {% endautoescape %}
+
+ {% autoescape false %}
+ Everything will be outputted as is in this block
+ {% endautoescape %}
+
+ {% autoescape true js %}
+ Everything will be automatically escaped in this block
+ using the js escaping strategy
+ {% endautoescape %}
+
+When automatic escaping is enabled everything is escaped by default except for
+values explicitly marked as safe. Those can be marked in the template by using
+the :doc:`raw<../filters/raw>` filter:
+
+.. code-block:: twig
+
+ {% autoescape %}
+ {{ safe_value|raw }}
+ {% endautoescape %}
+
+Functions returning template data (like :doc:`macros` and
+:doc:`parent<../functions/parent>`) always return safe markup.
+
+.. note::
+
+ Twig is smart enough to not escape an already escaped value by the
+ :doc:`escape<../filters/escape>` filter.
+
+.. note::
+
+ Twig does not escape static expressions:
+
+ .. code-block:: twig
+
+ {% set hello = "Hello" %}
+ {{ hello }}
+ {{ "world" }}
+
+ Will be rendered "Hello **world**".
+
+.. note::
+
+ The chapter :doc:`Twig for Developers<../api>` gives more information
+ about when and how automatic escaping is applied.
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/tags/block.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/tags/block.rst
new file mode 100644
index 0000000..e380482
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/tags/block.rst
@@ -0,0 +1,11 @@
+``block``
+=========
+
+Blocks are used for inheritance and act as placeholders and replacements at
+the same time. They are documented in detail in the documentation for the
+:doc:`extends<../tags/extends>` tag.
+
+Block names should consist of alphanumeric characters, and underscores. Dashes
+are not permitted.
+
+.. seealso:: :doc:`block<../functions/block>`, :doc:`parent<../functions/parent>`, :doc:`use<../tags/use>`, :doc:`extends<../tags/extends>`
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/tags/deprecated.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/tags/deprecated.rst
new file mode 100644
index 0000000..95828ac
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/tags/deprecated.rst
@@ -0,0 +1,30 @@
+``deprecated``
+==============
+
+.. versionadded:: 1.36 and 2.6
+ The ``deprecated`` tag was added in Twig 1.36 and 2.6.
+
+Twig generates a deprecation notice (via a call to the ``trigger_error()``
+PHP function) where the ``deprecated`` tag is used in a template:
+
+.. code-block:: twig
+
+ {# base.twig #}
+ {% deprecated 'The "base.twig" template is deprecated, use "layout.twig" instead.' %}
+ {% extends 'layout.twig' %}
+
+Also you can deprecate a block in the following way:
+
+.. code-block:: twig
+
+ {% block hey %}
+ {% deprecated 'The "hey" block is deprecated, use "greet" instead.' %}
+ {{ block('greet') }}
+ {% endblock %}
+
+ {% block greet %}
+ Hey you!
+ {% endblock %}
+
+Note that by default, the deprecation notices are silenced and never displayed nor logged.
+See :ref:`deprecation-notices` to learn how to handle them.
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/tags/do.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/tags/do.rst
new file mode 100644
index 0000000..b5e83eb
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/tags/do.rst
@@ -0,0 +1,12 @@
+``do``
+======
+
+.. versionadded:: 1.5
+ The ``do`` tag was added in Twig 1.5.
+
+The ``do`` tag works exactly like the regular variable expression (``{{ ...
+}}``) just that it doesn't print anything:
+
+.. code-block:: twig
+
+ {% do 1 + 2 %}
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/tags/embed.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/tags/embed.rst
new file mode 100644
index 0000000..e2796b2
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/tags/embed.rst
@@ -0,0 +1,178 @@
+``embed``
+=========
+
+.. versionadded:: 1.8
+ The ``embed`` tag was added in Twig 1.8.
+
+The ``embed`` tag combines the behaviour of :doc:`include` and
+:doc:`extends`.
+It allows you to include another template's contents, just like ``include``
+does. But it also allows you to override any block defined inside the
+included template, like when extending a template.
+
+Think of an embedded template as a "micro layout skeleton".
+
+.. code-block:: twig
+
+ {% embed "teasers_skeleton.twig" %}
+ {# These blocks are defined in "teasers_skeleton.twig" #}
+ {# and we override them right here: #}
+ {% block left_teaser %}
+ Some content for the left teaser box
+ {% endblock %}
+ {% block right_teaser %}
+ Some content for the right teaser box
+ {% endblock %}
+ {% endembed %}
+
+The ``embed`` tag takes the idea of template inheritance to the level of
+content fragments. While template inheritance allows for "document skeletons",
+which are filled with life by child templates, the ``embed`` tag allows you to
+create "skeletons" for smaller units of content and re-use and fill them
+anywhere you like.
+
+Since the use case may not be obvious, let's look at a simplified example.
+Imagine a base template shared by multiple HTML pages, defining a single block
+named "content":
+
+.. code-block:: text
+
+ ┌─── page layout ─────────────────────┐
+ │ │
+ │ ┌── block "content" ──┐ │
+ │ │ │ │
+ │ │ │ │
+ │ │ (child template to │ │
+ │ │ put content here) │ │
+ │ │ │ │
+ │ │ │ │
+ │ └─────────────────────┘ │
+ │ │
+ └─────────────────────────────────────┘
+
+Some pages ("foo" and "bar") share the same content structure -
+two vertically stacked boxes:
+
+.. code-block:: text
+
+ ┌─── page layout ─────────────────────┐
+ │ │
+ │ ┌── block "content" ──┐ │
+ │ │ ┌─ block "top" ───┐ │ │
+ │ │ │ │ │ │
+ │ │ └─────────────────┘ │ │
+ │ │ ┌─ block "bottom" ┐ │ │
+ │ │ │ │ │ │
+ │ │ └─────────────────┘ │ │
+ │ └─────────────────────┘ │
+ │ │
+ └─────────────────────────────────────┘
+
+While other pages ("boom" and "baz") share a different content structure -
+two boxes side by side:
+
+.. code-block:: text
+
+ ┌─── page layout ─────────────────────┐
+ │ │
+ │ ┌── block "content" ──┐ │
+ │ │ │ │
+ │ │ ┌ block ┐ ┌ block ┐ │ │
+ │ │ │"left" │ │"right"│ │ │
+ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ │
+ │ │ └───────┘ └───────┘ │ │
+ │ └─────────────────────┘ │
+ │ │
+ └─────────────────────────────────────┘
+
+Without the ``embed`` tag, you have two ways to design your templates:
+
+* Create two "intermediate" base templates that extend the master layout
+ template: one with vertically stacked boxes to be used by the "foo" and
+ "bar" pages and another one with side-by-side boxes for the "boom" and
+ "baz" pages.
+
+* Embed the markup for the top/bottom and left/right boxes into each page
+ template directly.
+
+These two solutions do not scale well because they each have a major drawback:
+
+* The first solution may indeed work for this simplified example. But imagine
+ we add a sidebar, which may again contain different, recurring structures
+ of content. Now we would need to create intermediate base templates for
+ all occurring combinations of content structure and sidebar structure...
+ and so on.
+
+* The second solution involves duplication of common code with all its negative
+ consequences: any change involves finding and editing all affected copies
+ of the structure, correctness has to be verified for each copy, copies may
+ go out of sync by careless modifications etc.
+
+In such a situation, the ``embed`` tag comes in handy. The common layout
+code can live in a single base template, and the two different content structures,
+let's call them "micro layouts" go into separate templates which are embedded
+as necessary:
+
+Page template ``foo.twig``:
+
+.. code-block:: twig
+
+ {% extends "layout_skeleton.twig" %}
+
+ {% block content %}
+ {% embed "vertical_boxes_skeleton.twig" %}
+ {% block top %}
+ Some content for the top box
+ {% endblock %}
+
+ {% block bottom %}
+ Some content for the bottom box
+ {% endblock %}
+ {% endembed %}
+ {% endblock %}
+
+And here is the code for ``vertical_boxes_skeleton.twig``:
+
+.. code-block:: html+twig
+
+
+ {% block top %}
+ Top box default content
+ {% endblock %}
+
+
+The goal of the ``vertical_boxes_skeleton.twig`` template being to factor
+out the HTML markup for the boxes.
+
+The ``embed`` tag takes the exact same arguments as the ``include`` tag:
+
+.. code-block:: twig
+
+ {% embed "base" with {'foo': 'bar'} %}
+ ...
+ {% endembed %}
+
+ {% embed "base" with {'foo': 'bar'} only %}
+ ...
+ {% endembed %}
+
+ {% embed "base" ignore missing %}
+ ...
+ {% endembed %}
+
+.. warning::
+
+ As embedded templates do not have "names", auto-escaping strategies based
+ on the template name won't work as expected if you change the context (for
+ instance, if you embed a CSS/JavaScript template into an HTML one). In that
+ case, explicitly set the default auto-escaping strategy with the
+ ``autoescape`` tag.
+
+.. seealso:: :doc:`include<../tags/include>`
diff --git a/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/tags/extends.rst b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/tags/extends.rst
new file mode 100644
index 0000000..e2dc763
--- /dev/null
+++ b/system/templateEngines/Twig/Twig1x/vendor/twig/twig/doc/tags/extends.rst
@@ -0,0 +1,272 @@
+``extends``
+===========
+
+The ``extends`` tag can be used to extend a template from another one.
+
+.. note::
+
+ Like PHP, Twig does not support multiple inheritance. So you can only have
+ one extends tag called per rendering. However, Twig supports horizontal
+ :doc:`reuse