summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFbenas <philbeansburton@gmail.com>2017-03-12 04:02:03 +0000
committerFbenas <philbeansburton@gmail.com>2017-03-12 04:02:03 +0000
commit755248886ad294bade86cb8a5ce36465b5193f36 (patch)
treed7a55ad3b1913b2a71e3616a3b14693268b10b22
parent1eeeb808275e6e0bcff6ed0c2e7b109d81da67e7 (diff)
Inital commit, created message handler
-rw-r--r--composer.json8
-rw-r--r--composer.lock64
-rw-r--r--config/messages.php5
-rw-r--r--overview.txt27
-rw-r--r--src/Config/Config.php17
-rw-r--r--src/Core/Main.php29
-rw-r--r--src/Game.php35
-rw-r--r--src/Message/Base.php72
-rw-r--r--src/Message/Handler.php69
-rw-r--r--src/Message/Overview.php25
-rw-r--r--vendor/autoload.php7
-rw-r--r--vendor/composer/ClassLoader.php441
-rw-r--r--vendor/composer/LICENSE19
-rw-r--r--vendor/composer/autoload_classmap.php9
-rw-r--r--vendor/composer/autoload_namespaces.php10
-rw-r--r--vendor/composer/autoload_psr4.php10
-rw-r--r--vendor/composer/autoload_real.php52
-rw-r--r--vendor/composer/autoload_static.php42
-rw-r--r--vendor/composer/installed.json50
-rw-r--r--vendor/mustache/mustache/.gitignore4
-rw-r--r--vendor/mustache/mustache/.gitmodules6
-rw-r--r--vendor/mustache/mustache/.php_cs26
-rw-r--r--vendor/mustache/mustache/.styleci.yml13
-rw-r--r--vendor/mustache/mustache/.travis.yml15
-rw-r--r--vendor/mustache/mustache/CONTRIBUTING.md35
-rw-r--r--vendor/mustache/mustache/LICENSE21
-rw-r--r--vendor/mustache/mustache/README.md72
-rwxr-xr-xvendor/mustache/mustache/bin/build_bootstrap.php178
-rw-r--r--vendor/mustache/mustache/composer.json25
-rw-r--r--vendor/mustache/mustache/phpunit.xml.dist17
-rw-r--r--vendor/mustache/mustache/src/Mustache/Autoloader.php74
-rw-r--r--vendor/mustache/mustache/src/Mustache/Cache.php36
-rw-r--r--vendor/mustache/mustache/src/Mustache/Cache/AbstractCache.php60
-rw-r--r--vendor/mustache/mustache/src/Mustache/Cache/FilesystemCache.php155
-rw-r--r--vendor/mustache/mustache/src/Mustache/Cache/NoopCache.php47
-rw-r--r--vendor/mustache/mustache/src/Mustache/Compiler.php687
-rw-r--r--vendor/mustache/mustache/src/Mustache/Context.php242
-rw-r--r--vendor/mustache/mustache/src/Mustache/Engine.php787
-rw-r--r--vendor/mustache/mustache/src/Mustache/Exception.php18
-rw-r--r--vendor/mustache/mustache/src/Mustache/Exception/InvalidArgumentException.php18
-rw-r--r--vendor/mustache/mustache/src/Mustache/Exception/LogicException.php18
-rw-r--r--vendor/mustache/mustache/src/Mustache/Exception/RuntimeException.php18
-rw-r--r--vendor/mustache/mustache/src/Mustache/Exception/SyntaxException.php41
-rw-r--r--vendor/mustache/mustache/src/Mustache/Exception/UnknownFilterException.php38
-rw-r--r--vendor/mustache/mustache/src/Mustache/Exception/UnknownHelperException.php38
-rw-r--r--vendor/mustache/mustache/src/Mustache/Exception/UnknownTemplateException.php38
-rw-r--r--vendor/mustache/mustache/src/Mustache/HelperCollection.php172
-rw-r--r--vendor/mustache/mustache/src/Mustache/LambdaHelper.php76
-rw-r--r--vendor/mustache/mustache/src/Mustache/Loader.php27
-rw-r--r--vendor/mustache/mustache/src/Mustache/Loader/ArrayLoader.php79
-rw-r--r--vendor/mustache/mustache/src/Mustache/Loader/CascadingLoader.php69
-rw-r--r--vendor/mustache/mustache/src/Mustache/Loader/FilesystemLoader.php135
-rw-r--r--vendor/mustache/mustache/src/Mustache/Loader/InlineLoader.php123
-rw-r--r--vendor/mustache/mustache/src/Mustache/Loader/MutableLoader.php31
-rw-r--r--vendor/mustache/mustache/src/Mustache/Loader/StringLoader.php39
-rw-r--r--vendor/mustache/mustache/src/Mustache/Logger.php126
-rw-r--r--vendor/mustache/mustache/src/Mustache/Logger/AbstractLogger.php121
-rw-r--r--vendor/mustache/mustache/src/Mustache/Logger/StreamLogger.php194
-rw-r--r--vendor/mustache/mustache/src/Mustache/Parser.php317
-rw-r--r--vendor/mustache/mustache/src/Mustache/Template.php180
-rw-r--r--vendor/mustache/mustache/src/Mustache/Tokenizer.php322
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/AutoloaderTest.php36
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/Cache/AbstractCacheTest.php44
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/Cache/FilesystemCacheTest.php36
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/CompilerTest.php154
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/ContextTest.php282
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/EngineTest.php361
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/Exception/SyntaxExceptionTest.php39
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/Exception/UnknownFilterExceptionTest.php44
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/Exception/UnknownHelperExceptionTest.php43
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/Exception/UnknownTemplateExceptionTest.php43
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/FiveThree/Functional/ClosureQuirksTest.php32
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/FiveThree/Functional/EngineTest.php50
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/FiveThree/Functional/FiltersTest.php187
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/FiveThree/Functional/HigherOrderSectionsTest.php77
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/FiveThree/Functional/LambdaHelperTest.php67
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/FiveThree/Functional/MustacheSpecTest.php68
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/FiveThree/Functional/PartialLambdaIndentTest.php94
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/FiveThree/Functional/StrictCallablesTest.php135
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/Functional/CallTest.php40
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/Functional/ExamplesTest.php142
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/Functional/HigherOrderSectionsTest.php177
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/Functional/InheritanceTest.php526
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/Functional/MustacheInjectionTest.php83
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/Functional/MustacheSpecTest.php121
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/Functional/NestedPartialIndentTest.php45
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/Functional/ObjectSectionTest.php110
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/FunctionalTestCase.php47
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/HelperCollectionTest.php163
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/Loader/ArrayLoaderTest.php52
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/Loader/CascadingLoaderTest.php40
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/Loader/FilesystemLoaderTest.php80
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/Loader/InlineLoaderTest.php56
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/Loader/StringLoaderTest.php25
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/Logger/AbstractLoggerTest.php60
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/Logger/StreamLoggerTest.php209
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/ParserTest.php425
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/SpecTestCase.php67
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/TemplateTest.php55
-rw-r--r--vendor/mustache/mustache/test/Mustache/Test/TokenizerTest.php306
-rw-r--r--vendor/mustache/mustache/test/bootstrap.php91
-rw-r--r--vendor/mustache/mustache/test/fixtures/autoloader/Mustache/Bar.php15
-rw-r--r--vendor/mustache/mustache/test/fixtures/autoloader/Mustache/Foo.php15
-rw-r--r--vendor/mustache/mustache/test/fixtures/autoloader/NonMustacheClass.php15
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/blocks/Blocks.php15
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/blocks/blocks.mustache4
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/blocks/blocks.txt3
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/blocks/partials/parent.mustache4
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/child_context/ChildContext.php23
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/child_context/child_context.mustache2
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/child_context/child_context.txt2
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/comments/Comments.php18
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/comments/comments.mustache1
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/comments/comments.txt1
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/complex/complex.mustache16
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/complex/complex.php31
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/complex/complex.txt6
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/delimiters/Delimiters.php25
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/delimiters/delimiters.mustache8
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/delimiters/delimiters.txt4
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/dot_notation/DotNotation.php24
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/dot_notation/dot_notation.mustache4
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/dot_notation/dot_notation.txt4
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/double_section/DoubleSection.php20
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/double_section/double_section.mustache7
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/double_section/double_section.txt3
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/escaped/Escaped.php15
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/escaped/escaped.mustache1
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/escaped/escaped.txt1
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/filters/Filters.php97
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/filters/filters.mustache4
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/filters/filters.txt50
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/grand_parent_context/GrandParentContext.php33
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/grand_parent_context/grand_parent_context.mustache7
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/grand_parent_context/grand_parent_context.txt7
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/i18n/I18n.php30
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/i18n/i18n.mustache1
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/i18n/i18n.txt1
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/implicit_iterator/ImplicitIterator.php15
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/implicit_iterator/implicit_iterator.mustache3
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/implicit_iterator/implicit_iterator.txt5
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/inverted_double_section/InvertedDoubleSection.php16
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/inverted_double_section/inverted_double_section.mustache7
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/inverted_double_section/inverted_double_section.txt3
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/inverted_section/InvertedSection.php15
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/inverted_section/inverted_section.mustache6
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/inverted_section/inverted_section.txt1
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/nested_partials/NestedPartials.php15
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/nested_partials/nested_partials.mustache3
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/nested_partials/nested_partials.txt7
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/nested_partials/partials/fourth.mustache1
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/nested_partials/partials/second.mustache3
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/nested_partials/partials/third.mustache3
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/partials/Partials.php19
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/partials/partials.mustache7
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/partials/partials.txt8
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/partials/partials/header.mustache4
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/recursive_partials/RecursivePartials.php22
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/recursive_partials/partials/child.mustache1
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/recursive_partials/recursive_partials.mustache1
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/recursive_partials/recursive_partials.txt1
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/section_iterator_objects/SectionIteratorObjects.php27
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/section_iterator_objects/section_iterator_objects.mustache5
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/section_iterator_objects/section_iterator_objects.txt4
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/section_magic_objects/SectionMagicObjects.php40
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/section_magic_objects/section_magic_objects.mustache6
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/section_magic_objects/section_magic_objects.txt4
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/section_objects/SectionObjects.php28
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/section_objects/section_objects.mustache6
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/section_objects/section_objects.txt4
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/sections/Sections.php25
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/sections/sections.mustache5
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/sections/sections.txt4
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/sections_nested/SectionsNested.php44
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/sections_nested/sections_nested.mustache7
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/sections_nested/sections_nested.txt12
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/simple/Simple.php23
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/simple/simple.mustache5
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/simple/simple.txt3
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/unescaped/Unescaped.php15
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/unescaped/unescaped.mustache1
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/unescaped/unescaped.txt1
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/utf8/UTF8.php15
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/utf8/utf8.mustache1
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/utf8/utf8.txt1
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/utf8_unescaped/UTF8Unescaped.php15
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/utf8_unescaped/utf8_unescaped.mustache1
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/utf8_unescaped/utf8_unescaped.txt1
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/whitespace/Whitespace.php43
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/whitespace/partials/alphabet.mustache1
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/whitespace/whitespace.mustache10
-rw-r--r--vendor/mustache/mustache/test/fixtures/examples/whitespace/whitespace.txt12
-rw-r--r--vendor/mustache/mustache/test/fixtures/templates/alpha.ms1
-rw-r--r--vendor/mustache/mustache/test/fixtures/templates/beta.ms1
-rw-r--r--vendor/mustache/mustache/test/fixtures/templates/one.mustache1
-rw-r--r--vendor/mustache/mustache/test/fixtures/templates/two.mustache1
-rw-r--r--web/index.php9
197 files changed, 11506 insertions, 0 deletions
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..08fb2ef
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,8 @@
+{
+ "require": {
+ "mustache/mustache": "^2.11"
+ },
+ "autoload": {
+ "psr-4": {"App\\": "src/"}
+ }
+} \ No newline at end of file
diff --git a/composer.lock b/composer.lock
new file mode 100644
index 0000000..367dd36
--- /dev/null
+++ b/composer.lock
@@ -0,0 +1,64 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
+ "This file is @generated automatically"
+ ],
+ "content-hash": "58a49ddda9ef333b2bf511ceffee55ff",
+ "packages": [
+ {
+ "name": "mustache/mustache",
+ "version": "v2.11.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/bobthecow/mustache.php.git",
+ "reference": "a3f6d55996dd28b58f3a909d474189a3c1aa693f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/bobthecow/mustache.php/zipball/a3f6d55996dd28b58f3a909d474189a3c1aa693f",
+ "reference": "a3f6d55996dd28b58f3a909d474189a3c1aa693f",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.2.4"
+ },
+ "require-dev": {
+ "friendsofphp/php-cs-fixer": "~1.11",
+ "phpunit/phpunit": "~3.7|~4.0|~5.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-0": {
+ "Mustache": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Justin Hileman",
+ "email": "justin@justinhileman.info",
+ "homepage": "http://justinhileman.com"
+ }
+ ],
+ "description": "A Mustache implementation in PHP.",
+ "homepage": "https://github.com/bobthecow/mustache.php",
+ "keywords": [
+ "mustache",
+ "templating"
+ ],
+ "time": "2016-07-31T06:18:27+00:00"
+ }
+ ],
+ "packages-dev": [],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": [],
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": [],
+ "platform-dev": []
+}
diff --git a/config/messages.php b/config/messages.php
new file mode 100644
index 0000000..0d53096
--- /dev/null
+++ b/config/messages.php
@@ -0,0 +1,5 @@
+<?php
+
+return [
+ 'opening' => 'This is a message, {{inject}} is injected. Also {{second}}'
+]; \ No newline at end of file
diff --git a/overview.txt b/overview.txt
new file mode 100644
index 0000000..9bf2927
--- /dev/null
+++ b/overview.txt
@@ -0,0 +1,27 @@
+
+**** Rouge A.I. ****
+
+* Backstory *
+
+Set in the future, in a <location in the verse> we find ourselves aboard <ship, bar, or place>.
+
+<no of players> men and women from <organisation or group> gather at a <table or meeting area> for the first time.
+
+Known to most, a job like this one, <job description> isn't a spacewalk in the park system! A mish-mash of folk form all areas of the 'verse is very common for this type of work. Unknown to most, today's meeting is a rare and special one, amongst the <no of players> people at the <table or meeting area> are <no of A.I.> rogue Artificial Intelligence bots. These well engineered sophisticated machines escaped from <place they escaped from> and are on a mission of murder and deceit.
+
+Luckily for some amongst the group today we also have a top hacker, a well trained medic, and a cyborg.
+
+Hackers in this part of the verse' have top skills when it comes to AI and with this comes the perception and integration skills learnt working for <some work place>. They are well placed to uncover a secret or two.
+
+The medic just got back from <some conflict> and their skills are hard to match. If the medic chooses, there's plenty of healthcare on offer.
+
+The Cyborg is a genuine <Place> albeit implanted up the teeth. These implants tie-in to the Cyborgs central nervous system and brain stem, giving them improved cognitive abilities beyond imagination, some even say they have mental powers that push the limits of even <some place> scientists.
+
+******
+Pre-start
+Order of the day - vote a leader
+
+while (noWin):
+ Night
+ Day
+end \ No newline at end of file
diff --git a/src/Config/Config.php b/src/Config/Config.php
new file mode 100644
index 0000000..10236f0
--- /dev/null
+++ b/src/Config/Config.php
@@ -0,0 +1,17 @@
+<?php
+
+namespace App\Config;
+
+class Config
+{
+ protected static $config;
+
+ public static function getconfig()
+ {
+ if (!static::$config) {
+ static::$config = include SITE_ROOT . '/config/messages.php';
+ }
+
+ return static::$config;
+ }
+} \ No newline at end of file
diff --git a/src/Core/Main.php b/src/Core/Main.php
new file mode 100644
index 0000000..594b15c
--- /dev/null
+++ b/src/Core/Main.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace App\Core;
+
+use App\Game;
+
+/**
+* Core Main class, deals with all set-up
+*/
+class Main
+{
+
+ public function __construct()
+ {
+ $this->init();
+
+ $this->run();
+ }
+
+ protected function init()
+ {
+ return true;
+ }
+
+ protected function run()
+ {
+ $game = new Game();
+ }
+} \ No newline at end of file
diff --git a/src/Game.php b/src/Game.php
new file mode 100644
index 0000000..3a62f3e
--- /dev/null
+++ b/src/Game.php
@@ -0,0 +1,35 @@
+<?php
+
+namespace App;
+
+use App\Message\Handler;
+
+/**
+ * A Game class that handles game execution
+ */
+class Game
+{
+ protected $messages;
+
+ public function __construct()
+ {
+ $this->init();
+ }
+
+ protected function init()
+ {
+ // Do any pre set-up
+ $this->handler = new Handler(['inject']);
+ $this->sendOpeningMessage();
+ }
+
+ public function sendOpeningMessage()
+ {
+ $message = $this->handler->renderOpeningMessage();
+
+ $important = $this->handler->returnImportant('inject');
+
+ var_dump($message, $important);
+ }
+
+}
diff --git a/src/Message/Base.php b/src/Message/Base.php
new file mode 100644
index 0000000..a4430da
--- /dev/null
+++ b/src/Message/Base.php
@@ -0,0 +1,72 @@
+<?php
+
+namespace App\Message;
+
+use Mustache_Engine;
+use App\Config\Config;
+use App\Message\Handler;
+
+/**
+* Base class for a message
+*/
+class Base
+{
+ protected $message_name;
+ protected $config;
+ protected $message;
+ protected $injects = [];
+ protected $important;
+
+ protected function loadMessage()
+ {
+ if (!array_key_exists($this->message_name, $this->config)) {
+ throw new Exception('Could not load messge from config (' . $this->message_name . ')');
+ }
+
+ $this->message = $this->config[$this->message_name];
+ }
+
+ protected function loadConfig()
+ {
+ $config =Config::getConfig();
+
+ if (!$config) {
+ throw new \Exception('Could not load config');
+ }
+
+ $this->config = $config;
+ }
+
+ public function __construct()
+ {
+ $this->loadConfig();
+
+ $this->loadMessage();
+ }
+
+ public function renderMessage()
+ {
+ $m = new Mustache_Engine;
+ return $m->render($this->message, $this->getInjectValues());
+ }
+
+ public function getInjectValues()
+ {
+ $out = [];
+ foreach ($this->injects as $inject) {
+ $out[$inject] = $this->$inject;
+ }
+
+ return $out;
+ }
+
+ public function getImportantValues()
+ {
+ $out = [];
+ foreach ($this->important as $important) {
+ $out[$important] = $this->$important;
+ }
+
+ return $out;
+ }
+} \ No newline at end of file
diff --git a/src/Message/Handler.php b/src/Message/Handler.php
new file mode 100644
index 0000000..8729c1a
--- /dev/null
+++ b/src/Message/Handler.php
@@ -0,0 +1,69 @@
+<?php
+
+namespace App\Message;
+
+use App\Message\Overview;
+
+/**
+* Handles messages and context
+*/
+class Handler
+{
+ protected $important = [];
+
+ protected $importantValues = [];
+
+ public function __construct($important)
+ {
+ $this->setupImportant($important);
+ }
+ /**
+ * Set's up important attributes on this class
+ */
+ public function setupImportant($important = [])
+ {
+ $this->important = $important;
+ }
+
+ protected function setImportantValues($array)
+ {
+ foreach ($array as $name => $value) {
+ $this->addImportantValue($name, $value);
+ }
+ }
+
+ protected function addImportantValue($name, $value)
+ {
+ if (in_array($name, $this->important)) {
+ $this->importantValues[$name] = $value;
+ }
+
+ return $name;
+ }
+
+ public function returnImportant($name)
+ {
+ if (!array_key_exists($name, $this->importantValues)) {
+ throw new \Exception('The var ' . $name . ' is not set in this context');
+ }
+
+ return $this->importantValues[$name];
+ }
+
+ public function __call($name, $arguments)
+ {
+ if (strpos($name, 'get') === 0) {
+ $this->returnImporant(substr($name, 3));
+ }
+ }
+
+ public function renderOpeningMessage()
+ {
+ $overview = new Overview();
+ $message = $overview->renderMessage();
+
+ $this->setImportantValues($overview->getImportantValues());
+
+ return $message;
+ }
+} \ No newline at end of file
diff --git a/src/Message/Overview.php b/src/Message/Overview.php
new file mode 100644
index 0000000..3676176
--- /dev/null
+++ b/src/Message/Overview.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace App\Message;
+
+use App\Message\Base;
+
+class Overview extends Base
+{
+ protected $message_name = 'opening';
+ protected $injects = ['inject', 'second'];
+ protected $important = ['inject'];
+ public $inject;
+ public $second = "second";
+
+ public function __construct()
+ {
+ $this->inject = $this->getInject();
+ parent::__construct();
+ }
+
+ public function getInject()
+ {
+ return 'foo';
+ }
+} \ No newline at end of file
diff --git a/vendor/autoload.php b/vendor/autoload.php
new file mode 100644
index 0000000..2dedf57
--- /dev/null
+++ b/vendor/autoload.php
@@ -0,0 +1,7 @@
+<?php
+
+// autoload.php @generated by Composer
+
+require_once __DIR__ . '/composer/autoload_real.php';
+
+return ComposerAutoloaderInit266aa82cdfb705e81f7eec35f3a301c0::getLoader();
diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php
new file mode 100644
index 0000000..4626994
--- /dev/null
+++ b/vendor/composer/ClassLoader.php
@@ -0,0 +1,441 @@
+<?php
+
+/*
+ * This file is part of Composer.
+ *
+ * (c) Nils Adermann <naderman@naderman.de>
+ * Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * 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 <fabien@symfony.com>
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ * @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') && ini_get('apc.enabled') ? $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])) {
+ foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
+ if (0 === strpos($class, $prefix)) {
+ foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
+ 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/vendor/composer/LICENSE b/vendor/composer/LICENSE
new file mode 100644
index 0000000..b0794ff
--- /dev/null
+++ b/vendor/composer/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2016 Nils Adermann, Jordi Boggiano
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php
new file mode 100644
index 0000000..7a91153
--- /dev/null
+++ b/vendor/composer/autoload_classmap.php
@@ -0,0 +1,9 @@
+<?php
+
+// autoload_classmap.php @generated by Composer
+
+$vendorDir = dirname(dirname(__FILE__));
+$baseDir = dirname($vendorDir);
+
+return array(
+);
diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php
new file mode 100644
index 0000000..3e8eb85
--- /dev/null
+++ b/vendor/composer/autoload_namespaces.php
@@ -0,0 +1,10 @@
+<?php
+
+// autoload_namespaces.php @generated by Composer
+
+$vendorDir = dirname(dirname(__FILE__));
+$baseDir = dirname($vendorDir);
+
+return array(
+ 'Mustache' => array($vendorDir . '/mustache/mustache/src'),
+);
diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php
new file mode 100644
index 0000000..741c79f
--- /dev/null
+++ b/vendor/composer/autoload_psr4.php
@@ -0,0 +1,10 @@
+<?php
+
+// autoload_psr4.php @generated by Composer
+
+$vendorDir = dirname(dirname(__FILE__));
+$baseDir = dirname($vendorDir);
+
+return array(
+ 'App\\' => array($baseDir . '/src'),
+);
diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php
new file mode 100644
index 0000000..b54fb66
--- /dev/null
+++ b/vendor/composer/autoload_real.php
@@ -0,0 +1,52 @@
+<?php
+
+// autoload_real.php @generated by Composer
+
+class ComposerAutoloaderInit266aa82cdfb705e81f7eec35f3a301c0
+{
+ private static $loader;
+
+ public static function loadClassLoader($class)
+ {
+ if ('Composer\Autoload\ClassLoader' === $class) {
+ require __DIR__ . '/ClassLoader.php';
+ }
+ }
+
+ public static function getLoader()
+ {
+ if (null !== self::$loader) {
+ return self::$loader;
+ }
+
+ spl_autoload_register(array('ComposerAutoloaderInit266aa82cdfb705e81f7eec35f3a301c0', 'loadClassLoader'), true, true);
+ self::$loader = $loader = new \Composer\Autoload\ClassLoader();
+ spl_autoload_unregister(array('ComposerAutoloaderInit266aa82cdfb705e81f7eec35f3a301c0', 'loadClassLoader'));
+
+ $useStaticLoader = PHP_VERSION_ID >= 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\ComposerStaticInit266aa82cdfb705e81f7eec35f3a301c0::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);
+
+ return $loader;
+ }
+}
diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php
new file mode 100644
index 0000000..3337d7b
--- /dev/null
+++ b/vendor/composer/autoload_static.php
@@ -0,0 +1,42 @@
+<?php
+
+// autoload_static.php @generated by Composer
+
+namespace Composer\Autoload;
+
+class ComposerStaticInit266aa82cdfb705e81f7eec35f3a301c0
+{
+ public static $prefixLengthsPsr4 = array (
+ 'A' =>
+ array (
+ 'App\\' => 4,
+ ),
+ );
+
+ public static $prefixDirsPsr4 = array (
+ 'App\\' =>
+ array (
+ 0 => __DIR__ . '/../..' . '/src',
+ ),
+ );
+
+ public static $prefixesPsr0 = array (
+ 'M' =>
+ array (
+ 'Mustache' =>
+ array (
+ 0 => __DIR__ . '/..' . '/mustache/mustache/src',
+ ),
+ ),
+ );
+
+ public static function getInitializer(ClassLoader $loader)
+ {
+ return \Closure::bind(function () use ($loader) {
+ $loader->prefixLengthsPsr4 = ComposerStaticInit266aa82cdfb705e81f7eec35f3a301c0::$prefixLengthsPsr4;
+ $loader->prefixDirsPsr4 = ComposerStaticInit266aa82cdfb705e81f7eec35f3a301c0::$prefixDirsPsr4;
+ $loader->prefixesPsr0 = ComposerStaticInit266aa82cdfb705e81f7eec35f3a301c0::$prefixesPsr0;
+
+ }, null, ClassLoader::class);
+ }
+}
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
new file mode 100644
index 0000000..0ed2d62
--- /dev/null
+++ b/vendor/composer/installed.json
@@ -0,0 +1,50 @@
+[
+ {
+ "name": "mustache/mustache",
+ "version": "v2.11.1",
+ "version_normalized": "2.11.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/bobthecow/mustache.php.git",
+ "reference": "a3f6d55996dd28b58f3a909d474189a3c1aa693f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/bobthecow/mustache.php/zipball/a3f6d55996dd28b58f3a909d474189a3c1aa693f",
+ "reference": "a3f6d55996dd28b58f3a909d474189a3c1aa693f",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.2.4"
+ },
+ "require-dev": {
+ "friendsofphp/php-cs-fixer": "~1.11",
+ "phpunit/phpunit": "~3.7|~4.0|~5.0"
+ },
+ "time": "2016-07-31T06:18:27+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-0": {
+ "Mustache": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Justin Hileman",
+ "email": "justin@justinhileman.info",
+ "homepage": "http://justinhileman.com"
+ }
+ ],
+ "description": "A Mustache implementation in PHP.",
+ "homepage": "https://github.com/bobthecow/mustache.php",
+ "keywords": [
+ "mustache",
+ "templating"
+ ]
+ }
+]
diff --git a/vendor/mustache/mustache/.gitignore b/vendor/mustache/mustache/.gitignore
new file mode 100644
index 0000000..3861f00
--- /dev/null
+++ b/vendor/mustache/mustache/.gitignore
@@ -0,0 +1,4 @@
+.php_cs.cache
+composer.lock
+mustache.php
+vendor
diff --git a/vendor/mustache/mustache/.gitmodules b/vendor/mustache/mustache/.gitmodules
new file mode 100644
index 0000000..042ea4d
--- /dev/null
+++ b/vendor/mustache/mustache/.gitmodules
@@ -0,0 +1,6 @@
+[submodule "vendor/spec"]
+ path = vendor/spec
+ url = https://github.com/mustache/spec.git
+[submodule "vendor/yaml"]
+ path = vendor/yaml
+ url = https://github.com/fabpot/yaml.git
diff --git a/vendor/mustache/mustache/.php_cs b/vendor/mustache/mustache/.php_cs
new file mode 100644
index 0000000..d924712
--- /dev/null
+++ b/vendor/mustache/mustache/.php_cs
@@ -0,0 +1,26 @@
+<?php
+
+use Symfony\CS\Config\Config;
+use Symfony\CS\FixerInterface;
+
+$config = Config::create()
+ // use symfony level and extra fixers:
+ ->level(Symfony\CS\FixerInterface::SYMFONY_LEVEL)
+ ->fixers(array(
+ '-concat_without_spaces',
+ '-pre_increment',
+ '-unalign_double_arrow',
+ '-unalign_equals',
+ 'align_double_arrow',
+ 'concat_with_spaces',
+ 'ordered_use',
+ 'strict',
+ ))
+ ->setUsingLinter(false);
+
+$finder = $config->getFinder()
+ ->in('bin')
+ ->in('src')
+ ->in('test');
+
+return $config;
diff --git a/vendor/mustache/mustache/.styleci.yml b/vendor/mustache/mustache/.styleci.yml
new file mode 100644
index 0000000..1aebcc3
--- /dev/null
+++ b/vendor/mustache/mustache/.styleci.yml
@@ -0,0 +1,13 @@
+preset: symfony
+
+enabled:
+ - align_double_arrow
+ - concat_with_spaces
+ - ordered_use
+ - strict
+
+disabled:
+ - concat_without_spaces
+ - pre_increment
+ - unalign_double_arrow
+ - unalign_equals
diff --git a/vendor/mustache/mustache/.travis.yml b/vendor/mustache/mustache/.travis.yml
new file mode 100644
index 0000000..e68b99c
--- /dev/null
+++ b/vendor/mustache/mustache/.travis.yml
@@ -0,0 +1,15 @@
+language: php
+
+php:
+ - 5.2
+ - 5.3
+ - 5.4
+ - 5.5
+ - 5.6
+ - 7.0
+ - hhvm
+
+script:
+ - phpunit
+
+sudo: false
diff --git a/vendor/mustache/mustache/CONTRIBUTING.md b/vendor/mustache/mustache/CONTRIBUTING.md
new file mode 100644
index 0000000..c0b323d
--- /dev/null
+++ b/vendor/mustache/mustache/CONTRIBUTING.md
@@ -0,0 +1,35 @@
+# Contributions welcome!
+
+
+### Here's a quick guide:
+
+ 1. [Fork the repo on GitHub](https://github.com/bobthecow/mustache.php).
+
+ 2. Update submodules: `git submodule update --init`
+
+ 3. Run the test suite. We only take pull requests with passing tests, and it's great to know that you have a clean slate. Make sure you have PHPUnit 3.5+, then run `phpunit` from the project directory.
+
+ 4. Add tests for your change. Only refactoring and documentation changes require no new tests. If you are adding functionality or fixing a bug, add a test!
+
+ 5. Make the tests pass.
+
+ 6. Push your fork to GitHub and submit a pull request against the `dev` branch.
+
+
+### You can do some things to increase the chance that your pull request is accepted the first time:
+
+ * Submit one pull request per fix or feature.
+ * To help with that, do all your work in a feature branch (e.g. `feature/my-alsome-feature`).
+ * Follow the conventions you see used in the project.
+ * Use `phpcs --standard=PSR2` to check your changes against the coding standard.
+ * Write tests that fail without your code, and pass with it.
+ * Don't bump version numbers. Those will be updated — per [semver](http://semver.org) — once your change is merged into `master`.
+ * Update any documentation: docblocks, README, examples, etc.
+ * ... Don't update the wiki until your change is merged and released, but make a note in your pull request so we don't forget.
+
+
+### Mustache.php follows the PSR-* coding standards:
+
+ * [PSR-0: Class and file naming conventions](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md)
+ * [PSR-1: Basic coding standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md)
+ * [PSR-2: Coding style guide](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)
diff --git a/vendor/mustache/mustache/LICENSE b/vendor/mustache/mustache/LICENSE
new file mode 100644
index 0000000..e0aecc9
--- /dev/null
+++ b/vendor/mustache/mustache/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2010-2015 Justin Hileman
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
+OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/mustache/mustache/README.md b/vendor/mustache/mustache/README.md
new file mode 100644
index 0000000..a596ace
--- /dev/null
+++ b/vendor/mustache/mustache/README.md
@@ -0,0 +1,72 @@
+Mustache.php
+============
+
+A [Mustache](http://mustache.github.com/) implementation in PHP.
+
+[![Package version](http://img.shields.io/packagist/v/mustache/mustache.svg?style=flat-square)](https://packagist.org/packages/mustache/mustache)
+[![Build status](http://img.shields.io/travis/bobthecow/mustache.php/dev.svg?style=flat-square)](http://travis-ci.org/bobthecow/mustache.php)
+[![StyleCI](https://styleci.io/repos/569670/shield)](https://styleci.io/repos/569670)
+[![Monthly downloads](http://img.shields.io/packagist/dm/mustache/mustache.svg?style=flat-square)](https://packagist.org/packages/mustache/mustache)
+
+
+Usage
+-----
+
+A quick example:
+
+```php
+<?php
+$m = new Mustache_Engine;
+echo $m->render('Hello {{planet}}', array('planet' => 'World!')); // "Hello World!"
+```
+
+
+And a more in-depth example -- this is the canonical Mustache template:
+
+```html+jinja
+Hello {{name}}
+You have just won {{value}} dollars!
+{{#in_ca}}
+Well, {{taxed_value}} dollars, after taxes.
+{{/in_ca}}
+```
+
+
+Create a view "context" object -- which could also be an associative array, but those don't do functions quite as well:
+
+```php
+<?php
+class Chris {
+ public $name = "Chris";
+ public $value = 10000;
+
+ public function taxed_value() {
+ return $this->value - ($this->value * 0.4);
+ }
+
+ public $in_ca = true;
+}
+```
+
+
+And render it:
+
+```php
+<?php
+$m = new Mustache_Engine;
+$chris = new Chris;
+echo $m->render($template, $chris);
+```
+
+
+And That's Not All!
+-------------------
+
+Read [the Mustache.php documentation](https://github.com/bobthecow/mustache.php/wiki/Home) for more information.
+
+
+See Also
+--------
+
+ * [Readme for the Ruby Mustache implementation](http://github.com/defunkt/mustache/blob/master/README.md).
+ * [mustache(5)](http://mustache.github.com/mustache.5.html) man page.
diff --git a/vendor/mustache/mustache/bin/build_bootstrap.php b/vendor/mustache/mustache/bin/build_bootstrap.php
new file mode 100755
index 0000000..cc23b2b
--- /dev/null
+++ b/vendor/mustache/mustache/bin/build_bootstrap.php
@@ -0,0 +1,178 @@
+#!/usr/bin/env php
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2015 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * A shell script to create a single-file class cache of the entire Mustache
+ * library.
+ *
+ * $ bin/build_bootstrap.php
+ *
+ * ... will create a `mustache.php` bootstrap file in the project directory,
+ * containing all Mustache library classes. This file can then be included in
+ * your project, rather than requiring the Mustache Autoloader.
+ */
+$baseDir = realpath(dirname(__FILE__) . '/..');
+
+require $baseDir . '/src/Mustache/Autoloader.php';
+Mustache_Autoloader::register();
+
+// delete the old file
+$file = $baseDir . '/mustache.php';
+if (file_exists($file)) {
+ unlink($file);
+}
+
+// and load the new one
+SymfonyClassCollectionLoader::load(array(
+ 'Mustache_Engine',
+ 'Mustache_Cache',
+ 'Mustache_Cache_AbstractCache',
+ 'Mustache_Cache_FilesystemCache',
+ 'Mustache_Cache_NoopCache',
+ 'Mustache_Compiler',
+ 'Mustache_Context',
+ 'Mustache_Exception',
+ 'Mustache_Exception_InvalidArgumentException',
+ 'Mustache_Exception_LogicException',
+ 'Mustache_Exception_RuntimeException',
+ 'Mustache_Exception_SyntaxException',
+ 'Mustache_Exception_UnknownFilterException',
+ 'Mustache_Exception_UnknownHelperException',
+ 'Mustache_Exception_UnknownTemplateException',
+ 'Mustache_HelperCollection',
+ 'Mustache_LambdaHelper',
+ 'Mustache_Loader',
+ 'Mustache_Loader_ArrayLoader',
+ 'Mustache_Loader_CascadingLoader',
+ 'Mustache_Loader_FilesystemLoader',
+ 'Mustache_Loader_InlineLoader',
+ 'Mustache_Loader_MutableLoader',
+ 'Mustache_Loader_StringLoader',
+ 'Mustache_Logger',
+ 'Mustache_Logger_AbstractLogger',
+ 'Mustache_Logger_StreamLogger',
+ 'Mustache_Parser',
+ 'Mustache_Template',
+ 'Mustache_Tokenizer',
+), dirname($file), basename($file, '.php'));
+
+/**
+ * SymfonyClassCollectionLoader.
+ *
+ * Based heavily on the Symfony ClassCollectionLoader component, with all
+ * the unnecessary bits removed.
+ *
+ * @license http://www.opensource.org/licenses/MIT
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class SymfonyClassCollectionLoader
+{
+ private static $loaded;
+
+ const HEADER = <<<'EOS'
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-%d Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+EOS;
+
+ /**
+ * Loads a list of classes and caches them in one big file.
+ *
+ * @param array $classes An array of classes to load
+ * @param string $cacheDir A cache directory
+ * @param string $name The cache name prefix
+ * @param string $extension File extension of the resulting file
+ *
+ * @throws InvalidArgumentException When class can't be loaded
+ */
+ public static function load(array $classes, $cacheDir, $name, $extension = '.php')
+ {
+ // each $name can only be loaded once per PHP process
+ if (isset(self::$loaded[$name])) {
+ return;
+ }
+
+ self::$loaded[$name] = true;
+
+ $content = '';
+ foreach ($classes as $class) {
+ if (!class_exists($class) && !interface_exists($class) && (!function_exists('trait_exists') || !trait_exists($class))) {
+ throw new InvalidArgumentException(sprintf('Unable to load class "%s"', $class));
+ }
+
+ $r = new ReflectionClass($class);
+ $content .= preg_replace(array('/^\s*<\?php/', '/\?>\s*$/'), '', file_get_contents($r->getFileName()));
+ }
+
+ $cache = $cacheDir . '/' . $name . $extension;
+ $header = sprintf(self::HEADER, strftime('%Y'));
+ self::writeCacheFile($cache, $header . substr(self::stripComments('<?php ' . $content), 5));
+ }
+
+ /**
+ * Writes a cache file.
+ *
+ * @param string $file Filename
+ * @param string $content Temporary file content
+ *
+ * @throws RuntimeException when a cache file cannot be written
+ */
+ private static function writeCacheFile($file, $content)
+ {
+ $tmpFile = tempnam(dirname($file), basename($file));
+ if (false !== @file_put_contents($tmpFile, $content) && @rename($tmpFile, $file)) {
+ chmod($file, 0666 & ~umask());
+
+ return;
+ }
+
+ throw new RuntimeException(sprintf('Failed to write cache file "%s".', $file));
+ }
+
+ /**
+ * Removes comments from a PHP source string.
+ *
+ * We don't use the PHP php_strip_whitespace() function
+ * as we want the content to be readable and well-formatted.
+ *
+ * @param string $source A PHP string
+ *
+ * @return string The PHP string with the comments removed
+ */
+ private static function stripComments($source)
+ {
+ if (!function_exists('token_get_all')) {
+ return $source;
+ }
+
+ $output = '';
+ foreach (token_get_all($source) as $token) {
+ if (is_string($token)) {
+ $output .= $token;
+ } elseif (!in_array($token[0], array(T_COMMENT, T_DOC_COMMENT))) {
+ $output .= $token[1];
+ }
+ }
+
+ // replace multiple new lines with a single newline
+ $output = preg_replace(array('/\s+$/Sm', '/\n+/S'), "\n", $output);
+
+ return $output;
+ }
+}
diff --git a/vendor/mustache/mustache/composer.json b/vendor/mustache/mustache/composer.json
new file mode 100644
index 0000000..d0514f3
--- /dev/null
+++ b/vendor/mustache/mustache/composer.json
@@ -0,0 +1,25 @@
+{
+ "name": "mustache/mustache",
+ "description": "A Mustache implementation in PHP.",
+ "keywords": ["templating", "mustache"],
+ "homepage": "https://github.com/bobthecow/mustache.php",
+ "type": "library",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Justin Hileman",
+ "email": "justin@justinhileman.info",
+ "homepage": "http://justinhileman.com"
+ }
+ ],
+ "require": {
+ "php": ">=5.2.4"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~3.7|~4.0|~5.0",
+ "friendsofphp/php-cs-fixer": "~1.11"
+ },
+ "autoload": {
+ "psr-0": { "Mustache": "src/" }
+ }
+}
diff --git a/vendor/mustache/mustache/phpunit.xml.dist b/vendor/mustache/mustache/phpunit.xml.dist
new file mode 100644
index 0000000..3c620b6
--- /dev/null
+++ b/vendor/mustache/mustache/phpunit.xml.dist
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit backupGlobals="false" colors="true" bootstrap="./test/bootstrap.php">
+ <testsuite name="Mustache">
+ <directory suffix="Test.php">./test</directory>
+ <exclude>./test/Mustache/Test/FiveThree</exclude>
+ </testsuite>
+
+ <testsuite name="Mustache FiveThree">
+ <directory suffix="Test.php" phpVersion="5.3.0" phpVersionOperator=">=">./test/Mustache/Test/FiveThree</directory>
+ </testsuite>
+
+ <filter>
+ <whitelist>
+ <directory suffix=".php">./src/Mustache</directory>
+ </whitelist>
+ </filter>
+</phpunit> \ No newline at end of file
diff --git a/vendor/mustache/mustache/src/Mustache/Autoloader.php b/vendor/mustache/mustache/src/Mustache/Autoloader.php
new file mode 100644
index 0000000..b16ac14
--- /dev/null
+++ b/vendor/mustache/mustache/src/Mustache/Autoloader.php
@@ -0,0 +1,74 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Mustache class autoloader.
+ */
+class Mustache_Autoloader
+{
+ private $baseDir;
+
+ /**
+ * Autoloader constructor.
+ *
+ * @param string $baseDir Mustache library base directory (default: dirname(__FILE__).'/..')
+ */
+ public function __construct($baseDir = null)
+ {
+ if ($baseDir === null) {
+ $baseDir = dirname(__FILE__) . '/..';
+ }
+
+ // realpath doesn't always work, for example, with stream URIs
+ $realDir = realpath($baseDir);
+ if (is_dir($realDir)) {
+ $this->baseDir = $realDir;
+ } else {
+ $this->baseDir = $baseDir;
+ }
+ }
+
+ /**
+ * Register a new instance as an SPL autoloader.
+ *
+ * @param string $baseDir Mustache library base directory (default: dirname(__FILE__).'/..')
+ *
+ * @return Mustache_Autoloader Registered Autoloader instance
+ */
+ public static function register($baseDir = null)
+ {
+ $loader = new self($baseDir);
+ spl_autoload_register(array($loader, 'autoload'));
+
+ return $loader;
+ }
+
+ /**
+ * Autoload Mustache classes.
+ *
+ * @param string $class
+ */
+ public function autoload($class)
+ {
+ if ($class[0] === '\\') {
+ $class = substr($class, 1);
+ }
+
+ if (strpos($class, 'Mustache') !== 0) {
+ return;
+ }
+
+ $file = sprintf('%s/%s.php', $this->baseDir, str_replace('_', '/', $class));
+ if (is_file($file)) {
+ require $file;
+ }
+ }
+}
diff --git a/vendor/mustache/mustache/src/Mustache/Cache.php b/vendor/mustache/mustache/src/Mustache/Cache.php
new file mode 100644
index 0000000..7b465ab
--- /dev/null
+++ b/vendor/mustache/mustache/src/Mustache/Cache.php
@@ -0,0 +1,36 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Mustache Cache interface.
+ *
+ * Interface for caching and loading Mustache_Template classes
+ * generated by the Mustache_Compiler.
+ */
+interface Mustache_Cache
+{
+ /**
+ * Load a compiled Mustache_Template class from cache.
+ *
+ * @param string $key
+ *
+ * @return bool indicates successfully class load
+ */
+ public function load($key);
+
+ /**
+ * Cache and load a compiled Mustache_Template class.
+ *
+ * @param string $key
+ * @param string $value
+ */
+ public function cache($key, $value);
+}
diff --git a/vendor/mustache/mustache/src/Mustache/Cache/AbstractCache.php b/vendor/mustache/mustache/src/Mustache/Cache/AbstractCache.php
new file mode 100644
index 0000000..495090b
--- /dev/null
+++ b/vendor/mustache/mustache/src/Mustache/Cache/AbstractCache.php
@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Abstract Mustache Cache class.
+ *
+ * Provides logging support to child implementations.
+ *
+ * @abstract
+ */
+abstract class Mustache_Cache_AbstractCache implements Mustache_Cache
+{
+ private $logger = null;
+
+ /**
+ * Get the current logger instance.
+ *
+ * @return Mustache_Logger|Psr\Log\LoggerInterface
+ */
+ public function getLogger()
+ {
+ return $this->logger;
+ }
+
+ /**
+ * Set a logger instance.
+ *
+ * @param Mustache_Logger|Psr\Log\LoggerInterface $logger
+ */
+ public function setLogger($logger = null)
+ {
+ if ($logger !== null && !($logger instanceof Mustache_Logger || is_a($logger, 'Psr\\Log\\LoggerInterface'))) {
+ throw new Mustache_Exception_InvalidArgumentException('Expected an instance of Mustache_Logger or Psr\\Log\\LoggerInterface.');
+ }
+
+ $this->logger = $logger;
+ }
+
+ /**
+ * Add a log record if logging is enabled.
+ *
+ * @param int $level The logging level
+ * @param string $message The log message
+ * @param array $context The log context
+ */
+ protected function log($level, $message, array $context = array())
+ {
+ if (isset($this->logger)) {
+ $this->logger->log($level, $message, $context);
+ }
+ }
+}
diff --git a/vendor/mustache/mustache/src/Mustache/Cache/FilesystemCache.php b/vendor/mustache/mustache/src/Mustache/Cache/FilesystemCache.php
new file mode 100644
index 0000000..0dbe8f9
--- /dev/null
+++ b/vendor/mustache/mustache/src/Mustache/Cache/FilesystemCache.php
@@ -0,0 +1,155 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Mustache Cache filesystem implementation.
+ *
+ * A FilesystemCache instance caches Mustache Template classes from the filesystem by name:
+ *
+ * $cache = new Mustache_Cache_FilesystemCache(dirname(__FILE__).'/cache');
+ * $cache->cache($className, $compiledSource);
+ *
+ * The FilesystemCache benefits from any opcode caching that may be setup in your environment. So do that, k?
+ */
+class Mustache_Cache_FilesystemCache extends Mustache_Cache_AbstractCache
+{
+ private $baseDir;
+ private $fileMode;
+
+ /**
+ * Filesystem cache constructor.
+ *
+ * @param string $baseDir Directory for compiled templates
+ * @param int $fileMode Override default permissions for cache files. Defaults to using the system-defined umask
+ */
+ public function __construct($baseDir, $fileMode = null)
+ {
+ $this->baseDir = $baseDir;
+ $this->fileMode = $fileMode;
+ }
+
+ /**
+ * Load the class from cache using `require_once`.
+ *
+ * @param string $key
+ *
+ * @return bool
+ */
+ public function load($key)
+ {
+ $fileName = $this->getCacheFilename($key);
+ if (!is_file($fileName)) {
+ return false;
+ }
+
+ require_once $fileName;
+
+ return true;
+ }
+
+ /**
+ * Cache and load the compiled class.
+ *
+ * @param string $key
+ * @param string $value
+ */
+ public function cache($key, $value)
+ {
+ $fileName = $this->getCacheFilename($key);
+
+ $this->log(
+ Mustache_Logger::DEBUG,
+ 'Writing to template cache: "{fileName}"',
+ array('fileName' => $fileName)
+ );
+
+ $this->writeFile($fileName, $value);
+ $this->load($key);
+ }
+
+ /**
+ * Build the cache filename.
+ * Subclasses should override for custom cache directory structures.
+ *
+ * @param string $name
+ *
+ * @return string
+ */
+ protected function getCacheFilename($name)
+ {
+ return sprintf('%s/%s.php', $this->baseDir, $name);
+ }
+
+ /**
+ * Create cache directory.
+ *
+ * @throws Mustache_Exception_RuntimeException If unable to create directory
+ *
+ * @param string $fileName
+ *
+ * @return string
+ */
+ private function buildDirectoryForFilename($fileName)
+ {
+ $dirName = dirname($fileName);
+ if (!is_dir($dirName)) {
+ $this->log(
+ Mustache_Logger::INFO,
+ 'Creating Mustache template cache directory: "{dirName}"',
+ array('dirName' => $dirName)
+ );
+
+ @mkdir($dirName, 0777, true);
+ if (!is_dir($dirName)) {
+ throw new Mustache_Exception_RuntimeException(sprintf('Failed to create cache directory "%s".', $dirName));
+ }
+ }
+
+ return $dirName;
+ }
+
+ /**
+ * Write cache file.
+ *
+ * @throws Mustache_Exception_RuntimeException If unable to write file
+ *
+ * @param string $fileName
+ * @param string $value
+ */
+ private function writeFile($fileName, $value)
+ {
+ $dirName = $this->buildDirectoryForFilename($fileName);
+
+ $this->log(
+ Mustache_Logger::DEBUG,
+ 'Caching compiled template to "{fileName}"',
+ array('fileName' => $fileName)
+ );
+
+ $tempFile = tempnam($dirName, basename($fileName));
+ if (false !== @file_put_contents($tempFile, $value)) {
+ if (@rename($tempFile, $fileName)) {
+ $mode = isset($this->fileMode) ? $this->fileMode : (0666 & ~umask());
+ @chmod($fileName, $mode);
+
+ return;
+ }
+
+ $this->log(
+ Mustache_Logger::ERROR,
+ 'Unable to rename Mustache temp cache file: "{tempName}" -> "{fileName}"',
+ array('tempName' => $tempFile, 'fileName' => $fileName)
+ );
+ }
+
+ throw new Mustache_Exception_RuntimeException(sprintf('Failed to write cache file "%s".', $fileName));
+ }
+}
diff --git a/vendor/mustache/mustache/src/Mustache/Cache/NoopCache.php b/vendor/mustache/mustache/src/Mustache/Cache/NoopCache.php
new file mode 100644
index 0000000..ca0007d
--- /dev/null
+++ b/vendor/mustache/mustache/src/Mustache/Cache/NoopCache.php
@@ -0,0 +1,47 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Mustache Cache in-memory implementation.
+ *
+ * The in-memory cache is used for uncached lambda section templates. It's also useful during development, but is not
+ * recommended for production use.
+ */
+class Mustache_Cache_NoopCache extends Mustache_Cache_AbstractCache
+{
+ /**
+ * Loads nothing. Move along.
+ *
+ * @param string $key
+ *
+ * @return bool
+ */
+ public function load($key)
+ {
+ return false;
+ }
+
+ /**
+ * Loads the compiled Mustache Template class without caching.
+ *
+ * @param string $key
+ * @param string $value
+ */
+ public function cache($key, $value)
+ {
+ $this->log(
+ Mustache_Logger::WARNING,
+ 'Template cache disabled, evaluating "{className}" class at runtime',
+ array('className' => $key)
+ );
+ eval('?>' . $value);
+ }
+}
diff --git a/vendor/mustache/mustache/src/Mustache/Compiler.php b/vendor/mustache/mustache/src/Mustache/Compiler.php
new file mode 100644
index 0000000..2a831d6
--- /dev/null
+++ b/vendor/mustache/mustache/src/Mustache/Compiler.php
@@ -0,0 +1,687 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Mustache Compiler class.
+ *
+ * This class is responsible for turning a Mustache token parse tree into normal PHP source code.
+ */
+class Mustache_Compiler
+{
+ private $pragmas;
+ private $defaultPragmas = array();
+ private $sections;
+ private $blocks;
+ private $source;
+ private $indentNextLine;
+ private $customEscape;
+ private $entityFlags;
+ private $charset;
+ private $strictCallables;
+
+ /**
+ * Compile a Mustache token parse tree into PHP source code.
+ *
+ * @param string $source Mustache Template source code
+ * @param string $tree Parse tree of Mustache tokens
+ * @param string $name Mustache Template class name
+ * @param bool $customEscape (default: false)
+ * @param string $charset (default: 'UTF-8')
+ * @param bool $strictCallables (default: false)
+ * @param int $entityFlags (default: ENT_COMPAT)
+ *
+ * @return string Generated PHP source code
+ */
+ public function compile($source, array $tree, $name, $customEscape = false, $charset = 'UTF-8', $strictCallables = false, $entityFlags = ENT_COMPAT)
+ {
+ $this->pragmas = $this->defaultPragmas;
+ $this->sections = array();
+ $this->blocks = array();
+ $this->source = $source;
+ $this->indentNextLine = true;
+ $this->customEscape = $customEscape;
+ $this->entityFlags = $entityFlags;
+ $this->charset = $charset;
+ $this->strictCallables = $strictCallables;
+
+ return $this->writeCode($tree, $name);
+ }
+
+ /**
+ * Enable pragmas across all templates, regardless of the presence of pragma
+ * tags in the individual templates.
+ *
+ * @internal Users should set global pragmas in Mustache_Engine, not here :)
+ *
+ * @param string[] $pragmas
+ */
+ public function setPragmas(array $pragmas)
+ {
+ $this->pragmas = array();
+ foreach ($pragmas as $pragma) {
+ $this->pragmas[$pragma] = true;
+ }
+ $this->defaultPragmas = $this->pragmas;
+ }
+
+ /**
+ * Helper function for walking the Mustache token parse tree.
+ *
+ * @throws Mustache_Exception_SyntaxException upon encountering unknown token types
+ *
+ * @param array $tree Parse tree of Mustache tokens
+ * @param int $level (default: 0)
+ *
+ * @return string Generated PHP source code
+ */
+ private function walk(array $tree, $level = 0)
+ {
+ $code = '';
+ $level++;
+ foreach ($tree as $node) {
+ switch ($node[Mustache_Tokenizer::TYPE]) {
+ case Mustache_Tokenizer::T_PRAGMA:
+ $this->pragmas[$node[Mustache_Tokenizer::NAME]] = true;
+ break;
+
+ case Mustache_Tokenizer::T_SECTION:
+ $code .= $this->section(
+ $node[Mustache_Tokenizer::NODES],
+ $node[Mustache_Tokenizer::NAME],
+ isset($node[Mustache_Tokenizer::FILTERS]) ? $node[Mustache_Tokenizer::FILTERS] : array(),
+ $node[Mustache_Tokenizer::INDEX],
+ $node[Mustache_Tokenizer::END],
+ $node[Mustache_Tokenizer::OTAG],
+ $node[Mustache_Tokenizer::CTAG],
+ $level
+ );
+ break;
+
+ case Mustache_Tokenizer::T_INVERTED:
+ $code .= $this->invertedSection(
+ $node[Mustache_Tokenizer::NODES],
+ $node[Mustache_Tokenizer::NAME],
+ isset($node[Mustache_Tokenizer::FILTERS]) ? $node[Mustache_Tokenizer::FILTERS] : array(),
+ $level
+ );
+ break;
+
+ case Mustache_Tokenizer::T_PARTIAL:
+ $code .= $this->partial(
+ $node[Mustache_Tokenizer::NAME],
+ isset($node[Mustache_Tokenizer::INDENT]) ? $node[Mustache_Tokenizer::INDENT] : '',
+ $level
+ );
+ break;
+
+ case Mustache_Tokenizer::T_PARENT:
+ $code .= $this->parent(
+ $node[Mustache_Tokenizer::NAME],
+ isset($node[Mustache_Tokenizer::INDENT]) ? $node[Mustache_Tokenizer::INDENT] : '',
+ $node[Mustache_Tokenizer::NODES],
+ $level
+ );
+ break;
+
+ case Mustache_Tokenizer::T_BLOCK_ARG:
+ $code .= $this->blockArg(
+ $node[Mustache_Tokenizer::NODES],
+ $node[Mustache_Tokenizer::NAME],
+ $node[Mustache_Tokenizer::INDEX],
+ $node[Mustache_Tokenizer::END],
+ $node[Mustache_Tokenizer::OTAG],
+ $node[Mustache_Tokenizer::CTAG],
+ $level
+ );
+ break;
+
+ case Mustache_Tokenizer::T_BLOCK_VAR:
+ $code .= $this->blockVar(
+ $node[Mustache_Tokenizer::NODES],
+ $node[Mustache_Tokenizer::NAME],
+ $node[Mustache_Tokenizer::INDEX],
+ $node[Mustache_Tokenizer::END],
+ $node[Mustache_Tokenizer::OTAG],
+ $node[Mustache_Tokenizer::CTAG],
+ $level
+ );
+ break;
+
+ case Mustache_Tokenizer::T_COMMENT:
+ break;
+
+ case Mustache_Tokenizer::T_ESCAPED:
+ case Mustache_Tokenizer::T_UNESCAPED:
+ case Mustache_Tokenizer::T_UNESCAPED_2:
+ $code .= $this->variable(
+ $node[Mustache_Tokenizer::NAME],
+ isset($node[Mustache_Tokenizer::FILTERS]) ? $node[Mustache_Tokenizer::FILTERS] : array(),
+ $node[Mustache_Tokenizer::TYPE] === Mustache_Tokenizer::T_ESCAPED,
+ $level
+ );
+ break;
+
+ case Mustache_Tokenizer::T_TEXT:
+ $code .= $this->text($node[Mustache_Tokenizer::VALUE], $level);
+ break;
+
+ default:
+ throw new Mustache_Exception_SyntaxException(sprintf('Unknown token type: %s', $node[Mustache_Tokenizer::TYPE]), $node);
+ }
+ }
+
+ return $code;
+ }
+
+ const KLASS = '<?php
+
+ class %s extends Mustache_Template
+ {
+ private $lambdaHelper;%s
+
+ public function renderInternal(Mustache_Context $context, $indent = \'\')
+ {
+ $this->lambdaHelper = new Mustache_LambdaHelper($this->mustache, $context);
+ $buffer = \'\';
+ $blocksContext = array();
+ %s
+
+ return $buffer;
+ }
+ %s
+ %s
+ }';
+
+ const KLASS_NO_LAMBDAS = '<?php
+
+ class %s extends Mustache_Template
+ {%s
+ public function renderInternal(Mustache_Context $context, $indent = \'\')
+ {
+ $buffer = \'\';
+ $blocksContext = array();
+ %s
+
+ return $buffer;
+ }
+ }';
+
+ const STRICT_CALLABLE = 'protected $strictCallables = true;';
+
+ /**
+ * Generate Mustache Template class PHP source.
+ *
+ * @param array $tree Parse tree of Mustache tokens
+ * @param string $name Mustache Template class name
+ *
+ * @return string Generated PHP source code
+ */
+ private function writeCode($tree, $name)
+ {
+ $code = $this->walk($tree);
+ $sections = implode("\n", $this->sections);
+ $blocks = implode("\n", $this->blocks);
+ $klass = empty($this->sections) && empty($this->blocks) ? self::KLASS_NO_LAMBDAS : self::KLASS;
+
+ $callable = $this->strictCallables ? $this->prepare(self::STRICT_CALLABLE) : '';
+
+ return sprintf($this->prepare($klass, 0, false, true), $name, $callable, $code, $sections, $blocks);
+ }
+
+ const BLOCK_VAR = '
+ $blockFunction = $context->findInBlock(%s);
+ if (is_callable($blockFunction)) {
+ $buffer .= call_user_func($blockFunction, $context);
+ } else {%s
+ }
+ ';
+
+ /**
+ * Generate Mustache Template inheritance block variable PHP source.
+ *
+ * @param array $nodes Array of child tokens
+ * @param string $id Section name
+ * @param int $start Section start offset
+ * @param int $end Section end offset
+ * @param string $otag Current Mustache opening tag
+ * @param string $ctag Current Mustache closing tag
+ * @param int $level
+ *
+ * @return string Generated PHP source code
+ */
+ private function blockVar($nodes, $id, $start, $end, $otag, $ctag, $level)
+ {
+ $id = var_export($id, true);
+
+ return sprintf($this->prepare(self::BLOCK_VAR, $level), $id, $this->walk($nodes, $level));
+ }
+
+ const BLOCK_ARG = '$blocksContext[%s] = array($this, \'block%s\');';
+
+ /**
+ * Generate Mustache Template inheritance block argument PHP source.
+ *
+ * @param array $nodes Array of child tokens
+ * @param string $id Section name
+ * @param int $start Section start offset
+ * @param int $end Section end offset
+ * @param string $otag Current Mustache opening tag
+ * @param string $ctag Current Mustache closing tag
+ * @param int $level
+ *
+ * @return string Generated PHP source code
+ */
+ private function blockArg($nodes, $id, $start, $end, $otag, $ctag, $level)
+ {
+ $key = $this->block($nodes);
+ $keystr = var_export($key, true);
+ $id = var_export($id, true);
+
+ return sprintf($this->prepare(self::BLOCK_ARG, 1), $id, $key);
+ }
+
+ const BLOCK_FUNCTION = '
+ public function block%s($context)
+ {
+ $indent = $buffer = \'\';
+ $blocksContext = array();%s
+
+ return $buffer;
+ }
+ ';
+
+ /**
+ * Generate Mustache Template inheritance block function PHP source.
+ *
+ * @param array $nodes Array of child tokens
+ *
+ * @return string key of new block function
+ */
+ private function block($nodes)
+ {
+ $code = $this->walk($nodes, 0);
+ $key = ucfirst(md5($code));
+
+ if (!isset($this->blocks[$key])) {
+ $this->blocks[$key] = sprintf($this->prepare(self::BLOCK_FUNCTION, 0), $key, $code);
+ }
+
+ return $key;
+ }
+
+ const SECTION_CALL = '
+ // %s section
+ $value = $context->%s(%s);%s
+ $buffer .= $this->section%s($context, $indent, $value);
+ ';
+
+ const SECTION = '
+ private function section%s(Mustache_Context $context, $indent, $value)
+ {
+ $buffer = \'\';
+ $blocksContext = array();
+
+ if (%s) {
+ $source = %s;
+ $result = call_user_func($value, $source, %s);
+ if (strpos($result, \'{{\') === false) {
+ $buffer .= $result;
+ } else {
+ $buffer .= $this->mustache
+ ->loadLambda((string) $result%s)
+ ->renderInternal($context);
+ }
+ } elseif (!empty($value)) {
+ $values = $this->isIterable($value) ? $value : array($value);
+ foreach ($values as $value) {
+ $context->push($value);
+ %s
+ $context->pop();
+ }
+ }
+
+ return $buffer;
+ }
+ ';
+
+ /**
+ * Generate Mustache Template section PHP source.
+ *
+ * @param array $nodes Array of child tokens
+ * @param string $id Section name
+ * @param string[] $filters Array of filters
+ * @param int $start Section start offset
+ * @param int $end Section end offset
+ * @param string $otag Current Mustache opening tag
+ * @param string $ctag Current Mustache closing tag
+ * @param int $level
+ * @param bool $arg (default: false)
+ *
+ * @return string Generated section PHP source code
+ */
+ private function section($nodes, $id, $filters, $start, $end, $otag, $ctag, $level, $arg = false)
+ {
+ $source = var_export(substr($this->source, $start, $end - $start), true);
+ $callable = $this->getCallable();
+
+ if ($otag !== '{{' || $ctag !== '}}') {
+ $delimTag = var_export(sprintf('{{= %s %s =}}', $otag, $ctag), true);
+ $helper = sprintf('$this->lambdaHelper->withDelimiters(%s)', $delimTag);
+ $delims = ', ' . $delimTag;
+ } else {
+ $helper = '$this->lambdaHelper';
+ $delims = '';
+ }
+
+ $key = ucfirst(md5($delims . "\n" . $source));
+
+ if (!isset($this->sections[$key])) {
+ $this->sections[$key] = sprintf($this->prepare(self::SECTION), $key, $callable, $source, $helper, $delims, $this->walk($nodes, 2));
+ }
+
+ if ($arg === true) {
+ return $key;
+ } else {
+ $method = $this->getFindMethod($id);
+ $id = var_export($id, true);
+ $filters = $this->getFilters($filters, $level);
+
+ return sprintf($this->prepare(self::SECTION_CALL, $level), $id, $method, $id, $filters, $key);
+ }
+ }
+
+ const INVERTED_SECTION = '
+ // %s inverted section
+ $value = $context->%s(%s);%s
+ if (empty($value)) {
+ %s
+ }
+ ';
+
+ /**
+ * Generate Mustache Template inverted section PHP source.
+ *
+ * @param array $nodes Array of child tokens
+ * @param string $id Section name
+ * @param string[] $filters Array of filters
+ * @param int $level
+ *
+ * @return string Generated inverted section PHP source code
+ */
+ private function invertedSection($nodes, $id, $filters, $level)
+ {
+ $method = $this->getFindMethod($id);
+ $id = var_export($id, true);
+ $filters = $this->getFilters($filters, $level);
+
+ return sprintf($this->prepare(self::INVERTED_SECTION, $level), $id, $method, $id, $filters, $this->walk($nodes, $level));
+ }
+
+ const PARTIAL_INDENT = ', $indent . %s';
+ const PARTIAL = '
+ if ($partial = $this->mustache->loadPartial(%s)) {
+ $buffer .= $partial->renderInternal($context%s);
+ }
+ ';
+
+ /**
+ * Generate Mustache Template partial call PHP source.
+ *
+ * @param string $id Partial name
+ * @param string $indent Whitespace indent to apply to partial
+ * @param int $level
+ *
+ * @return string Generated partial call PHP source code
+ */
+ private function partial($id, $indent, $level)
+ {
+ if ($indent !== '') {
+ $indentParam = sprintf(self::PARTIAL_INDENT, var_export($indent, true));
+ } else {
+ $indentParam = '';
+ }
+
+ return sprintf(
+ $this->prepare(self::PARTIAL, $level),
+ var_export($id, true),
+ $indentParam
+ );
+ }
+
+ const PARENT = '
+ %s
+
+ if ($parent = $this->mustache->loadPartial(%s)) {
+ $context->pushBlockContext($blocksContext);
+ $buffer .= $parent->renderInternal($context, $indent);
+ $context->popBlockContext();
+ }
+ ';
+
+ /**
+ * Generate Mustache Template inheritance parent call PHP source.
+ *
+ * @param string $id Parent tag name
+ * @param string $indent Whitespace indent to apply to parent
+ * @param array $children Child nodes
+ * @param int $level
+ *
+ * @return string Generated PHP source code
+ */
+ private function parent($id, $indent, array $children, $level)
+ {
+ $realChildren = array_filter($children, array(__CLASS__, 'onlyBlockArgs'));
+
+ return sprintf(
+ $this->prepare(self::PARENT, $level),
+ $this->walk($realChildren, $level),
+ var_export($id, true),
+ var_export($indent, true)
+ );
+ }
+
+ /**
+ * Helper method for filtering out non-block-arg tokens.
+ *
+ * @param array $node
+ *
+ * @return bool True if $node is a block arg token
+ */
+ private static function onlyBlockArgs(array $node)
+ {
+ return $node[Mustache_Tokenizer::TYPE] === Mustache_Tokenizer::T_BLOCK_ARG;
+ }
+
+ const VARIABLE = '
+ $value = $this->resolveValue($context->%s(%s), $context);%s
+ $buffer .= %s%s;
+ ';
+
+ /**
+ * Generate Mustache Template variable interpolation PHP source.
+ *
+ * @param string $id Variable name
+ * @param string[] $filters Array of filters
+ * @param bool $escape Escape the variable value for output?
+ * @param int $level
+ *
+ * @return string Generated variable interpolation PHP source
+ */
+ private function variable($id, $filters, $escape, $level)
+ {
+ $method = $this->getFindMethod($id);
+ $id = ($method !== 'last') ? var_export($id, true) : '';
+ $filters = $this->getFilters($filters, $level);
+ $value = $escape ? $this->getEscape() : '$value';
+
+ return sprintf($this->prepare(self::VARIABLE, $level), $method, $id, $filters, $this->flushIndent(), $value);
+ }
+
+ const FILTER = '
+ $filter = $context->%s(%s);
+ if (!(%s)) {
+ throw new Mustache_Exception_UnknownFilterException(%s);
+ }
+ $value = call_user_func($filter, $value);%s
+ ';
+
+ /**
+ * Generate Mustache Template variable filtering PHP source.
+ *
+ * @param string[] $filters Array of filters
+ * @param int $level
+ *
+ * @return string Generated filter PHP source
+ */
+ private function getFilters(array $filters, $level)
+ {
+ if (empty($filters)) {
+ return '';
+ }
+
+ $name = array_shift($filters);
+ $method = $this->getFindMethod($name);
+ $filter = ($method !== 'last') ? var_export($name, true) : '';
+ $callable = $this->getCallable('$filter');
+ $msg = var_export($name, true);
+
+ return sprintf($this->prepare(self::FILTER, $level), $method, $filter, $callable, $msg, $this->getFilters($filters, $level));
+ }
+
+ const LINE = '$buffer .= "\n";';
+ const TEXT = '$buffer .= %s%s;';
+
+ /**
+ * Generate Mustache Template output Buffer call PHP source.
+ *
+ * @param string $text
+ * @param int $level
+ *
+ * @return string Generated output Buffer call PHP source
+ */
+ private function text($text, $level)
+ {
+ $indentNextLine = (substr($text, -1) === "\n");
+ $code = sprintf($this->prepare(self::TEXT, $level), $this->flushIndent(), var_export($text, true));
+ $this->indentNextLine = $indentNextLine;
+
+ return $code;
+ }
+
+ /**
+ * Prepare PHP source code snippet for output.
+ *
+ * @param string $text
+ * @param int $bonus Additional indent level (default: 0)
+ * @param bool $prependNewline Prepend a newline to the snippet? (default: true)
+ * @param bool $appendNewline Append a newline to the snippet? (default: false)
+ *
+ * @return string PHP source code snippet
+ */
+ private function prepare($text, $bonus = 0, $prependNewline = true, $appendNewline = false)
+ {
+ $text = ($prependNewline ? "\n" : '') . trim($text);
+ if ($prependNewline) {
+ $bonus++;
+ }
+ if ($appendNewline) {
+ $text .= "\n";
+ }
+
+ return preg_replace("/\n( {8})?/", "\n" . str_repeat(' ', $bonus * 4), $text);
+ }
+
+ const DEFAULT_ESCAPE = 'htmlspecialchars(%s, %s, %s)';
+ const CUSTOM_ESCAPE = 'call_user_func($this->mustache->getEscape(), %s)';
+
+ /**
+ * Get the current escaper.
+ *
+ * @param string $value (default: '$value')
+ *
+ * @return string Either a custom callback, or an inline call to `htmlspecialchars`
+ */
+ private function getEscape($value = '$value')
+ {
+ if ($this->customEscape) {
+ return sprintf(self::CUSTOM_ESCAPE, $value);
+ }
+
+ return sprintf(self::DEFAULT_ESCAPE, $value, var_export($this->entityFlags, true), var_export($this->charset, true));
+ }
+
+ /**
+ * Select the appropriate Context `find` method for a given $id.
+ *
+ * The return value will be one of `find`, `findDot` or `last`.
+ *
+ * @see Mustache_Context::find
+ * @see Mustache_Context::findDot
+ * @see Mustache_Context::last
+ *
+ * @param string $id Variable name
+ *
+ * @return string `find` method name
+ */
+ private function getFindMethod($id)
+ {
+ if ($id === '.') {
+ return 'last';
+ }
+
+ if (isset($this->pragmas[Mustache_Engine::PRAGMA_ANCHORED_DOT]) && $this->pragmas[Mustache_Engine::PRAGMA_ANCHORED_DOT]) {
+ if (substr($id, 0, 1) === '.') {
+ return 'findAnchoredDot';
+ }
+ }
+
+ if (strpos($id, '.') === false) {
+ return 'find';
+ }
+
+ return 'findDot';
+ }
+
+ const IS_CALLABLE = '!is_string(%s) && is_callable(%s)';
+ const STRICT_IS_CALLABLE = 'is_object(%s) && is_callable(%s)';
+
+ /**
+ * Helper function to compile strict vs lax "is callable" logic.
+ *
+ * @param string $variable (default: '$value')
+ *
+ * @return string "is callable" logic
+ */
+ private function getCallable($variable = '$value')
+ {
+ $tpl = $this->strictCallables ? self::STRICT_IS_CALLABLE : self::IS_CALLABLE;
+
+ return sprintf($tpl, $variable, $variable);
+ }
+
+ const LINE_INDENT = '$indent . ';
+
+ /**
+ * Get the current $indent prefix to write to the buffer.
+ *
+ * @return string "$indent . " or ""
+ */
+ private function flushIndent()
+ {
+ if (!$this->indentNextLine) {
+ return '';
+ }
+
+ $this->indentNextLine = false;
+
+ return self::LINE_INDENT;
+ }
+}
diff --git a/vendor/mustache/mustache/src/Mustache/Context.php b/vendor/mustache/mustache/src/Mustache/Context.php
new file mode 100644
index 0000000..f59faea
--- /dev/null
+++ b/vendor/mustache/mustache/src/Mustache/Context.php
@@ -0,0 +1,242 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Mustache Template rendering Context.
+ */
+class Mustache_Context
+{
+ private $stack = array();
+ private $blockStack = array();
+
+ /**
+ * Mustache rendering Context constructor.
+ *
+ * @param mixed $context Default rendering context (default: null)
+ */
+ public function __construct($context = null)
+ {
+ if ($context !== null) {
+ $this->stack = array($context);
+ }
+ }
+
+ /**
+ * Push a new Context frame onto the stack.
+ *
+ * @param mixed $value Object or array to use for context
+ */
+ public function push($value)
+ {
+ array_push($this->stack, $value);
+ }
+
+ /**
+ * Push a new Context frame onto the block context stack.
+ *
+ * @param mixed $value Object or array to use for block context
+ */
+ public function pushBlockContext($value)
+ {
+ array_push($this->blockStack, $value);
+ }
+
+ /**
+ * Pop the last Context frame from the stack.
+ *
+ * @return mixed Last Context frame (object or array)
+ */
+ public function pop()
+ {
+ return array_pop($this->stack);
+ }
+
+ /**
+ * Pop the last block Context frame from the stack.
+ *
+ * @return mixed Last block Context frame (object or array)
+ */
+ public function popBlockContext()
+ {
+ return array_pop($this->blockStack);
+ }
+
+ /**
+ * Get the last Context frame.
+ *
+ * @return mixed Last Context frame (object or array)
+ */
+ public function last()
+ {
+ return end($this->stack);
+ }
+
+ /**
+ * Find a variable in the Context stack.
+ *
+ * Starting with the last Context frame (the context of the innermost section), and working back to the top-level
+ * rendering context, look for a variable with the given name:
+ *
+ * * If the Context frame is an associative array which contains the key $id, returns the value of that element.
+ * * If the Context frame is an object, this will check first for a public method, then a public property named
+ * $id. Failing both of these, it will try `__isset` and `__get` magic methods.
+ * * If a value named $id is not found in any Context frame, returns an empty string.
+ *
+ * @param string $id Variable name
+ *
+ * @return mixed Variable value, or '' if not found
+ */
+ public function find($id)
+ {
+ return $this->findVariableInStack($id, $this->stack);
+ }
+
+ /**
+ * Find a 'dot notation' variable in the Context stack.
+ *
+ * Note that dot notation traversal bubbles through scope differently than the regular find method. After finding
+ * the initial chunk of the dotted name, each subsequent chunk is searched for only within the value of the previous
+ * result. For example, given the following context stack:
+ *
+ * $data = array(
+ * 'name' => 'Fred',
+ * 'child' => array(
+ * 'name' => 'Bob'
+ * ),
+ * );
+ *
+ * ... and the Mustache following template:
+ *
+ * {{ child.name }}
+ *
+ * ... the `name` value is only searched for within the `child` value of the global Context, not within parent
+ * Context frames.
+ *
+ * @param string $id Dotted variable selector
+ *
+ * @return mixed Variable value, or '' if not found
+ */
+ public function findDot($id)
+ {
+ $chunks = explode('.', $id);
+ $first = array_shift($chunks);
+ $value = $this->findVariableInStack($first, $this->stack);
+
+ foreach ($chunks as $chunk) {
+ if ($value === '') {
+ return $value;
+ }
+
+ $value = $this->findVariableInStack($chunk, array($value));
+ }
+
+ return $value;
+ }
+
+ /**
+ * Find an 'anchored dot notation' variable in the Context stack.
+ *
+ * This is the same as findDot(), except it looks in the top of the context
+ * stack for the first value, rather than searching the whole context stack
+ * and starting from there.
+ *
+ * @see Mustache_Context::findDot
+ *
+ * @throws Mustache_Exception_InvalidArgumentException if given an invalid anchored dot $id
+ *
+ * @param string $id Dotted variable selector
+ *
+ * @return mixed Variable value, or '' if not found
+ */
+ public function findAnchoredDot($id)
+ {
+ $chunks = explode('.', $id);
+ $first = array_shift($chunks);
+ if ($first !== '') {
+ throw new Mustache_Exception_InvalidArgumentException(sprintf('Unexpected id for findAnchoredDot: %s', $id));
+ }
+
+ $value = $this->last();
+
+ foreach ($chunks as $chunk) {
+ if ($value === '') {
+ return $value;
+ }
+
+ $value = $this->findVariableInStack($chunk, array($value));
+ }
+
+ return $value;
+ }
+
+ /**
+ * Find an argument in the block context stack.
+ *
+ * @param string $id
+ *
+ * @return mixed Variable value, or '' if not found
+ */
+ public function findInBlock($id)
+ {
+ foreach ($this->blockStack as $context) {
+ if (array_key_exists($id, $context)) {
+ return $context[$id];
+ }
+ }
+
+ return '';
+ }
+
+ /**
+ * Helper function to find a variable in the Context stack.
+ *
+ * @see Mustache_Context::find
+ *
+ * @param string $id Variable name
+ * @param array $stack Context stack
+ *
+ * @return mixed Variable value, or '' if not found
+ */
+ private function findVariableInStack($id, array $stack)
+ {
+ for ($i = count($stack) - 1; $i >= 0; $i--) {
+ $frame = &$stack[$i];
+
+ switch (gettype($frame)) {
+ case 'object':
+ if (!($frame instanceof Closure)) {
+ // Note that is_callable() *will not work here*
+ // See https://github.com/bobthecow/mustache.php/wiki/Magic-Methods
+ if (method_exists($frame, $id)) {
+ return $frame->$id();
+ }
+
+ if (isset($frame->$id)) {
+ return $frame->$id;
+ }
+
+ if ($frame instanceof ArrayAccess && isset($frame[$id])) {
+ return $frame[$id];
+ }
+ }
+ break;
+
+ case 'array':
+ if (array_key_exists($id, $frame)) {
+ return $frame[$id];
+ }
+ break;
+ }
+ }
+
+ return '';
+ }
+}
diff --git a/vendor/mustache/mustache/src/Mustache/Engine.php b/vendor/mustache/mustache/src/Mustache/Engine.php
new file mode 100644
index 0000000..856d4ef
--- /dev/null
+++ b/vendor/mustache/mustache/src/Mustache/Engine.php
@@ -0,0 +1,787 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * A Mustache implementation in PHP.
+ *
+ * {@link http://defunkt.github.com/mustache}
+ *
+ * Mustache is a framework-agnostic logic-less templating language. It enforces separation of view
+ * logic from template files. In fact, it is not even possible to embed logic in the template.
+ *
+ * This is very, very rad.
+ *
+ * @author Justin Hileman {@link http://justinhileman.com}
+ */
+class Mustache_Engine
+{
+ const VERSION = '2.11.1';
+ const SPEC_VERSION = '1.1.2';
+
+ const PRAGMA_FILTERS = 'FILTERS';
+ const PRAGMA_BLOCKS = 'BLOCKS';
+ const PRAGMA_ANCHORED_DOT = 'ANCHORED-DOT';
+
+ // Known pragmas
+ private static $knownPragmas = array(
+ self::PRAGMA_FILTERS => true,
+ self::PRAGMA_BLOCKS => true,
+ self::PRAGMA_ANCHORED_DOT => true,
+ );
+
+ // Template cache
+ private $templates = array();
+
+ // Environment
+ private $templateClassPrefix = '__Mustache_';
+ private $cache;
+ private $lambdaCache;
+ private $cacheLambdaTemplates = false;
+ private $loader;
+ private $partialsLoader;
+ private $helpers;
+ private $escape;
+ private $entityFlags = ENT_COMPAT;
+ private $charset = 'UTF-8';
+ private $logger;
+ private $strictCallables = false;
+ private $pragmas = array();
+
+ // Services
+ private $tokenizer;
+ private $parser;
+ private $compiler;
+
+ /**
+ * Mustache class constructor.
+ *
+ * Passing an $options array allows overriding certain Mustache options during instantiation:
+ *
+ * $options = array(
+ * // The class prefix for compiled templates. Defaults to '__Mustache_'.
+ * 'template_class_prefix' => '__MyTemplates_',
+ *
+ * // A Mustache cache instance or a cache directory string for compiled templates.
+ * // Mustache will not cache templates unless this is set.
+ * 'cache' => dirname(__FILE__).'/tmp/cache/mustache',
+ *
+ * // Override default permissions for cache files. Defaults to using the system-defined umask. It is
+ * // *strongly* recommended that you configure your umask properly rather than overriding permissions here.
+ * 'cache_file_mode' => 0666,
+ *
+ * // Optionally, enable caching for lambda section templates. This is generally not recommended, as lambda
+ * // sections are often too dynamic to benefit from caching.
+ * 'cache_lambda_templates' => true,
+ *
+ * // A Mustache template loader instance. Uses a StringLoader if not specified.
+ * 'loader' => new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views'),
+ *
+ * // A Mustache loader instance for partials.
+ * 'partials_loader' => new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views/partials'),
+ *
+ * // An array of Mustache partials. Useful for quick-and-dirty string template loading, but not as
+ * // efficient or lazy as a Filesystem (or database) loader.
+ * 'partials' => array('foo' => file_get_contents(dirname(__FILE__).'/views/partials/foo.mustache')),
+ *
+ * // An array of 'helpers'. Helpers can be global variables or objects, closures (e.g. for higher order
+ * // sections), or any other valid Mustache context value. They will be prepended to the context stack,
+ * // so they will be available in any template loaded by this Mustache instance.
+ * 'helpers' => array('i18n' => function ($text) {
+ * // do something translatey here...
+ * }),
+ *
+ * // An 'escape' callback, responsible for escaping double-mustache variables.
+ * 'escape' => function ($value) {
+ * return htmlspecialchars($buffer, ENT_COMPAT, 'UTF-8');
+ * },
+ *
+ * // Type argument for `htmlspecialchars`. Defaults to ENT_COMPAT. You may prefer ENT_QUOTES.
+ * 'entity_flags' => ENT_QUOTES,
+ *
+ * // Character set for `htmlspecialchars`. Defaults to 'UTF-8'. Use 'UTF-8'.
+ * 'charset' => 'ISO-8859-1',
+ *
+ * // A Mustache Logger instance. No logging will occur unless this is set. Using a PSR-3 compatible
+ * // logging library -- such as Monolog -- is highly recommended. A simple stream logger implementation is
+ * // available as well:
+ * 'logger' => new Mustache_Logger_StreamLogger('php://stderr'),
+ *
+ * // Only treat Closure instances and invokable classes as callable. If true, values like
+ * // `array('ClassName', 'methodName')` and `array($classInstance, 'methodName')`, which are traditionally
+ * // "callable" in PHP, are not called to resolve variables for interpolation or section contexts. This
+ * // helps protect against arbitrary code execution when user input is passed directly into the template.
+ * // This currently defaults to false, but will default to true in v3.0.
+ * 'strict_callables' => true,
+ *
+ * // Enable pragmas across all templates, regardless of the presence of pragma tags in the individual
+ * // templates.
+ * 'pragmas' => [Mustache_Engine::PRAGMA_FILTERS],
+ * );
+ *
+ * @throws Mustache_Exception_InvalidArgumentException If `escape` option is not callable
+ *
+ * @param array $options (default: array())
+ */
+ public function __construct(array $options = array())
+ {
+ if (isset($options['template_class_prefix'])) {
+ $this->templateClassPrefix = $options['template_class_prefix'];
+ }
+
+ if (isset($options['cache'])) {
+ $cache = $options['cache'];
+
+ if (is_string($cache)) {
+ $mode = isset($options['cache_file_mode']) ? $options['cache_file_mode'] : null;
+ $cache = new Mustache_Cache_FilesystemCache($cache, $mode);
+ }
+
+ $this->setCache($cache);
+ }
+
+ if (isset($options['cache_lambda_templates'])) {
+ $this->cacheLambdaTemplates = (bool) $options['cache_lambda_templates'];
+ }
+
+ if (isset($options['loader'])) {
+ $this->setLoader($options['loader']);
+ }
+
+ if (isset($options['partials_loader'])) {
+ $this->setPartialsLoader($options['partials_loader']);
+ }
+
+ if (isset($options['partials'])) {
+ $this->setPartials($options['partials']);
+ }
+
+ if (isset($options['helpers'])) {
+ $this->setHelpers($options['helpers']);
+ }
+
+ if (isset($options['escape'])) {
+ if (!is_callable($options['escape'])) {
+ throw new Mustache_Exception_InvalidArgumentException('Mustache Constructor "escape" option must be callable');
+ }
+
+ $this->escape = $options['escape'];
+ }
+
+ if (isset($options['entity_flags'])) {
+ $this->entityFlags = $options['entity_flags'];
+ }
+
+ if (isset($options['charset'])) {
+ $this->charset = $options['charset'];
+ }
+
+ if (isset($options['logger'])) {
+ $this->setLogger($options['logger']);
+ }
+
+ if (isset($options['strict_callables'])) {
+ $this->strictCallables = $options['strict_callables'];
+ }
+
+ if (isset($options['pragmas'])) {
+ foreach ($options['pragmas'] as $pragma) {
+ if (!isset(self::$knownPragmas[$pragma])) {
+ throw new Mustache_Exception_InvalidArgumentException(sprintf('Unknown pragma: "%s".', $pragma));
+ }
+ $this->pragmas[$pragma] = true;
+ }
+ }
+ }
+
+ /**
+ * Shortcut 'render' invocation.
+ *
+ * Equivalent to calling `$mustache->loadTemplate($template)->render($context);`
+ *
+ * @see Mustache_Engine::loadTemplate
+ * @see Mustache_Template::render
+ *
+ * @param string $template
+ * @param mixed $context (default: array())
+ *
+ * @return string Rendered template
+ */
+ public function render($template, $context = array())
+ {
+ return $this->loadTemplate($template)->render($context);
+ }
+
+ /**
+ * Get the current Mustache escape callback.
+ *
+ * @return callable|null
+ */
+ public function getEscape()
+ {
+ return $this->escape;
+ }
+
+ /**
+ * Get the current Mustache entitity type to escape.
+ *
+ * @return int
+ */
+ public function getEntityFlags()
+ {
+ return $this->entityFlags;
+ }
+
+ /**
+ * Get the current Mustache character set.
+ *
+ * @return string
+ */
+ public function getCharset()
+ {
+ return $this->charset;
+ }
+
+ /**
+ * Get the current globally enabled pragmas.
+ *
+ * @return array
+ */
+ public function getPragmas()
+ {
+ return array_keys($this->pragmas);
+ }
+
+ /**
+ * Set the Mustache template Loader instance.
+ *
+ * @param Mustache_Loader $loader
+ */
+ public function setLoader(Mustache_Loader $loader)
+ {
+ $this->loader = $loader;
+ }
+
+ /**
+ * Get the current Mustache template Loader instance.
+ *
+ * If no Loader instance has been explicitly specified, this method will instantiate and return
+ * a StringLoader instance.
+ *
+ * @return Mustache_Loader
+ */
+ public function getLoader()
+ {
+ if (!isset($this->loader)) {
+ $this->loader = new Mustache_Loader_StringLoader();
+ }
+
+ return $this->loader;
+ }
+
+ /**
+ * Set the Mustache partials Loader instance.
+ *
+ * @param Mustache_Loader $partialsLoader
+ */
+ public function setPartialsLoader(Mustache_Loader $partialsLoader)
+ {
+ $this->partialsLoader = $partialsLoader;
+ }
+
+ /**
+ * Get the current Mustache partials Loader instance.
+ *
+ * If no Loader instance has been explicitly specified, this method will instantiate and return
+ * an ArrayLoader instance.
+ *
+ * @return Mustache_Loader
+ */
+ public function getPartialsLoader()
+ {
+ if (!isset($this->partialsLoader)) {
+ $this->partialsLoader = new Mustache_Loader_ArrayLoader();
+ }
+
+ return $this->partialsLoader;
+ }
+
+ /**
+ * Set partials for the current partials Loader instance.
+ *
+ * @throws Mustache_Exception_RuntimeException If the current Loader instance is immutable
+ *
+ * @param array $partials (default: array())
+ */
+ public function setPartials(array $partials = array())
+ {
+ if (!isset($this->partialsLoader)) {
+ $this->partialsLoader = new Mustache_Loader_ArrayLoader();
+ }
+
+ if (!$this->partialsLoader instanceof Mustache_Loader_MutableLoader) {
+ throw new Mustache_Exception_RuntimeException('Unable to set partials on an immutable Mustache Loader instance');
+ }
+
+ $this->partialsLoader->setTemplates($partials);
+ }
+
+ /**
+ * Set an array of Mustache helpers.
+ *
+ * An array of 'helpers'. Helpers can be global variables or objects, closures (e.g. for higher order sections), or
+ * any other valid Mustache context value. They will be prepended to the context stack, so they will be available in
+ * any template loaded by this Mustache instance.
+ *
+ * @throws Mustache_Exception_InvalidArgumentException if $helpers is not an array or Traversable
+ *
+ * @param array|Traversable $helpers
+ */
+ public function setHelpers($helpers)
+ {
+ if (!is_array($helpers) && !$helpers instanceof Traversable) {
+ throw new Mustache_Exception_InvalidArgumentException('setHelpers expects an array of helpers');
+ }
+
+ $this->getHelpers()->clear();
+
+ foreach ($helpers as $name => $helper) {
+ $this->addHelper($name, $helper);
+ }
+ }
+
+ /**
+ * Get the current set of Mustache helpers.
+ *
+ * @see Mustache_Engine::setHelpers
+ *
+ * @return Mustache_HelperCollection
+ */
+ public function getHelpers()
+ {
+ if (!isset($this->helpers)) {
+ $this->helpers = new Mustache_HelperCollection();
+ }
+
+ return $this->helpers;
+ }
+
+ /**
+ * Add a new Mustache helper.
+ *
+ * @see Mustache_Engine::setHelpers
+ *
+ * @param string $name
+ * @param mixed $helper
+ */
+ public function addHelper($name, $helper)
+ {
+ $this->getHelpers()->add($name, $helper);
+ }
+
+ /**
+ * Get a Mustache helper by name.
+ *
+ * @see Mustache_Engine::setHelpers
+ *
+ * @param string $name
+ *
+ * @return mixed Helper
+ */
+ public function getHelper($name)
+ {
+ return $this->getHelpers()->get($name);
+ }
+
+ /**
+ * Check whether this Mustache instance has a helper.
+ *
+ * @see Mustache_Engine::setHelpers
+ *
+ * @param string $name
+ *
+ * @return bool True if the helper is present
+ */
+ public function hasHelper($name)
+ {
+ return $this->getHelpers()->has($name);
+ }
+
+ /**
+ * Remove a helper by name.
+ *
+ * @see Mustache_Engine::setHelpers
+ *
+ * @param string $name
+ */
+ public function removeHelper($name)
+ {
+ $this->getHelpers()->remove($name);
+ }
+
+ /**
+ * Set the Mustache Logger instance.
+ *
+ * @throws Mustache_Exception_InvalidArgumentException If logger is not an instance of Mustache_Logger or Psr\Log\LoggerInterface
+ *
+ * @param Mustache_Logger|Psr\Log\LoggerInterface $logger
+ */
+ public function setLogger($logger = null)
+ {
+ if ($logger !== null && !($logger instanceof Mustache_Logger || is_a($logger, 'Psr\\Log\\LoggerInterface'))) {
+ throw new Mustache_Exception_InvalidArgumentException('Expected an instance of Mustache_Logger or Psr\\Log\\LoggerInterface.');
+ }
+
+ if ($this->getCache()->getLogger() === null) {
+ $this->getCache()->setLogger($logger);
+ }
+
+ $this->logger = $logger;
+ }
+
+ /**
+ * Get the current Mustache Logger instance.
+ *
+ * @return Mustache_Logger|Psr\Log\LoggerInterface
+ */
+ public function getLogger()
+ {
+ return $this->logger;
+ }
+
+ /**
+ * Set the Mustache Tokenizer instance.
+ *
+ * @param Mustache_Tokenizer $tokenizer
+ */
+ public function setTokenizer(Mustache_Tokenizer $tokenizer)
+ {
+ $this->tokenizer = $tokenizer;
+ }
+
+ /**
+ * Get the current Mustache Tokenizer instance.
+ *
+ * If no Tokenizer instance has been explicitly specified, this method will instantiate and return a new one.
+ *
+ * @return Mustache_Tokenizer
+ */
+ public function getTokenizer()
+ {
+ if (!isset($this->tokenizer)) {
+ $this->tokenizer = new Mustache_Tokenizer();
+ }
+
+ return $this->tokenizer;
+ }
+
+ /**
+ * Set the Mustache Parser instance.
+ *
+ * @param Mustache_Parser $parser
+ */
+ public function setParser(Mustache_Parser $parser)
+ {
+ $this->parser = $parser;
+ }
+
+ /**
+ * Get the current Mustache Parser instance.
+ *
+ * If no Parser instance has been explicitly specified, this method will instantiate and return a new one.
+ *
+ * @return Mustache_Parser
+ */
+ public function getParser()
+ {
+ if (!isset($this->parser)) {
+ $this->parser = new Mustache_Parser();
+ }
+
+ return $this->parser;
+ }
+
+ /**
+ * Set the Mustache Compiler instance.
+ *
+ * @param Mustache_Compiler $compiler
+ */
+ public function setCompiler(Mustache_Compiler $compiler)
+ {
+ $this->compiler = $compiler;
+ }
+
+ /**
+ * Get the current Mustache Compiler instance.
+ *
+ * If no Compiler instance has been explicitly specified, this method will instantiate and return a new one.
+ *
+ * @return Mustache_Compiler
+ */
+ public function getCompiler()
+ {
+ if (!isset($this->compiler)) {
+ $this->compiler = new Mustache_Compiler();
+ }
+
+ return $this->compiler;
+ }
+
+ /**
+ * Set the Mustache Cache instance.
+ *
+ * @param Mustache_Cache $cache
+ */
+ public function setCache(Mustache_Cache $cache)
+ {
+ if (isset($this->logger) && $cache->getLogger() === null) {
+ $cache->setLogger($this->getLogger());
+ }
+
+ $this->cache = $cache;
+ }
+
+ /**
+ * Get the current Mustache Cache instance.
+ *
+ * If no Cache instance has been explicitly specified, this method will instantiate and return a new one.
+ *
+ * @return Mustache_Cache
+ */
+ public function getCache()
+ {
+ if (!isset($this->cache)) {
+ $this->setCache(new Mustache_Cache_NoopCache());
+ }
+
+ return $this->cache;
+ }
+
+ /**
+ * Get the current Lambda Cache instance.
+ *
+ * If 'cache_lambda_templates' is enabled, this is the default cache instance. Otherwise, it is a NoopCache.
+ *
+ * @see Mustache_Engine::getCache
+ *
+ * @return Mustache_Cache
+ */
+ protected function getLambdaCache()
+ {
+ if ($this->cacheLambdaTemplates) {
+ return $this->getCache();
+ }
+
+ if (!isset($this->lambdaCache)) {
+ $this->lambdaCache = new Mustache_Cache_NoopCache();
+ }
+
+ return $this->lambdaCache;
+ }
+
+ /**
+ * Helper method to generate a Mustache template class.
+ *
+ * @param string $source
+ *
+ * @return string Mustache Template class name
+ */
+ public function getTemplateClassName($source)
+ {
+ return $this->templateClassPrefix . md5(sprintf(
+ 'version:%s,escape:%s,entity_flags:%i,charset:%s,strict_callables:%s,pragmas:%s,source:%s',
+ self::VERSION,
+ isset($this->escape) ? 'custom' : 'default',
+ $this->entityFlags,
+ $this->charset,
+ $this->strictCallables ? 'true' : 'false',
+ implode(' ', $this->getPragmas()),
+ $source
+ ));
+ }
+
+ /**
+ * Load a Mustache Template by name.
+ *
+ * @param string $name
+ *
+ * @return Mustache_Template
+ */
+ public function loadTemplate($name)
+ {
+ return $this->loadSource($this->getLoader()->load($name));
+ }
+
+ /**
+ * Load a Mustache partial Template by name.
+ *
+ * This is a helper method used internally by Template instances for loading partial templates. You can most likely
+ * ignore it completely.
+ *
+ * @param string $name
+ *
+ * @return Mustache_Template
+ */
+ public function loadPartial($name)
+ {
+ try {
+ if (isset($this->partialsLoader)) {
+ $loader = $this->partialsLoader;
+ } elseif (isset($this->loader) && !$this->loader instanceof Mustache_Loader_StringLoader) {
+ $loader = $this->loader;
+ } else {
+ throw new Mustache_Exception_UnknownTemplateException($name);
+ }
+
+ return $this->loadSource($loader->load($name));
+ } catch (Mustache_Exception_UnknownTemplateException $e) {
+ // If the named partial cannot be found, log then return null.
+ $this->log(
+ Mustache_Logger::WARNING,
+ 'Partial not found: "{name}"',
+ array('name' => $e->getTemplateName())
+ );
+ }
+ }
+
+ /**
+ * Load a Mustache lambda Template by source.
+ *
+ * This is a helper method used by Template instances to generate subtemplates for Lambda sections. You can most
+ * likely ignore it completely.
+ *
+ * @param string $source
+ * @param string $delims (default: null)
+ *
+ * @return Mustache_Template
+ */
+ public function loadLambda($source, $delims = null)
+ {
+ if ($delims !== null) {
+ $source = $delims . "\n" . $source;
+ }
+
+ return $this->loadSource($source, $this->getLambdaCache());
+ }
+
+ /**
+ * Instantiate and return a Mustache Template instance by source.
+ *
+ * Optionally provide a Mustache_Cache instance. This is used internally by Mustache_Engine::loadLambda to respect
+ * the 'cache_lambda_templates' configuration option.
+ *
+ * @see Mustache_Engine::loadTemplate
+ * @see Mustache_Engine::loadPartial
+ * @see Mustache_Engine::loadLambda
+ *
+ * @param string $source
+ * @param Mustache_Cache $cache (default: null)
+ *
+ * @return Mustache_Template
+ */
+ private function loadSource($source, Mustache_Cache $cache = null)
+ {
+ $className = $this->getTemplateClassName($source);
+
+ if (!isset($this->templates[$className])) {
+ if ($cache === null) {
+ $cache = $this->getCache();
+ }
+
+ if (!class_exists($className, false)) {
+ if (!$cache->load($className)) {
+ $compiled = $this->compile($source);
+ $cache->cache($className, $compiled);
+ }
+ }
+
+ $this->log(
+ Mustache_Logger::DEBUG,
+ 'Instantiating template: "{className}"',
+ array('className' => $className)
+ );
+
+ $this->templates[$className] = new $className($this);
+ }
+
+ return $this->templates[$className];
+ }
+
+ /**
+ * Helper method to tokenize a Mustache template.
+ *
+ * @see Mustache_Tokenizer::scan
+ *
+ * @param string $source
+ *
+ * @return array Tokens
+ */
+ private function tokenize($source)
+ {
+ return $this->getTokenizer()->scan($source);
+ }
+
+ /**
+ * Helper method to parse a Mustache template.
+ *
+ * @see Mustache_Parser::parse
+ *
+ * @param string $source
+ *
+ * @return array Token tree
+ */
+ private function parse($source)
+ {
+ $parser = $this->getParser();
+ $parser->setPragmas($this->getPragmas());
+
+ return $parser->parse($this->tokenize($source));
+ }
+
+ /**
+ * Helper method to compile a Mustache template.
+ *
+ * @see Mustache_Compiler::compile
+ *
+ * @param string $source
+ *
+ * @return string generated Mustache template class code
+ */
+ private function compile($source)
+ {
+ $tree = $this->parse($source);
+ $name = $this->getTemplateClassName($source);
+
+ $this->log(
+ Mustache_Logger::INFO,
+ 'Compiling template to "{className}" class',
+ array('className' => $name)
+ );
+
+ $compiler = $this->getCompiler();
+ $compiler->setPragmas($this->getPragmas());
+
+ return $compiler->compile($source, $tree, $name, isset($this->escape), $this->charset, $this->strictCallables, $this->entityFlags);
+ }
+
+ /**
+ * Add a log record if logging is enabled.
+ *
+ * @param int $level The logging level
+ * @param string $message The log message
+ * @param array $context The log context
+ */
+ private function log($level, $message, array $context = array())
+ {
+ if (isset($this->logger)) {
+ $this->logger->log($level, $message, $context);
+ }
+ }
+}
diff --git a/vendor/mustache/mustache/src/Mustache/Exception.php b/vendor/mustache/mustache/src/Mustache/Exception.php
new file mode 100644
index 0000000..66bd6bd
--- /dev/null
+++ b/vendor/mustache/mustache/src/Mustache/Exception.php
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * A Mustache Exception interface.
+ */
+interface Mustache_Exception
+{
+ // This space intentionally left blank.
+}
diff --git a/vendor/mustache/mustache/src/Mustache/Exception/InvalidArgumentException.php b/vendor/mustache/mustache/src/Mustache/Exception/InvalidArgumentException.php
new file mode 100644
index 0000000..46b200c
--- /dev/null
+++ b/vendor/mustache/mustache/src/Mustache/Exception/InvalidArgumentException.php
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Invalid argument exception.
+ */
+class Mustache_Exception_InvalidArgumentException extends InvalidArgumentException implements Mustache_Exception
+{
+ // This space intentionally left blank.
+}
diff --git a/vendor/mustache/mustache/src/Mustache/Exception/LogicException.php b/vendor/mustache/mustache/src/Mustache/Exception/LogicException.php
new file mode 100644
index 0000000..8e75e7e
--- /dev/null
+++ b/vendor/mustache/mustache/src/Mustache/Exception/LogicException.php
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Logic exception.
+ */
+class Mustache_Exception_LogicException extends LogicException implements Mustache_Exception
+{
+ // This space intentionally left blank.
+}
diff --git a/vendor/mustache/mustache/src/Mustache/Exception/RuntimeException.php b/vendor/mustache/mustache/src/Mustache/Exception/RuntimeException.php
new file mode 100644
index 0000000..9a7b90b
--- /dev/null
+++ b/vendor/mustache/mustache/src/Mustache/Exception/RuntimeException.php
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Runtime exception.
+ */
+class Mustache_Exception_RuntimeException extends RuntimeException implements Mustache_Exception
+{
+ // This space intentionally left blank.
+}
diff --git a/vendor/mustache/mustache/src/Mustache/Exception/SyntaxException.php b/vendor/mustache/mustache/src/Mustache/Exception/SyntaxException.php
new file mode 100644
index 0000000..4fcb39d
--- /dev/null
+++ b/vendor/mustache/mustache/src/Mustache/Exception/SyntaxException.php
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Mustache syntax exception.
+ */
+class Mustache_Exception_SyntaxException extends LogicException implements Mustache_Exception
+{
+ protected $token;
+
+ /**
+ * @param string $msg
+ * @param array $token
+ * @param Exception $previous
+ */
+ public function __construct($msg, array $token, Exception $previous = null)
+ {
+ $this->token = $token;
+ if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
+ parent::__construct($msg, 0, $previous);
+ } else {
+ parent::__construct($msg);
+ }
+ }
+
+ /**
+ * @return array
+ */
+ public function getToken()
+ {
+ return $this->token;
+ }
+}
diff --git a/vendor/mustache/mustache/src/Mustache/Exception/UnknownFilterException.php b/vendor/mustache/mustache/src/Mustache/Exception/UnknownFilterException.php
new file mode 100644
index 0000000..44505e4
--- /dev/null
+++ b/vendor/mustache/mustache/src/Mustache/Exception/UnknownFilterException.php
@@ -0,0 +1,38 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Unknown filter exception.
+ */
+class Mustache_Exception_UnknownFilterException extends UnexpectedValueException implements Mustache_Exception
+{
+ protected $filterName;
+
+ /**
+ * @param string $filterName
+ * @param Exception $previous
+ */
+ public function __construct($filterName, Exception $previous = null)
+ {
+ $this->filterName = $filterName;
+ $message = sprintf('Unknown filter: %s', $filterName);
+ if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
+ parent::__construct($message, 0, $previous);
+ } else {
+ parent::__construct($message);
+ }
+ }
+
+ public function getFilterName()
+ {
+ return $this->filterName;
+ }
+}
diff --git a/vendor/mustache/mustache/src/Mustache/Exception/UnknownHelperException.php b/vendor/mustache/mustache/src/Mustache/Exception/UnknownHelperException.php
new file mode 100644
index 0000000..e1bc4d2
--- /dev/null
+++ b/vendor/mustache/mustache/src/Mustache/Exception/UnknownHelperException.php
@@ -0,0 +1,38 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Unknown helper exception.
+ */
+class Mustache_Exception_UnknownHelperException extends InvalidArgumentException implements Mustache_Exception
+{
+ protected $helperName;
+
+ /**
+ * @param string $helperName
+ * @param Exception $previous
+ */
+ public function __construct($helperName, Exception $previous = null)
+ {
+ $this->helperName = $helperName;
+ $message = sprintf('Unknown helper: %s', $helperName);
+ if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
+ parent::__construct($message, 0, $previous);
+ } else {
+ parent::__construct($message);
+ }
+ }
+
+ public function getHelperName()
+ {
+ return $this->helperName;
+ }
+}
diff --git a/vendor/mustache/mustache/src/Mustache/Exception/UnknownTemplateException.php b/vendor/mustache/mustache/src/Mustache/Exception/UnknownTemplateException.php
new file mode 100644
index 0000000..0c37796
--- /dev/null
+++ b/vendor/mustache/mustache/src/Mustache/Exception/UnknownTemplateException.php
@@ -0,0 +1,38 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Unknown template exception.
+ */
+class Mustache_Exception_UnknownTemplateException extends InvalidArgumentException implements Mustache_Exception
+{
+ protected $templateName;
+
+ /**
+ * @param string $templateName
+ * @param Exception $previous
+ */
+ public function __construct($templateName, Exception $previous = null)
+ {
+ $this->templateName = $templateName;
+ $message = sprintf('Unknown template: %s', $templateName);
+ if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
+ parent::__construct($message, 0, $previous);
+ } else {
+ parent::__construct($message);
+ }
+ }
+
+ public function getTemplateName()
+ {
+ return $this->templateName;
+ }
+}
diff --git a/vendor/mustache/mustache/src/Mustache/HelperCollection.php b/vendor/mustache/mustache/src/Mustache/HelperCollection.php
new file mode 100644
index 0000000..86c56b7
--- /dev/null
+++ b/vendor/mustache/mustache/src/Mustache/HelperCollection.php
@@ -0,0 +1,172 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * A collection of helpers for a Mustache instance.
+ */
+class Mustache_HelperCollection
+{
+ private $helpers = array();
+
+ /**
+ * Helper Collection constructor.
+ *
+ * Optionally accepts an array (or Traversable) of `$name => $helper` pairs.
+ *
+ * @throws Mustache_Exception_InvalidArgumentException if the $helpers argument isn't an array or Traversable
+ *
+ * @param array|Traversable $helpers (default: null)
+ */
+ public function __construct($helpers = null)
+ {
+ if ($helpers === null) {
+ return;
+ }
+
+ if (!is_array($helpers) && !$helpers instanceof Traversable) {
+ throw new Mustache_Exception_InvalidArgumentException('HelperCollection constructor expects an array of helpers');
+ }
+
+ foreach ($helpers as $name => $helper) {
+ $this->add($name, $helper);
+ }
+ }
+
+ /**
+ * Magic mutator.
+ *
+ * @see Mustache_HelperCollection::add
+ *
+ * @param string $name
+ * @param mixed $helper
+ */
+ public function __set($name, $helper)
+ {
+ $this->add($name, $helper);
+ }
+
+ /**
+ * Add a helper to this collection.
+ *
+ * @param string $name
+ * @param mixed $helper
+ */
+ public function add($name, $helper)
+ {
+ $this->helpers[$name] = $helper;
+ }
+
+ /**
+ * Magic accessor.
+ *
+ * @see Mustache_HelperCollection::get
+ *
+ * @param string $name
+ *
+ * @return mixed Helper
+ */
+ public function __get($name)
+ {
+ return $this->get($name);
+ }
+
+ /**
+ * Get a helper by name.
+ *
+ * @throws Mustache_Exception_UnknownHelperException If helper does not exist
+ *
+ * @param string $name
+ *
+ * @return mixed Helper
+ */
+ public function get($name)
+ {
+ if (!$this->has($name)) {
+ throw new Mustache_Exception_UnknownHelperException($name);
+ }
+
+ return $this->helpers[$name];
+ }
+
+ /**
+ * Magic isset().
+ *
+ * @see Mustache_HelperCollection::has
+ *
+ * @param string $name
+ *
+ * @return bool True if helper is present
+ */
+ public function __isset($name)
+ {
+ return $this->has($name);
+ }
+
+ /**
+ * Check whether a given helper is present in the collection.
+ *
+ * @param string $name
+ *
+ * @return bool True if helper is present
+ */
+ public function has($name)
+ {
+ return array_key_exists($name, $this->helpers);
+ }
+
+ /**
+ * Magic unset().
+ *
+ * @see Mustache_HelperCollection::remove
+ *
+ * @param string $name
+ */
+ public function __unset($name)
+ {
+ $this->remove($name);
+ }
+
+ /**
+ * Check whether a given helper is present in the collection.
+ *
+ * @throws Mustache_Exception_UnknownHelperException if the requested helper is not present
+ *
+ * @param string $name
+ */
+ public function remove($name)
+ {
+ if (!$this->has($name)) {
+ throw new Mustache_Exception_UnknownHelperException($name);
+ }
+
+ unset($this->helpers[$name]);
+ }
+
+ /**
+ * Clear the helper collection.
+ *
+ * Removes all helpers from this collection
+ */
+ public function clear()
+ {
+ $this->helpers = array();
+ }
+
+ /**
+ * Check whether the helper collection is empty.
+ *
+ * @return bool True if the collection is empty
+ */
+ public function isEmpty()
+ {
+ return empty($this->helpers);
+ }
+}
diff --git a/vendor/mustache/mustache/src/Mustache/LambdaHelper.php b/vendor/mustache/mustache/src/Mustache/LambdaHelper.php
new file mode 100644
index 0000000..1d203d5
--- /dev/null
+++ b/vendor/mustache/mustache/src/Mustache/LambdaHelper.php
@@ -0,0 +1,76 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Mustache Lambda Helper.
+ *
+ * Passed as the second argument to section lambdas (higher order sections),
+ * giving them access to a `render` method for rendering a string with the
+ * current context.
+ */
+class Mustache_LambdaHelper
+{
+ private $mustache;
+ private $context;
+ private $delims;
+
+ /**
+ * Mustache Lambda Helper constructor.
+ *
+ * @param Mustache_Engine $mustache Mustache engine instance
+ * @param Mustache_Context $context Rendering context
+ * @param string $delims Optional custom delimiters, in the format `{{= <% %> =}}`. (default: null)
+ */
+ public function __construct(Mustache_Engine $mustache, Mustache_Context $context, $delims = null)
+ {
+ $this->mustache = $mustache;
+ $this->context = $context;
+ $this->delims = $delims;
+ }
+
+ /**
+ * Render a string as a Mustache template with the current rendering context.
+ *
+ * @param string $string
+ *
+ * @return string Rendered template
+ */
+ public function render($string)
+ {
+ return $this->mustache
+ ->loadLambda((string) $string, $this->delims)
+ ->renderInternal($this->context);
+ }
+
+ /**
+ * Render a string as a Mustache template with the current rendering context.
+ *
+ * @param string $string
+ *
+ * @return string Rendered template
+ */
+ public function __invoke($string)
+ {
+ return $this->render($string);
+ }
+
+ /**
+ * Get a Lambda Helper with custom delimiters.
+ *
+ * @param string $delims Custom delimiters, in the format `{{= <% %> =}}`
+ *
+ * @return Mustache_LambdaHelper
+ */
+ public function withDelimiters($delims)
+ {
+ return new self($this->mustache, $this->context, $delims);
+ }
+}
diff --git a/vendor/mustache/mustache/src/Mustache/Loader.php b/vendor/mustache/mustache/src/Mustache/Loader.php
new file mode 100644
index 0000000..c5e1a19
--- /dev/null
+++ b/vendor/mustache/mustache/src/Mustache/Loader.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Mustache Template Loader interface.
+ */
+interface Mustache_Loader
+{
+ /**
+ * Load a Template by name.
+ *
+ * @throws Mustache_Exception_UnknownTemplateException If a template file is not found
+ *
+ * @param string $name
+ *
+ * @return string Mustache Template source
+ */
+ public function load($name);
+}
diff --git a/vendor/mustache/mustache/src/Mustache/Loader/ArrayLoader.php b/vendor/mustache/mustache/src/Mustache/Loader/ArrayLoader.php
new file mode 100644
index 0000000..c0d6a4d
--- /dev/null
+++ b/vendor/mustache/mustache/src/Mustache/Loader/ArrayLoader.php
@@ -0,0 +1,79 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Mustache Template array Loader implementation.
+ *
+ * An ArrayLoader instance loads Mustache Template source by name from an initial array:
+ *
+ * $loader = new ArrayLoader(
+ * 'foo' => '{{ bar }}',
+ * 'baz' => 'Hey {{ qux }}!'
+ * );
+ *
+ * $tpl = $loader->load('foo'); // '{{ bar }}'
+ *
+ * The ArrayLoader is used internally as a partials loader by Mustache_Engine instance when an array of partials
+ * is set. It can also be used as a quick-and-dirty Template loader.
+ */
+class Mustache_Loader_ArrayLoader implements Mustache_Loader, Mustache_Loader_MutableLoader
+{
+ private $templates;
+
+ /**
+ * ArrayLoader constructor.
+ *
+ * @param array $templates Associative array of Template source (default: array())
+ */
+ public function __construct(array $templates = array())
+ {
+ $this->templates = $templates;
+ }
+
+ /**
+ * Load a Template.
+ *
+ * @throws Mustache_Exception_UnknownTemplateException If a template file is not found
+ *
+ * @param string $name
+ *
+ * @return string Mustache Template source
+ */
+ public function load($name)
+ {
+ if (!isset($this->templates[$name])) {
+ throw new Mustache_Exception_UnknownTemplateException($name);
+ }
+
+ return $this->templates[$name];
+ }
+
+ /**
+ * Set an associative array of Template sources for this loader.
+ *
+ * @param array $templates
+ */
+ public function setTemplates(array $templates)
+ {
+ $this->templates = $templates;
+ }
+
+ /**
+ * Set a Template source by name.
+ *
+ * @param string $name
+ * @param string $template Mustache Template source
+ */
+ public function setTemplate($name, $template)
+ {
+ $this->templates[$name] = $template;
+ }
+}
diff --git a/vendor/mustache/mustache/src/Mustache/Loader/CascadingLoader.php b/vendor/mustache/mustache/src/Mustache/Loader/CascadingLoader.php
new file mode 100644
index 0000000..b4726bc
--- /dev/null
+++ b/vendor/mustache/mustache/src/Mustache/Loader/CascadingLoader.php
@@ -0,0 +1,69 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * A Mustache Template cascading loader implementation, which delegates to other
+ * Loader instances.
+ */
+class Mustache_Loader_CascadingLoader implements Mustache_Loader
+{
+ private $loaders;
+
+ /**
+ * Construct a CascadingLoader with an array of loaders.
+ *
+ * $loader = new Mustache_Loader_CascadingLoader(array(
+ * new Mustache_Loader_InlineLoader(__FILE__, __COMPILER_HALT_OFFSET__),
+ * new Mustache_Loader_FilesystemLoader(__DIR__.'/templates')
+ * ));
+ *
+ * @param Mustache_Loader[] $loaders
+ */
+ public function __construct(array $loaders = array())
+ {
+ $this->loaders = array();
+ foreach ($loaders as $loader) {
+ $this->addLoader($loader);
+ }
+ }
+
+ /**
+ * Add a Loader instance.
+ *
+ * @param Mustache_Loader $loader
+ */
+ public function addLoader(Mustache_Loader $loader)
+ {
+ $this->loaders[] = $loader;
+ }
+
+ /**
+ * Load a Template by name.
+ *
+ * @throws Mustache_Exception_UnknownTemplateException If a template file is not found
+ *
+ * @param string $name
+ *
+ * @return string Mustache Template source
+ */
+ public function load($name)
+ {
+ foreach ($this->loaders as $loader) {
+ try {
+ return $loader->load($name);
+ } catch (Mustache_Exception_UnknownTemplateException $e) {
+ // do nothing, check the next loader.
+ }
+ }
+
+ throw new Mustache_Exception_UnknownTemplateException($name);
+ }
+}
diff --git a/vendor/mustache/mustache/src/Mustache/Loader/FilesystemLoader.php b/vendor/mustache/mustache/src/Mustache/Loader/FilesystemLoader.php
new file mode 100644
index 0000000..a313751
--- /dev/null
+++ b/vendor/mustache/mustache/src/Mustache/Loader/FilesystemLoader.php
@@ -0,0 +1,135 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Mustache Template filesystem Loader implementation.
+ *
+ * A FilesystemLoader instance loads Mustache Template source from the filesystem by name:
+ *
+ * $loader = new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views');
+ * $tpl = $loader->load('foo'); // equivalent to `file_get_contents(dirname(__FILE__).'/views/foo.mustache');
+ *
+ * This is probably the most useful Mustache Loader implementation. It can be used for partials and normal Templates:
+ *
+ * $m = new Mustache(array(
+ * 'loader' => new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views'),
+ * 'partials_loader' => new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views/partials'),
+ * ));
+ */
+class Mustache_Loader_FilesystemLoader implements Mustache_Loader
+{
+ private $baseDir;
+ private $extension = '.mustache';
+ private $templates = array();
+
+ /**
+ * Mustache filesystem Loader constructor.
+ *
+ * Passing an $options array allows overriding certain Loader options during instantiation:
+ *
+ * $options = array(
+ * // The filename extension used for Mustache templates. Defaults to '.mustache'
+ * 'extension' => '.ms',
+ * );
+ *
+ * @throws Mustache_Exception_RuntimeException if $baseDir does not exist
+ *
+ * @param string $baseDir Base directory containing Mustache template files
+ * @param array $options Array of Loader options (default: array())
+ */
+ public function __construct($baseDir, array $options = array())
+ {
+ $this->baseDir = $baseDir;
+
+ if (strpos($this->baseDir, '://') === false) {
+ $this->baseDir = realpath($this->baseDir);
+ }
+
+ if ($this->shouldCheckPath() && !is_dir($this->baseDir)) {
+ throw new Mustache_Exception_RuntimeException(sprintf('FilesystemLoader baseDir must be a directory: %s', $baseDir));
+ }
+
+ if (array_key_exists('extension', $options)) {
+ if (empty($options['extension'])) {
+ $this->extension = '';
+ } else {
+ $this->extension = '.' . ltrim($options['extension'], '.');
+ }
+ }
+ }
+
+ /**
+ * Load a Template by name.
+ *
+ * $loader = new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views');
+ * $loader->load('admin/dashboard'); // loads "./views/admin/dashboard.mustache";
+ *
+ * @param string $name
+ *
+ * @return string Mustache Template source
+ */
+ public function load($name)
+ {
+ if (!isset($this->templates[$name])) {
+ $this->templates[$name] = $this->loadFile($name);
+ }
+
+ return $this->templates[$name];
+ }
+
+ /**
+ * Helper function for loading a Mustache file by name.
+ *
+ * @throws Mustache_Exception_UnknownTemplateException If a template file is not found
+ *
+ * @param string $name
+ *
+ * @return string Mustache Template source
+ */
+ protected function loadFile($name)
+ {
+ $fileName = $this->getFileName($name);
+
+ if ($this->shouldCheckPath() && !file_exists($fileName)) {
+ throw new Mustache_Exception_UnknownTemplateException($name);
+ }
+
+ return file_get_contents($fileName);
+ }
+
+ /**
+ * Helper function for getting a Mustache template file name.
+ *
+ * @param string $name
+ *
+ * @return string Template file name
+ */
+ protected function getFileName($name)
+ {
+ $fileName = $this->baseDir . '/' . $name;
+ if (substr($fileName, 0 - strlen($this->extension)) !== $this->extension) {
+ $fileName .= $this->extension;
+ }
+
+ return $fileName;
+ }
+
+ /**
+ * Only check if baseDir is a directory and requested templates are files if
+ * baseDir is using the filesystem stream wrapper.
+ *
+ * @return bool Whether to check `is_dir` and `file_exists`
+ */
+ protected function shouldCheckPath()
+ {
+ return strpos($this->baseDir, '://') === false || strpos($this->baseDir, 'file://') === 0;
+ }
+}
diff --git a/vendor/mustache/mustache/src/Mustache/Loader/InlineLoader.php b/vendor/mustache/mustache/src/Mustache/Loader/InlineLoader.php
new file mode 100644
index 0000000..f6d4b17
--- /dev/null
+++ b/vendor/mustache/mustache/src/Mustache/Loader/InlineLoader.php
@@ -0,0 +1,123 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * A Mustache Template loader for inline templates.
+ *
+ * With the InlineLoader, templates can be defined at the end of any PHP source
+ * file:
+ *
+ * $loader = new Mustache_Loader_InlineLoader(__FILE__, __COMPILER_HALT_OFFSET__);
+ * $hello = $loader->load('hello');
+ * $goodbye = $loader->load('goodbye');
+ *
+ * __halt_compiler();
+ *
+ * @@ hello
+ * Hello, {{ planet }}!
+ *
+ * @@ goodbye
+ * Goodbye, cruel {{ planet }}
+ *
+ * Templates are deliniated by lines containing only `@@ name`.
+ *
+ * The InlineLoader is well-suited to micro-frameworks such as Silex:
+ *
+ * $app->register(new MustacheServiceProvider, array(
+ * 'mustache.loader' => new Mustache_Loader_InlineLoader(__FILE__, __COMPILER_HALT_OFFSET__)
+ * ));
+ *
+ * $app->get('/{name}', function ($name) use ($app) {
+ * return $app['mustache']->render('hello', compact('name'));
+ * })
+ * ->value('name', 'world');
+ *
+ * // ...
+ *
+ * __halt_compiler();
+ *
+ * @@ hello
+ * Hello, {{ name }}!
+ */
+class Mustache_Loader_InlineLoader implements Mustache_Loader
+{
+ protected $fileName;
+ protected $offset;
+ protected $templates;
+
+ /**
+ * The InlineLoader requires a filename and offset to process templates.
+ *
+ * The magic constants `__FILE__` and `__COMPILER_HALT_OFFSET__` are usually
+ * perfectly suited to the job:
+ *
+ * $loader = new Mustache_Loader_InlineLoader(__FILE__, __COMPILER_HALT_OFFSET__);
+ *
+ * Note that this only works if the loader is instantiated inside the same
+ * file as the inline templates. If the templates are located in another
+ * file, it would be necessary to manually specify the filename and offset.
+ *
+ * @param string $fileName The file to parse for inline templates
+ * @param int $offset A string offset for the start of the templates.
+ * This usually coincides with the `__halt_compiler`
+ * call, and the `__COMPILER_HALT_OFFSET__`
+ */
+ public function __construct($fileName, $offset)
+ {
+ if (!is_file($fileName)) {
+ throw new Mustache_Exception_InvalidArgumentException('InlineLoader expects a valid filename.');
+ }
+
+ if (!is_int($offset) || $offset < 0) {
+ throw new Mustache_Exception_InvalidArgumentException('InlineLoader expects a valid file offset.');
+ }
+
+ $this->fileName = $fileName;
+ $this->offset = $offset;
+ }
+
+ /**
+ * Load a Template by name.
+ *
+ * @throws Mustache_Exception_UnknownTemplateException If a template file is not found
+ *
+ * @param string $name
+ *
+ * @return string Mustache Template source
+ */
+ public function load($name)
+ {
+ $this->loadTemplates();
+
+ if (!array_key_exists($name, $this->templates)) {
+ throw new Mustache_Exception_UnknownTemplateException($name);
+ }
+
+ return $this->templates[$name];
+ }
+
+ /**
+ * Parse and load templates from the end of a source file.
+ */
+ protected function loadTemplates()
+ {
+ if ($this->templates === null) {
+ $this->templates = array();
+ $data = file_get_contents($this->fileName, false, null, $this->offset);
+ foreach (preg_split("/^@@(?= [\w\d\.]+$)/m", $data, -1) as $chunk) {
+ if (trim($chunk)) {
+ list($name, $content) = explode("\n", $chunk, 2);
+ $this->templates[trim($name)] = trim($content);
+ }
+ }
+ }
+ }
+}
diff --git a/vendor/mustache/mustache/src/Mustache/Loader/MutableLoader.php b/vendor/mustache/mustache/src/Mustache/Loader/MutableLoader.php
new file mode 100644
index 0000000..f228d90
--- /dev/null
+++ b/vendor/mustache/mustache/src/Mustache/Loader/MutableLoader.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Mustache Template mutable Loader interface.
+ */
+interface Mustache_Loader_MutableLoader
+{
+ /**
+ * Set an associative array of Template sources for this loader.
+ *
+ * @param array $templates
+ */
+ public function setTemplates(array $templates);
+
+ /**
+ * Set a Template source by name.
+ *
+ * @param string $name
+ * @param string $template Mustache Template source
+ */
+ public function setTemplate($name, $template);
+}
diff --git a/vendor/mustache/mustache/src/Mustache/Loader/StringLoader.php b/vendor/mustache/mustache/src/Mustache/Loader/StringLoader.php
new file mode 100644
index 0000000..79b616b
--- /dev/null
+++ b/vendor/mustache/mustache/src/Mustache/Loader/StringLoader.php
@@ -0,0 +1,39 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Mustache Template string Loader implementation.
+ *
+ * A StringLoader instance is essentially a noop. It simply passes the 'name' argument straight through:
+ *
+ * $loader = new StringLoader;
+ * $tpl = $loader->load('{{ foo }}'); // '{{ foo }}'
+ *
+ * This is the default Template Loader instance used by Mustache:
+ *
+ * $m = new Mustache;
+ * $tpl = $m->loadTemplate('{{ foo }}');
+ * echo $tpl->render(array('foo' => 'bar')); // "bar"
+ */
+class Mustache_Loader_StringLoader implements Mustache_Loader
+{
+ /**
+ * Load a Template by source.
+ *
+ * @param string $name Mustache Template source
+ *
+ * @return string Mustache Template source
+ */
+ public function load($name)
+ {
+ return $name;
+ }
+}
diff --git a/vendor/mustache/mustache/src/Mustache/Logger.php b/vendor/mustache/mustache/src/Mustache/Logger.php
new file mode 100644
index 0000000..324a7ce
--- /dev/null
+++ b/vendor/mustache/mustache/src/Mustache/Logger.php
@@ -0,0 +1,126 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Describes a Mustache logger instance.
+ *
+ * This is identical to the Psr\Log\LoggerInterface.
+ *
+ * The message MUST be a string or object implementing __toString().
+ *
+ * The message MAY contain placeholders in the form: {foo} where foo
+ * will be replaced by the context data in key "foo".
+ *
+ * The context array can contain arbitrary data, the only assumption that
+ * can be made by implementors is that if an Exception instance is given
+ * to produce a stack trace, it MUST be in a key named "exception".
+ *
+ * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md
+ * for the full interface specification.
+ */
+interface Mustache_Logger
+{
+ /**
+ * Psr\Log compatible log levels.
+ */
+ const EMERGENCY = 'emergency';
+ const ALERT = 'alert';
+ const CRITICAL = 'critical';
+ const ERROR = 'error';
+ const WARNING = 'warning';
+ const NOTICE = 'notice';
+ const INFO = 'info';
+ const DEBUG = 'debug';
+
+ /**
+ * System is unusable.
+ *
+ * @param string $message
+ * @param array $context
+ */
+ public function emergency($message, array $context = array());
+
+ /**
+ * Action must be taken immediately.
+ *
+ * Example: Entire website down, database unavailable, etc. This should
+ * trigger the SMS alerts and wake you up.
+ *
+ * @param string $message
+ * @param array $context
+ */
+ public function alert($message, array $context = array());
+
+ /**
+ * Critical conditions.
+ *
+ * Example: Application component unavailable, unexpected exception.
+ *
+ * @param string $message
+ * @param array $context
+ */
+ public function critical($message, array $context = array());
+
+ /**
+ * Runtime errors that do not require immediate action but should typically
+ * be logged and monitored.
+ *
+ * @param string $message
+ * @param array $context
+ */
+ public function error($message, array $context = array());
+
+ /**
+ * Exceptional occurrences that are not errors.
+ *
+ * Example: Use of deprecated APIs, poor use of an API, undesirable things
+ * that are not necessarily wrong.
+ *
+ * @param string $message
+ * @param array $context
+ */
+ public function warning($message, array $context = array());
+
+ /**
+ * Normal but significant events.
+ *
+ * @param string $message
+ * @param array $context
+ */
+ public function notice($message, array $context = array());
+
+ /**
+ * Interesting events.
+ *
+ * Example: User logs in, SQL logs.
+ *
+ * @param string $message
+ * @param array $context
+ */
+ public function info($message, array $context = array());
+
+ /**
+ * Detailed debug information.
+ *
+ * @param string $message
+ * @param array $context
+ */
+ public function debug($message, array $context = array());
+
+ /**
+ * Logs with an arbitrary level.
+ *
+ * @param mixed $level
+ * @param string $message
+ * @param array $context
+ */
+ public function log($level, $message, array $context = array());
+}
diff --git a/vendor/mustache/mustache/src/Mustache/Logger/AbstractLogger.php b/vendor/mustache/mustache/src/Mustache/Logger/AbstractLogger.php
new file mode 100644
index 0000000..64bdf66
--- /dev/null
+++ b/vendor/mustache/mustache/src/Mustache/Logger/AbstractLogger.php
@@ -0,0 +1,121 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * This is a simple Logger implementation that other Loggers can inherit from.
+ *
+ * This is identical to the Psr\Log\AbstractLogger.
+ *
+ * It simply delegates all log-level-specific methods to the `log` method to
+ * reduce boilerplate code that a simple Logger that does the same thing with
+ * messages regardless of the error level has to implement.
+ */
+abstract class Mustache_Logger_AbstractLogger implements Mustache_Logger
+{
+ /**
+ * System is unusable.
+ *
+ * @param string $message
+ * @param array $context
+ */
+ public function emergency($message, array $context = array())
+ {
+ $this->log(Mustache_Logger::EMERGENCY, $message, $context);
+ }
+
+ /**
+ * Action must be taken immediately.
+ *
+ * Example: Entire website down, database unavailable, etc. This should
+ * trigger the SMS alerts and wake you up.
+ *
+ * @param string $message
+ * @param array $context
+ */
+ public function alert($message, array $context = array())
+ {
+ $this->log(Mustache_Logger::ALERT, $message, $context);
+ }
+
+ /**
+ * Critical conditions.
+ *
+ * Example: Application component unavailable, unexpected exception.
+ *
+ * @param string $message
+ * @param array $context
+ */
+ public function critical($message, array $context = array())
+ {
+ $this->log(Mustache_Logger::CRITICAL, $message, $context);
+ }
+
+ /**
+ * Runtime errors that do not require immediate action but should typically
+ * be logged and monitored.
+ *
+ * @param string $message
+ * @param array $context
+ */
+ public function error($message, array $context = array())
+ {
+ $this->log(Mustache_Logger::ERROR, $message, $context);
+ }
+
+ /**
+ * Exceptional occurrences that are not errors.
+ *
+ * Example: Use of deprecated APIs, poor use of an API, undesirable things
+ * that are not necessarily wrong.
+ *
+ * @param string $message
+ * @param array $context
+ */
+ public function warning($message, array $context = array())
+ {
+ $this->log(Mustache_Logger::WARNING, $message, $context);
+ }
+
+ /**
+ * Normal but significant events.
+ *
+ * @param string $message
+ * @param array $context
+ */
+ public function notice($message, array $context = array())
+ {
+ $this->log(Mustache_Logger::NOTICE, $message, $context);
+ }
+
+ /**
+ * Interesting events.
+ *
+ * Example: User logs in, SQL logs.
+ *
+ * @param string $message
+ * @param array $context
+ */
+ public function info($message, array $context = array())
+ {
+ $this->log(Mustache_Logger::INFO, $message, $context);
+ }
+
+ /**
+ * Detailed debug information.
+ *
+ * @param string $message
+ * @param array $context
+ */
+ public function debug($message, array $context = array())
+ {
+ $this->log(Mustache_Logger::DEBUG, $message, $context);
+ }
+}
diff --git a/vendor/mustache/mustache/src/Mustache/Logger/StreamLogger.php b/vendor/mustache/mustache/src/Mustache/Logger/StreamLogger.php
new file mode 100644
index 0000000..efb3231
--- /dev/null
+++ b/vendor/mustache/mustache/src/Mustache/Logger/StreamLogger.php
@@ -0,0 +1,194 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * A Mustache Stream Logger.
+ *
+ * The Stream Logger wraps a file resource instance (such as a stream) or a
+ * stream URL. All log messages over the threshold level will be appended to
+ * this stream.
+ *
+ * Hint: Try `php://stderr` for your stream URL.
+ */
+class Mustache_Logger_StreamLogger extends Mustache_Logger_AbstractLogger
+{
+ protected static $levels = array(
+ self::DEBUG => 100,
+ self::INFO => 200,
+ self::NOTICE => 250,
+ self::WARNING => 300,
+ self::ERROR => 400,
+ self::CRITICAL => 500,
+ self::ALERT => 550,
+ self::EMERGENCY => 600,
+ );
+
+ protected $level;
+ protected $stream = null;
+ protected $url = null;
+
+ /**
+ * @throws InvalidArgumentException if the logging level is unknown
+ *
+ * @param resource|string $stream Resource instance or URL
+ * @param int $level The minimum logging level at which this handler will be triggered
+ */
+ public function __construct($stream, $level = Mustache_Logger::ERROR)
+ {
+ $this->setLevel($level);
+
+ if (is_resource($stream)) {
+ $this->stream = $stream;
+ } else {
+ $this->url = $stream;
+ }
+ }
+
+ /**
+ * Close stream resources.
+ */
+ public function __destruct()
+ {
+ if (is_resource($this->stream)) {
+ fclose($this->stream);
+ }
+ }
+
+ /**
+ * Set the minimum logging level.
+ *
+ * @throws Mustache_Exception_InvalidArgumentException if the logging level is unknown
+ *
+ * @param int $level The minimum logging level which will be written
+ */
+ public function setLevel($level)
+ {
+ if (!array_key_exists($level, self::$levels)) {
+ throw new Mustache_Exception_InvalidArgumentException(sprintf('Unexpected logging level: %s', $level));
+ }
+
+ $this->level = $level;
+ }
+
+ /**
+ * Get the current minimum logging level.
+ *
+ * @return int
+ */
+ public function getLevel()
+ {
+ return $this->level;
+ }
+
+ /**
+ * Logs with an arbitrary level.
+ *
+ * @throws Mustache_Exception_InvalidArgumentException if the logging level is unknown
+ *
+ * @param mixed $level
+ * @param string $message
+ * @param array $context
+ */
+ public function log($level, $message, array $context = array())
+ {
+ if (!array_key_exists($level, self::$levels)) {
+ throw new Mustache_Exception_InvalidArgumentException(sprintf('Unexpected logging level: %s', $level));
+ }
+
+ if (self::$levels[$level] >= self::$levels[$this->level]) {
+ $this->writeLog($level, $message, $context);
+ }
+ }
+
+ /**
+ * Write a record to the log.
+ *
+ * @throws Mustache_Exception_LogicException If neither a stream resource nor url is present
+ * @throws Mustache_Exception_RuntimeException If the stream url cannot be opened
+ *
+ * @param int $level The logging level
+ * @param string $message The log message
+ * @param array $context The log context
+ */
+ protected function writeLog($level, $message, array $context = array())
+ {
+ if (!is_resource($this->stream)) {
+ if (!isset($this->url)) {
+ throw new Mustache_Exception_LogicException('Missing stream url, the stream can not be opened. This may be caused by a premature call to close().');
+ }
+
+ $this->stream = fopen($this->url, 'a');
+ if (!is_resource($this->stream)) {
+ // @codeCoverageIgnoreStart
+ throw new Mustache_Exception_RuntimeException(sprintf('The stream or file "%s" could not be opened.', $this->url));
+ // @codeCoverageIgnoreEnd
+ }
+ }
+
+ fwrite($this->stream, self::formatLine($level, $message, $context));
+ }
+
+ /**
+ * Gets the name of the logging level.
+ *
+ * @throws InvalidArgumentException if the logging level is unknown
+ *
+ * @param int $level
+ *
+ * @return string
+ */
+ protected static function getLevelName($level)
+ {
+ return strtoupper($level);
+ }
+
+ /**
+ * Format a log line for output.
+ *
+ * @param int $level The logging level
+ * @param string $message The log message
+ * @param array $context The log context
+ *
+ * @return string
+ */
+ protected static function formatLine($level, $message, array $context = array())
+ {
+ return sprintf(
+ "%s: %s\n",
+ self::getLevelName($level),
+ self::interpolateMessage($message, $context)
+ );
+ }
+
+ /**
+ * Interpolate context values into the message placeholders.
+ *
+ * @param string $message
+ * @param array $context
+ *
+ * @return string
+ */
+ protected static function interpolateMessage($message, array $context = array())
+ {
+ if (strpos($message, '{') === false) {
+ return $message;
+ }
+
+ // build a replacement array with braces around the context keys
+ $replace = array();
+ foreach ($context as $key => $val) {
+ $replace['{' . $key . '}'] = $val;
+ }
+
+ // interpolate replacement values into the the message and return
+ return strtr($message, $replace);
+ }
+}
diff --git a/vendor/mustache/mustache/src/Mustache/Parser.php b/vendor/mustache/mustache/src/Mustache/Parser.php
new file mode 100644
index 0000000..adefebd
--- /dev/null
+++ b/vendor/mustache/mustache/src/Mustache/Parser.php
@@ -0,0 +1,317 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Mustache Parser class.
+ *
+ * This class is responsible for turning a set of Mustache tokens into a parse tree.
+ */
+class Mustache_Parser
+{
+ private $lineNum;
+ private $lineTokens;
+ private $pragmas;
+ private $defaultPragmas = array();
+
+ private $pragmaFilters;
+ private $pragmaBlocks;
+
+ /**
+ * Process an array of Mustache tokens and convert them into a parse tree.
+ *
+ * @param array $tokens Set of Mustache tokens
+ *
+ * @return array Mustache token parse tree
+ */
+ public function parse(array $tokens = array())
+ {
+ $this->lineNum = -1;
+ $this->lineTokens = 0;
+ $this->pragmas = $this->defaultPragmas;
+
+ $this->pragmaFilters = isset($this->pragmas[Mustache_Engine::PRAGMA_FILTERS]);
+ $this->pragmaBlocks = isset($this->pragmas[Mustache_Engine::PRAGMA_BLOCKS]);
+
+ return $this->buildTree($tokens);
+ }
+
+ /**
+ * Enable pragmas across all templates, regardless of the presence of pragma
+ * tags in the individual templates.
+ *
+ * @internal Users should set global pragmas in Mustache_Engine, not here :)
+ *
+ * @param string[] $pragmas
+ */
+ public function setPragmas(array $pragmas)
+ {
+ $this->pragmas = array();
+ foreach ($pragmas as $pragma) {
+ $this->enablePragma($pragma);
+ }
+ $this->defaultPragmas = $this->pragmas;
+ }
+
+ /**
+ * Helper method for recursively building a parse tree.
+ *
+ * @throws Mustache_Exception_SyntaxException when nesting errors or mismatched section tags are encountered
+ *
+ * @param array &$tokens Set of Mustache tokens
+ * @param array $parent Parent token (default: null)
+ *
+ * @return array Mustache Token parse tree
+ */
+ private function buildTree(array &$tokens, array $parent = null)
+ {
+ $nodes = array();
+
+ while (!empty($tokens)) {
+ $token = array_shift($tokens);
+
+ if ($token[Mustache_Tokenizer::LINE] === $this->lineNum) {
+ $this->lineTokens++;
+ } else {
+ $this->lineNum = $token[Mustache_Tokenizer::LINE];
+ $this->lineTokens = 0;
+ }
+
+ if ($this->pragmaFilters && isset($token[Mustache_Tokenizer::NAME])) {
+ list($name, $filters) = $this->getNameAndFilters($token[Mustache_Tokenizer::NAME]);
+ if (!empty($filters)) {
+ $token[Mustache_Tokenizer::NAME] = $name;
+ $token[Mustache_Tokenizer::FILTERS] = $filters;
+ }
+ }
+
+ switch ($token[Mustache_Tokenizer::TYPE]) {
+ case Mustache_Tokenizer::T_DELIM_CHANGE:
+ $this->checkIfTokenIsAllowedInParent($parent, $token);
+ $this->clearStandaloneLines($nodes, $tokens);
+ break;
+
+ case Mustache_Tokenizer::T_SECTION:
+ case Mustache_Tokenizer::T_INVERTED:
+ $this->checkIfTokenIsAllowedInParent($parent, $token);
+ $this->clearStandaloneLines($nodes, $tokens);
+ $nodes[] = $this->buildTree($tokens, $token);
+ break;
+
+ case Mustache_Tokenizer::T_END_SECTION:
+ if (!isset($parent)) {
+ $msg = sprintf(
+ 'Unexpected closing tag: /%s on line %d',
+ $token[Mustache_Tokenizer::NAME],
+ $token[Mustache_Tokenizer::LINE]
+ );
+ throw new Mustache_Exception_SyntaxException($msg, $token);
+ }
+
+ if ($token[Mustache_Tokenizer::NAME] !== $parent[Mustache_Tokenizer::NAME]) {
+ $msg = sprintf(
+ 'Nesting error: %s (on line %d) vs. %s (on line %d)',
+ $parent[Mustache_Tokenizer::NAME],
+ $parent[Mustache_Tokenizer::LINE],
+ $token[Mustache_Tokenizer::NAME],
+ $token[Mustache_Tokenizer::LINE]
+ );
+ throw new Mustache_Exception_SyntaxException($msg, $token);
+ }
+
+ $this->clearStandaloneLines($nodes, $tokens);
+ $parent[Mustache_Tokenizer::END] = $token[Mustache_Tokenizer::INDEX];
+ $parent[Mustache_Tokenizer::NODES] = $nodes;
+
+ return $parent;
+
+ case Mustache_Tokenizer::T_PARTIAL:
+ $this->checkIfTokenIsAllowedInParent($parent, $token);
+ //store the whitespace prefix for laters!
+ if ($indent = $this->clearStandaloneLines($nodes, $tokens)) {
+ $token[Mustache_Tokenizer::INDENT] = $indent[Mustache_Tokenizer::VALUE];
+ }
+ $nodes[] = $token;
+ break;
+
+ case Mustache_Tokenizer::T_PARENT:
+ $this->checkIfTokenIsAllowedInParent($parent, $token);
+ $nodes[] = $this->buildTree($tokens, $token);
+ break;
+
+ case Mustache_Tokenizer::T_BLOCK_VAR:
+ if ($this->pragmaBlocks) {
+ // BLOCKS pragma is enabled, let's do this!
+ if ($parent[Mustache_Tokenizer::TYPE] === Mustache_Tokenizer::T_PARENT) {
+ $token[Mustache_Tokenizer::TYPE] = Mustache_Tokenizer::T_BLOCK_ARG;
+ }
+ $this->clearStandaloneLines($nodes, $tokens);
+ $nodes[] = $this->buildTree($tokens, $token);
+ } else {
+ // pretend this was just a normal "escaped" token...
+ $token[Mustache_Tokenizer::TYPE] = Mustache_Tokenizer::T_ESCAPED;
+ // TODO: figure out how to figure out if there was a space after this dollar:
+ $token[Mustache_Tokenizer::NAME] = '$' . $token[Mustache_Tokenizer::NAME];
+ $nodes[] = $token;
+ }
+ break;
+
+ case Mustache_Tokenizer::T_PRAGMA:
+ $this->enablePragma($token[Mustache_Tokenizer::NAME]);
+ // no break
+
+ case Mustache_Tokenizer::T_COMMENT:
+ $this->clearStandaloneLines($nodes, $tokens);
+ $nodes[] = $token;
+ break;
+
+ default:
+ $nodes[] = $token;
+ break;
+ }
+ }
+
+ if (isset($parent)) {
+ $msg = sprintf(
+ 'Missing closing tag: %s opened on line %d',
+ $parent[Mustache_Tokenizer::NAME],
+ $parent[Mustache_Tokenizer::LINE]
+ );
+ throw new Mustache_Exception_SyntaxException($msg, $parent);
+ }
+
+ return $nodes;
+ }
+
+ /**
+ * Clear standalone line tokens.
+ *
+ * Returns a whitespace token for indenting partials, if applicable.
+ *
+ * @param array $nodes Parsed nodes
+ * @param array $tokens Tokens to be parsed
+ *
+ * @return array|null Resulting indent token, if any
+ */
+ private function clearStandaloneLines(array &$nodes, array &$tokens)
+ {
+ if ($this->lineTokens > 1) {
+ // this is the third or later node on this line, so it can't be standalone
+ return;
+ }
+
+ $prev = null;
+ if ($this->lineTokens === 1) {
+ // this is the second node on this line, so it can't be standalone
+ // unless the previous node is whitespace.
+ if ($prev = end($nodes)) {
+ if (!$this->tokenIsWhitespace($prev)) {
+ return;
+ }
+ }
+ }
+
+ if ($next = reset($tokens)) {
+ // If we're on a new line, bail.
+ if ($next[Mustache_Tokenizer::LINE] !== $this->lineNum) {
+ return;
+ }
+
+ // If the next token isn't whitespace, bail.
+ if (!$this->tokenIsWhitespace($next)) {
+ return;
+ }
+
+ if (count($tokens) !== 1) {
+ // Unless it's the last token in the template, the next token
+ // must end in newline for this to be standalone.
+ if (substr($next[Mustache_Tokenizer::VALUE], -1) !== "\n") {
+ return;
+ }
+ }
+
+ // Discard the whitespace suffix
+ array_shift($tokens);
+ }
+
+ if ($prev) {
+ // Return the whitespace prefix, if any
+ return array_pop($nodes);
+ }
+ }
+
+ /**
+ * Check whether token is a whitespace token.
+ *
+ * True if token type is T_TEXT and value is all whitespace characters.
+ *
+ * @param array $token
+ *
+ * @return bool True if token is a whitespace token
+ */
+ private function tokenIsWhitespace(array $token)
+ {
+ if ($token[Mustache_Tokenizer::TYPE] === Mustache_Tokenizer::T_TEXT) {
+ return preg_match('/^\s*$/', $token[Mustache_Tokenizer::VALUE]);
+ }
+
+ return false;
+ }
+
+ /**
+ * Check whether a token is allowed inside a parent tag.
+ *
+ * @throws Mustache_Exception_SyntaxException if an invalid token is found inside a parent tag
+ *
+ * @param array|null $parent
+ * @param array $token
+ */
+ private function checkIfTokenIsAllowedInParent($parent, array $token)
+ {
+ if ($parent[Mustache_Tokenizer::TYPE] === Mustache_Tokenizer::T_PARENT) {
+ throw new Mustache_Exception_SyntaxException('Illegal content in < parent tag', $token);
+ }
+ }
+
+ /**
+ * Split a tag name into name and filters.
+ *
+ * @param string $name
+ *
+ * @return array [Tag name, Array of filters]
+ */
+ private function getNameAndFilters($name)
+ {
+ $filters = array_map('trim', explode('|', $name));
+ $name = array_shift($filters);
+
+ return array($name, $filters);
+ }
+
+ /**
+ * Enable a pragma.
+ *
+ * @param string $name
+ */
+ private function enablePragma($name)
+ {
+ $this->pragmas[$name] = true;
+
+ switch ($name) {
+ case Mustache_Engine::PRAGMA_BLOCKS:
+ $this->pragmaBlocks = true;
+ break;
+
+ case Mustache_Engine::PRAGMA_FILTERS:
+ $this->pragmaFilters = true;
+ break;
+ }
+ }
+}
diff --git a/vendor/mustache/mustache/src/Mustache/Template.php b/vendor/mustache/mustache/src/Mustache/Template.php
new file mode 100644
index 0000000..2b7771c
--- /dev/null
+++ b/vendor/mustache/mustache/src/Mustache/Template.php
@@ -0,0 +1,180 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Abstract Mustache Template class.
+ *
+ * @abstract
+ */
+abstract class Mustache_Template
+{
+ /**
+ * @var Mustache_Engine
+ */
+ protected $mustache;
+
+ /**
+ * @var bool
+ */
+ protected $strictCallables = false;
+
+ /**
+ * Mustache Template constructor.
+ *
+ * @param Mustache_Engine $mustache
+ */
+ public function __construct(Mustache_Engine $mustache)
+ {
+ $this->mustache = $mustache;
+ }
+
+ /**
+ * Mustache Template instances can be treated as a function and rendered by simply calling them.
+ *
+ * $m = new Mustache_Engine;
+ * $tpl = $m->loadTemplate('Hello, {{ name }}!');
+ * echo $tpl(array('name' => 'World')); // "Hello, World!"
+ *
+ * @see Mustache_Template::render
+ *
+ * @param mixed $context Array or object rendering context (default: array())
+ *
+ * @return string Rendered template
+ */
+ public function __invoke($context = array())
+ {
+ return $this->render($context);
+ }
+
+ /**
+ * Render this template given the rendering context.
+ *
+ * @param mixed $context Array or object rendering context (default: array())
+ *
+ * @return string Rendered template
+ */
+ public function render($context = array())
+ {
+ return $this->renderInternal(
+ $this->prepareContextStack($context)
+ );
+ }
+
+ /**
+ * Internal rendering method implemented by Mustache Template concrete subclasses.
+ *
+ * This is where the magic happens :)
+ *
+ * NOTE: This method is not part of the Mustache.php public API.
+ *
+ * @param Mustache_Context $context
+ * @param string $indent (default: '')
+ *
+ * @return string Rendered template
+ */
+ abstract public function renderInternal(Mustache_Context $context, $indent = '');
+
+ /**
+ * Tests whether a value should be iterated over (e.g. in a section context).
+ *
+ * In most languages there are two distinct array types: list and hash (or whatever you want to call them). Lists
+ * should be iterated, hashes should be treated as objects. Mustache follows this paradigm for Ruby, Javascript,
+ * Java, Python, etc.
+ *
+ * PHP, however, treats lists and hashes as one primitive type: array. So Mustache.php needs a way to distinguish
+ * between between a list of things (numeric, normalized array) and a set of variables to be used as section context
+ * (associative array). In other words, this will be iterated over:
+ *
+ * $items = array(
+ * array('name' => 'foo'),
+ * array('name' => 'bar'),
+ * array('name' => 'baz'),
+ * );
+ *
+ * ... but this will be used as a section context block:
+ *
+ * $items = array(
+ * 1 => array('name' => 'foo'),
+ * 'banana' => array('name' => 'bar'),
+ * 42 => array('name' => 'baz'),
+ * );
+ *
+ * @param mixed $value
+ *
+ * @return bool True if the value is 'iterable'
+ */
+ protected function isIterable($value)
+ {
+ switch (gettype($value)) {
+ case 'object':
+ return $value instanceof Traversable;
+
+ case 'array':
+ $i = 0;
+ foreach ($value as $k => $v) {
+ if ($k !== $i++) {
+ return false;
+ }
+ }
+
+ return true;
+
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Helper method to prepare the Context stack.
+ *
+ * Adds the Mustache HelperCollection to the stack's top context frame if helpers are present.
+ *
+ * @param mixed $context Optional first context frame (default: null)
+ *
+ * @return Mustache_Context
+ */
+ protected function prepareContextStack($context = null)
+ {
+ $stack = new Mustache_Context();
+
+ $helpers = $this->mustache->getHelpers();
+ if (!$helpers->isEmpty()) {
+ $stack->push($helpers);
+ }
+
+ if (!empty($context)) {
+ $stack->push($context);
+ }
+
+ return $stack;
+ }
+
+ /**
+ * Resolve a context value.
+ *
+ * Invoke the value if it is callable, otherwise return the value.
+ *
+ * @param mixed $value
+ * @param Mustache_Context $context
+ *
+ * @return string
+ */
+ protected function resolveValue($value, Mustache_Context $context)
+ {
+ if (($this->strictCallables ? is_object($value) : !is_string($value)) && is_callable($value)) {
+ return $this->mustache
+ ->loadLambda((string) call_user_func($value))
+ ->renderInternal($context);
+ }
+
+ return $value;
+ }
+}
diff --git a/vendor/mustache/mustache/src/Mustache/Tokenizer.php b/vendor/mustache/mustache/src/Mustache/Tokenizer.php
new file mode 100644
index 0000000..27e4d05
--- /dev/null
+++ b/vendor/mustache/mustache/src/Mustache/Tokenizer.php
@@ -0,0 +1,322 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Mustache Tokenizer class.
+ *
+ * This class is responsible for turning raw template source into a set of Mustache tokens.
+ */
+class Mustache_Tokenizer
+{
+ // Finite state machine states
+ const IN_TEXT = 0;
+ const IN_TAG_TYPE = 1;
+ const IN_TAG = 2;
+
+ // Token types
+ const T_SECTION = '#';
+ const T_INVERTED = '^';
+ const T_END_SECTION = '/';
+ const T_COMMENT = '!';
+ const T_PARTIAL = '>';
+ const T_PARENT = '<';
+ const T_DELIM_CHANGE = '=';
+ const T_ESCAPED = '_v';
+ const T_UNESCAPED = '{';
+ const T_UNESCAPED_2 = '&';
+ const T_TEXT = '_t';
+ const T_PRAGMA = '%';
+ const T_BLOCK_VAR = '$';
+ const T_BLOCK_ARG = '$arg';
+
+ // Valid token types
+ private static $tagTypes = array(
+ self::T_SECTION => true,
+ self::T_INVERTED => true,
+ self::T_END_SECTION => true,
+ self::T_COMMENT => true,
+ self::T_PARTIAL => true,
+ self::T_PARENT => true,
+ self::T_DELIM_CHANGE => true,
+ self::T_ESCAPED => true,
+ self::T_UNESCAPED => true,
+ self::T_UNESCAPED_2 => true,
+ self::T_PRAGMA => true,
+ self::T_BLOCK_VAR => true,
+ );
+
+ // Token properties
+ const TYPE = 'type';
+ const NAME = 'name';
+ const OTAG = 'otag';
+ const CTAG = 'ctag';
+ const LINE = 'line';
+ const INDEX = 'index';
+ const END = 'end';
+ const INDENT = 'indent';
+ const NODES = 'nodes';
+ const VALUE = 'value';
+ const FILTERS = 'filters';
+
+ private $state;
+ private $tagType;
+ private $buffer;
+ private $tokens;
+ private $seenTag;
+ private $line;
+ private $otag;
+ private $ctag;
+ private $otagLen;
+ private $ctagLen;
+
+ /**
+ * Scan and tokenize template source.
+ *
+ * @throws Mustache_Exception_SyntaxException when mismatched section tags are encountered
+ *
+ * @param string $text Mustache template source to tokenize
+ * @param string $delimiters Optionally, pass initial opening and closing delimiters (default: null)
+ *
+ * @return array Set of Mustache tokens
+ */
+ public function scan($text, $delimiters = null)
+ {
+ // Setting mbstring.func_overload makes things *really* slow.
+ // Let's do everyone a favor and scan this string as ASCII instead.
+ $encoding = null;
+ if (function_exists('mb_internal_encoding') && ini_get('mbstring.func_overload') & 2) {
+ $encoding = mb_internal_encoding();
+ mb_internal_encoding('ASCII');
+ }
+
+ $this->reset();
+
+ if ($delimiters = trim($delimiters)) {
+ $this->setDelimiters($delimiters);
+ }
+
+ $len = strlen($text);
+ for ($i = 0; $i < $len; $i++) {
+ switch ($this->state) {
+ case self::IN_TEXT:
+ if ($this->tagChange($this->otag, $this->otagLen, $text, $i)) {
+ $i--;
+ $this->flushBuffer();
+ $this->state = self::IN_TAG_TYPE;
+ } else {
+ $char = $text[$i];
+ $this->buffer .= $char;
+ if ($char === "\n") {
+ $this->flushBuffer();
+ $this->line++;
+ }
+ }
+ break;
+
+ case self::IN_TAG_TYPE:
+ $i += $this->otagLen - 1;
+ $char = $text[$i + 1];
+ if (isset(self::$tagTypes[$char])) {
+ $tag = $char;
+ $this->tagType = $tag;
+ } else {
+ $tag = null;
+ $this->tagType = self::T_ESCAPED;
+ }
+
+ if ($this->tagType === self::T_DELIM_CHANGE) {
+ $i = $this->changeDelimiters($text, $i);
+ $this->state = self::IN_TEXT;
+ } elseif ($this->tagType === self::T_PRAGMA) {
+ $i = $this->addPragma($text, $i);
+ $this->state = self::IN_TEXT;
+ } else {
+ if ($tag !== null) {
+ $i++;
+ }
+ $this->state = self::IN_TAG;
+ }
+ $this->seenTag = $i;
+ break;
+
+ default:
+ if ($this->tagChange($this->ctag, $this->ctagLen, $text, $i)) {
+ $token = array(
+ self::TYPE => $this->tagType,
+ self::NAME => trim($this->buffer),
+ self::OTAG => $this->otag,
+ self::CTAG => $this->ctag,
+ self::LINE => $this->line,
+ self::INDEX => ($this->tagType === self::T_END_SECTION) ? $this->seenTag - $this->otagLen : $i + $this->ctagLen,
+ );
+
+ if ($this->tagType === self::T_UNESCAPED) {
+ // Clean up `{{{ tripleStache }}}` style tokens.
+ if ($this->ctag === '}}') {
+ if (($i + 2 < $len) && $text[$i + 2] === '}') {
+ $i++;
+ } else {
+ $msg = sprintf(
+ 'Mismatched tag delimiters: %s on line %d',
+ $token[self::NAME],
+ $token[self::LINE]
+ );
+
+ throw new Mustache_Exception_SyntaxException($msg, $token);
+ }
+ } else {
+ $lastName = $token[self::NAME];
+ if (substr($lastName, -1) === '}') {
+ $token[self::NAME] = trim(substr($lastName, 0, -1));
+ } else {
+ $msg = sprintf(
+ 'Mismatched tag delimiters: %s on line %d',
+ $token[self::NAME],
+ $token[self::LINE]
+ );
+
+ throw new Mustache_Exception_SyntaxException($msg, $token);
+ }
+ }
+ }
+
+ $this->buffer = '';
+ $i += $this->ctagLen - 1;
+ $this->state = self::IN_TEXT;
+ $this->tokens[] = $token;
+ } else {
+ $this->buffer .= $text[$i];
+ }
+ break;
+ }
+ }
+
+ $this->flushBuffer();
+
+ // Restore the user's encoding...
+ if ($encoding) {
+ mb_internal_encoding($encoding);
+ }
+
+ return $this->tokens;
+ }
+
+ /**
+ * Helper function to reset tokenizer internal state.
+ */
+ private function reset()
+ {
+ $this->state = self::IN_TEXT;
+ $this->tagType = null;
+ $this->buffer = '';
+ $this->tokens = array();
+ $this->seenTag = false;
+ $this->line = 0;
+ $this->otag = '{{';
+ $this->ctag = '}}';
+ $this->otagLen = 2;
+ $this->ctagLen = 2;
+ }
+
+ /**
+ * Flush the current buffer to a token.
+ */
+ private function flushBuffer()
+ {
+ if (strlen($this->buffer) > 0) {
+ $this->tokens[] = array(
+ self::TYPE => self::T_TEXT,
+ self::LINE => $this->line,
+ self::VALUE => $this->buffer,
+ );
+ $this->buffer = '';
+ }
+ }
+
+ /**
+ * Change the current Mustache delimiters. Set new `otag` and `ctag` values.
+ *
+ * @param string $text Mustache template source
+ * @param int $index Current tokenizer index
+ *
+ * @return int New index value
+ */
+ private function changeDelimiters($text, $index)
+ {
+ $startIndex = strpos($text, '=', $index) + 1;
+ $close = '=' . $this->ctag;
+ $closeIndex = strpos($text, $close, $index);
+
+ $this->setDelimiters(trim(substr($text, $startIndex, $closeIndex - $startIndex)));
+
+ $this->tokens[] = array(
+ self::TYPE => self::T_DELIM_CHANGE,
+ self::LINE => $this->line,
+ );
+
+ return $closeIndex + strlen($close) - 1;
+ }
+
+ /**
+ * Set the current Mustache `otag` and `ctag` delimiters.
+ *
+ * @param string $delimiters
+ */
+ private function setDelimiters($delimiters)
+ {
+ list($otag, $ctag) = explode(' ', $delimiters);
+ $this->otag = $otag;
+ $this->ctag = $ctag;
+ $this->otagLen = strlen($otag);
+ $this->ctagLen = strlen($ctag);
+ }
+
+ /**
+ * Add pragma token.
+ *
+ * Pragmas are hoisted to the front of the template, so all pragma tokens
+ * will appear at the front of the token list.
+ *
+ * @param string $text
+ * @param int $index
+ *
+ * @return int New index value
+ */
+ private function addPragma($text, $index)
+ {
+ $end = strpos($text, $this->ctag, $index);
+ $pragma = trim(substr($text, $index + 2, $end - $index - 2));
+
+ // Pragmas are hoisted to the front of the template.
+ array_unshift($this->tokens, array(
+ self::TYPE => self::T_PRAGMA,
+ self::NAME => $pragma,
+ self::LINE => 0,
+ ));
+
+ return $end + $this->ctagLen - 1;
+ }
+
+ /**
+ * Test whether it's time to change tags.
+ *
+ * @param string $tag Current tag name
+ * @param int $tagLen Current tag name length
+ * @param string $text Mustache template source
+ * @param int $index Current tokenizer index
+ *
+ * @return bool True if this is a closing section tag
+ */
+ private function tagChange($tag, $tagLen, $text, $index)
+ {
+ return substr($text, $index, $tagLen) === $tag;
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/AutoloaderTest.php b/vendor/mustache/mustache/test/Mustache/Test/AutoloaderTest.php
new file mode 100644
index 0000000..40af5ee
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/AutoloaderTest.php
@@ -0,0 +1,36 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @group unit
+ */
+class Mustache_Test_AutoloaderTest extends PHPUnit_Framework_TestCase
+{
+ public function testRegister()
+ {
+ $loader = Mustache_Autoloader::register();
+ $this->assertTrue(spl_autoload_unregister(array($loader, 'autoload')));
+ }
+
+ public function testAutoloader()
+ {
+ $loader = new Mustache_Autoloader(dirname(__FILE__) . '/../../fixtures/autoloader');
+
+ $this->assertNull($loader->autoload('NonMustacheClass'));
+ $this->assertFalse(class_exists('NonMustacheClass'));
+
+ $loader->autoload('Mustache_Foo');
+ $this->assertTrue(class_exists('Mustache_Foo'));
+
+ $loader->autoload('\Mustache_Bar');
+ $this->assertTrue(class_exists('Mustache_Bar'));
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/Cache/AbstractCacheTest.php b/vendor/mustache/mustache/test/Mustache/Test/Cache/AbstractCacheTest.php
new file mode 100644
index 0000000..d977388
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/Cache/AbstractCacheTest.php
@@ -0,0 +1,44 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Mustache_Test_Cache_AbstractCacheTest extends PHPUnit_Framework_TestCase
+{
+ public function testGetSetLogger()
+ {
+ $cache = new CacheStub();
+ $logger = new Mustache_Logger_StreamLogger('php://stdout');
+ $cache->setLogger($logger);
+ $this->assertSame($logger, $cache->getLogger());
+ }
+
+ /**
+ * @expectedException Mustache_Exception_InvalidArgumentException
+ */
+ public function testSetLoggerThrowsExceptions()
+ {
+ $cache = new CacheStub();
+ $logger = new StdClass();
+ $cache->setLogger($logger);
+ }
+}
+
+class CacheStub extends Mustache_Cache_AbstractCache
+{
+ public function load($key)
+ {
+ // nada
+ }
+
+ public function cache($key, $value)
+ {
+ // nada
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/Cache/FilesystemCacheTest.php b/vendor/mustache/mustache/test/Mustache/Test/Cache/FilesystemCacheTest.php
new file mode 100644
index 0000000..2413125
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/Cache/FilesystemCacheTest.php
@@ -0,0 +1,36 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @group functional
+ */
+class Mustache_Test_Cache_FilesystemCacheTest extends Mustache_Test_FunctionalTestCase
+{
+ public function testCacheGetNone()
+ {
+ $key = 'some key';
+ $cache = new Mustache_Cache_FilesystemCache(self::$tempDir);
+ $loaded = $cache->load($key);
+
+ $this->assertFalse($loaded);
+ }
+
+ public function testCachePut()
+ {
+ $key = 'some key';
+ $value = '<?php /* some value */';
+ $cache = new Mustache_Cache_FilesystemCache(self::$tempDir);
+ $cache->cache($key, $value);
+ $loaded = $cache->load($key);
+
+ $this->assertTrue($loaded);
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/CompilerTest.php b/vendor/mustache/mustache/test/Mustache/Test/CompilerTest.php
new file mode 100644
index 0000000..725a82c
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/CompilerTest.php
@@ -0,0 +1,154 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @group unit
+ */
+class Mustache_Test_CompilerTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getCompileValues
+ */
+ public function testCompile($source, array $tree, $name, $customEscaper, $entityFlags, $charset, $expected)
+ {
+ $compiler = new Mustache_Compiler();
+
+ $compiled = $compiler->compile($source, $tree, $name, $customEscaper, $charset, false, $entityFlags);
+ foreach ($expected as $contains) {
+ $this->assertContains($contains, $compiled);
+ }
+ }
+
+ public function getCompileValues()
+ {
+ return array(
+ array('', array(), 'Banana', false, ENT_COMPAT, 'ISO-8859-1', array(
+ "\nclass Banana extends Mustache_Template",
+ 'return $buffer;',
+ )),
+
+ array('', array($this->createTextToken('TEXT')), 'Monkey', false, ENT_COMPAT, 'UTF-8', array(
+ "\nclass Monkey extends Mustache_Template",
+ '$buffer .= $indent . \'TEXT\';',
+ 'return $buffer;',
+ )),
+
+ array(
+ '',
+ array(
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
+ Mustache_Tokenizer::NAME => 'name',
+ ),
+ ),
+ 'Monkey',
+ true,
+ ENT_COMPAT,
+ 'ISO-8859-1',
+ array(
+ "\nclass Monkey extends Mustache_Template",
+ '$value = $this->resolveValue($context->find(\'name\'), $context);',
+ '$buffer .= $indent . call_user_func($this->mustache->getEscape(), $value);',
+ 'return $buffer;',
+ ),
+ ),
+
+ array(
+ '',
+ array(
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
+ Mustache_Tokenizer::NAME => 'name',
+ ),
+ ),
+ 'Monkey',
+ false,
+ ENT_COMPAT,
+ 'ISO-8859-1',
+ array(
+ "\nclass Monkey extends Mustache_Template",
+ '$value = $this->resolveValue($context->find(\'name\'), $context);',
+ '$buffer .= $indent . htmlspecialchars($value, ' . ENT_COMPAT . ', \'ISO-8859-1\');',
+ 'return $buffer;',
+ ),
+ ),
+
+ array(
+ '',
+ array(
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
+ Mustache_Tokenizer::NAME => 'name',
+ ),
+ ),
+ 'Monkey',
+ false,
+ ENT_QUOTES,
+ 'ISO-8859-1',
+ array(
+ "\nclass Monkey extends Mustache_Template",
+ '$value = $this->resolveValue($context->find(\'name\'), $context);',
+ '$buffer .= $indent . htmlspecialchars($value, ' . ENT_QUOTES . ', \'ISO-8859-1\');',
+ 'return $buffer;',
+ ),
+ ),
+
+ array(
+ '',
+ array(
+ $this->createTextToken("foo\n"),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
+ Mustache_Tokenizer::NAME => 'name',
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
+ Mustache_Tokenizer::NAME => '.',
+ ),
+ $this->createTextToken("'bar'"),
+ ),
+ 'Monkey',
+ false,
+ ENT_COMPAT,
+ 'UTF-8',
+ array(
+ "\nclass Monkey extends Mustache_Template",
+ "\$buffer .= \$indent . 'foo\n';",
+ '$value = $this->resolveValue($context->find(\'name\'), $context);',
+ '$buffer .= htmlspecialchars($value, ' . ENT_COMPAT . ', \'UTF-8\');',
+ '$value = $this->resolveValue($context->last(), $context);',
+ '$buffer .= \'\\\'bar\\\'\';',
+ 'return $buffer;',
+ ),
+ ),
+ );
+ }
+
+ /**
+ * @expectedException Mustache_Exception_SyntaxException
+ */
+ public function testCompilerThrowsSyntaxException()
+ {
+ $compiler = new Mustache_Compiler();
+ $compiler->compile('', array(array(Mustache_Tokenizer::TYPE => 'invalid')), 'SomeClass');
+ }
+
+ /**
+ * @param string $value
+ */
+ private function createTextToken($value)
+ {
+ return array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
+ Mustache_Tokenizer::VALUE => $value,
+ );
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/ContextTest.php b/vendor/mustache/mustache/test/Mustache/Test/ContextTest.php
new file mode 100644
index 0000000..029c2ba
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/ContextTest.php
@@ -0,0 +1,282 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @group unit
+ */
+class Mustache_Test_ContextTest extends PHPUnit_Framework_TestCase
+{
+ public function testConstructor()
+ {
+ $one = new Mustache_Context();
+ $this->assertSame('', $one->find('foo'));
+ $this->assertSame('', $one->find('bar'));
+
+ $two = new Mustache_Context(array(
+ 'foo' => 'FOO',
+ 'bar' => '<BAR>',
+ ));
+ $this->assertEquals('FOO', $two->find('foo'));
+ $this->assertEquals('<BAR>', $two->find('bar'));
+
+ $obj = new StdClass();
+ $obj->name = 'NAME';
+ $three = new Mustache_Context($obj);
+ $this->assertSame($obj, $three->last());
+ $this->assertEquals('NAME', $three->find('name'));
+ }
+
+ public function testPushPopAndLast()
+ {
+ $context = new Mustache_Context();
+ $this->assertFalse($context->last());
+
+ $dummy = new Mustache_Test_TestDummy();
+ $context->push($dummy);
+ $this->assertSame($dummy, $context->last());
+ $this->assertSame($dummy, $context->pop());
+ $this->assertFalse($context->last());
+
+ $obj = new StdClass();
+ $context->push($dummy);
+ $this->assertSame($dummy, $context->last());
+ $context->push($obj);
+ $this->assertSame($obj, $context->last());
+ $this->assertSame($obj, $context->pop());
+ $this->assertSame($dummy, $context->pop());
+ $this->assertFalse($context->last());
+ }
+
+ public function testFind()
+ {
+ $context = new Mustache_Context();
+
+ $dummy = new Mustache_Test_TestDummy();
+
+ $obj = new StdClass();
+ $obj->name = 'obj';
+
+ $arr = array(
+ 'a' => array('b' => array('c' => 'see')),
+ 'b' => 'bee',
+ );
+
+ $string = 'some arbitrary string';
+
+ $context->push($dummy);
+ $this->assertEquals('dummy', $context->find('name'));
+
+ $context->push($obj);
+ $this->assertEquals('obj', $context->find('name'));
+
+ $context->pop();
+ $this->assertEquals('dummy', $context->find('name'));
+
+ $dummy->name = 'dummyer';
+ $this->assertEquals('dummyer', $context->find('name'));
+
+ $context->push($arr);
+ $this->assertEquals('bee', $context->find('b'));
+ $this->assertEquals('see', $context->findDot('a.b.c'));
+
+ $dummy->name = 'dummy';
+
+ $context->push($string);
+ $this->assertSame($string, $context->last());
+ $this->assertEquals('dummy', $context->find('name'));
+ $this->assertEquals('see', $context->findDot('a.b.c'));
+ $this->assertEquals('<foo>', $context->find('foo'));
+ $this->assertEquals('<bar>', $context->findDot('bar'));
+ }
+
+ public function testArrayAccessFind()
+ {
+ $access = new Mustache_Test_TestArrayAccess(array(
+ 'a' => array('b' => array('c' => 'see')),
+ 'b' => 'bee',
+ ));
+
+ $context = new Mustache_Context($access);
+ $this->assertEquals('bee', $context->find('b'));
+ $this->assertEquals('see', $context->findDot('a.b.c'));
+ $this->assertEquals(null, $context->findDot('a.b.c.d'));
+ }
+
+ public function testAccessorPriority()
+ {
+ $context = new Mustache_Context(new Mustache_Test_AllTheThings());
+
+ $this->assertEquals('win', $context->find('foo'), 'method beats property');
+ $this->assertEquals('win', $context->find('bar'), 'property beats ArrayAccess');
+ $this->assertEquals('win', $context->find('baz'), 'ArrayAccess stands alone');
+ $this->assertEquals('win', $context->find('qux'), 'ArrayAccess beats private property');
+ }
+
+ public function testAnchoredDotNotation()
+ {
+ $context = new Mustache_Context();
+
+ $a = array(
+ 'name' => 'a',
+ 'number' => 1,
+ );
+
+ $b = array(
+ 'number' => 2,
+ 'child' => array(
+ 'name' => 'baby bee',
+ ),
+ );
+
+ $c = array(
+ 'name' => 'cee',
+ );
+
+ $context->push($a);
+ $this->assertEquals('a', $context->find('name'));
+ $this->assertEquals('', $context->findDot('.name'));
+ $this->assertEquals('a', $context->findAnchoredDot('.name'));
+ $this->assertEquals(1, $context->find('number'));
+ $this->assertEquals('', $context->findDot('.number'));
+ $this->assertEquals(1, $context->findAnchoredDot('.number'));
+
+ $context->push($b);
+ $this->assertEquals('a', $context->find('name'));
+ $this->assertEquals(2, $context->find('number'));
+ $this->assertEquals('', $context->findDot('.name'));
+ $this->assertEquals('', $context->findDot('.number'));
+ $this->assertEquals('', $context->findAnchoredDot('.name'));
+ $this->assertEquals(2, $context->findAnchoredDot('.number'));
+ $this->assertEquals('baby bee', $context->findDot('child.name'));
+ $this->assertEquals('', $context->findDot('.child.name'));
+ $this->assertEquals('baby bee', $context->findAnchoredDot('.child.name'));
+
+ $context->push($c);
+ $this->assertEquals('cee', $context->find('name'));
+ $this->assertEquals('', $context->findDot('.name'));
+ $this->assertEquals('cee', $context->findAnchoredDot('.name'));
+ $this->assertEquals(2, $context->find('number'));
+ $this->assertEquals('', $context->findDot('.number'));
+ $this->assertEquals('', $context->findAnchoredDot('.number'));
+ $this->assertEquals('baby bee', $context->findDot('child.name'));
+ $this->assertEquals('', $context->findDot('.child.name'));
+ $this->assertEquals('', $context->findAnchoredDot('.child.name'));
+ }
+
+ /**
+ * @expectedException Mustache_Exception_InvalidArgumentException
+ */
+ public function testAnchoredDotNotationThrowsExceptions()
+ {
+ $context = new Mustache_Context();
+ $context->push(array('a' => 1));
+ $context->findAnchoredDot('a');
+ }
+}
+
+class Mustache_Test_TestDummy
+{
+ public $name = 'dummy';
+
+ public function __invoke()
+ {
+ // nothing
+ }
+
+ public static function foo()
+ {
+ return '<foo>';
+ }
+
+ public function bar()
+ {
+ return '<bar>';
+ }
+}
+
+class Mustache_Test_TestArrayAccess implements ArrayAccess
+{
+ private $container = array();
+
+ public function __construct($array)
+ {
+ foreach ($array as $key => $value) {
+ $this->container[$key] = $value;
+ }
+ }
+
+ public function offsetSet($offset, $value)
+ {
+ if (is_null($offset)) {
+ $this->container[] = $value;
+ } else {
+ $this->container[$offset] = $value;
+ }
+ }
+
+ public function offsetExists($offset)
+ {
+ return isset($this->container[$offset]);
+ }
+
+ public function offsetUnset($offset)
+ {
+ unset($this->container[$offset]);
+ }
+
+ public function offsetGet($offset)
+ {
+ return isset($this->container[$offset]) ? $this->container[$offset] : null;
+ }
+}
+
+class Mustache_Test_AllTheThings implements ArrayAccess
+{
+ public $foo = 'fail';
+ public $bar = 'win';
+ private $qux = 'fail';
+
+ public function foo()
+ {
+ return 'win';
+ }
+
+ public function offsetExists($offset)
+ {
+ return true;
+ }
+
+ public function offsetGet($offset)
+ {
+ switch ($offset) {
+ case 'foo':
+ case 'bar':
+ return 'fail';
+
+ case 'baz':
+ case 'qux':
+ return 'win';
+
+ default:
+ return 'lolwhut';
+ }
+ }
+
+ public function offsetSet($offset, $value)
+ {
+ // nada
+ }
+
+ public function offsetUnset($offset)
+ {
+ // nada
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/EngineTest.php b/vendor/mustache/mustache/test/Mustache/Test/EngineTest.php
new file mode 100644
index 0000000..e8743d7
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/EngineTest.php
@@ -0,0 +1,361 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @group unit
+ */
+class Mustache_Test_EngineTest extends Mustache_Test_FunctionalTestCase
+{
+ public function testConstructor()
+ {
+ $logger = new Mustache_Logger_StreamLogger(tmpfile());
+ $loader = new Mustache_Loader_StringLoader();
+ $partialsLoader = new Mustache_Loader_ArrayLoader();
+ $mustache = new Mustache_Engine(array(
+ 'template_class_prefix' => '__whot__',
+ 'cache' => self::$tempDir,
+ 'cache_file_mode' => 777,
+ 'logger' => $logger,
+ 'loader' => $loader,
+ 'partials_loader' => $partialsLoader,
+ 'partials' => array(
+ 'foo' => '{{ foo }}',
+ ),
+ 'helpers' => array(
+ 'foo' => array($this, 'getFoo'),
+ 'bar' => 'BAR',
+ ),
+ 'escape' => 'strtoupper',
+ 'entity_flags' => ENT_QUOTES,
+ 'charset' => 'ISO-8859-1',
+ 'pragmas' => array(Mustache_Engine::PRAGMA_FILTERS),
+ ));
+
+ $this->assertSame($logger, $mustache->getLogger());
+ $this->assertSame($loader, $mustache->getLoader());
+ $this->assertSame($partialsLoader, $mustache->getPartialsLoader());
+ $this->assertEquals('{{ foo }}', $partialsLoader->load('foo'));
+ $this->assertContains('__whot__', $mustache->getTemplateClassName('{{ foo }}'));
+ $this->assertEquals('strtoupper', $mustache->getEscape());
+ $this->assertEquals(ENT_QUOTES, $mustache->getEntityFlags());
+ $this->assertEquals('ISO-8859-1', $mustache->getCharset());
+ $this->assertTrue($mustache->hasHelper('foo'));
+ $this->assertTrue($mustache->hasHelper('bar'));
+ $this->assertFalse($mustache->hasHelper('baz'));
+ $this->assertInstanceOf('Mustache_Cache_FilesystemCache', $mustache->getCache());
+ $this->assertEquals(array(Mustache_Engine::PRAGMA_FILTERS), $mustache->getPragmas());
+ }
+
+ public static function getFoo()
+ {
+ return 'foo';
+ }
+
+ public function testRender()
+ {
+ $source = '{{ foo }}';
+ $data = array('bar' => 'baz');
+ $output = 'TEH OUTPUT';
+
+ $template = $this->getMockBuilder('Mustache_Template')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $mustache = new MustacheStub();
+ $mustache->template = $template;
+
+ $template->expects($this->once())
+ ->method('render')
+ ->with($data)
+ ->will($this->returnValue($output));
+
+ $this->assertEquals($output, $mustache->render($source, $data));
+ $this->assertEquals($source, $mustache->source);
+ }
+
+ public function testSettingServices()
+ {
+ $logger = new Mustache_Logger_StreamLogger(tmpfile());
+ $loader = new Mustache_Loader_StringLoader();
+ $tokenizer = new Mustache_Tokenizer();
+ $parser = new Mustache_Parser();
+ $compiler = new Mustache_Compiler();
+ $mustache = new Mustache_Engine();
+ $cache = new Mustache_Cache_FilesystemCache(self::$tempDir);
+
+ $this->assertNotSame($logger, $mustache->getLogger());
+ $mustache->setLogger($logger);
+ $this->assertSame($logger, $mustache->getLogger());
+
+ $this->assertNotSame($loader, $mustache->getLoader());
+ $mustache->setLoader($loader);
+ $this->assertSame($loader, $mustache->getLoader());
+
+ $this->assertNotSame($loader, $mustache->getPartialsLoader());
+ $mustache->setPartialsLoader($loader);
+ $this->assertSame($loader, $mustache->getPartialsLoader());
+
+ $this->assertNotSame($tokenizer, $mustache->getTokenizer());
+ $mustache->setTokenizer($tokenizer);
+ $this->assertSame($tokenizer, $mustache->getTokenizer());
+
+ $this->assertNotSame($parser, $mustache->getParser());
+ $mustache->setParser($parser);
+ $this->assertSame($parser, $mustache->getParser());
+
+ $this->assertNotSame($compiler, $mustache->getCompiler());
+ $mustache->setCompiler($compiler);
+ $this->assertSame($compiler, $mustache->getCompiler());
+
+ $this->assertNotSame($cache, $mustache->getCache());
+ $mustache->setCache($cache);
+ $this->assertSame($cache, $mustache->getCache());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testCache()
+ {
+ $mustache = new Mustache_Engine(array(
+ 'template_class_prefix' => '__whot__',
+ 'cache' => self::$tempDir,
+ ));
+
+ $source = '{{ foo }}';
+ $template = $mustache->loadTemplate($source);
+ $className = $mustache->getTemplateClassName($source);
+
+ $this->assertInstanceOf($className, $template);
+ }
+
+ public function testLambdaCache()
+ {
+ $mustache = new MustacheStub(array(
+ 'cache' => self::$tempDir,
+ 'cache_lambda_templates' => true,
+ ));
+
+ $this->assertNotInstanceOf('Mustache_Cache_NoopCache', $mustache->getProtectedLambdaCache());
+ $this->assertSame($mustache->getCache(), $mustache->getProtectedLambdaCache());
+ }
+
+ public function testWithoutLambdaCache()
+ {
+ $mustache = new MustacheStub(array(
+ 'cache' => self::$tempDir,
+ ));
+
+ $this->assertInstanceOf('Mustache_Cache_NoopCache', $mustache->getProtectedLambdaCache());
+ $this->assertNotSame($mustache->getCache(), $mustache->getProtectedLambdaCache());
+ }
+
+ /**
+ * @expectedException Mustache_Exception_InvalidArgumentException
+ * @dataProvider getBadEscapers
+ */
+ public function testNonCallableEscapeThrowsException($escape)
+ {
+ new Mustache_Engine(array('escape' => $escape));
+ }
+
+ public function getBadEscapers()
+ {
+ return array(
+ array('nothing'),
+ array('foo', 'bar'),
+ );
+ }
+
+ /**
+ * @expectedException Mustache_Exception_RuntimeException
+ */
+ public function testImmutablePartialsLoadersThrowException()
+ {
+ $mustache = new Mustache_Engine(array(
+ 'partials_loader' => new Mustache_Loader_StringLoader(),
+ ));
+
+ $mustache->setPartials(array('foo' => '{{ foo }}'));
+ }
+
+ public function testMissingPartialsTreatedAsEmptyString()
+ {
+ $mustache = new Mustache_Engine(array(
+ 'partials_loader' => new Mustache_Loader_ArrayLoader(array(
+ 'foo' => 'FOO',
+ 'baz' => 'BAZ',
+ )),
+ ));
+
+ $this->assertEquals('FOOBAZ', $mustache->render('{{>foo}}{{>bar}}{{>baz}}', array()));
+ }
+
+ public function testHelpers()
+ {
+ $foo = array($this, 'getFoo');
+ $bar = 'BAR';
+ $mustache = new Mustache_Engine(array('helpers' => array(
+ 'foo' => $foo,
+ 'bar' => $bar,
+ )));
+
+ $helpers = $mustache->getHelpers();
+ $this->assertTrue($mustache->hasHelper('foo'));
+ $this->assertTrue($mustache->hasHelper('bar'));
+ $this->assertTrue($helpers->has('foo'));
+ $this->assertTrue($helpers->has('bar'));
+ $this->assertSame($foo, $mustache->getHelper('foo'));
+ $this->assertSame($bar, $mustache->getHelper('bar'));
+
+ $mustache->removeHelper('bar');
+ $this->assertFalse($mustache->hasHelper('bar'));
+ $mustache->addHelper('bar', $bar);
+ $this->assertSame($bar, $mustache->getHelper('bar'));
+
+ $baz = array($this, 'wrapWithUnderscores');
+ $this->assertFalse($mustache->hasHelper('baz'));
+ $this->assertFalse($helpers->has('baz'));
+
+ $mustache->addHelper('baz', $baz);
+ $this->assertTrue($mustache->hasHelper('baz'));
+ $this->assertTrue($helpers->has('baz'));
+
+ // ... and a functional test
+ $tpl = $mustache->loadTemplate('{{foo}} - {{bar}} - {{#baz}}qux{{/baz}}');
+ $this->assertEquals('foo - BAR - __qux__', $tpl->render());
+ $this->assertEquals('foo - BAR - __qux__', $tpl->render(array('qux' => "won't mess things up")));
+ }
+
+ public static function wrapWithUnderscores($text)
+ {
+ return '__' . $text . '__';
+ }
+
+ /**
+ * @expectedException Mustache_Exception_InvalidArgumentException
+ */
+ public function testSetHelpersThrowsExceptions()
+ {
+ $mustache = new Mustache_Engine();
+ $mustache->setHelpers('monkeymonkeymonkey');
+ }
+
+ /**
+ * @expectedException Mustache_Exception_InvalidArgumentException
+ */
+ public function testSetLoggerThrowsExceptions()
+ {
+ $mustache = new Mustache_Engine();
+ $mustache->setLogger(new StdClass());
+ }
+
+ public function testLoadPartialCascading()
+ {
+ $loader = new Mustache_Loader_ArrayLoader(array(
+ 'foo' => 'FOO',
+ ));
+
+ $mustache = new Mustache_Engine(array('loader' => $loader));
+
+ $tpl = $mustache->loadTemplate('foo');
+
+ $this->assertSame($tpl, $mustache->loadPartial('foo'));
+
+ $mustache->setPartials(array(
+ 'foo' => 'f00',
+ ));
+
+ // setting partials overrides the default template loading fallback.
+ $this->assertNotSame($tpl, $mustache->loadPartial('foo'));
+
+ // but it didn't overwrite the original template loader templates.
+ $this->assertSame($tpl, $mustache->loadTemplate('foo'));
+ }
+
+ public function testPartialLoadFailLogging()
+ {
+ $name = tempnam(sys_get_temp_dir(), 'mustache-test');
+ $mustache = new Mustache_Engine(array(
+ 'logger' => new Mustache_Logger_StreamLogger($name, Mustache_Logger::WARNING),
+ 'partials' => array(
+ 'foo' => 'FOO',
+ 'bar' => 'BAR',
+ ),
+ ));
+
+ $result = $mustache->render('{{> foo }}{{> bar }}{{> baz }}', array());
+ $this->assertEquals('FOOBAR', $result);
+
+ $this->assertContains('WARNING: Partial not found: "baz"', file_get_contents($name));
+ }
+
+ public function testCacheWarningLogging()
+ {
+ list($name, $mustache) = $this->getLoggedMustache(Mustache_Logger::WARNING);
+ $mustache->render('{{ foo }}', array('foo' => 'FOO'));
+ $this->assertContains('WARNING: Template cache disabled, evaluating', file_get_contents($name));
+ }
+
+ public function testLoggingIsNotTooAnnoying()
+ {
+ list($name, $mustache) = $this->getLoggedMustache();
+ $mustache->render('{{ foo }}{{> bar }}', array('foo' => 'FOO'));
+ $this->assertEmpty(file_get_contents($name));
+ }
+
+ public function testVerboseLoggingIsVerbose()
+ {
+ list($name, $mustache) = $this->getLoggedMustache(Mustache_Logger::DEBUG);
+ $mustache->render('{{ foo }}{{> bar }}', array('foo' => 'FOO'));
+ $log = file_get_contents($name);
+ $this->assertContains('DEBUG: Instantiating template: ', $log);
+ $this->assertContains('WARNING: Partial not found: "bar"', $log);
+ }
+
+ /**
+ * @expectedException Mustache_Exception_InvalidArgumentException
+ */
+ public function testUnknownPragmaThrowsException()
+ {
+ new Mustache_Engine(array(
+ 'pragmas' => array('UNKNOWN'),
+ ));
+ }
+
+ private function getLoggedMustache($level = Mustache_Logger::ERROR)
+ {
+ $name = tempnam(sys_get_temp_dir(), 'mustache-test');
+ $mustache = new Mustache_Engine(array(
+ 'logger' => new Mustache_Logger_StreamLogger($name, $level),
+ ));
+
+ return array($name, $mustache);
+ }
+}
+
+class MustacheStub extends Mustache_Engine
+{
+ public $source;
+ public $template;
+
+ public function loadTemplate($source)
+ {
+ $this->source = $source;
+
+ return $this->template;
+ }
+
+ public function getProtectedLambdaCache()
+ {
+ return $this->getLambdaCache();
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/Exception/SyntaxExceptionTest.php b/vendor/mustache/mustache/test/Mustache/Test/Exception/SyntaxExceptionTest.php
new file mode 100644
index 0000000..3f6b2e4
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/Exception/SyntaxExceptionTest.php
@@ -0,0 +1,39 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Mustache_Test_Exception_SyntaxExceptionTest extends PHPUnit_Framework_TestCase
+{
+ public function testInstance()
+ {
+ $e = new Mustache_Exception_SyntaxException('whot', array('is' => 'this'));
+ $this->assertTrue($e instanceof LogicException);
+ $this->assertTrue($e instanceof Mustache_Exception);
+ }
+
+ public function testGetToken()
+ {
+ $token = array(Mustache_Tokenizer::TYPE => 'whatever');
+ $e = new Mustache_Exception_SyntaxException('ignore this', $token);
+ $this->assertEquals($token, $e->getToken());
+ }
+
+ public function testPrevious()
+ {
+ if (version_compare(PHP_VERSION, '5.3.0', '<')) {
+ $this->markTestSkipped('Exception chaining requires at least PHP 5.3');
+ }
+
+ $previous = new Exception();
+ $e = new Mustache_Exception_SyntaxException('foo', array(), $previous);
+
+ $this->assertSame($previous, $e->getPrevious());
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/Exception/UnknownFilterExceptionTest.php b/vendor/mustache/mustache/test/Mustache/Test/Exception/UnknownFilterExceptionTest.php
new file mode 100644
index 0000000..049c842
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/Exception/UnknownFilterExceptionTest.php
@@ -0,0 +1,44 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Mustache_Test_Exception_UnknownFilterExceptionTest extends PHPUnit_Framework_TestCase
+{
+ public function testInstance()
+ {
+ $e = new Mustache_Exception_UnknownFilterException('bacon');
+ $this->assertTrue($e instanceof UnexpectedValueException);
+ $this->assertTrue($e instanceof Mustache_Exception);
+ }
+
+ public function testMessage()
+ {
+ $e = new Mustache_Exception_UnknownFilterException('sausage');
+ $this->assertEquals('Unknown filter: sausage', $e->getMessage());
+ }
+
+ public function testGetFilterName()
+ {
+ $e = new Mustache_Exception_UnknownFilterException('eggs');
+ $this->assertEquals('eggs', $e->getFilterName());
+ }
+
+ public function testPrevious()
+ {
+ if (version_compare(PHP_VERSION, '5.3.0', '<')) {
+ $this->markTestSkipped('Exception chaining requires at least PHP 5.3');
+ }
+
+ $previous = new Exception();
+ $e = new Mustache_Exception_UnknownFilterException('foo', $previous);
+
+ $this->assertSame($previous, $e->getPrevious());
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/Exception/UnknownHelperExceptionTest.php b/vendor/mustache/mustache/test/Mustache/Test/Exception/UnknownHelperExceptionTest.php
new file mode 100644
index 0000000..b1682cd
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/Exception/UnknownHelperExceptionTest.php
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Mustache_Test_Exception_UnknownHelperExceptionTest extends PHPUnit_Framework_TestCase
+{
+ public function testInstance()
+ {
+ $e = new Mustache_Exception_UnknownHelperException('alpha');
+ $this->assertTrue($e instanceof InvalidArgumentException);
+ $this->assertTrue($e instanceof Mustache_Exception);
+ }
+
+ public function testMessage()
+ {
+ $e = new Mustache_Exception_UnknownHelperException('beta');
+ $this->assertEquals('Unknown helper: beta', $e->getMessage());
+ }
+
+ public function testGetHelperName()
+ {
+ $e = new Mustache_Exception_UnknownHelperException('gamma');
+ $this->assertEquals('gamma', $e->getHelperName());
+ }
+
+ public function testPrevious()
+ {
+ if (version_compare(PHP_VERSION, '5.3.0', '<')) {
+ $this->markTestSkipped('Exception chaining requires at least PHP 5.3');
+ }
+
+ $previous = new Exception();
+ $e = new Mustache_Exception_UnknownHelperException('foo', $previous);
+ $this->assertSame($previous, $e->getPrevious());
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/Exception/UnknownTemplateExceptionTest.php b/vendor/mustache/mustache/test/Mustache/Test/Exception/UnknownTemplateExceptionTest.php
new file mode 100644
index 0000000..2452749
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/Exception/UnknownTemplateExceptionTest.php
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Mustache_Test_Exception_UnknownTemplateExceptionTest extends PHPUnit_Framework_TestCase
+{
+ public function testInstance()
+ {
+ $e = new Mustache_Exception_UnknownTemplateException('mario');
+ $this->assertTrue($e instanceof InvalidArgumentException);
+ $this->assertTrue($e instanceof Mustache_Exception);
+ }
+
+ public function testMessage()
+ {
+ $e = new Mustache_Exception_UnknownTemplateException('luigi');
+ $this->assertEquals('Unknown template: luigi', $e->getMessage());
+ }
+
+ public function testGetTemplateName()
+ {
+ $e = new Mustache_Exception_UnknownTemplateException('yoshi');
+ $this->assertEquals('yoshi', $e->getTemplateName());
+ }
+
+ public function testPrevious()
+ {
+ if (version_compare(PHP_VERSION, '5.3.0', '<')) {
+ $this->markTestSkipped('Exception chaining requires at least PHP 5.3');
+ }
+
+ $previous = new Exception();
+ $e = new Mustache_Exception_UnknownTemplateException('foo', $previous);
+ $this->assertSame($previous, $e->getPrevious());
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/FiveThree/Functional/ClosureQuirksTest.php b/vendor/mustache/mustache/test/Mustache/Test/FiveThree/Functional/ClosureQuirksTest.php
new file mode 100644
index 0000000..c997a1d
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/FiveThree/Functional/ClosureQuirksTest.php
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @group lambdas
+ * @group functional
+ */
+class Mustache_Test_FiveThree_Functional_ClosureQuirksTest extends PHPUnit_Framework_TestCase
+{
+ private $mustache;
+
+ public function setUp()
+ {
+ $this->mustache = new Mustache_Engine();
+ }
+
+ public function testClosuresDontLikeItWhenYouTouchTheirProperties()
+ {
+ $tpl = $this->mustache->loadTemplate('{{ foo.bar }}');
+ $this->assertEquals('', $tpl->render(array('foo' => function () {
+ return 'FOO';
+ })));
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/FiveThree/Functional/EngineTest.php b/vendor/mustache/mustache/test/Mustache/Test/FiveThree/Functional/EngineTest.php
new file mode 100644
index 0000000..3ed70c7
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/FiveThree/Functional/EngineTest.php
@@ -0,0 +1,50 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @group pragmas
+ * @group functional
+ */
+class Mustache_Test_FiveThree_Functional_EngineTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider pragmaData
+ */
+ public function testPragmasConstructorOption($pragmas, $helpers, $data, $tpl, $expect)
+ {
+ $mustache = new Mustache_Engine(array(
+ 'pragmas' => $pragmas,
+ 'helpers' => $helpers,
+ ));
+
+ $this->assertEquals($expect, $mustache->render($tpl, $data));
+ }
+
+ public function pragmaData()
+ {
+ $helpers = array(
+ 'longdate' => function (\DateTime $value) {
+ return $value->format('Y-m-d h:m:s');
+ },
+ );
+
+ $data = array(
+ 'date' => new DateTime('1/1/2000', new DateTimeZone('UTC')),
+ );
+
+ $tpl = '{{ date | longdate }}';
+
+ return array(
+ array(array(Mustache_Engine::PRAGMA_FILTERS), $helpers, $data, $tpl, '2000-01-01 12:01:00'),
+ array(array(), $helpers, $data, $tpl, ''),
+ );
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/FiveThree/Functional/FiltersTest.php b/vendor/mustache/mustache/test/Mustache/Test/FiveThree/Functional/FiltersTest.php
new file mode 100644
index 0000000..7adc663
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/FiveThree/Functional/FiltersTest.php
@@ -0,0 +1,187 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @group filters
+ * @group functional
+ */
+class Mustache_Test_FiveThree_Functional_FiltersTest extends PHPUnit_Framework_TestCase
+{
+ private $mustache;
+
+ public function setUp()
+ {
+ $this->mustache = new Mustache_Engine();
+ }
+
+ /**
+ * @dataProvider singleFilterData
+ */
+ public function testSingleFilter($tpl, $helpers, $data, $expect)
+ {
+ $this->mustache->setHelpers($helpers);
+ $this->assertEquals($expect, $this->mustache->render($tpl, $data));
+ }
+
+ public function singleFilterData()
+ {
+ $helpers = array(
+ 'longdate' => function (\DateTime $value) {
+ return $value->format('Y-m-d h:m:s');
+ },
+ 'echo' => function ($value) {
+ return array($value, $value, $value);
+ },
+ );
+
+ return array(
+ array(
+ '{{% FILTERS }}{{ date | longdate }}',
+ $helpers,
+ (object) array('date' => new DateTime('1/1/2000', new DateTimeZone('UTC'))),
+ '2000-01-01 12:01:00',
+ ),
+
+ array(
+ '{{% FILTERS }}{{# word | echo }}{{ . }}!{{/ word | echo }}',
+ $helpers,
+ array('word' => 'bacon'),
+ 'bacon!bacon!bacon!',
+ ),
+ );
+ }
+
+ public function testChainedFilters()
+ {
+ $tpl = $this->mustache->loadTemplate('{{% FILTERS }}{{ date | longdate | withbrackets }}');
+
+ $this->mustache->addHelper('longdate', function (\DateTime $value) {
+ return $value->format('Y-m-d h:m:s');
+ });
+
+ $this->mustache->addHelper('withbrackets', function ($value) {
+ return sprintf('[[%s]]', $value);
+ });
+
+ $foo = new \StdClass();
+ $foo->date = new DateTime('1/1/2000', new DateTimeZone('UTC'));
+
+ $this->assertEquals('[[2000-01-01 12:01:00]]', $tpl->render($foo));
+ }
+
+ const CHAINED_SECTION_FILTERS_TPL = <<<'EOS'
+{{% FILTERS }}
+{{# word | echo | with_index }}
+{{ key }}: {{ value }}
+{{/ word | echo | with_index }}
+EOS;
+
+ public function testChainedSectionFilters()
+ {
+ $tpl = $this->mustache->loadTemplate(self::CHAINED_SECTION_FILTERS_TPL);
+
+ $this->mustache->addHelper('echo', function ($value) {
+ return array($value, $value, $value);
+ });
+
+ $this->mustache->addHelper('with_index', function ($value) {
+ return array_map(function ($k, $v) {
+ return array(
+ 'key' => $k,
+ 'value' => $v,
+ );
+ }, array_keys($value), $value);
+ });
+
+ $this->assertEquals("0: bacon\n1: bacon\n2: bacon\n", $tpl->render(array('word' => 'bacon')));
+ }
+
+ /**
+ * @dataProvider interpolateFirstData
+ */
+ public function testInterpolateFirst($tpl, $data, $expect)
+ {
+ $this->assertEquals($expect, $this->mustache->render($tpl, $data));
+ }
+
+ public function interpolateFirstData()
+ {
+ $data = array(
+ 'foo' => 'FOO',
+ 'bar' => function ($value) {
+ return ($value === 'FOO') ? 'win!' : 'fail :(';
+ },
+ );
+
+ return array(
+ array('{{% FILTERS }}{{ foo | bar }}', $data, 'win!'),
+ array('{{% FILTERS }}{{# foo | bar }}{{ . }}{{/ foo | bar }}', $data, 'win!'),
+ );
+ }
+
+ /**
+ * @expectedException Mustache_Exception_UnknownFilterException
+ * @dataProvider brokenPipeData
+ */
+ public function testThrowsExceptionForBrokenPipes($tpl, $data)
+ {
+ $this->mustache->render($tpl, $data);
+ }
+
+ public function brokenPipeData()
+ {
+ return array(
+ array('{{% FILTERS }}{{ foo | bar }}', array()),
+ array('{{% FILTERS }}{{ foo | bar }}', array('foo' => 'FOO')),
+ array('{{% FILTERS }}{{ foo | bar }}', array('foo' => 'FOO', 'bar' => 'BAR')),
+ array('{{% FILTERS }}{{ foo | bar }}', array('foo' => 'FOO', 'bar' => array(1, 2))),
+ array('{{% FILTERS }}{{ foo | bar | baz }}', array('foo' => 'FOO', 'bar' => function () {
+ return 'BAR';
+ })),
+ array('{{% FILTERS }}{{ foo | bar | baz }}', array('foo' => 'FOO', 'baz' => function () {
+ return 'BAZ';
+ })),
+ array('{{% FILTERS }}{{ foo | bar | baz }}', array('bar' => function () {
+ return 'BAR';
+ })),
+ array('{{% FILTERS }}{{ foo | bar | baz }}', array('baz' => function () {
+ return 'BAZ';
+ })),
+ array('{{% FILTERS }}{{ foo | bar.baz }}', array('foo' => 'FOO', 'bar' => function () {
+ return 'BAR';
+ }, 'baz' => function () {
+ return 'BAZ';
+ })),
+
+ array('{{% FILTERS }}{{# foo | bar }}{{ . }}{{/ foo | bar }}', array()),
+ array('{{% FILTERS }}{{# foo | bar }}{{ . }}{{/ foo | bar }}', array('foo' => 'FOO')),
+ array('{{% FILTERS }}{{# foo | bar }}{{ . }}{{/ foo | bar }}', array('foo' => 'FOO', 'bar' => 'BAR')),
+ array('{{% FILTERS }}{{# foo | bar }}{{ . }}{{/ foo | bar }}', array('foo' => 'FOO', 'bar' => array(1, 2))),
+ array('{{% FILTERS }}{{# foo | bar | baz }}{{ . }}{{/ foo | bar | baz }}', array('foo' => 'FOO', 'bar' => function () {
+ return 'BAR';
+ })),
+ array('{{% FILTERS }}{{# foo | bar | baz }}{{ . }}{{/ foo | bar | baz }}', array('foo' => 'FOO', 'baz' => function () {
+ return 'BAZ';
+ })),
+ array('{{% FILTERS }}{{# foo | bar | baz }}{{ . }}{{/ foo | bar | baz }}', array('bar' => function () {
+ return 'BAR';
+ })),
+ array('{{% FILTERS }}{{# foo | bar | baz }}{{ . }}{{/ foo | bar | baz }}', array('baz' => function () {
+ return 'BAZ';
+ })),
+ array('{{% FILTERS }}{{# foo | bar.baz }}{{ . }}{{/ foo | bar.baz }}', array('foo' => 'FOO', 'bar' => function () {
+ return 'BAR';
+ }, 'baz' => function () {
+ return 'BAZ';
+ })),
+ );
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/FiveThree/Functional/HigherOrderSectionsTest.php b/vendor/mustache/mustache/test/Mustache/Test/FiveThree/Functional/HigherOrderSectionsTest.php
new file mode 100644
index 0000000..f926fdf
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/FiveThree/Functional/HigherOrderSectionsTest.php
@@ -0,0 +1,77 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @group lambdas
+ * @group functional
+ */
+class Mustache_Test_FiveThree_Functional_HigherOrderSectionsTest extends PHPUnit_Framework_TestCase
+{
+ private $mustache;
+
+ public function setUp()
+ {
+ $this->mustache = new Mustache_Engine();
+ }
+
+ public function testAnonymousFunctionSectionCallback()
+ {
+ $tpl = $this->mustache->loadTemplate('{{#wrapper}}{{name}}{{/wrapper}}');
+
+ $foo = new Mustache_Test_FiveThree_Functional_Foo();
+ $foo->name = 'Mario';
+ $foo->wrapper = function ($text) {
+ return sprintf('<div class="anonymous">%s</div>', $text);
+ };
+
+ $this->assertEquals(sprintf('<div class="anonymous">%s</div>', $foo->name), $tpl->render($foo));
+ }
+
+ public function testSectionCallback()
+ {
+ $one = $this->mustache->loadTemplate('{{name}}');
+ $two = $this->mustache->loadTemplate('{{#wrap}}{{name}}{{/wrap}}');
+
+ $foo = new Mustache_Test_FiveThree_Functional_Foo();
+ $foo->name = 'Luigi';
+
+ $this->assertEquals($foo->name, $one->render($foo));
+ $this->assertEquals(sprintf('<em>%s</em>', $foo->name), $two->render($foo));
+ }
+
+ public function testViewArrayAnonymousSectionCallback()
+ {
+ $tpl = $this->mustache->loadTemplate('{{#wrap}}{{name}}{{/wrap}}');
+
+ $data = array(
+ 'name' => 'Bob',
+ 'wrap' => function ($text) {
+ return sprintf('[[%s]]', $text);
+ },
+ );
+
+ $this->assertEquals(sprintf('[[%s]]', $data['name']), $tpl->render($data));
+ }
+}
+
+class Mustache_Test_FiveThree_Functional_Foo
+{
+ public $name = 'Justin';
+ public $lorem = 'Lorem ipsum dolor sit amet,';
+ public $wrap;
+
+ public function __construct()
+ {
+ $this->wrap = function ($text) {
+ return sprintf('<em>%s</em>', $text);
+ };
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/FiveThree/Functional/LambdaHelperTest.php b/vendor/mustache/mustache/test/Mustache/Test/FiveThree/Functional/LambdaHelperTest.php
new file mode 100644
index 0000000..c67957e
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/FiveThree/Functional/LambdaHelperTest.php
@@ -0,0 +1,67 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @group lambdas
+ * @group functional
+ */
+class Mustache_Test_FiveThree_Functional_LambdaHelperTest extends PHPUnit_Framework_TestCase
+{
+ private $mustache;
+
+ public function setUp()
+ {
+ $this->mustache = new Mustache_Engine();
+ }
+
+ public function testSectionLambdaHelper()
+ {
+ $one = $this->mustache->loadTemplate('{{name}}');
+ $two = $this->mustache->loadTemplate('{{#lambda}}{{name}}{{/lambda}}');
+
+ $foo = new StdClass();
+ $foo->name = 'Mario';
+ $foo->lambda = function ($text, $mustache) {
+ return strtoupper($mustache->render($text));
+ };
+
+ $this->assertEquals('Mario', $one->render($foo));
+ $this->assertEquals('MARIO', $two->render($foo));
+ }
+
+ public function testSectionLambdaHelperRespectsDelimiterChanges()
+ {
+ $tpl = $this->mustache->loadTemplate("{{=<% %>=}}\n<%# bang %><% value %><%/ bang %>");
+
+ $data = new StdClass();
+ $data->value = 'hello world';
+ $data->bang = function ($text, $mustache) {
+ return $mustache->render($text) . '!';
+ };
+
+ $this->assertEquals('hello world!', $tpl->render($data));
+ }
+
+ public function testLambdaHelperIsInvokable()
+ {
+ $one = $this->mustache->loadTemplate('{{name}}');
+ $two = $this->mustache->loadTemplate('{{#lambda}}{{name}}{{/lambda}}');
+
+ $foo = new StdClass();
+ $foo->name = 'Mario';
+ $foo->lambda = function ($text, $render) {
+ return strtoupper($render($text));
+ };
+
+ $this->assertEquals('Mario', $one->render($foo));
+ $this->assertEquals('MARIO', $two->render($foo));
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/FiveThree/Functional/MustacheSpecTest.php b/vendor/mustache/mustache/test/Mustache/Test/FiveThree/Functional/MustacheSpecTest.php
new file mode 100644
index 0000000..d72686d
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/FiveThree/Functional/MustacheSpecTest.php
@@ -0,0 +1,68 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * A PHPUnit test case wrapping the Mustache Spec.
+ *
+ * @group mustache-spec
+ * @group functional
+ */
+class Mustache_Test_FiveThree_Functional_MustacheSpecTest extends Mustache_Test_SpecTestCase
+{
+ /**
+ * For some reason data providers can't mark tests skipped, so this test exists
+ * simply to provide a 'skipped' test if the `spec` submodule isn't initialized.
+ */
+ public function testSpecInitialized()
+ {
+ if (!file_exists(dirname(__FILE__) . '/../../../../../vendor/spec/specs/')) {
+ $this->markTestSkipped('Mustache spec submodule not initialized: run "git submodule update --init"');
+ }
+ }
+
+ /**
+ * @group lambdas
+ * @dataProvider loadLambdasSpec
+ */
+ public function testLambdasSpec($desc, $source, $partials, $data, $expected)
+ {
+ $template = self::loadTemplate($source, $partials);
+ $this->assertEquals($expected, $template($this->prepareLambdasSpec($data)), $desc);
+ }
+
+ public function loadLambdasSpec()
+ {
+ return $this->loadSpec('~lambdas');
+ }
+
+ /**
+ * Extract and lambdafy any 'lambda' values found in the $data array.
+ */
+ private function prepareLambdasSpec($data)
+ {
+ foreach ($data as $key => $val) {
+ if ($key === 'lambda') {
+ if (!isset($val['php'])) {
+ $this->markTestSkipped(sprintf('PHP lambda test not implemented for this test.'));
+ }
+
+ $func = $val['php'];
+ $data[$key] = function ($text = null) use ($func) {
+ return eval($func);
+ };
+ } elseif (is_array($val)) {
+ $data[$key] = $this->prepareLambdasSpec($val);
+ }
+ }
+
+ return $data;
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/FiveThree/Functional/PartialLambdaIndentTest.php b/vendor/mustache/mustache/test/Mustache/Test/FiveThree/Functional/PartialLambdaIndentTest.php
new file mode 100644
index 0000000..605003c
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/FiveThree/Functional/PartialLambdaIndentTest.php
@@ -0,0 +1,94 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @group lambdas
+ * @group functional
+ */
+class Mustache_Test_FiveThree_Functional_PartialLambdaIndentTest extends PHPUnit_Framework_TestCase
+{
+ public function testLambdasInsidePartialsAreIndentedProperly()
+ {
+ $src = <<<'EOS'
+<fieldset>
+ {{> input }}
+</fieldset>
+
+EOS;
+ $partial = <<<'EOS'
+<input placeholder="{{# _t }}Enter your name{{/ _t }}">
+
+EOS;
+
+ $expected = <<<'EOS'
+<fieldset>
+ <input placeholder="ENTER YOUR NAME">
+</fieldset>
+
+EOS;
+
+ $m = new Mustache_Engine(array(
+ 'partials' => array('input' => $partial),
+ ));
+
+ $tpl = $m->loadTemplate($src);
+
+ $data = new Mustache_Test_FiveThree_Functional_ClassWithLambda();
+ $this->assertEquals($expected, $tpl->render($data));
+ }
+
+ public function testLambdaInterpolationsInsidePartialsAreIndentedProperly()
+ {
+ $src = <<<'EOS'
+<fieldset>
+ {{> input }}
+</fieldset>
+
+EOS;
+ $partial = <<<'EOS'
+<input placeholder="{{ placeholder }}">
+
+EOS;
+
+ $expected = <<<'EOS'
+<fieldset>
+ <input placeholder="Enter your name">
+</fieldset>
+
+EOS;
+
+ $m = new Mustache_Engine(array(
+ 'partials' => array('input' => $partial),
+ ));
+
+ $tpl = $m->loadTemplate($src);
+
+ $data = new Mustache_Test_FiveThree_Functional_ClassWithLambda();
+ $this->assertEquals($expected, $tpl->render($data));
+ }
+}
+
+class Mustache_Test_FiveThree_Functional_ClassWithLambda
+{
+ public function _t()
+ {
+ return function ($val) {
+ return strtoupper($val);
+ };
+ }
+
+ public function placeholder()
+ {
+ return function () {
+ return 'Enter your name';
+ };
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/FiveThree/Functional/StrictCallablesTest.php b/vendor/mustache/mustache/test/Mustache/Test/FiveThree/Functional/StrictCallablesTest.php
new file mode 100644
index 0000000..fc91072
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/FiveThree/Functional/StrictCallablesTest.php
@@ -0,0 +1,135 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @group lambdas
+ * @group functional
+ */
+class Mustache_Test_FiveThree_Functional_StrictCallablesTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider callables
+ */
+ public function testStrictCallables($strict, $name, $section, $expected)
+ {
+ $mustache = new Mustache_Engine(array('strict_callables' => $strict));
+ $tpl = $mustache->loadTemplate('{{# section }}{{ name }}{{/ section }}');
+
+ $data = new StdClass();
+ $data->name = $name;
+ $data->section = $section;
+
+ $this->assertEquals($expected, $tpl->render($data));
+ }
+
+ public function callables()
+ {
+ $lambda = function ($tpl, $mustache) {
+ return strtoupper($mustache->render($tpl));
+ };
+
+ return array(
+ // Interpolation lambdas
+ array(
+ false,
+ array($this, 'instanceName'),
+ $lambda,
+ 'YOSHI',
+ ),
+ array(
+ false,
+ array(__CLASS__, 'staticName'),
+ $lambda,
+ 'YOSHI',
+ ),
+ array(
+ false,
+ function () {
+ return 'Yoshi';
+ },
+ $lambda,
+ 'YOSHI',
+ ),
+
+ // Section lambdas
+ array(
+ false,
+ 'Yoshi',
+ array($this, 'instanceCallable'),
+ 'YOSHI',
+ ),
+ array(
+ false,
+ 'Yoshi',
+ array(__CLASS__, 'staticCallable'),
+ 'YOSHI',
+ ),
+ array(
+ false,
+ 'Yoshi',
+ $lambda,
+ 'YOSHI',
+ ),
+
+ // Strict interpolation lambdas
+ array(
+ true,
+ function () {
+ return 'Yoshi';
+ },
+ $lambda,
+ 'YOSHI',
+ ),
+
+ // Strict section lambdas
+ array(
+ true,
+ 'Yoshi',
+ array($this, 'instanceCallable'),
+ 'YoshiYoshi',
+ ),
+ array(
+ true,
+ 'Yoshi',
+ array(__CLASS__, 'staticCallable'),
+ 'YoshiYoshi',
+ ),
+ array(
+ true,
+ 'Yoshi',
+ function ($tpl, $mustache) {
+ return strtoupper($mustache->render($tpl));
+ },
+ 'YOSHI',
+ ),
+ );
+ }
+
+ public function instanceCallable($tpl, $mustache)
+ {
+ return strtoupper($mustache->render($tpl));
+ }
+
+ public static function staticCallable($tpl, $mustache)
+ {
+ return strtoupper($mustache->render($tpl));
+ }
+
+ public function instanceName()
+ {
+ return 'Yoshi';
+ }
+
+ public static function staticName()
+ {
+ return 'Yoshi';
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/Functional/CallTest.php b/vendor/mustache/mustache/test/Mustache/Test/Functional/CallTest.php
new file mode 100644
index 0000000..fddeacf
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/Functional/CallTest.php
@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @group magic_methods
+ * @group functional
+ */
+class Mustache_Test_Functional_CallTest extends PHPUnit_Framework_TestCase
+{
+ public function testCallEatsContext()
+ {
+ $m = new Mustache_Engine();
+ $tpl = $m->loadTemplate('{{# foo }}{{ label }}: {{ name }}{{/ foo }}');
+
+ $foo = new Mustache_Test_Functional_ClassWithCall();
+ $foo->name = 'Bob';
+
+ $data = array('label' => 'name', 'foo' => $foo);
+
+ $this->assertEquals('name: Bob', $tpl->render($data));
+ }
+}
+
+class Mustache_Test_Functional_ClassWithCall
+{
+ public $name;
+
+ public function __call($method, $args)
+ {
+ return 'unknown value';
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/Functional/ExamplesTest.php b/vendor/mustache/mustache/test/Mustache/Test/Functional/ExamplesTest.php
new file mode 100644
index 0000000..d7ef51a
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/Functional/ExamplesTest.php
@@ -0,0 +1,142 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @group examples
+ * @group functional
+ */
+class Mustache_Test_Functional_ExamplesTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * Test everything in the `examples` directory.
+ *
+ * @dataProvider getExamples
+ *
+ * @param string $context
+ * @param string $source
+ * @param array $partials
+ * @param string $expected
+ */
+ public function testExamples($context, $source, $partials, $expected)
+ {
+ $mustache = new Mustache_Engine(array(
+ 'partials' => $partials,
+ ));
+ $this->assertEquals($expected, $mustache->loadTemplate($source)->render($context));
+ }
+
+ /**
+ * Data provider for testExamples method.
+ *
+ * Loads examples from the test fixtures directory.
+ *
+ * This examples directory should contain any number of subdirectories, each of which contains
+ * three files: one Mustache class (.php), one Mustache template (.mustache), and one output file
+ * (.txt). Optionally, the directory may contain a folder full of partials.
+ *
+ * @return array
+ */
+ public function getExamples()
+ {
+ $path = realpath(dirname(__FILE__) . '/../../../fixtures/examples');
+ $examples = array();
+
+ $handle = opendir($path);
+ while (($file = readdir($handle)) !== false) {
+ if ($file === '.' || $file === '..') {
+ continue;
+ }
+
+ $fullpath = $path . '/' . $file;
+ if (is_dir($fullpath)) {
+ $examples[$file] = $this->loadExample($fullpath);
+ }
+ }
+ closedir($handle);
+
+ return $examples;
+ }
+
+ /**
+ * Helper method to load an example given the full path.
+ *
+ * @param string $path
+ *
+ * @return array arguments for testExamples
+ */
+ private function loadExample($path)
+ {
+ $context = null;
+ $source = null;
+ $partials = array();
+ $expected = null;
+
+ $handle = opendir($path);
+ while (($file = readdir($handle)) !== false) {
+ $fullpath = $path . '/' . $file;
+ $info = pathinfo($fullpath);
+
+ if (is_dir($fullpath) && $info['basename'] === 'partials') {
+ // load partials
+ $partials = $this->loadPartials($fullpath);
+ } elseif (is_file($fullpath)) {
+ // load other files
+ switch ($info['extension']) {
+ case 'php':
+ require_once $fullpath;
+ $className = $info['filename'];
+ $context = new $className();
+ break;
+
+ case 'mustache':
+ $source = file_get_contents($fullpath);
+ break;
+
+ case 'txt':
+ $expected = file_get_contents($fullpath);
+ break;
+ }
+ }
+ }
+ closedir($handle);
+
+ return array($context, $source, $partials, $expected);
+ }
+
+ /**
+ * Helper method to load partials given an example directory.
+ *
+ * @param string $path
+ *
+ * @return array $partials
+ */
+ private function loadPartials($path)
+ {
+ $partials = array();
+
+ $handle = opendir($path);
+ while (($file = readdir($handle)) !== false) {
+ if ($file === '.' || $file === '..') {
+ continue;
+ }
+
+ $fullpath = $path . '/' . $file;
+ $info = pathinfo($fullpath);
+
+ if ($info['extension'] === 'mustache') {
+ $partials[$info['filename']] = file_get_contents($fullpath);
+ }
+ }
+ closedir($handle);
+
+ return $partials;
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/Functional/HigherOrderSectionsTest.php b/vendor/mustache/mustache/test/Mustache/Test/Functional/HigherOrderSectionsTest.php
new file mode 100644
index 0000000..e2f68b0
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/Functional/HigherOrderSectionsTest.php
@@ -0,0 +1,177 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @group lambdas
+ * @group functional
+ */
+class Mustache_Test_Functional_HigherOrderSectionsTest extends Mustache_Test_FunctionalTestCase
+{
+ private $mustache;
+
+ public function setUp()
+ {
+ $this->mustache = new Mustache_Engine();
+ }
+
+ /**
+ * @dataProvider sectionCallbackData
+ */
+ public function testSectionCallback($data, $tpl, $expect)
+ {
+ $this->assertEquals($expect, $this->mustache->render($tpl, $data));
+ }
+
+ public function sectionCallbackData()
+ {
+ $foo = new Mustache_Test_Functional_Foo();
+ $foo->doublewrap = array($foo, 'wrapWithBoth');
+
+ $bar = new Mustache_Test_Functional_Foo();
+ $bar->trimmer = array(get_class($bar), 'staticTrim');
+
+ return array(
+ array($foo, '{{#doublewrap}}{{name}}{{/doublewrap}}', sprintf('<strong><em>%s</em></strong>', $foo->name)),
+ array($bar, '{{#trimmer}} {{name}} {{/trimmer}}', $bar->name),
+ );
+ }
+
+ public function testViewArraySectionCallback()
+ {
+ $tpl = $this->mustache->loadTemplate('{{#trim}} {{name}} {{/trim}}');
+
+ $foo = new Mustache_Test_Functional_Foo();
+
+ $data = array(
+ 'name' => 'Bob',
+ 'trim' => array(get_class($foo), 'staticTrim'),
+ );
+
+ $this->assertEquals($data['name'], $tpl->render($data));
+ }
+
+ public function testMonsters()
+ {
+ $tpl = $this->mustache->loadTemplate('{{#title}}{{title}} {{/title}}{{name}}');
+
+ $frank = new Mustache_Test_Functional_Monster();
+ $frank->title = 'Dr.';
+ $frank->name = 'Frankenstein';
+ $this->assertEquals('Dr. Frankenstein', $tpl->render($frank));
+
+ $dracula = new Mustache_Test_Functional_Monster();
+ $dracula->title = 'Count';
+ $dracula->name = 'Dracula';
+ $this->assertEquals('Count Dracula', $tpl->render($dracula));
+ }
+
+ public function testPassthroughOptimization()
+ {
+ $mustache = $this->getMock('Mustache_Engine', array('loadLambda'));
+ $mustache->expects($this->never())
+ ->method('loadLambda');
+
+ $tpl = $mustache->loadTemplate('{{#wrap}}NAME{{/wrap}}');
+
+ $foo = new Mustache_Test_Functional_Foo();
+ $foo->wrap = array($foo, 'wrapWithEm');
+
+ $this->assertEquals('<em>NAME</em>', $tpl->render($foo));
+ }
+
+ public function testWithoutPassthroughOptimization()
+ {
+ $mustache = $this->getMock('Mustache_Engine', array('loadLambda'));
+ $mustache->expects($this->once())
+ ->method('loadLambda')
+ ->will($this->returnValue($mustache->loadTemplate('<em>{{ name }}</em>')));
+
+ $tpl = $mustache->loadTemplate('{{#wrap}}{{name}}{{/wrap}}');
+
+ $foo = new Mustache_Test_Functional_Foo();
+ $foo->wrap = array($foo, 'wrapWithEm');
+
+ $this->assertEquals('<em>' . $foo->name . '</em>', $tpl->render($foo));
+ }
+
+ /**
+ * @dataProvider cacheLambdaTemplatesData
+ */
+ public function testCacheLambdaTemplatesOptionWorks($dirName, $tplPrefix, $enable, $expect)
+ {
+ $cacheDir = $this->setUpCacheDir($dirName);
+ $mustache = new Mustache_Engine(array(
+ 'template_class_prefix' => $tplPrefix,
+ 'cache' => $cacheDir,
+ 'cache_lambda_templates' => $enable,
+ ));
+
+ $tpl = $mustache->loadTemplate('{{#wrap}}{{name}}{{/wrap}}');
+ $foo = new Mustache_Test_Functional_Foo();
+ $foo->wrap = array($foo, 'wrapWithEm');
+ $this->assertEquals('<em>' . $foo->name . '</em>', $tpl->render($foo));
+ $this->assertCount($expect, glob($cacheDir . '/*.php'));
+ }
+
+ public function cacheLambdaTemplatesData()
+ {
+ return array(
+ array('test_enabling_lambda_cache', '_TestEnablingLambdaCache_', true, 2),
+ array('test_disabling_lambda_cache', '_TestDisablingLambdaCache_', false, 1),
+ );
+ }
+
+ protected function setUpCacheDir($name)
+ {
+ $cacheDir = self::$tempDir . '/' . $name;
+ if (file_exists($cacheDir)) {
+ self::rmdir($cacheDir);
+ }
+ mkdir($cacheDir, 0777, true);
+
+ return $cacheDir;
+ }
+}
+
+class Mustache_Test_Functional_Foo
+{
+ public $name = 'Justin';
+ public $lorem = 'Lorem ipsum dolor sit amet,';
+
+ public function wrapWithEm($text)
+ {
+ return sprintf('<em>%s</em>', $text);
+ }
+
+ /**
+ * @param string $text
+ */
+ public function wrapWithStrong($text)
+ {
+ return sprintf('<strong>%s</strong>', $text);
+ }
+
+ public function wrapWithBoth($text)
+ {
+ return self::wrapWithStrong(self::wrapWithEm($text));
+ }
+
+ public static function staticTrim($text)
+ {
+ return trim($text);
+ }
+}
+
+class Mustache_Test_Functional_Monster
+{
+ public $title;
+ public $name;
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/Functional/InheritanceTest.php b/vendor/mustache/mustache/test/Mustache/Test/Functional/InheritanceTest.php
new file mode 100644
index 0000000..b39555f
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/Functional/InheritanceTest.php
@@ -0,0 +1,526 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @group inheritance
+ * @group functional
+ */
+class Mustache_Test_Functional_InheritanceTest extends PHPUnit_Framework_TestCase
+{
+ private $mustache;
+
+ public function setUp()
+ {
+ $this->mustache = new Mustache_Engine(array(
+ 'pragmas' => array(Mustache_Engine::PRAGMA_BLOCKS),
+ ));
+ }
+
+ public function getIllegalInheritanceExamples()
+ {
+ return array(
+ array(
+ array(
+ 'foo' => '{{$baz}}default content{{/baz}}',
+ ),
+ array(
+ 'bar' => 'set by user',
+ ),
+ '{{< foo }}{{# bar }}{{$ baz }}{{/ baz }}{{/ bar }}{{/ foo }}',
+ ),
+ array(
+ array(
+ 'foo' => '{{$baz}}default content{{/baz}}',
+ ),
+ array(
+ ),
+ '{{<foo}}{{^bar}}{{$baz}}set by template{{/baz}}{{/bar}}{{/foo}}',
+ ),
+ array(
+ array(
+ 'foo' => '{{$baz}}default content{{/baz}}',
+ 'qux' => 'I am a partial',
+ ),
+ array(
+ ),
+ '{{<foo}}{{>qux}}{{$baz}}set by template{{/baz}}{{/foo}}',
+ ),
+ array(
+ array(
+ 'foo' => '{{$baz}}default content{{/baz}}',
+ ),
+ array(),
+ '{{<foo}}{{=<% %>=}}<%={{ }}=%>{{/foo}}',
+ ),
+ );
+ }
+
+ public function getLegalInheritanceExamples()
+ {
+ return array(
+ array(
+ array(
+ 'foo' => '{{$baz}}default content{{/baz}}',
+ ),
+ array(
+ 'bar' => 'set by user',
+ ),
+ '{{<foo}}{{bar}}{{$baz}}override{{/baz}}{{/foo}}',
+ 'override',
+ ),
+ array(
+ array(
+ 'foo' => '{{$baz}}default content{{/baz}}',
+ ),
+ array(
+ ),
+ '{{<foo}}{{! ignore me }}{{$baz}}set by template{{/baz}}{{/foo}}',
+ 'set by template',
+ ),
+ array(
+ array(
+ 'foo' => '{{$baz}}defualt content{{/baz}}',
+ ),
+ array(),
+ '{{<foo}}set by template{{$baz}}also set by template{{/baz}}{{/foo}}',
+ 'also set by template',
+ ),
+ array(
+ array(
+ 'foo' => '{{$a}}FAIL!{{/a}}',
+ 'bar' => 'WIN!!',
+ ),
+ array(),
+ '{{<foo}}{{$a}}{{<bar}}FAIL{{/bar}}{{/a}}{{/foo}}',
+ 'WIN!!',
+ ),
+ );
+ }
+
+ public function testDefaultContent()
+ {
+ $tpl = $this->mustache->loadTemplate('{{$title}}Default title{{/title}}');
+
+ $data = array();
+
+ $this->assertEquals('Default title', $tpl->render($data));
+ }
+
+ public function testDefaultContentRendersVariables()
+ {
+ $tpl = $this->mustache->loadTemplate('{{$foo}}default {{bar}} content{{/foo}}');
+
+ $data = array(
+ 'bar' => 'baz',
+ );
+
+ $this->assertEquals('default baz content', $tpl->render($data));
+ }
+
+ public function testDefaultContentRendersTripleMustacheVariables()
+ {
+ $tpl = $this->mustache->loadTemplate('{{$foo}}default {{{bar}}} content{{/foo}}');
+
+ $data = array(
+ 'bar' => '<baz>',
+ );
+
+ $this->assertEquals('default <baz> content', $tpl->render($data));
+ }
+
+ public function testDefaultContentRendersSections()
+ {
+ $tpl = $this->mustache->loadTemplate(
+ '{{$foo}}default {{#bar}}{{baz}}{{/bar}} content{{/foo}}'
+ );
+
+ $data = array(
+ 'bar' => array('baz' => 'qux'),
+ );
+
+ $this->assertEquals('default qux content', $tpl->render($data));
+ }
+
+ public function testDefaultContentRendersNegativeSections()
+ {
+ $tpl = $this->mustache->loadTemplate(
+ '{{$foo}}default {{^bar}}{{baz}}{{/bar}} content{{/foo}}'
+ );
+
+ $data = array(
+ 'foo' => array('bar' => 'qux'),
+ 'baz' => 'three',
+ );
+
+ $this->assertEquals('default three content', $tpl->render($data));
+ }
+
+ public function testMustacheInjectionInDefaultContent()
+ {
+ $tpl = $this->mustache->loadTemplate(
+ '{{$foo}}default {{#bar}}{{baz}}{{/bar}} content{{/foo}}'
+ );
+
+ $data = array(
+ 'bar' => array('baz' => '{{qux}}'),
+ );
+
+ $this->assertEquals('default {{qux}} content', $tpl->render($data));
+ }
+
+ public function testDefaultContentRenderedInsideIncludedTemplates()
+ {
+ $partials = array(
+ 'include' => '{{$foo}}default content{{/foo}}',
+ );
+
+ $this->mustache->setPartials($partials);
+
+ $tpl = $this->mustache->loadTemplate(
+ '{{<include}}{{/include}}'
+ );
+
+ $data = array();
+
+ $this->assertEquals('default content', $tpl->render($data));
+ }
+
+ public function testOverriddenContent()
+ {
+ $partials = array(
+ 'super' => '...{{$title}}Default title{{/title}}...',
+ );
+
+ $this->mustache->setPartials($partials);
+
+ $tpl = $this->mustache->loadTemplate(
+ '{{<super}}{{$title}}sub template title{{/title}}{{/super}}'
+ );
+
+ $data = array();
+
+ $this->assertEquals('...sub template title...', $tpl->render($data));
+ }
+
+ public function testOverriddenPartial()
+ {
+ $partials = array(
+ 'partial' => '|{{$stuff}}...{{/stuff}}{{$default}} default{{/default}}|',
+ );
+
+ $this->mustache->setPartials($partials);
+
+ $tpl = $this->mustache->loadTemplate(
+ 'test {{<partial}}{{$stuff}}override1{{/stuff}}{{/partial}} {{<partial}}{{$stuff}}override2{{/stuff}}{{/partial}}'
+ );
+
+ $data = array();
+
+ $this->assertEquals('test |override1 default| |override2 default|', $tpl->render($data));
+ }
+
+ public function testDataDoesNotOverrideBlock()
+ {
+ $partials = array(
+ 'include' => '{{$var}}var in include{{/var}}',
+ );
+
+ $this->mustache->setPartials($partials);
+
+ $tpl = $this->mustache->loadTemplate(
+ '{{<include}}{{$var}}var in template{{/var}}{{/include}}'
+ );
+
+ $data = array(
+ 'var' => 'var in data',
+ );
+
+ $this->assertEquals('var in template', $tpl->render($data));
+ }
+
+ public function testDataDoesNotOverrideDefaultBlockValue()
+ {
+ $partials = array(
+ 'include' => '{{$var}}var in include{{/var}}',
+ );
+
+ $this->mustache->setPartials($partials);
+
+ $tpl = $this->mustache->loadTemplate(
+ '{{<include}}{{/include}}'
+ );
+
+ $data = array(
+ 'var' => 'var in data',
+ );
+
+ $this->assertEquals('var in include', $tpl->render($data));
+ }
+
+ public function testOverridePartialWithNewlines()
+ {
+ $partials = array(
+ 'partial' => '{{$ballmer}}peaking{{/ballmer}}',
+ );
+
+ $this->mustache->setPartials($partials);
+
+ $tpl = $this->mustache->loadTemplate(
+ "{{<partial}}{{\$ballmer}}\npeaked\n\n:(\n{{/ballmer}}{{/partial}}"
+ );
+
+ $data = array();
+
+ $this->assertEquals("peaked\n\n:(\n", $tpl->render($data));
+ }
+
+ public function testInheritIndentationWhenOverridingAPartial()
+ {
+ $partials = array(
+ 'partial' => 'stop:
+ {{$nineties}}collaborate and listen{{/nineties}}',
+ );
+
+ $this->mustache->setPartials($partials);
+
+ $tpl = $this->mustache->loadTemplate(
+ '{{<partial}}{{$nineties}}hammer time{{/nineties}}{{/partial}}'
+ );
+
+ $data = array();
+
+ $this->assertEquals(
+ 'stop:
+ hammer time',
+ $tpl->render($data)
+ );
+ }
+
+ public function testInheritSpacingWhenOverridingAPartial()
+ {
+ $partials = array(
+ 'parent' => 'collaborate_and{{$id}}{{/id}}',
+ 'child' => '{{<parent}}{{$id}}_listen{{/id}}{{/parent}}',
+ );
+
+ $this->mustache->setPartials($partials);
+
+ $tpl = $this->mustache->loadTemplate(
+ 'stop:
+ {{>child}}'
+ );
+
+ $data = array();
+
+ $this->assertEquals(
+ 'stop:
+ collaborate_and_listen',
+ $tpl->render($data)
+ );
+ }
+
+ public function testOverrideOneSubstitutionButNotTheOther()
+ {
+ $partials = array(
+ 'partial' => '{{$stuff}}default one{{/stuff}}, {{$stuff2}}default two{{/stuff2}}',
+ );
+
+ $this->mustache->setPartials($partials);
+
+ $tpl = $this->mustache->loadTemplate(
+ '{{<partial}}{{$stuff2}}override two{{/stuff2}}{{/partial}}'
+ );
+
+ $data = array();
+
+ $this->assertEquals('default one, override two', $tpl->render($data));
+ }
+
+ public function testSuperTemplatesWithNoParameters()
+ {
+ $partials = array(
+ 'include' => '{{$foo}}default content{{/foo}}',
+ );
+
+ $this->mustache->setPartials($partials);
+
+ $tpl = $this->mustache->loadTemplate(
+ '{{>include}}|{{<include}}{{/include}}'
+ );
+
+ $data = array();
+
+ $this->assertEquals('default content|default content', $tpl->render($data));
+ }
+
+ public function testRecursionInInheritedTemplates()
+ {
+ $partials = array(
+ 'include' => '{{$foo}}default content{{/foo}} {{$bar}}{{<include2}}{{/include2}}{{/bar}}',
+ 'include2' => '{{$foo}}include2 default content{{/foo}} {{<include}}{{$bar}}don\'t recurse{{/bar}}{{/include}}',
+ );
+
+ $this->mustache->setPartials($partials);
+
+ $tpl = $this->mustache->loadTemplate(
+ '{{<include}}{{$foo}}override{{/foo}}{{/include}}'
+ );
+
+ $data = array();
+
+ $this->assertEquals('override override override don\'t recurse', $tpl->render($data));
+ }
+
+ public function testTopLevelSubstitutionsTakePrecedenceInMultilevelInheritance()
+ {
+ $partials = array(
+ 'parent' => '{{<older}}{{$a}}p{{/a}}{{/older}}',
+ 'older' => '{{<grandParent}}{{$a}}o{{/a}}{{/grandParent}}',
+ 'grandParent' => '{{$a}}g{{/a}}',
+ );
+
+ $this->mustache->setPartials($partials);
+
+ $tpl = $this->mustache->loadTemplate(
+ '{{<parent}}{{$a}}c{{/a}}{{/parent}}'
+ );
+
+ $data = array();
+
+ $this->assertEquals('c', $tpl->render($data));
+ }
+
+ public function testMultiLevelInheritanceNoSubChild()
+ {
+ $partials = array(
+ 'parent' => '{{<older}}{{$a}}p{{/a}}{{/older}}',
+ 'older' => '{{<grandParent}}{{$a}}o{{/a}}{{/grandParent}}',
+ 'grandParent' => '{{$a}}g{{/a}}',
+ );
+
+ $this->mustache->setPartials($partials);
+
+ $tpl = $this->mustache->loadTemplate(
+ '{{<parent}}{{/parent}}'
+ );
+
+ $data = array();
+
+ $this->assertEquals('p', $tpl->render($data));
+ }
+
+ public function testIgnoreTextInsideSuperTemplatesButParseArgs()
+ {
+ $partials = array(
+ 'include' => '{{$foo}}default content{{/foo}}',
+ );
+
+ $this->mustache->setPartials($partials);
+
+ $tpl = $this->mustache->loadTemplate(
+ '{{<include}} asdfasd {{$foo}}hmm{{/foo}} asdfasdfasdf {{/include}}'
+ );
+
+ $data = array();
+
+ $this->assertEquals('hmm', $tpl->render($data));
+ }
+
+ public function testIgnoreTextInsideSuperTemplates()
+ {
+ $partials = array(
+ 'include' => '{{$foo}}default content{{/foo}}',
+ );
+
+ $this->mustache->setPartials($partials);
+
+ $tpl = $this->mustache->loadTemplate(
+ '{{<include}} asdfasd asdfasdfasdf {{/include}}'
+ );
+
+ $data = array();
+
+ $this->assertEquals('default content', $tpl->render($data));
+ }
+
+ public function testInheritanceWithLazyEvaluation()
+ {
+ $partials = array(
+ 'parent' => '{{#items}}{{$value}}ignored{{/value}}{{/items}}',
+ );
+
+ $this->mustache->setPartials($partials);
+
+ $tpl = $this->mustache->loadTemplate(
+ '{{<parent}}{{$value}}<{{ . }}>{{/value}}{{/parent}}'
+ );
+
+ $data = array('items' => array(1, 2, 3));
+
+ $this->assertEquals('<1><2><3>', $tpl->render($data));
+ }
+
+ public function testInheritanceWithLazyEvaluationWhitespaceIgnored()
+ {
+ $partials = array(
+ 'parent' => '{{#items}}{{$value}}\n\nignored\n\n{{/value}}{{/items}}',
+ );
+
+ $this->mustache->setPartials($partials);
+
+ $tpl = $this->mustache->loadTemplate(
+ '{{<parent}}\n\n\n{{$value}}<{{ . }}>{{/value}}\n\n{{/parent}}'
+ );
+
+ $data = array('items' => array(1, 2, 3));
+
+ $this->assertEquals('<1><2><3>', $tpl->render($data));
+ }
+
+ public function testInheritanceWithLazyEvaluationAndSections()
+ {
+ $partials = array(
+ 'parent' => '{{#items}}{{$value}}\n\nignored {{.}} {{#more}} there is more {{/more}}\n\n{{/value}}{{/items}}',
+ );
+
+ $this->mustache->setPartials($partials);
+
+ $tpl = $this->mustache->loadTemplate(
+ '{{<parent}}\n\n\n{{$value}}<{{ . }}>{{#more}} there is less {{/more}}{{/value}}\n\n{{/parent}}'
+ );
+
+ $data = array('items' => array(1, 2, 3), 'more' => 'stuff');
+
+ $this->assertEquals('<1> there is less <2> there is less <3> there is less ', $tpl->render($data));
+ }
+
+ /**
+ * @dataProvider getIllegalInheritanceExamples
+ * @expectedException Mustache_Exception_SyntaxException
+ * @expectedExceptionMessage Illegal content in < parent tag
+ */
+ public function testIllegalInheritanceExamples($partials, $data, $template)
+ {
+ $this->mustache->setPartials($partials);
+ $tpl = $this->mustache->loadTemplate($template);
+ $tpl->render($data);
+ }
+
+ /**
+ * @dataProvider getLegalInheritanceExamples
+ */
+ public function testLegalInheritanceExamples($partials, $data, $template, $expect)
+ {
+ $this->mustache->setPartials($partials);
+ $tpl = $this->mustache->loadTemplate($template);
+ $this->assertSame($expect, $tpl->render($data));
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/Functional/MustacheInjectionTest.php b/vendor/mustache/mustache/test/Mustache/Test/Functional/MustacheInjectionTest.php
new file mode 100644
index 0000000..d0bdb48
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/Functional/MustacheInjectionTest.php
@@ -0,0 +1,83 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @group mustache_injection
+ * @group functional
+ */
+class Mustache_Test_Functional_MustacheInjectionTest extends PHPUnit_Framework_TestCase
+{
+ private $mustache;
+
+ public function setUp()
+ {
+ $this->mustache = new Mustache_Engine();
+ }
+
+ /**
+ * @dataProvider injectionData
+ */
+ public function testInjection($tpl, $data, $partials, $expect)
+ {
+ $this->mustache->setPartials($partials);
+ $this->assertEquals($expect, $this->mustache->render($tpl, $data));
+ }
+
+ public function injectionData()
+ {
+ $interpolationData = array(
+ 'a' => '{{ b }}',
+ 'b' => 'FAIL',
+ );
+
+ $sectionData = array(
+ 'a' => true,
+ 'b' => '{{ c }}',
+ 'c' => 'FAIL',
+ );
+
+ $lambdaInterpolationData = array(
+ 'a' => array($this, 'lambdaInterpolationCallback'),
+ 'b' => '{{ c }}',
+ 'c' => 'FAIL',
+ );
+
+ $lambdaSectionData = array(
+ 'a' => array($this, 'lambdaSectionCallback'),
+ 'b' => '{{ c }}',
+ 'c' => 'FAIL',
+ );
+
+ return array(
+ array('{{ a }}', $interpolationData, array(), '{{ b }}'),
+ array('{{{ a }}}', $interpolationData, array(), '{{ b }}'),
+
+ array('{{# a }}{{ b }}{{/ a }}', $sectionData, array(), '{{ c }}'),
+ array('{{# a }}{{{ b }}}{{/ a }}', $sectionData, array(), '{{ c }}'),
+
+ array('{{> partial }}', $interpolationData, array('partial' => '{{ a }}'), '{{ b }}'),
+ array('{{> partial }}', $interpolationData, array('partial' => '{{{ a }}}'), '{{ b }}'),
+
+ array('{{ a }}', $lambdaInterpolationData, array(), '{{ c }}'),
+ array('{{# a }}b{{/ a }}', $lambdaSectionData, array(), '{{ c }}'),
+ );
+ }
+
+ public static function lambdaInterpolationCallback()
+ {
+ return '{{ b }}';
+ }
+
+ public static function lambdaSectionCallback($text)
+ {
+ return '{{ ' . $text . ' }}';
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/Functional/MustacheSpecTest.php b/vendor/mustache/mustache/test/Mustache/Test/Functional/MustacheSpecTest.php
new file mode 100644
index 0000000..7ba0843
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/Functional/MustacheSpecTest.php
@@ -0,0 +1,121 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * A PHPUnit test case wrapping the Mustache Spec.
+ *
+ * @group mustache-spec
+ * @group functional
+ */
+class Mustache_Test_Functional_MustacheSpecTest extends Mustache_Test_SpecTestCase
+{
+ /**
+ * For some reason data providers can't mark tests skipped, so this test exists
+ * simply to provide a 'skipped' test if the `spec` submodule isn't initialized.
+ */
+ public function testSpecInitialized()
+ {
+ if (!file_exists(dirname(__FILE__) . '/../../../../vendor/spec/specs/')) {
+ $this->markTestSkipped('Mustache spec submodule not initialized: run "git submodule update --init"');
+ }
+ }
+
+ /**
+ * @group comments
+ * @dataProvider loadCommentSpec
+ */
+ public function testCommentSpec($desc, $source, $partials, $data, $expected)
+ {
+ $template = self::loadTemplate($source, $partials);
+ $this->assertEquals($expected, $template->render($data), $desc);
+ }
+
+ public function loadCommentSpec()
+ {
+ return $this->loadSpec('comments');
+ }
+
+ /**
+ * @group delimiters
+ * @dataProvider loadDelimitersSpec
+ */
+ public function testDelimitersSpec($desc, $source, $partials, $data, $expected)
+ {
+ $template = self::loadTemplate($source, $partials);
+ $this->assertEquals($expected, $template->render($data), $desc);
+ }
+
+ public function loadDelimitersSpec()
+ {
+ return $this->loadSpec('delimiters');
+ }
+
+ /**
+ * @group interpolation
+ * @dataProvider loadInterpolationSpec
+ */
+ public function testInterpolationSpec($desc, $source, $partials, $data, $expected)
+ {
+ $template = self::loadTemplate($source, $partials);
+ $this->assertEquals($expected, $template->render($data), $desc);
+ }
+
+ public function loadInterpolationSpec()
+ {
+ return $this->loadSpec('interpolation');
+ }
+
+ /**
+ * @group inverted
+ * @group inverted-sections
+ * @dataProvider loadInvertedSpec
+ */
+ public function testInvertedSpec($desc, $source, $partials, $data, $expected)
+ {
+ $template = self::loadTemplate($source, $partials);
+ $this->assertEquals($expected, $template->render($data), $desc);
+ }
+
+ public function loadInvertedSpec()
+ {
+ return $this->loadSpec('inverted');
+ }
+
+ /**
+ * @group partials
+ * @dataProvider loadPartialsSpec
+ */
+ public function testPartialsSpec($desc, $source, $partials, $data, $expected)
+ {
+ $template = self::loadTemplate($source, $partials);
+ $this->assertEquals($expected, $template->render($data), $desc);
+ }
+
+ public function loadPartialsSpec()
+ {
+ return $this->loadSpec('partials');
+ }
+
+ /**
+ * @group sections
+ * @dataProvider loadSectionsSpec
+ */
+ public function testSectionsSpec($desc, $source, $partials, $data, $expected)
+ {
+ $template = self::loadTemplate($source, $partials);
+ $this->assertEquals($expected, $template->render($data), $desc);
+ }
+
+ public function loadSectionsSpec()
+ {
+ return $this->loadSpec('sections');
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/Functional/NestedPartialIndentTest.php b/vendor/mustache/mustache/test/Mustache/Test/Functional/NestedPartialIndentTest.php
new file mode 100644
index 0000000..673339c
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/Functional/NestedPartialIndentTest.php
@@ -0,0 +1,45 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @group functional
+ * @group partials
+ */
+class Mustache_Test_Functional_NestedPartialIndentTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider partialsAndStuff
+ */
+ public function testNestedPartialsAreIndentedProperly($src, array $partials, $expected)
+ {
+ $m = new Mustache_Engine(array(
+ 'partials' => $partials,
+ ));
+ $tpl = $m->loadTemplate($src);
+ $this->assertEquals($expected, $tpl->render());
+ }
+
+ public function partialsAndStuff()
+ {
+ $partials = array(
+ 'a' => ' {{> b }}',
+ 'b' => ' {{> d }}',
+ 'c' => ' {{> d }}{{> d }}',
+ 'd' => 'D!',
+ );
+
+ return array(
+ array(' {{> a }}', $partials, ' D!'),
+ array(' {{> b }}', $partials, ' D!'),
+ array(' {{> c }}', $partials, ' D!D!'),
+ );
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/Functional/ObjectSectionTest.php b/vendor/mustache/mustache/test/Mustache/Test/Functional/ObjectSectionTest.php
new file mode 100644
index 0000000..963b0f7
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/Functional/ObjectSectionTest.php
@@ -0,0 +1,110 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @group sections
+ * @group functional
+ */
+class Mustache_Test_Functional_ObjectSectionTest extends PHPUnit_Framework_TestCase
+{
+ private $mustache;
+
+ public function setUp()
+ {
+ $this->mustache = new Mustache_Engine();
+ }
+
+ public function testBasicObject()
+ {
+ $tpl = $this->mustache->loadTemplate('{{#foo}}{{name}}{{/foo}}');
+ $this->assertEquals('Foo', $tpl->render(new Mustache_Test_Functional_Alpha()));
+ }
+
+ /**
+ * @group magic_methods
+ */
+ public function testObjectWithGet()
+ {
+ $tpl = $this->mustache->loadTemplate('{{#foo}}{{name}}{{/foo}}');
+ $this->assertEquals('Foo', $tpl->render(new Mustache_Test_Functional_Beta()));
+ }
+
+ /**
+ * @group magic_methods
+ */
+ public function testSectionObjectWithGet()
+ {
+ $tpl = $this->mustache->loadTemplate('{{#bar}}{{#foo}}{{name}}{{/foo}}{{/bar}}');
+ $this->assertEquals('Foo', $tpl->render(new Mustache_Test_Functional_Gamma()));
+ }
+
+ public function testSectionObjectWithFunction()
+ {
+ $tpl = $this->mustache->loadTemplate('{{#foo}}{{name}}{{/foo}}');
+ $alpha = new Mustache_Test_Functional_Alpha();
+ $alpha->foo = new Mustache_Test_Functional_Delta();
+ $this->assertEquals('Foo', $tpl->render($alpha));
+ }
+}
+
+class Mustache_Test_Functional_Alpha
+{
+ public $foo;
+
+ public function __construct()
+ {
+ $this->foo = new StdClass();
+ $this->foo->name = 'Foo';
+ $this->foo->number = 1;
+ }
+}
+
+class Mustache_Test_Functional_Beta
+{
+ protected $_data = array();
+
+ public function __construct()
+ {
+ $this->_data['foo'] = new StdClass();
+ $this->_data['foo']->name = 'Foo';
+ $this->_data['foo']->number = 1;
+ }
+
+ public function __isset($name)
+ {
+ return array_key_exists($name, $this->_data);
+ }
+
+ public function __get($name)
+ {
+ return $this->_data[$name];
+ }
+}
+
+class Mustache_Test_Functional_Gamma
+{
+ public $bar;
+
+ public function __construct()
+ {
+ $this->bar = new Mustache_Test_Functional_Beta();
+ }
+}
+
+class Mustache_Test_Functional_Delta
+{
+ protected $_name = 'Foo';
+
+ public function name()
+ {
+ return $this->_name;
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/FunctionalTestCase.php b/vendor/mustache/mustache/test/Mustache/Test/FunctionalTestCase.php
new file mode 100644
index 0000000..59185d1
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/FunctionalTestCase.php
@@ -0,0 +1,47 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+abstract class Mustache_Test_FunctionalTestCase extends PHPUnit_Framework_TestCase
+{
+ protected static $tempDir;
+
+ public static function setUpBeforeClass()
+ {
+ self::$tempDir = sys_get_temp_dir() . '/mustache_test';
+ if (file_exists(self::$tempDir)) {
+ self::rmdir(self::$tempDir);
+ }
+ }
+
+ /**
+ * @param string $path
+ */
+ protected static function rmdir($path)
+ {
+ $path = rtrim($path, '/') . '/';
+ $handle = opendir($path);
+ while (($file = readdir($handle)) !== false) {
+ if ($file === '.' || $file === '..') {
+ continue;
+ }
+
+ $fullpath = $path . $file;
+ if (is_dir($fullpath)) {
+ self::rmdir($fullpath);
+ } else {
+ unlink($fullpath);
+ }
+ }
+
+ closedir($handle);
+ rmdir($path);
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/HelperCollectionTest.php b/vendor/mustache/mustache/test/Mustache/Test/HelperCollectionTest.php
new file mode 100644
index 0000000..df64e97
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/HelperCollectionTest.php
@@ -0,0 +1,163 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Mustache_Test_HelperCollectionTest extends PHPUnit_Framework_TestCase
+{
+ public function testConstructor()
+ {
+ $foo = array($this, 'getFoo');
+ $bar = 'BAR';
+
+ $helpers = new Mustache_HelperCollection(array(
+ 'foo' => $foo,
+ 'bar' => $bar,
+ ));
+
+ $this->assertSame($foo, $helpers->get('foo'));
+ $this->assertSame($bar, $helpers->get('bar'));
+ }
+
+ public static function getFoo()
+ {
+ echo 'foo';
+ }
+
+ public function testAccessorsAndMutators()
+ {
+ $foo = array($this, 'getFoo');
+ $bar = 'BAR';
+
+ $helpers = new Mustache_HelperCollection();
+ $this->assertTrue($helpers->isEmpty());
+ $this->assertFalse($helpers->has('foo'));
+ $this->assertFalse($helpers->has('bar'));
+
+ $helpers->add('foo', $foo);
+ $this->assertFalse($helpers->isEmpty());
+ $this->assertTrue($helpers->has('foo'));
+ $this->assertFalse($helpers->has('bar'));
+
+ $helpers->add('bar', $bar);
+ $this->assertFalse($helpers->isEmpty());
+ $this->assertTrue($helpers->has('foo'));
+ $this->assertTrue($helpers->has('bar'));
+
+ $helpers->remove('foo');
+ $this->assertFalse($helpers->isEmpty());
+ $this->assertFalse($helpers->has('foo'));
+ $this->assertTrue($helpers->has('bar'));
+ }
+
+ public function testMagicMethods()
+ {
+ $foo = array($this, 'getFoo');
+ $bar = 'BAR';
+
+ $helpers = new Mustache_HelperCollection();
+ $this->assertTrue($helpers->isEmpty());
+ $this->assertFalse($helpers->has('foo'));
+ $this->assertFalse($helpers->has('bar'));
+ $this->assertFalse(isset($helpers->foo));
+ $this->assertFalse(isset($helpers->bar));
+
+ $helpers->foo = $foo;
+ $this->assertFalse($helpers->isEmpty());
+ $this->assertTrue($helpers->has('foo'));
+ $this->assertFalse($helpers->has('bar'));
+ $this->assertTrue(isset($helpers->foo));
+ $this->assertFalse(isset($helpers->bar));
+
+ $helpers->bar = $bar;
+ $this->assertFalse($helpers->isEmpty());
+ $this->assertTrue($helpers->has('foo'));
+ $this->assertTrue($helpers->has('bar'));
+ $this->assertTrue(isset($helpers->foo));
+ $this->assertTrue(isset($helpers->bar));
+
+ unset($helpers->foo);
+ $this->assertFalse($helpers->isEmpty());
+ $this->assertFalse($helpers->has('foo'));
+ $this->assertTrue($helpers->has('bar'));
+ $this->assertFalse(isset($helpers->foo));
+ $this->assertTrue(isset($helpers->bar));
+ }
+
+ /**
+ * @dataProvider getInvalidHelperArguments
+ */
+ public function testHelperCollectionIsntAfraidToThrowExceptions($helpers = array(), $actions = array(), $exception = null)
+ {
+ if ($exception) {
+ $this->setExpectedException($exception);
+ }
+
+ $helpers = new Mustache_HelperCollection($helpers);
+
+ foreach ($actions as $method => $args) {
+ call_user_func_array(array($helpers, $method), $args);
+ }
+ }
+
+ public function getInvalidHelperArguments()
+ {
+ return array(
+ array(
+ 'not helpers',
+ array(),
+ 'InvalidArgumentException',
+ ),
+ array(
+ array(),
+ array('get' => array('foo')),
+ 'InvalidArgumentException',
+ ),
+ array(
+ array('foo' => 'FOO'),
+ array('get' => array('foo')),
+ null,
+ ),
+ array(
+ array('foo' => 'FOO'),
+ array('get' => array('bar')),
+ 'InvalidArgumentException',
+ ),
+ array(
+ array('foo' => 'FOO'),
+ array(
+ 'add' => array('bar', 'BAR'),
+ 'get' => array('bar'),
+ ),
+ null,
+ ),
+ array(
+ array('foo' => 'FOO'),
+ array(
+ 'get' => array('foo'),
+ 'remove' => array('foo'),
+ ),
+ null,
+ ),
+ array(
+ array('foo' => 'FOO'),
+ array(
+ 'remove' => array('foo'),
+ 'get' => array('foo'),
+ ),
+ 'InvalidArgumentException',
+ ),
+ array(
+ array(),
+ array('remove' => array('foo')),
+ 'InvalidArgumentException',
+ ),
+ );
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/Loader/ArrayLoaderTest.php b/vendor/mustache/mustache/test/Mustache/Test/Loader/ArrayLoaderTest.php
new file mode 100644
index 0000000..9960c9b
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/Loader/ArrayLoaderTest.php
@@ -0,0 +1,52 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @group unit
+ */
+class Mustache_Test_Loader_ArrayLoaderTest extends PHPUnit_Framework_TestCase
+{
+ public function testConstructor()
+ {
+ $loader = new Mustache_Loader_ArrayLoader(array(
+ 'foo' => 'bar',
+ ));
+
+ $this->assertEquals('bar', $loader->load('foo'));
+ }
+
+ public function testSetAndLoadTemplates()
+ {
+ $loader = new Mustache_Loader_ArrayLoader(array(
+ 'foo' => 'bar',
+ ));
+ $this->assertEquals('bar', $loader->load('foo'));
+
+ $loader->setTemplate('baz', 'qux');
+ $this->assertEquals('qux', $loader->load('baz'));
+
+ $loader->setTemplates(array(
+ 'foo' => 'FOO',
+ 'baz' => 'BAZ',
+ ));
+ $this->assertEquals('FOO', $loader->load('foo'));
+ $this->assertEquals('BAZ', $loader->load('baz'));
+ }
+
+ /**
+ * @expectedException Mustache_Exception_UnknownTemplateException
+ */
+ public function testMissingTemplatesThrowExceptions()
+ {
+ $loader = new Mustache_Loader_ArrayLoader();
+ $loader->load('not_a_real_template');
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/Loader/CascadingLoaderTest.php b/vendor/mustache/mustache/test/Mustache/Test/Loader/CascadingLoaderTest.php
new file mode 100644
index 0000000..6d97d8d
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/Loader/CascadingLoaderTest.php
@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @group unit
+ */
+class Mustache_Test_Loader_CascadingLoaderTest extends PHPUnit_Framework_TestCase
+{
+ public function testLoadTemplates()
+ {
+ $loader = new Mustache_Loader_CascadingLoader(array(
+ new Mustache_Loader_ArrayLoader(array('foo' => '{{ foo }}')),
+ new Mustache_Loader_ArrayLoader(array('bar' => '{{#bar}}BAR{{/bar}}')),
+ ));
+
+ $this->assertEquals('{{ foo }}', $loader->load('foo'));
+ $this->assertEquals('{{#bar}}BAR{{/bar}}', $loader->load('bar'));
+ }
+
+ /**
+ * @expectedException Mustache_Exception_UnknownTemplateException
+ */
+ public function testMissingTemplatesThrowExceptions()
+ {
+ $loader = new Mustache_Loader_CascadingLoader(array(
+ new Mustache_Loader_ArrayLoader(array('foo' => '{{ foo }}')),
+ new Mustache_Loader_ArrayLoader(array('bar' => '{{#bar}}BAR{{/bar}}')),
+ ));
+
+ $loader->load('not_a_real_template');
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/Loader/FilesystemLoaderTest.php b/vendor/mustache/mustache/test/Mustache/Test/Loader/FilesystemLoaderTest.php
new file mode 100644
index 0000000..75880d4
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/Loader/FilesystemLoaderTest.php
@@ -0,0 +1,80 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @group unit
+ */
+class Mustache_Test_Loader_FilesystemLoaderTest extends PHPUnit_Framework_TestCase
+{
+ public function testConstructor()
+ {
+ $baseDir = realpath(dirname(__FILE__) . '/../../../fixtures/templates');
+ $loader = new Mustache_Loader_FilesystemLoader($baseDir, array('extension' => '.ms'));
+ $this->assertEquals('alpha contents', $loader->load('alpha'));
+ $this->assertEquals('beta contents', $loader->load('beta.ms'));
+ }
+
+ public function testTrailingSlashes()
+ {
+ $baseDir = dirname(__FILE__) . '/../../../fixtures/templates/';
+ $loader = new Mustache_Loader_FilesystemLoader($baseDir);
+ $this->assertEquals('one contents', $loader->load('one'));
+ }
+
+ public function testConstructorWithProtocol()
+ {
+ $baseDir = realpath(dirname(__FILE__) . '/../../../fixtures/templates');
+
+ $loader = new Mustache_Loader_FilesystemLoader('test://' . $baseDir, array('extension' => '.ms'));
+ $this->assertEquals('alpha contents', $loader->load('alpha'));
+ $this->assertEquals('beta contents', $loader->load('beta.ms'));
+ }
+
+ public function testLoadTemplates()
+ {
+ $baseDir = realpath(dirname(__FILE__) . '/../../../fixtures/templates');
+ $loader = new Mustache_Loader_FilesystemLoader($baseDir);
+ $this->assertEquals('one contents', $loader->load('one'));
+ $this->assertEquals('two contents', $loader->load('two.mustache'));
+ }
+
+ public function testEmptyExtensionString()
+ {
+ $baseDir = realpath(dirname(__FILE__) . '/../../../fixtures/templates');
+
+ $loader = new Mustache_Loader_FilesystemLoader($baseDir, array('extension' => ''));
+ $this->assertEquals('one contents', $loader->load('one.mustache'));
+ $this->assertEquals('alpha contents', $loader->load('alpha.ms'));
+
+ $loader = new Mustache_Loader_FilesystemLoader($baseDir, array('extension' => null));
+ $this->assertEquals('two contents', $loader->load('two.mustache'));
+ $this->assertEquals('beta contents', $loader->load('beta.ms'));
+ }
+
+ /**
+ * @expectedException Mustache_Exception_RuntimeException
+ */
+ public function testMissingBaseDirThrowsException()
+ {
+ new Mustache_Loader_FilesystemLoader(dirname(__FILE__) . '/not_a_directory');
+ }
+
+ /**
+ * @expectedException Mustache_Exception_UnknownTemplateException
+ */
+ public function testMissingTemplateThrowsException()
+ {
+ $baseDir = realpath(dirname(__FILE__) . '/../../../fixtures/templates');
+ $loader = new Mustache_Loader_FilesystemLoader($baseDir);
+
+ $loader->load('fake');
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/Loader/InlineLoaderTest.php b/vendor/mustache/mustache/test/Mustache/Test/Loader/InlineLoaderTest.php
new file mode 100644
index 0000000..2f1d414
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/Loader/InlineLoaderTest.php
@@ -0,0 +1,56 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2015 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @group unit
+ */
+class Mustache_Test_Loader_InlineLoaderTest extends PHPUnit_Framework_TestCase
+{
+ public function testLoadTemplates()
+ {
+ $loader = new Mustache_Loader_InlineLoader(__FILE__, __COMPILER_HALT_OFFSET__);
+ $this->assertEquals('{{ foo }}', $loader->load('foo'));
+ $this->assertEquals('{{#bar}}BAR{{/bar}}', $loader->load('bar'));
+ }
+
+ /**
+ * @expectedException Mustache_Exception_UnknownTemplateException
+ */
+ public function testMissingTemplatesThrowExceptions()
+ {
+ $loader = new Mustache_Loader_InlineLoader(__FILE__, __COMPILER_HALT_OFFSET__);
+ $loader->load('not_a_real_template');
+ }
+
+ /**
+ * @expectedException Mustache_Exception_InvalidArgumentException
+ */
+ public function testInvalidOffsetThrowsException()
+ {
+ new Mustache_Loader_InlineLoader(__FILE__, 'notanumber');
+ }
+
+ /**
+ * @expectedException Mustache_Exception_InvalidArgumentException
+ */
+ public function testInvalidFileThrowsException()
+ {
+ new Mustache_Loader_InlineLoader('notarealfile', __COMPILER_HALT_OFFSET__);
+ }
+}
+
+__halt_compiler();
+
+@@ foo
+{{ foo }}
+
+@@ bar
+{{#bar}}BAR{{/bar}}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/Loader/StringLoaderTest.php b/vendor/mustache/mustache/test/Mustache/Test/Loader/StringLoaderTest.php
new file mode 100644
index 0000000..f2e47d9
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/Loader/StringLoaderTest.php
@@ -0,0 +1,25 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @group unit
+ */
+class Mustache_Test_Loader_StringLoaderTest extends PHPUnit_Framework_TestCase
+{
+ public function testLoadTemplates()
+ {
+ $loader = new Mustache_Loader_StringLoader();
+
+ $this->assertEquals('foo', $loader->load('foo'));
+ $this->assertEquals('{{ bar }}', $loader->load('{{ bar }}'));
+ $this->assertEquals("\n{{! comment }}\n", $loader->load("\n{{! comment }}\n"));
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/Logger/AbstractLoggerTest.php b/vendor/mustache/mustache/test/Mustache/Test/Logger/AbstractLoggerTest.php
new file mode 100644
index 0000000..e8865e9
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/Logger/AbstractLoggerTest.php
@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @group unit
+ */
+class Mustache_Test_Logger_AbstractLoggerTest extends PHPUnit_Framework_TestCase
+{
+ public function testEverything()
+ {
+ $logger = new Mustache_Test_Logger_TestLogger();
+
+ $logger->emergency('emergency message');
+ $logger->alert('alert message');
+ $logger->critical('critical message');
+ $logger->error('error message');
+ $logger->warning('warning message');
+ $logger->notice('notice message');
+ $logger->info('info message');
+ $logger->debug('debug message');
+
+ $expected = array(
+ array(Mustache_Logger::EMERGENCY, 'emergency message', array()),
+ array(Mustache_Logger::ALERT, 'alert message', array()),
+ array(Mustache_Logger::CRITICAL, 'critical message', array()),
+ array(Mustache_Logger::ERROR, 'error message', array()),
+ array(Mustache_Logger::WARNING, 'warning message', array()),
+ array(Mustache_Logger::NOTICE, 'notice message', array()),
+ array(Mustache_Logger::INFO, 'info message', array()),
+ array(Mustache_Logger::DEBUG, 'debug message', array()),
+ );
+
+ $this->assertEquals($expected, $logger->log);
+ }
+}
+
+class Mustache_Test_Logger_TestLogger extends Mustache_Logger_AbstractLogger
+{
+ public $log = array();
+
+ /**
+ * Logs with an arbitrary level.
+ *
+ * @param mixed $level
+ * @param string $message
+ * @param array $context
+ */
+ public function log($level, $message, array $context = array())
+ {
+ $this->log[] = array($level, $message, $context);
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/Logger/StreamLoggerTest.php b/vendor/mustache/mustache/test/Mustache/Test/Logger/StreamLoggerTest.php
new file mode 100644
index 0000000..6cb198a
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/Logger/StreamLoggerTest.php
@@ -0,0 +1,209 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @group unit
+ */
+class Mustache_Test_Logger_StreamLoggerTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider acceptsStreamData
+ */
+ public function testAcceptsStream($name, $stream)
+ {
+ $logger = new Mustache_Logger_StreamLogger($stream);
+ $logger->log(Mustache_Logger::CRITICAL, 'message');
+
+ $this->assertEquals("CRITICAL: message\n", file_get_contents($name));
+ }
+
+ public function acceptsStreamData()
+ {
+ $one = tempnam(sys_get_temp_dir(), 'mustache-test');
+ $two = tempnam(sys_get_temp_dir(), 'mustache-test');
+
+ return array(
+ array($one, $one),
+ array($two, fopen($two, 'a')),
+ );
+ }
+
+ /**
+ * @expectedException Mustache_Exception_LogicException
+ */
+ public function testPrematurelyClosedStreamThrowsException()
+ {
+ $stream = tmpfile();
+ $logger = new Mustache_Logger_StreamLogger($stream);
+ fclose($stream);
+
+ $logger->log(Mustache_Logger::CRITICAL, 'message');
+ }
+
+ /**
+ * @dataProvider getLevels
+ */
+ public function testLoggingThresholds($logLevel, $level, $shouldLog)
+ {
+ $stream = tmpfile();
+ $logger = new Mustache_Logger_StreamLogger($stream, $logLevel);
+ $logger->log($level, 'logged');
+
+ rewind($stream);
+ $result = fread($stream, 1024);
+
+ if ($shouldLog) {
+ $this->assertContains('logged', $result);
+ } else {
+ $this->assertEmpty($result);
+ }
+ }
+
+ public function getLevels()
+ {
+ // $logLevel, $level, $shouldLog
+ return array(
+ // identities
+ array(Mustache_Logger::EMERGENCY, Mustache_Logger::EMERGENCY, true),
+ array(Mustache_Logger::ALERT, Mustache_Logger::ALERT, true),
+ array(Mustache_Logger::CRITICAL, Mustache_Logger::CRITICAL, true),
+ array(Mustache_Logger::ERROR, Mustache_Logger::ERROR, true),
+ array(Mustache_Logger::WARNING, Mustache_Logger::WARNING, true),
+ array(Mustache_Logger::NOTICE, Mustache_Logger::NOTICE, true),
+ array(Mustache_Logger::INFO, Mustache_Logger::INFO, true),
+ array(Mustache_Logger::DEBUG, Mustache_Logger::DEBUG, true),
+
+ // one above
+ array(Mustache_Logger::ALERT, Mustache_Logger::EMERGENCY, true),
+ array(Mustache_Logger::CRITICAL, Mustache_Logger::ALERT, true),
+ array(Mustache_Logger::ERROR, Mustache_Logger::CRITICAL, true),
+ array(Mustache_Logger::WARNING, Mustache_Logger::ERROR, true),
+ array(Mustache_Logger::NOTICE, Mustache_Logger::WARNING, true),
+ array(Mustache_Logger::INFO, Mustache_Logger::NOTICE, true),
+ array(Mustache_Logger::DEBUG, Mustache_Logger::INFO, true),
+
+ // one below
+ array(Mustache_Logger::EMERGENCY, Mustache_Logger::ALERT, false),
+ array(Mustache_Logger::ALERT, Mustache_Logger::CRITICAL, false),
+ array(Mustache_Logger::CRITICAL, Mustache_Logger::ERROR, false),
+ array(Mustache_Logger::ERROR, Mustache_Logger::WARNING, false),
+ array(Mustache_Logger::WARNING, Mustache_Logger::NOTICE, false),
+ array(Mustache_Logger::NOTICE, Mustache_Logger::INFO, false),
+ array(Mustache_Logger::INFO, Mustache_Logger::DEBUG, false),
+ );
+ }
+
+ /**
+ * @dataProvider getLogMessages
+ */
+ public function testLogging($level, $message, $context, $expected)
+ {
+ $stream = tmpfile();
+ $logger = new Mustache_Logger_StreamLogger($stream, Mustache_Logger::DEBUG);
+ $logger->log($level, $message, $context);
+
+ rewind($stream);
+ $result = fread($stream, 1024);
+
+ $this->assertEquals($expected, $result);
+ }
+
+ public function getLogMessages()
+ {
+ // $level, $message, $context, $expected
+ return array(
+ array(Mustache_Logger::DEBUG, 'debug message', array(), "DEBUG: debug message\n"),
+ array(Mustache_Logger::INFO, 'info message', array(), "INFO: info message\n"),
+ array(Mustache_Logger::NOTICE, 'notice message', array(), "NOTICE: notice message\n"),
+ array(Mustache_Logger::WARNING, 'warning message', array(), "WARNING: warning message\n"),
+ array(Mustache_Logger::ERROR, 'error message', array(), "ERROR: error message\n"),
+ array(Mustache_Logger::CRITICAL, 'critical message', array(), "CRITICAL: critical message\n"),
+ array(Mustache_Logger::ALERT, 'alert message', array(), "ALERT: alert message\n"),
+ array(Mustache_Logger::EMERGENCY, 'emergency message', array(), "EMERGENCY: emergency message\n"),
+
+ // with context
+ array(
+ Mustache_Logger::ERROR,
+ 'error message',
+ array('name' => 'foo', 'number' => 42),
+ "ERROR: error message\n",
+ ),
+
+ // with interpolation
+ array(
+ Mustache_Logger::ERROR,
+ 'error {name}-{number}',
+ array('name' => 'foo', 'number' => 42),
+ "ERROR: error foo-42\n",
+ ),
+
+ // with iterpolation false positive
+ array(
+ Mustache_Logger::ERROR,
+ 'error {nothing}',
+ array('name' => 'foo', 'number' => 42),
+ "ERROR: error {nothing}\n",
+ ),
+
+ // with interpolation injection
+ array(
+ Mustache_Logger::ERROR,
+ '{foo}',
+ array('foo' => '{bar}', 'bar' => 'FAIL'),
+ "ERROR: {bar}\n",
+ ),
+ );
+ }
+
+ public function testChangeLoggingLevels()
+ {
+ $stream = tmpfile();
+ $logger = new Mustache_Logger_StreamLogger($stream);
+
+ $logger->setLevel(Mustache_Logger::ERROR);
+ $this->assertEquals(Mustache_Logger::ERROR, $logger->getLevel());
+
+ $logger->log(Mustache_Logger::WARNING, 'ignore this');
+
+ $logger->setLevel(Mustache_Logger::INFO);
+ $this->assertEquals(Mustache_Logger::INFO, $logger->getLevel());
+
+ $logger->log(Mustache_Logger::WARNING, 'log this');
+
+ $logger->setLevel(Mustache_Logger::CRITICAL);
+ $this->assertEquals(Mustache_Logger::CRITICAL, $logger->getLevel());
+
+ $logger->log(Mustache_Logger::ERROR, 'ignore this');
+
+ rewind($stream);
+ $result = fread($stream, 1024);
+
+ $this->assertEquals("WARNING: log this\n", $result);
+ }
+
+ /**
+ * @expectedException Mustache_Exception_InvalidArgumentException
+ */
+ public function testThrowsInvalidArgumentExceptionWhenSettingUnknownLevels()
+ {
+ $logger = new Mustache_Logger_StreamLogger(tmpfile());
+ $logger->setLevel('bacon');
+ }
+
+ /**
+ * @expectedException Mustache_Exception_InvalidArgumentException
+ */
+ public function testThrowsInvalidArgumentExceptionWhenLoggingUnknownLevels()
+ {
+ $logger = new Mustache_Logger_StreamLogger(tmpfile());
+ $logger->log('bacon', 'CODE BACON ERROR!');
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/ParserTest.php b/vendor/mustache/mustache/test/Mustache/Test/ParserTest.php
new file mode 100644
index 0000000..85e5701
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/ParserTest.php
@@ -0,0 +1,425 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @group unit
+ */
+class Mustache_Test_ParserTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getTokenSets
+ */
+ public function testParse($tokens, $expected)
+ {
+ $parser = new Mustache_Parser();
+ $this->assertEquals($expected, $parser->parse($tokens));
+ }
+
+ public function getTokenSets()
+ {
+ return array(
+ array(
+ array(),
+ array(),
+ ),
+
+ array(
+ array(array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::VALUE => 'text',
+ )),
+ array(array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::VALUE => 'text',
+ )),
+ ),
+
+ array(
+ array(array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::NAME => 'name',
+ )),
+ array(array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::NAME => 'name',
+ )),
+ ),
+
+ array(
+ array(
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::VALUE => 'foo',
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_INVERTED,
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::INDEX => 123,
+ Mustache_Tokenizer::NAME => 'parent',
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::NAME => 'name',
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_END_SECTION,
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::INDEX => 456,
+ Mustache_Tokenizer::NAME => 'parent',
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::VALUE => 'bar',
+ ),
+ ),
+
+ array(
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::VALUE => 'foo',
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_INVERTED,
+ Mustache_Tokenizer::NAME => 'parent',
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::INDEX => 123,
+ Mustache_Tokenizer::END => 456,
+ Mustache_Tokenizer::NODES => array(
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::NAME => 'name',
+ ),
+ ),
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::VALUE => 'bar',
+ ),
+ ),
+ ),
+
+ // This *would* be an invalid inheritance parse tree, but that pragma
+ // isn't enabled so it'll thunk it back into an "escaped" token:
+ array(
+ array(
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_BLOCK_VAR,
+ Mustache_Tokenizer::NAME => 'foo',
+ Mustache_Tokenizer::OTAG => '{{',
+ Mustache_Tokenizer::CTAG => '}}',
+ Mustache_Tokenizer::LINE => 0,
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::VALUE => 'bar',
+ ),
+ ),
+ array(
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
+ Mustache_Tokenizer::NAME => '$foo',
+ Mustache_Tokenizer::OTAG => '{{',
+ Mustache_Tokenizer::CTAG => '}}',
+ Mustache_Tokenizer::LINE => 0,
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::VALUE => 'bar',
+ ),
+ ),
+ ),
+
+ array(
+ array(
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::VALUE => ' ',
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_DELIM_CHANGE,
+ Mustache_Tokenizer::LINE => 0,
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::VALUE => " \n",
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
+ Mustache_Tokenizer::NAME => 'foo',
+ Mustache_Tokenizer::OTAG => '[[',
+ Mustache_Tokenizer::CTAG => ']]',
+ Mustache_Tokenizer::LINE => 1,
+ ),
+ ),
+ array(
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
+ Mustache_Tokenizer::NAME => 'foo',
+ Mustache_Tokenizer::OTAG => '[[',
+ Mustache_Tokenizer::CTAG => ']]',
+ Mustache_Tokenizer::LINE => 1,
+ ),
+ ),
+ ),
+
+ );
+ }
+
+ /**
+ * @dataProvider getInheritanceTokenSets
+ */
+ public function testParseWithInheritance($tokens, $expected)
+ {
+ $parser = new Mustache_Parser();
+ $parser->setPragmas(array(Mustache_Engine::PRAGMA_BLOCKS));
+ $this->assertEquals($expected, $parser->parse($tokens));
+ }
+
+ public function getInheritanceTokenSets()
+ {
+ return array(
+ array(
+ array(
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_PARENT,
+ Mustache_Tokenizer::NAME => 'foo',
+ Mustache_Tokenizer::OTAG => '{{',
+ Mustache_Tokenizer::CTAG => '}}',
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::INDEX => 8,
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_BLOCK_VAR,
+ Mustache_Tokenizer::NAME => 'bar',
+ Mustache_Tokenizer::OTAG => '{{',
+ Mustache_Tokenizer::CTAG => '}}',
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::INDEX => 16,
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::VALUE => 'baz',
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_END_SECTION,
+ Mustache_Tokenizer::NAME => 'bar',
+ Mustache_Tokenizer::OTAG => '{{',
+ Mustache_Tokenizer::CTAG => '}}',
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::INDEX => 19,
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_END_SECTION,
+ Mustache_Tokenizer::NAME => 'foo',
+ Mustache_Tokenizer::OTAG => '{{',
+ Mustache_Tokenizer::CTAG => '}}',
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::INDEX => 27,
+ ),
+ ),
+ array(
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_PARENT,
+ Mustache_Tokenizer::NAME => 'foo',
+ Mustache_Tokenizer::OTAG => '{{',
+ Mustache_Tokenizer::CTAG => '}}',
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::INDEX => 8,
+ Mustache_Tokenizer::END => 27,
+ Mustache_Tokenizer::NODES => array(
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_BLOCK_ARG,
+ Mustache_Tokenizer::NAME => 'bar',
+ Mustache_Tokenizer::OTAG => '{{',
+ Mustache_Tokenizer::CTAG => '}}',
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::INDEX => 16,
+ Mustache_Tokenizer::END => 19,
+ Mustache_Tokenizer::NODES => array(
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::VALUE => 'baz',
+ ),
+ ),
+ ),
+ ),
+ ),
+ ),
+ ),
+
+ array(
+ array(
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_BLOCK_VAR,
+ Mustache_Tokenizer::NAME => 'foo',
+ Mustache_Tokenizer::OTAG => '{{',
+ Mustache_Tokenizer::CTAG => '}}',
+ Mustache_Tokenizer::LINE => 0,
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::VALUE => 'bar',
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_END_SECTION,
+ Mustache_Tokenizer::NAME => 'foo',
+ Mustache_Tokenizer::OTAG => '{{',
+ Mustache_Tokenizer::CTAG => '}}',
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::INDEX => 11,
+ ),
+ ),
+ array(
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_BLOCK_VAR,
+ Mustache_Tokenizer::NAME => 'foo',
+ Mustache_Tokenizer::OTAG => '{{',
+ Mustache_Tokenizer::CTAG => '}}',
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::END => 11,
+ Mustache_Tokenizer::NODES => array(
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::VALUE => 'bar',
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider getBadParseTrees
+ * @expectedException Mustache_Exception_SyntaxException
+ */
+ public function testParserThrowsExceptions($tokens)
+ {
+ $parser = new Mustache_Parser();
+ $parser->parse($tokens);
+ }
+
+ public function getBadParseTrees()
+ {
+ return array(
+ // no close
+ array(
+ array(
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_SECTION,
+ Mustache_Tokenizer::NAME => 'parent',
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::INDEX => 123,
+ ),
+ ),
+ ),
+
+ // no close inverted
+ array(
+ array(
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_INVERTED,
+ Mustache_Tokenizer::NAME => 'parent',
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::INDEX => 123,
+ ),
+ ),
+ ),
+
+ // no opening inverted
+ array(
+ array(
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_END_SECTION,
+ Mustache_Tokenizer::NAME => 'parent',
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::INDEX => 123,
+ ),
+ ),
+ ),
+
+ // weird nesting
+ array(
+ array(
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_SECTION,
+ Mustache_Tokenizer::NAME => 'parent',
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::INDEX => 123,
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_SECTION,
+ Mustache_Tokenizer::NAME => 'child',
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::INDEX => 123,
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_END_SECTION,
+ Mustache_Tokenizer::NAME => 'parent',
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::INDEX => 123,
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_END_SECTION,
+ Mustache_Tokenizer::NAME => 'child',
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::INDEX => 123,
+ ),
+ ),
+ ),
+
+ // This *would* be a valid inheritance parse tree, but that pragma
+ // isn't enabled here so it's going to fail :)
+ array(
+ array(
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_BLOCK_VAR,
+ Mustache_Tokenizer::NAME => 'foo',
+ Mustache_Tokenizer::OTAG => '{{',
+ Mustache_Tokenizer::CTAG => '}}',
+ Mustache_Tokenizer::LINE => 0,
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::VALUE => 'bar',
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_END_SECTION,
+ Mustache_Tokenizer::NAME => 'foo',
+ Mustache_Tokenizer::OTAG => '{{',
+ Mustache_Tokenizer::CTAG => '}}',
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::INDEX => 11,
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/SpecTestCase.php b/vendor/mustache/mustache/test/Mustache/Test/SpecTestCase.php
new file mode 100644
index 0000000..9fb4a15
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/SpecTestCase.php
@@ -0,0 +1,67 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+abstract class Mustache_Test_SpecTestCase extends PHPUnit_Framework_TestCase
+{
+ protected static $mustache;
+
+ public static function setUpBeforeClass()
+ {
+ self::$mustache = new Mustache_Engine();
+ }
+
+ protected static function loadTemplate($source, $partials)
+ {
+ self::$mustache->setPartials($partials);
+
+ return self::$mustache->loadTemplate($source);
+ }
+
+ /**
+ * Data provider for the mustache spec test.
+ *
+ * Loads YAML files from the spec and converts them to PHPisms.
+ *
+ * @param string $name
+ *
+ * @return array
+ */
+ protected function loadSpec($name)
+ {
+ $filename = dirname(__FILE__) . '/../../../vendor/spec/specs/' . $name . '.yml';
+ if (!file_exists($filename)) {
+ return array();
+ }
+
+ $data = array();
+ $yaml = new sfYamlParser();
+ $file = file_get_contents($filename);
+
+ // @hack: pre-process the 'lambdas' spec so the Symfony YAML parser doesn't complain.
+ if ($name === '~lambdas') {
+ $file = str_replace(" !code\n", "\n", $file);
+ }
+
+ $spec = $yaml->parse($file);
+
+ foreach ($spec['tests'] as $test) {
+ $data[] = array(
+ $test['name'] . ': ' . $test['desc'],
+ $test['template'],
+ isset($test['partials']) ? $test['partials'] : array(),
+ $test['data'],
+ $test['expected'],
+ );
+ }
+
+ return $data;
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/TemplateTest.php b/vendor/mustache/mustache/test/Mustache/Test/TemplateTest.php
new file mode 100644
index 0000000..bb260d2
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/TemplateTest.php
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @group unit
+ */
+class Mustache_Test_TemplateTest extends PHPUnit_Framework_TestCase
+{
+ public function testConstructor()
+ {
+ $mustache = new Mustache_Engine();
+ $template = new Mustache_Test_TemplateStub($mustache);
+ $this->assertSame($mustache, $template->getMustache());
+ }
+
+ public function testRendering()
+ {
+ $rendered = '<< wheee >>';
+ $mustache = new Mustache_Engine();
+ $template = new Mustache_Test_TemplateStub($mustache);
+ $template->rendered = $rendered;
+ $context = new Mustache_Context();
+
+ if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
+ $this->assertEquals($rendered, $template());
+ }
+
+ $this->assertEquals($rendered, $template->render());
+ $this->assertEquals($rendered, $template->renderInternal($context));
+ $this->assertEquals($rendered, $template->render(array('foo' => 'bar')));
+ }
+}
+
+class Mustache_Test_TemplateStub extends Mustache_Template
+{
+ public $rendered;
+
+ public function getMustache()
+ {
+ return $this->mustache;
+ }
+
+ public function renderInternal(Mustache_Context $context, $indent = '', $escape = false)
+ {
+ return $this->rendered;
+ }
+}
diff --git a/vendor/mustache/mustache/test/Mustache/Test/TokenizerTest.php b/vendor/mustache/mustache/test/Mustache/Test/TokenizerTest.php
new file mode 100644
index 0000000..09be3fe
--- /dev/null
+++ b/vendor/mustache/mustache/test/Mustache/Test/TokenizerTest.php
@@ -0,0 +1,306 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @group unit
+ */
+class Mustache_Test_TokenizerTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getTokens
+ */
+ public function testScan($text, $delimiters, $expected)
+ {
+ $tokenizer = new Mustache_Tokenizer();
+ $this->assertSame($expected, $tokenizer->scan($text, $delimiters));
+ }
+
+ /**
+ * @expectedException Mustache_Exception_SyntaxException
+ */
+ public function testUnevenBracesThrowExceptions()
+ {
+ $tokenizer = new Mustache_Tokenizer();
+
+ $text = '{{{ name }}';
+ $tokenizer->scan($text, null);
+ }
+
+ /**
+ * @expectedException Mustache_Exception_SyntaxException
+ */
+ public function testUnevenBracesWithCustomDelimiterThrowExceptions()
+ {
+ $tokenizer = new Mustache_Tokenizer();
+
+ $text = '<%{ name %>';
+ $tokenizer->scan($text, '<% %>');
+ }
+
+ public function getTokens()
+ {
+ return array(
+ array(
+ 'text',
+ null,
+ array(
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::VALUE => 'text',
+ ),
+ ),
+ ),
+
+ array(
+ 'text',
+ '<<< >>>',
+ array(
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::VALUE => 'text',
+ ),
+ ),
+ ),
+
+ array(
+ '{{ name }}',
+ null,
+ array(
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
+ Mustache_Tokenizer::NAME => 'name',
+ Mustache_Tokenizer::OTAG => '{{',
+ Mustache_Tokenizer::CTAG => '}}',
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::INDEX => 10,
+ ),
+ ),
+ ),
+
+ array(
+ '{{ name }}',
+ '<<< >>>',
+ array(
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::VALUE => '{{ name }}',
+ ),
+ ),
+ ),
+
+ array(
+ '<<< name >>>',
+ '<<< >>>',
+ array(
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
+ Mustache_Tokenizer::NAME => 'name',
+ Mustache_Tokenizer::OTAG => '<<<',
+ Mustache_Tokenizer::CTAG => '>>>',
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::INDEX => 12,
+ ),
+ ),
+ ),
+
+ array(
+ "{{{ a }}}\n{{# b }} \n{{= | | =}}| c ||/ b |\n|{ d }|",
+ null,
+ array(
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_UNESCAPED,
+ Mustache_Tokenizer::NAME => 'a',
+ Mustache_Tokenizer::OTAG => '{{',
+ Mustache_Tokenizer::CTAG => '}}',
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::INDEX => 8,
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::VALUE => "\n",
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_SECTION,
+ Mustache_Tokenizer::NAME => 'b',
+ Mustache_Tokenizer::OTAG => '{{',
+ Mustache_Tokenizer::CTAG => '}}',
+ Mustache_Tokenizer::LINE => 1,
+ Mustache_Tokenizer::INDEX => 18,
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
+ Mustache_Tokenizer::LINE => 1,
+ Mustache_Tokenizer::VALUE => " \n",
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_DELIM_CHANGE,
+ Mustache_Tokenizer::LINE => 2,
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
+ Mustache_Tokenizer::NAME => 'c',
+ Mustache_Tokenizer::OTAG => '|',
+ Mustache_Tokenizer::CTAG => '|',
+ Mustache_Tokenizer::LINE => 2,
+ Mustache_Tokenizer::INDEX => 37,
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_END_SECTION,
+ Mustache_Tokenizer::NAME => 'b',
+ Mustache_Tokenizer::OTAG => '|',
+ Mustache_Tokenizer::CTAG => '|',
+ Mustache_Tokenizer::LINE => 2,
+ Mustache_Tokenizer::INDEX => 37,
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
+ Mustache_Tokenizer::LINE => 2,
+ Mustache_Tokenizer::VALUE => "\n",
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_UNESCAPED,
+ Mustache_Tokenizer::NAME => 'd',
+ Mustache_Tokenizer::OTAG => '|',
+ Mustache_Tokenizer::CTAG => '|',
+ Mustache_Tokenizer::LINE => 3,
+ Mustache_Tokenizer::INDEX => 51,
+ ),
+
+ ),
+ ),
+
+ // See https://github.com/bobthecow/mustache.php/issues/183
+ array(
+ '{{# a }}0{{/ a }}',
+ null,
+ array(
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_SECTION,
+ Mustache_Tokenizer::NAME => 'a',
+ Mustache_Tokenizer::OTAG => '{{',
+ Mustache_Tokenizer::CTAG => '}}',
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::INDEX => 8,
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::VALUE => '0',
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_END_SECTION,
+ Mustache_Tokenizer::NAME => 'a',
+ Mustache_Tokenizer::OTAG => '{{',
+ Mustache_Tokenizer::CTAG => '}}',
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::INDEX => 9,
+ ),
+ ),
+ ),
+
+ // custom delimiters don't swallow the next character, even if it is a }, }}}, or the same delimiter
+ array(
+ '<% a %>} <% b %>%> <% c %>}}}',
+ '<% %>',
+ array(
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
+ Mustache_Tokenizer::NAME => 'a',
+ Mustache_Tokenizer::OTAG => '<%',
+ Mustache_Tokenizer::CTAG => '%>',
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::INDEX => 7,
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::VALUE => '} ',
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
+ Mustache_Tokenizer::NAME => 'b',
+ Mustache_Tokenizer::OTAG => '<%',
+ Mustache_Tokenizer::CTAG => '%>',
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::INDEX => 16,
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::VALUE => '%> ',
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
+ Mustache_Tokenizer::NAME => 'c',
+ Mustache_Tokenizer::OTAG => '<%',
+ Mustache_Tokenizer::CTAG => '%>',
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::INDEX => 26,
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::VALUE => '}}}',
+ ),
+ ),
+ ),
+
+ // unescaped custom delimiters are properly parsed
+ array(
+ '<%{ a }%>',
+ '<% %>',
+ array(
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_UNESCAPED,
+ Mustache_Tokenizer::NAME => 'a',
+ Mustache_Tokenizer::OTAG => '<%',
+ Mustache_Tokenizer::CTAG => '%>',
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::INDEX => 9,
+ ),
+ ),
+ ),
+
+ // Ensure that $arg token is not picked up during tokenization
+ array(
+ '{{$arg}}default{{/arg}}',
+ null,
+ array(
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_BLOCK_VAR,
+ Mustache_Tokenizer::NAME => 'arg',
+ Mustache_Tokenizer::OTAG => '{{',
+ Mustache_Tokenizer::CTAG => '}}',
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::INDEX => 8,
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::VALUE => 'default',
+ ),
+ array(
+ Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_END_SECTION,
+ Mustache_Tokenizer::NAME => 'arg',
+ Mustache_Tokenizer::OTAG => '{{',
+ Mustache_Tokenizer::CTAG => '}}',
+ Mustache_Tokenizer::LINE => 0,
+ Mustache_Tokenizer::INDEX => 15,
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/vendor/mustache/mustache/test/bootstrap.php b/vendor/mustache/mustache/test/bootstrap.php
new file mode 100644
index 0000000..21fc689
--- /dev/null
+++ b/vendor/mustache/mustache/test/bootstrap.php
@@ -0,0 +1,91 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+require dirname(__FILE__) . '/../src/Mustache/Autoloader.php';
+Mustache_Autoloader::register();
+Mustache_Autoloader::register(dirname(__FILE__) . '/../test');
+
+require dirname(__FILE__) . '/../vendor/yaml/lib/sfYamlParser.php';
+
+/**
+ * Minimal stream wrapper to test protocol-based access to templates.
+ */
+class TestStream
+{
+ private $filehandle;
+
+ /**
+ * Always returns false.
+ *
+ * @param string $path
+ * @param int $flags
+ *
+ * @return array
+ */
+ public function url_stat($path, $flags)
+ {
+ return false;
+ }
+
+ /**
+ * Open the file.
+ *
+ * @param string $path
+ * @param string $mode
+ *
+ * @return bool
+ */
+ public function stream_open($path, $mode)
+ {
+ $path = preg_replace('-^test://-', '', $path);
+ $this->filehandle = fopen($path, $mode);
+
+ return $this->filehandle !== false;
+ }
+
+ /**
+ * @return array
+ */
+ public function stream_stat()
+ {
+ return array();
+ }
+
+ /**
+ * @param int $count
+ *
+ * @return string
+ */
+ public function stream_read($count)
+ {
+ return fgets($this->filehandle, $count);
+ }
+
+ /**
+ * @return bool
+ */
+ public function stream_eof()
+ {
+ return feof($this->filehandle);
+ }
+
+ /**
+ * @return bool
+ */
+ public function stream_close()
+ {
+ return fclose($this->filehandle);
+ }
+}
+
+if (!stream_wrapper_register('test', 'TestStream')) {
+ die('Failed to register protocol');
+}
diff --git a/vendor/mustache/mustache/test/fixtures/autoloader/Mustache/Bar.php b/vendor/mustache/mustache/test/fixtures/autoloader/Mustache/Bar.php
new file mode 100644
index 0000000..8092722
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/autoloader/Mustache/Bar.php
@@ -0,0 +1,15 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Mustache_Bar
+{
+ // nada
+}
diff --git a/vendor/mustache/mustache/test/fixtures/autoloader/Mustache/Foo.php b/vendor/mustache/mustache/test/fixtures/autoloader/Mustache/Foo.php
new file mode 100644
index 0000000..7e6ef3a
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/autoloader/Mustache/Foo.php
@@ -0,0 +1,15 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Mustache_Foo
+{
+ // nada
+}
diff --git a/vendor/mustache/mustache/test/fixtures/autoloader/NonMustacheClass.php b/vendor/mustache/mustache/test/fixtures/autoloader/NonMustacheClass.php
new file mode 100644
index 0000000..d8d5929
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/autoloader/NonMustacheClass.php
@@ -0,0 +1,15 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class NonMustacheClass
+{
+ // noop
+}
diff --git a/vendor/mustache/mustache/test/fixtures/examples/blocks/Blocks.php b/vendor/mustache/mustache/test/fixtures/examples/blocks/Blocks.php
new file mode 100644
index 0000000..2a7cb20
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/blocks/Blocks.php
@@ -0,0 +1,15 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Blocks
+{
+ public $items = array(1, 2, 3);
+}
diff --git a/vendor/mustache/mustache/test/fixtures/examples/blocks/blocks.mustache b/vendor/mustache/mustache/test/fixtures/examples/blocks/blocks.mustache
new file mode 100644
index 0000000..a9fff39
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/blocks/blocks.mustache
@@ -0,0 +1,4 @@
+{{% BLOCKS }}
+{{< parent }}
+{{$ value }}[{{ . }}]{{/ value }}
+{{/ parent }} \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/blocks/blocks.txt b/vendor/mustache/mustache/test/fixtures/examples/blocks/blocks.txt
new file mode 100644
index 0000000..2749019
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/blocks/blocks.txt
@@ -0,0 +1,3 @@
+[1]
+[2]
+[3]
diff --git a/vendor/mustache/mustache/test/fixtures/examples/blocks/partials/parent.mustache b/vendor/mustache/mustache/test/fixtures/examples/blocks/partials/parent.mustache
new file mode 100644
index 0000000..cbb30f0
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/blocks/partials/parent.mustache
@@ -0,0 +1,4 @@
+{{% BLOCKS }}
+{{# items }}
+{{$ value }}ignored{{/ value }}
+{{/ items }} \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/child_context/ChildContext.php b/vendor/mustache/mustache/test/fixtures/examples/child_context/ChildContext.php
new file mode 100644
index 0000000..9ef84ae
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/child_context/ChildContext.php
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class ChildContext
+{
+ public $parent = array(
+ 'child' => 'child works',
+ );
+
+ public $grandparent = array(
+ 'parent' => array(
+ 'child' => 'grandchild works',
+ ),
+ );
+}
diff --git a/vendor/mustache/mustache/test/fixtures/examples/child_context/child_context.mustache b/vendor/mustache/mustache/test/fixtures/examples/child_context/child_context.mustache
new file mode 100644
index 0000000..e1f2ebc
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/child_context/child_context.mustache
@@ -0,0 +1,2 @@
+<h1>{{#parent}}{{child}}{{/parent}}</h1>
+<h2>{{#grandparent}}{{#parent}}{{child}}{{/parent}}{{/grandparent}}</h2> \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/child_context/child_context.txt b/vendor/mustache/mustache/test/fixtures/examples/child_context/child_context.txt
new file mode 100644
index 0000000..cfb76bf
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/child_context/child_context.txt
@@ -0,0 +1,2 @@
+<h1>child works</h1>
+<h2>grandchild works</h2> \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/comments/Comments.php b/vendor/mustache/mustache/test/fixtures/examples/comments/Comments.php
new file mode 100644
index 0000000..690d139
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/comments/Comments.php
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Comments
+{
+ public function title()
+ {
+ return 'A Comedy of Errors';
+ }
+}
diff --git a/vendor/mustache/mustache/test/fixtures/examples/comments/comments.mustache b/vendor/mustache/mustache/test/fixtures/examples/comments/comments.mustache
new file mode 100644
index 0000000..846e449
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/comments/comments.mustache
@@ -0,0 +1 @@
+<h1>{{title}}{{! just something interesting... #or ^not... }}</h1> \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/comments/comments.txt b/vendor/mustache/mustache/test/fixtures/examples/comments/comments.txt
new file mode 100644
index 0000000..9f40e77
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/comments/comments.txt
@@ -0,0 +1 @@
+<h1>A Comedy of Errors</h1> \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/complex/complex.mustache b/vendor/mustache/mustache/test/fixtures/examples/complex/complex.mustache
new file mode 100644
index 0000000..807c201
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/complex/complex.mustache
@@ -0,0 +1,16 @@
+<h1>{{header}}</h1>
+{{#notEmpty}}
+<ul>
+{{#item}}
+{{#current}}
+ <li><strong>{{name}}</strong></li>
+{{/current}}
+{{^current}}
+ <li><a href="{{url}}">{{name}}</a></li>
+{{/current}}
+{{/item}}
+</ul>
+{{/notEmpty}}
+{{#isEmpty}}
+<p>The list is empty.</p>
+{{/isEmpty}} \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/complex/complex.php b/vendor/mustache/mustache/test/fixtures/examples/complex/complex.php
new file mode 100644
index 0000000..ebb2733
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/complex/complex.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Complex
+{
+ public $header = 'Colors';
+
+ public $item = array(
+ array('name' => 'red', 'current' => true, 'url' => '#Red'),
+ array('name' => 'green', 'current' => false, 'url' => '#Green'),
+ array('name' => 'blue', 'current' => false, 'url' => '#Blue'),
+ );
+
+ public function notEmpty()
+ {
+ return !($this->isEmpty());
+ }
+
+ public function isEmpty()
+ {
+ return count($this->item) === 0;
+ }
+}
diff --git a/vendor/mustache/mustache/test/fixtures/examples/complex/complex.txt b/vendor/mustache/mustache/test/fixtures/examples/complex/complex.txt
new file mode 100644
index 0000000..facee6d
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/complex/complex.txt
@@ -0,0 +1,6 @@
+<h1>Colors</h1>
+<ul>
+ <li><strong>red</strong></li>
+ <li><a href="#Green">green</a></li>
+ <li><a href="#Blue">blue</a></li>
+</ul>
diff --git a/vendor/mustache/mustache/test/fixtures/examples/delimiters/Delimiters.php b/vendor/mustache/mustache/test/fixtures/examples/delimiters/Delimiters.php
new file mode 100644
index 0000000..e3b044d
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/delimiters/Delimiters.php
@@ -0,0 +1,25 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Delimiters
+{
+ public $start = 'It worked the first time.';
+
+ public function middle()
+ {
+ return array(
+ array('item' => 'And it worked the second time.'),
+ array('item' => 'As well as the third.'),
+ );
+ }
+
+ public $final = 'Then, surprisingly, it worked the final time.';
+}
diff --git a/vendor/mustache/mustache/test/fixtures/examples/delimiters/delimiters.mustache b/vendor/mustache/mustache/test/fixtures/examples/delimiters/delimiters.mustache
new file mode 100644
index 0000000..e9b0332
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/delimiters/delimiters.mustache
@@ -0,0 +1,8 @@
+{{=<% %>=}}
+* <% start %>
+<%=| |=%>
+|# middle |
+* | item |
+|/ middle |
+|={{ }}=|
+* {{ final }} \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/delimiters/delimiters.txt b/vendor/mustache/mustache/test/fixtures/examples/delimiters/delimiters.txt
new file mode 100644
index 0000000..e6b2d7a
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/delimiters/delimiters.txt
@@ -0,0 +1,4 @@
+* It worked the first time.
+* And it worked the second time.
+* As well as the third.
+* Then, surprisingly, it worked the final time. \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/dot_notation/DotNotation.php b/vendor/mustache/mustache/test/fixtures/examples/dot_notation/DotNotation.php
new file mode 100644
index 0000000..d400318
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/dot_notation/DotNotation.php
@@ -0,0 +1,24 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class DotNotation
+{
+ public $person = array(
+ 'name' => array('first' => 'Chris', 'last' => 'Firescythe'),
+ 'age' => 24,
+ 'hometown' => array(
+ 'city' => 'Cincinnati',
+ 'state' => 'OH',
+ ),
+ );
+
+ public $normal = 'Normal';
+}
diff --git a/vendor/mustache/mustache/test/fixtures/examples/dot_notation/dot_notation.mustache b/vendor/mustache/mustache/test/fixtures/examples/dot_notation/dot_notation.mustache
new file mode 100644
index 0000000..0566867
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/dot_notation/dot_notation.mustache
@@ -0,0 +1,4 @@
+* {{person.name.first}} {{person.name.last}}
+* {{person.age}}
+* {{person.hometown.city}}, {{person.hometown.state}}
+* {{normal}} \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/dot_notation/dot_notation.txt b/vendor/mustache/mustache/test/fixtures/examples/dot_notation/dot_notation.txt
new file mode 100644
index 0000000..f8cf1fa
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/dot_notation/dot_notation.txt
@@ -0,0 +1,4 @@
+* Chris Firescythe
+* 24
+* Cincinnati, OH
+* Normal \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/double_section/DoubleSection.php b/vendor/mustache/mustache/test/fixtures/examples/double_section/DoubleSection.php
new file mode 100644
index 0000000..6989d95
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/double_section/DoubleSection.php
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class DoubleSection
+{
+ public function t()
+ {
+ return true;
+ }
+
+ public $two = 'second';
+}
diff --git a/vendor/mustache/mustache/test/fixtures/examples/double_section/double_section.mustache b/vendor/mustache/mustache/test/fixtures/examples/double_section/double_section.mustache
new file mode 100644
index 0000000..c831645
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/double_section/double_section.mustache
@@ -0,0 +1,7 @@
+{{#t}}
+* first
+{{/t}}
+* {{two}}
+{{#t}}
+* third
+{{/t}} \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/double_section/double_section.txt b/vendor/mustache/mustache/test/fixtures/examples/double_section/double_section.txt
new file mode 100644
index 0000000..5433688
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/double_section/double_section.txt
@@ -0,0 +1,3 @@
+* first
+* second
+* third
diff --git a/vendor/mustache/mustache/test/fixtures/examples/escaped/Escaped.php b/vendor/mustache/mustache/test/fixtures/examples/escaped/Escaped.php
new file mode 100644
index 0000000..2e5805b
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/escaped/Escaped.php
@@ -0,0 +1,15 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Escaped
+{
+ public $title = '"Bear" > "Shark"';
+}
diff --git a/vendor/mustache/mustache/test/fixtures/examples/escaped/escaped.mustache b/vendor/mustache/mustache/test/fixtures/examples/escaped/escaped.mustache
new file mode 100644
index 0000000..8be4ccb
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/escaped/escaped.mustache
@@ -0,0 +1 @@
+<h1>{{title}}</h1> \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/escaped/escaped.txt b/vendor/mustache/mustache/test/fixtures/examples/escaped/escaped.txt
new file mode 100644
index 0000000..6ba3657
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/escaped/escaped.txt
@@ -0,0 +1 @@
+<h1>&quot;Bear&quot; &gt; &quot;Shark&quot;</h1> \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/filters/Filters.php b/vendor/mustache/mustache/test/fixtures/examples/filters/Filters.php
new file mode 100644
index 0000000..fb7c3f5
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/filters/Filters.php
@@ -0,0 +1,97 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Filters
+{
+ public $states = array(
+ 'al' => 'Alabama',
+ 'ak' => 'Alaska',
+ 'az' => 'Arizona',
+ 'ar' => 'Arkansas',
+ 'ca' => 'California',
+ 'co' => 'Colorado',
+ 'ct' => 'Connecticut',
+ 'de' => 'Delaware',
+ 'fl' => 'Florida',
+ 'ga' => 'Georgia',
+ 'hi' => 'Hawaii',
+ 'id' => 'Idaho',
+ 'il' => 'Illinois',
+ 'in' => 'Indiana',
+ 'ia' => 'Iowa',
+ 'ks' => 'Kansas',
+ 'ky' => 'Kentucky',
+ 'la' => 'Louisiana',
+ 'me' => 'Maine',
+ 'md' => 'Maryland',
+ 'ma' => 'Massachusetts',
+ 'mi' => 'Michigan',
+ 'mn' => 'Minnesota',
+ 'ms' => 'Mississippi',
+ 'mo' => 'Missouri',
+ 'mt' => 'Montana',
+ 'ne' => 'Nebraska',
+ 'nv' => 'Nevada',
+ 'nh' => 'New Hampshire',
+ 'nj' => 'New Jersey',
+ 'nm' => 'New Mexico',
+ 'ny' => 'New York',
+ 'nc' => 'North Carolina',
+ 'nd' => 'North Dakota',
+ 'oh' => 'Ohio',
+ 'ok' => 'Oklahoma',
+ 'or' => 'Oregon',
+ 'pa' => 'Pennsylvania',
+ 'ri' => 'Rhode Island',
+ 'sc' => 'South Carolina',
+ 'sd' => 'South Dakota',
+ 'tn' => 'Tennessee',
+ 'tx' => 'Texas',
+ 'ut' => 'Utah',
+ 'vt' => 'Vermont',
+ 'va' => 'Virginia',
+ 'wa' => 'Washington',
+ 'wv' => 'West Virginia',
+ 'wi' => 'Wisconsin',
+ 'wy' => 'Wyoming',
+ );
+
+ // The next few functions are ugly, because they have to work in PHP 5.2...
+ // for everyone who doesn't have to support 5.2, please, for the love, make
+ // your ViewModel return closures rather than `array($this, '...')`
+ //
+ // :)
+
+ public function upcase()
+ {
+ return array($this, '_upcase');
+ }
+
+ public function _upcase($val)
+ {
+ return strtoupper($val);
+ }
+
+ public function eachPair()
+ {
+ return array($this, '_eachPair');
+ }
+
+ public function _eachPair($val)
+ {
+ $ret = array();
+ foreach ($val as $key => $value) {
+ array_push($ret, compact('key', 'value'));
+ }
+
+ return $ret;
+ }
+}
diff --git a/vendor/mustache/mustache/test/fixtures/examples/filters/filters.mustache b/vendor/mustache/mustache/test/fixtures/examples/filters/filters.mustache
new file mode 100644
index 0000000..50f1465
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/filters/filters.mustache
@@ -0,0 +1,4 @@
+{{%FILTERS}}
+{{# states | eachPair }}
+{{ key | upcase }}: {{ value }}
+{{/ states }} \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/filters/filters.txt b/vendor/mustache/mustache/test/fixtures/examples/filters/filters.txt
new file mode 100644
index 0000000..67466fd
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/filters/filters.txt
@@ -0,0 +1,50 @@
+AL: Alabama
+AK: Alaska
+AZ: Arizona
+AR: Arkansas
+CA: California
+CO: Colorado
+CT: Connecticut
+DE: Delaware
+FL: Florida
+GA: Georgia
+HI: Hawaii
+ID: Idaho
+IL: Illinois
+IN: Indiana
+IA: Iowa
+KS: Kansas
+KY: Kentucky
+LA: Louisiana
+ME: Maine
+MD: Maryland
+MA: Massachusetts
+MI: Michigan
+MN: Minnesota
+MS: Mississippi
+MO: Missouri
+MT: Montana
+NE: Nebraska
+NV: Nevada
+NH: New Hampshire
+NJ: New Jersey
+NM: New Mexico
+NY: New York
+NC: North Carolina
+ND: North Dakota
+OH: Ohio
+OK: Oklahoma
+OR: Oregon
+PA: Pennsylvania
+RI: Rhode Island
+SC: South Carolina
+SD: South Dakota
+TN: Tennessee
+TX: Texas
+UT: Utah
+VT: Vermont
+VA: Virginia
+WA: Washington
+WV: West Virginia
+WI: Wisconsin
+WY: Wyoming
diff --git a/vendor/mustache/mustache/test/fixtures/examples/grand_parent_context/GrandParentContext.php b/vendor/mustache/mustache/test/fixtures/examples/grand_parent_context/GrandParentContext.php
new file mode 100644
index 0000000..e3ea25f
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/grand_parent_context/GrandParentContext.php
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class GrandParentContext
+{
+ public $grand_parent_id = 'grand_parent1';
+ public $parent_contexts = array();
+
+ public function __construct()
+ {
+ $this->parent_contexts[] = array('parent_id' => 'parent1', 'child_contexts' => array(
+ array('child_id' => 'parent1-child1'),
+ array('child_id' => 'parent1-child2'),
+ ));
+
+ $parent2 = new stdClass();
+ $parent2->parent_id = 'parent2';
+ $parent2->child_contexts = array(
+ array('child_id' => 'parent2-child1'),
+ array('child_id' => 'parent2-child2'),
+ );
+
+ $this->parent_contexts[] = $parent2;
+ }
+}
diff --git a/vendor/mustache/mustache/test/fixtures/examples/grand_parent_context/grand_parent_context.mustache b/vendor/mustache/mustache/test/fixtures/examples/grand_parent_context/grand_parent_context.mustache
new file mode 100644
index 0000000..6d03ddf
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/grand_parent_context/grand_parent_context.mustache
@@ -0,0 +1,7 @@
+{{grand_parent_id}}
+{{#parent_contexts}}
+ {{parent_id}} ({{grand_parent_id}})
+ {{#child_contexts}}
+ {{child_id}} ({{parent_id}} << {{grand_parent_id}})
+ {{/child_contexts}}
+{{/parent_contexts}}
diff --git a/vendor/mustache/mustache/test/fixtures/examples/grand_parent_context/grand_parent_context.txt b/vendor/mustache/mustache/test/fixtures/examples/grand_parent_context/grand_parent_context.txt
new file mode 100644
index 0000000..2687f84
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/grand_parent_context/grand_parent_context.txt
@@ -0,0 +1,7 @@
+grand_parent1
+ parent1 (grand_parent1)
+ parent1-child1 (parent1 << grand_parent1)
+ parent1-child2 (parent1 << grand_parent1)
+ parent2 (grand_parent1)
+ parent2-child1 (parent2 << grand_parent1)
+ parent2-child2 (parent2 << grand_parent1)
diff --git a/vendor/mustache/mustache/test/fixtures/examples/i18n/I18n.php b/vendor/mustache/mustache/test/fixtures/examples/i18n/I18n.php
new file mode 100644
index 0000000..77dc7b2
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/i18n/I18n.php
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class I18n
+{
+ // Variable to be interpolated
+ public $name = 'Bob';
+
+ // Add a {{#__}} lambda for i18n
+ public $__ = array(__CLASS__, '__trans');
+
+ // A *very* small i18n dictionary :)
+ private static $dictionary = array(
+ 'Hello.' => 'Hola.',
+ 'My name is {{ name }}.' => 'Me llamo {{ name }}.',
+ );
+
+ public static function __trans($text)
+ {
+ return isset(self::$dictionary[$text]) ? self::$dictionary[$text] : $text;
+ }
+}
diff --git a/vendor/mustache/mustache/test/fixtures/examples/i18n/i18n.mustache b/vendor/mustache/mustache/test/fixtures/examples/i18n/i18n.mustache
new file mode 100644
index 0000000..eef169b
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/i18n/i18n.mustache
@@ -0,0 +1 @@
+{{#__}}Hello.{{/__}} {{#__}}My name is {{ name }}.{{/__}} \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/i18n/i18n.txt b/vendor/mustache/mustache/test/fixtures/examples/i18n/i18n.txt
new file mode 100644
index 0000000..650a71a
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/i18n/i18n.txt
@@ -0,0 +1 @@
+Hola. Me llamo Bob. \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/implicit_iterator/ImplicitIterator.php b/vendor/mustache/mustache/test/fixtures/examples/implicit_iterator/ImplicitIterator.php
new file mode 100644
index 0000000..6a26477
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/implicit_iterator/ImplicitIterator.php
@@ -0,0 +1,15 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class ImplicitIterator
+{
+ public $data = array('Donkey Kong', 'Luigi', 'Mario', 'Peach', 'Yoshi');
+}
diff --git a/vendor/mustache/mustache/test/fixtures/examples/implicit_iterator/implicit_iterator.mustache b/vendor/mustache/mustache/test/fixtures/examples/implicit_iterator/implicit_iterator.mustache
new file mode 100644
index 0000000..b8d58ff
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/implicit_iterator/implicit_iterator.mustache
@@ -0,0 +1,3 @@
+{{#data}}
+* {{.}}
+{{/data}} \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/implicit_iterator/implicit_iterator.txt b/vendor/mustache/mustache/test/fixtures/examples/implicit_iterator/implicit_iterator.txt
new file mode 100644
index 0000000..bd7e945
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/implicit_iterator/implicit_iterator.txt
@@ -0,0 +1,5 @@
+* Donkey Kong
+* Luigi
+* Mario
+* Peach
+* Yoshi
diff --git a/vendor/mustache/mustache/test/fixtures/examples/inverted_double_section/InvertedDoubleSection.php b/vendor/mustache/mustache/test/fixtures/examples/inverted_double_section/InvertedDoubleSection.php
new file mode 100644
index 0000000..7946640
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/inverted_double_section/InvertedDoubleSection.php
@@ -0,0 +1,16 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class InvertedDoubleSection
+{
+ public $t = false;
+ public $two = 'second';
+}
diff --git a/vendor/mustache/mustache/test/fixtures/examples/inverted_double_section/inverted_double_section.mustache b/vendor/mustache/mustache/test/fixtures/examples/inverted_double_section/inverted_double_section.mustache
new file mode 100644
index 0000000..acc3ae0
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/inverted_double_section/inverted_double_section.mustache
@@ -0,0 +1,7 @@
+{{^t}}
+* first
+{{/t}}
+* {{two}}
+{{^t}}
+* third
+{{/t}} \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/inverted_double_section/inverted_double_section.txt b/vendor/mustache/mustache/test/fixtures/examples/inverted_double_section/inverted_double_section.txt
new file mode 100644
index 0000000..5433688
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/inverted_double_section/inverted_double_section.txt
@@ -0,0 +1,3 @@
+* first
+* second
+* third
diff --git a/vendor/mustache/mustache/test/fixtures/examples/inverted_section/InvertedSection.php b/vendor/mustache/mustache/test/fixtures/examples/inverted_section/InvertedSection.php
new file mode 100644
index 0000000..a4ab8d5
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/inverted_section/InvertedSection.php
@@ -0,0 +1,15 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class InvertedSection
+{
+ public $repo = array();
+}
diff --git a/vendor/mustache/mustache/test/fixtures/examples/inverted_section/inverted_section.mustache b/vendor/mustache/mustache/test/fixtures/examples/inverted_section/inverted_section.mustache
new file mode 100644
index 0000000..431073d
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/inverted_section/inverted_section.mustache
@@ -0,0 +1,6 @@
+{{#repo}}
+ <b>{{name}}</b>
+{{/repo}}
+{{^repo}}
+ No repos :(
+{{/repo}} \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/inverted_section/inverted_section.txt b/vendor/mustache/mustache/test/fixtures/examples/inverted_section/inverted_section.txt
new file mode 100644
index 0000000..6ba5a99
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/inverted_section/inverted_section.txt
@@ -0,0 +1 @@
+ No repos :(
diff --git a/vendor/mustache/mustache/test/fixtures/examples/nested_partials/NestedPartials.php b/vendor/mustache/mustache/test/fixtures/examples/nested_partials/NestedPartials.php
new file mode 100644
index 0000000..1a5afd3
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/nested_partials/NestedPartials.php
@@ -0,0 +1,15 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class NestedPartials
+{
+ public $val = 'FOURTH!';
+}
diff --git a/vendor/mustache/mustache/test/fixtures/examples/nested_partials/nested_partials.mustache b/vendor/mustache/mustache/test/fixtures/examples/nested_partials/nested_partials.mustache
new file mode 100644
index 0000000..7b80dc3
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/nested_partials/nested_partials.mustache
@@ -0,0 +1,3 @@
+<first>
+ {{> second }}
+</first> \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/nested_partials/nested_partials.txt b/vendor/mustache/mustache/test/fixtures/examples/nested_partials/nested_partials.txt
new file mode 100644
index 0000000..62776f9
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/nested_partials/nested_partials.txt
@@ -0,0 +1,7 @@
+<first>
+ <second>
+ <third>
+ FOURTH!
+ </third>
+ </second>
+</first> \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/nested_partials/partials/fourth.mustache b/vendor/mustache/mustache/test/fixtures/examples/nested_partials/partials/fourth.mustache
new file mode 100644
index 0000000..727676f
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/nested_partials/partials/fourth.mustache
@@ -0,0 +1 @@
+{{ val }}
diff --git a/vendor/mustache/mustache/test/fixtures/examples/nested_partials/partials/second.mustache b/vendor/mustache/mustache/test/fixtures/examples/nested_partials/partials/second.mustache
new file mode 100644
index 0000000..83f33cf
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/nested_partials/partials/second.mustache
@@ -0,0 +1,3 @@
+<second>
+ {{> third }}
+</second>
diff --git a/vendor/mustache/mustache/test/fixtures/examples/nested_partials/partials/third.mustache b/vendor/mustache/mustache/test/fixtures/examples/nested_partials/partials/third.mustache
new file mode 100644
index 0000000..f33301a
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/nested_partials/partials/third.mustache
@@ -0,0 +1,3 @@
+<third>
+ {{> fourth }}
+</third>
diff --git a/vendor/mustache/mustache/test/fixtures/examples/partials/Partials.php b/vendor/mustache/mustache/test/fixtures/examples/partials/Partials.php
new file mode 100644
index 0000000..1bdaaa1
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/partials/Partials.php
@@ -0,0 +1,19 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Partials
+{
+ public $page = array(
+ 'title' => 'Page Title',
+ 'subtitle' => 'Page Subtitle',
+ 'content' => 'Lorem ipsum dolor sit amet.',
+ );
+}
diff --git a/vendor/mustache/mustache/test/fixtures/examples/partials/partials.mustache b/vendor/mustache/mustache/test/fixtures/examples/partials/partials.mustache
new file mode 100644
index 0000000..54cf1c5
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/partials/partials.mustache
@@ -0,0 +1,7 @@
+<div>
+ {{> header }}
+
+ <div>
+ {{ page.content }}
+ </div>
+</div> \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/partials/partials.txt b/vendor/mustache/mustache/test/fixtures/examples/partials/partials.txt
new file mode 100644
index 0000000..f8e45ce
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/partials/partials.txt
@@ -0,0 +1,8 @@
+<div>
+ <h1>Page Title</h1>
+ <h2>Page Subtitle</h2>
+
+ <div>
+ Lorem ipsum dolor sit amet.
+ </div>
+</div> \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/partials/partials/header.mustache b/vendor/mustache/mustache/test/fixtures/examples/partials/partials/header.mustache
new file mode 100644
index 0000000..88d567b
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/partials/partials/header.mustache
@@ -0,0 +1,4 @@
+{{# page }}
+<h1>{{ title }}</h1>
+<h2>{{ subtitle }}</h2>
+{{/ page }} \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/recursive_partials/RecursivePartials.php b/vendor/mustache/mustache/test/fixtures/examples/recursive_partials/RecursivePartials.php
new file mode 100644
index 0000000..25d15fd
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/recursive_partials/RecursivePartials.php
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class RecursivePartials
+{
+ public $name = 'George';
+ public $child = array(
+ 'name' => 'Dan',
+ 'child' => array(
+ 'name' => 'Justin',
+ 'child' => false,
+ ),
+ );
+}
diff --git a/vendor/mustache/mustache/test/fixtures/examples/recursive_partials/partials/child.mustache b/vendor/mustache/mustache/test/fixtures/examples/recursive_partials/partials/child.mustache
new file mode 100644
index 0000000..1282941
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/recursive_partials/partials/child.mustache
@@ -0,0 +1 @@
+ > {{ name }}{{#child}}{{>child}}{{/child}} \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/recursive_partials/recursive_partials.mustache b/vendor/mustache/mustache/test/fixtures/examples/recursive_partials/recursive_partials.mustache
new file mode 100644
index 0000000..0bc5d03
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/recursive_partials/recursive_partials.mustache
@@ -0,0 +1 @@
+{{name}}{{#child}}{{>child}}{{/child}} \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/recursive_partials/recursive_partials.txt b/vendor/mustache/mustache/test/fixtures/examples/recursive_partials/recursive_partials.txt
new file mode 100644
index 0000000..681cdef
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/recursive_partials/recursive_partials.txt
@@ -0,0 +1 @@
+George > Dan > Justin \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/section_iterator_objects/SectionIteratorObjects.php b/vendor/mustache/mustache/test/fixtures/examples/section_iterator_objects/SectionIteratorObjects.php
new file mode 100644
index 0000000..77e083e
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/section_iterator_objects/SectionIteratorObjects.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class SectionIteratorObjects
+{
+ public $start = 'It worked the first time.';
+
+ protected $_data = array(
+ array('item' => 'And it worked the second time.'),
+ array('item' => 'As well as the third.'),
+ );
+
+ public function middle()
+ {
+ return new ArrayIterator($this->_data);
+ }
+
+ public $final = 'Then, surprisingly, it worked the final time.';
+}
diff --git a/vendor/mustache/mustache/test/fixtures/examples/section_iterator_objects/section_iterator_objects.mustache b/vendor/mustache/mustache/test/fixtures/examples/section_iterator_objects/section_iterator_objects.mustache
new file mode 100644
index 0000000..44dfce4
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/section_iterator_objects/section_iterator_objects.mustache
@@ -0,0 +1,5 @@
+* {{ start }}
+{{# middle }}
+* {{ item }}
+{{/ middle }}
+* {{ final }} \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/section_iterator_objects/section_iterator_objects.txt b/vendor/mustache/mustache/test/fixtures/examples/section_iterator_objects/section_iterator_objects.txt
new file mode 100644
index 0000000..e6b2d7a
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/section_iterator_objects/section_iterator_objects.txt
@@ -0,0 +1,4 @@
+* It worked the first time.
+* And it worked the second time.
+* As well as the third.
+* Then, surprisingly, it worked the final time. \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/section_magic_objects/SectionMagicObjects.php b/vendor/mustache/mustache/test/fixtures/examples/section_magic_objects/SectionMagicObjects.php
new file mode 100644
index 0000000..54288d6
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/section_magic_objects/SectionMagicObjects.php
@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class SectionMagicObjects
+{
+ public $start = 'It worked the first time.';
+
+ public function middle()
+ {
+ return new MagicObject();
+ }
+
+ public $final = 'Then, surprisingly, it worked the final time.';
+}
+
+class MagicObject
+{
+ protected $_data = array(
+ 'foo' => 'And it worked the second time.',
+ 'bar' => 'As well as the third.',
+ );
+
+ public function __get($key)
+ {
+ return isset($this->_data[$key]) ? $this->_data[$key] : null;
+ }
+
+ public function __isset($key)
+ {
+ return isset($this->_data[$key]);
+ }
+}
diff --git a/vendor/mustache/mustache/test/fixtures/examples/section_magic_objects/section_magic_objects.mustache b/vendor/mustache/mustache/test/fixtures/examples/section_magic_objects/section_magic_objects.mustache
new file mode 100644
index 0000000..9119608
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/section_magic_objects/section_magic_objects.mustache
@@ -0,0 +1,6 @@
+* {{ start }}
+{{# middle }}
+* {{ foo }}
+* {{ bar }}
+{{/ middle }}
+* {{ final }} \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/section_magic_objects/section_magic_objects.txt b/vendor/mustache/mustache/test/fixtures/examples/section_magic_objects/section_magic_objects.txt
new file mode 100644
index 0000000..e6b2d7a
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/section_magic_objects/section_magic_objects.txt
@@ -0,0 +1,4 @@
+* It worked the first time.
+* And it worked the second time.
+* As well as the third.
+* Then, surprisingly, it worked the final time. \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/section_objects/SectionObjects.php b/vendor/mustache/mustache/test/fixtures/examples/section_objects/SectionObjects.php
new file mode 100644
index 0000000..b977ec5
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/section_objects/SectionObjects.php
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class SectionObjects
+{
+ public $start = 'It worked the first time.';
+
+ public function middle()
+ {
+ return new SectionObject();
+ }
+
+ public $final = 'Then, surprisingly, it worked the final time.';
+}
+
+class SectionObject
+{
+ public $foo = 'And it worked the second time.';
+ public $bar = 'As well as the third.';
+}
diff --git a/vendor/mustache/mustache/test/fixtures/examples/section_objects/section_objects.mustache b/vendor/mustache/mustache/test/fixtures/examples/section_objects/section_objects.mustache
new file mode 100644
index 0000000..9119608
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/section_objects/section_objects.mustache
@@ -0,0 +1,6 @@
+* {{ start }}
+{{# middle }}
+* {{ foo }}
+* {{ bar }}
+{{/ middle }}
+* {{ final }} \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/section_objects/section_objects.txt b/vendor/mustache/mustache/test/fixtures/examples/section_objects/section_objects.txt
new file mode 100644
index 0000000..e6b2d7a
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/section_objects/section_objects.txt
@@ -0,0 +1,4 @@
+* It worked the first time.
+* And it worked the second time.
+* As well as the third.
+* Then, surprisingly, it worked the final time. \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/sections/Sections.php b/vendor/mustache/mustache/test/fixtures/examples/sections/Sections.php
new file mode 100644
index 0000000..86bc893
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/sections/Sections.php
@@ -0,0 +1,25 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Sections
+{
+ public $start = 'It worked the first time.';
+
+ public function middle()
+ {
+ return array(
+ array('item' => 'And it worked the second time.'),
+ array('item' => 'As well as the third.'),
+ );
+ }
+
+ public $final = 'Then, surprisingly, it worked the final time.';
+}
diff --git a/vendor/mustache/mustache/test/fixtures/examples/sections/sections.mustache b/vendor/mustache/mustache/test/fixtures/examples/sections/sections.mustache
new file mode 100644
index 0000000..44dfce4
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/sections/sections.mustache
@@ -0,0 +1,5 @@
+* {{ start }}
+{{# middle }}
+* {{ item }}
+{{/ middle }}
+* {{ final }} \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/sections/sections.txt b/vendor/mustache/mustache/test/fixtures/examples/sections/sections.txt
new file mode 100644
index 0000000..e6b2d7a
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/sections/sections.txt
@@ -0,0 +1,4 @@
+* It worked the first time.
+* And it worked the second time.
+* As well as the third.
+* Then, surprisingly, it worked the final time. \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/sections_nested/SectionsNested.php b/vendor/mustache/mustache/test/fixtures/examples/sections_nested/SectionsNested.php
new file mode 100644
index 0000000..dccc0d9
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/sections_nested/SectionsNested.php
@@ -0,0 +1,44 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class SectionsNested
+{
+ public $name = 'Little Mac';
+
+ public function enemies()
+ {
+ return array(
+ array(
+ 'name' => 'Von Kaiser',
+ 'enemies' => array(
+ array('name' => 'Super Macho Man'),
+ array('name' => 'Piston Honda'),
+ array('name' => 'Mr. Sandman'),
+ ),
+ ),
+ array(
+ 'name' => 'Mike Tyson',
+ 'enemies' => array(
+ array('name' => 'Soda Popinski'),
+ array('name' => 'King Hippo'),
+ array('name' => 'Great Tiger'),
+ array('name' => 'Glass Joe'),
+ ),
+ ),
+ array(
+ 'name' => 'Don Flamenco',
+ 'enemies' => array(
+ array('name' => 'Bald Bull'),
+ ),
+ ),
+ );
+ }
+}
diff --git a/vendor/mustache/mustache/test/fixtures/examples/sections_nested/sections_nested.mustache b/vendor/mustache/mustache/test/fixtures/examples/sections_nested/sections_nested.mustache
new file mode 100644
index 0000000..9f8007d
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/sections_nested/sections_nested.mustache
@@ -0,0 +1,7 @@
+Enemies of {{ name }}:
+{{# enemies }}
+{{ name }} ... who also has enemies:
+{{# enemies }}
+--> {{ name }}
+{{/ enemies }}
+{{/ enemies }} \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/sections_nested/sections_nested.txt b/vendor/mustache/mustache/test/fixtures/examples/sections_nested/sections_nested.txt
new file mode 100644
index 0000000..72c44d0
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/sections_nested/sections_nested.txt
@@ -0,0 +1,12 @@
+Enemies of Little Mac:
+Von Kaiser ... who also has enemies:
+--> Super Macho Man
+--> Piston Honda
+--> Mr. Sandman
+Mike Tyson ... who also has enemies:
+--> Soda Popinski
+--> King Hippo
+--> Great Tiger
+--> Glass Joe
+Don Flamenco ... who also has enemies:
+--> Bald Bull
diff --git a/vendor/mustache/mustache/test/fixtures/examples/simple/Simple.php b/vendor/mustache/mustache/test/fixtures/examples/simple/Simple.php
new file mode 100644
index 0000000..570af22
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/simple/Simple.php
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Simple
+{
+ public $name = 'Chris';
+ public $value = 10000;
+
+ public function taxed_value()
+ {
+ return $this->value - ($this->value * 0.4);
+ }
+
+ public $in_ca = true;
+}
diff --git a/vendor/mustache/mustache/test/fixtures/examples/simple/simple.mustache b/vendor/mustache/mustache/test/fixtures/examples/simple/simple.mustache
new file mode 100644
index 0000000..03df206
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/simple/simple.mustache
@@ -0,0 +1,5 @@
+Hello {{name}}
+You have just won ${{value}}!
+{{#in_ca}}
+Well, ${{ taxed_value }}, after taxes.
+{{/in_ca}} \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/simple/simple.txt b/vendor/mustache/mustache/test/fixtures/examples/simple/simple.txt
new file mode 100644
index 0000000..5d75d65
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/simple/simple.txt
@@ -0,0 +1,3 @@
+Hello Chris
+You have just won $10000!
+Well, $6000, after taxes.
diff --git a/vendor/mustache/mustache/test/fixtures/examples/unescaped/Unescaped.php b/vendor/mustache/mustache/test/fixtures/examples/unescaped/Unescaped.php
new file mode 100644
index 0000000..abe9178
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/unescaped/Unescaped.php
@@ -0,0 +1,15 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Unescaped
+{
+ public $title = 'Bear > Shark';
+}
diff --git a/vendor/mustache/mustache/test/fixtures/examples/unescaped/unescaped.mustache b/vendor/mustache/mustache/test/fixtures/examples/unescaped/unescaped.mustache
new file mode 100644
index 0000000..9982708
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/unescaped/unescaped.mustache
@@ -0,0 +1 @@
+<h1>{{{title}}}</h1> \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/unescaped/unescaped.txt b/vendor/mustache/mustache/test/fixtures/examples/unescaped/unescaped.txt
new file mode 100644
index 0000000..01fa404
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/unescaped/unescaped.txt
@@ -0,0 +1 @@
+<h1>Bear > Shark</h1> \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/utf8/UTF8.php b/vendor/mustache/mustache/test/fixtures/examples/utf8/UTF8.php
new file mode 100644
index 0000000..8c14941
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/utf8/UTF8.php
@@ -0,0 +1,15 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class UTF8
+{
+ public $test = '中文又来啦';
+}
diff --git a/vendor/mustache/mustache/test/fixtures/examples/utf8/utf8.mustache b/vendor/mustache/mustache/test/fixtures/examples/utf8/utf8.mustache
new file mode 100644
index 0000000..6954d47
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/utf8/utf8.mustache
@@ -0,0 +1 @@
+<h1>中文 {{test}}</h1> \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/utf8/utf8.txt b/vendor/mustache/mustache/test/fixtures/examples/utf8/utf8.txt
new file mode 100644
index 0000000..bf17971
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/utf8/utf8.txt
@@ -0,0 +1 @@
+<h1>中文 中文又来啦</h1> \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/utf8_unescaped/UTF8Unescaped.php b/vendor/mustache/mustache/test/fixtures/examples/utf8_unescaped/UTF8Unescaped.php
new file mode 100644
index 0000000..4309675
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/utf8_unescaped/UTF8Unescaped.php
@@ -0,0 +1,15 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class UTF8Unescaped
+{
+ public $test = '中文又来啦';
+}
diff --git a/vendor/mustache/mustache/test/fixtures/examples/utf8_unescaped/utf8_unescaped.mustache b/vendor/mustache/mustache/test/fixtures/examples/utf8_unescaped/utf8_unescaped.mustache
new file mode 100644
index 0000000..fd7fe4b
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/utf8_unescaped/utf8_unescaped.mustache
@@ -0,0 +1 @@
+<h1>中文 {{{test}}}</h1> \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/utf8_unescaped/utf8_unescaped.txt b/vendor/mustache/mustache/test/fixtures/examples/utf8_unescaped/utf8_unescaped.txt
new file mode 100644
index 0000000..bf17971
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/utf8_unescaped/utf8_unescaped.txt
@@ -0,0 +1 @@
+<h1>中文 中文又来啦</h1> \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/whitespace/Whitespace.php b/vendor/mustache/mustache/test/fixtures/examples/whitespace/Whitespace.php
new file mode 100644
index 0000000..d5a5c62
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/whitespace/Whitespace.php
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of Mustache.php.
+ *
+ * (c) 2010-2016 Justin Hileman
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Whitespace test for tag names.
+ *
+ * Per http://github.com/janl/mustache.js/issues/issue/34/#comment_244396
+ * tags should strip leading and trailing whitespace in key names.
+ *
+ * `{{> tag }}` and `{{> tag}}` and `{{>tag}}` should all be equivalent.
+ */
+class Whitespace
+{
+ public $foo = 'alpha';
+
+ public $bar = 'beta';
+
+ public function baz()
+ {
+ return 'gamma';
+ }
+
+ public function qux()
+ {
+ return array(
+ array('key with space' => 'A'),
+ array('key with space' => 'B'),
+ array('key with space' => 'C'),
+ array('key with space' => 'D'),
+ array('key with space' => 'E'),
+ array('key with space' => 'F'),
+ array('key with space' => 'G'),
+ );
+ }
+}
diff --git a/vendor/mustache/mustache/test/fixtures/examples/whitespace/partials/alphabet.mustache b/vendor/mustache/mustache/test/fixtures/examples/whitespace/partials/alphabet.mustache
new file mode 100644
index 0000000..d281c41
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/whitespace/partials/alphabet.mustache
@@ -0,0 +1 @@
+ * {{.}} \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/whitespace/whitespace.mustache b/vendor/mustache/mustache/test/fixtures/examples/whitespace/whitespace.mustache
new file mode 100644
index 0000000..0b3ba00
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/whitespace/whitespace.mustache
@@ -0,0 +1,10 @@
+{{^ inverted section test }}
+These are some things:
+{{/inverted section test }}
+* {{ foo }}
+* {{ bar}}
+* {{ baz }}
+{{# qux }}
+* {{ key with space }}
+{{/ qux }}
+{{#qux}}.{{/qux}} \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/examples/whitespace/whitespace.txt b/vendor/mustache/mustache/test/fixtures/examples/whitespace/whitespace.txt
new file mode 100644
index 0000000..5226c69
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/examples/whitespace/whitespace.txt
@@ -0,0 +1,12 @@
+These are some things:
+* alpha
+* beta
+* gamma
+* A
+* B
+* C
+* D
+* E
+* F
+* G
+....... \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/templates/alpha.ms b/vendor/mustache/mustache/test/fixtures/templates/alpha.ms
new file mode 100644
index 0000000..3845830
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/templates/alpha.ms
@@ -0,0 +1 @@
+alpha contents \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/templates/beta.ms b/vendor/mustache/mustache/test/fixtures/templates/beta.ms
new file mode 100644
index 0000000..a083dfe
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/templates/beta.ms
@@ -0,0 +1 @@
+beta contents \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/templates/one.mustache b/vendor/mustache/mustache/test/fixtures/templates/one.mustache
new file mode 100644
index 0000000..f83ad09
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/templates/one.mustache
@@ -0,0 +1 @@
+one contents \ No newline at end of file
diff --git a/vendor/mustache/mustache/test/fixtures/templates/two.mustache b/vendor/mustache/mustache/test/fixtures/templates/two.mustache
new file mode 100644
index 0000000..dacc40e
--- /dev/null
+++ b/vendor/mustache/mustache/test/fixtures/templates/two.mustache
@@ -0,0 +1 @@
+two contents \ No newline at end of file
diff --git a/web/index.php b/web/index.php
new file mode 100644
index 0000000..dc0553f
--- /dev/null
+++ b/web/index.php
@@ -0,0 +1,9 @@
+<?php
+
+// define site root
+define('SITE_ROOT', realpath('../'));
+
+// Bring in our composer autoloader
+require SITE_ROOT . '/vendor/autoload.php';
+
+$main = new App\Core\Main;