WP RSS Aggregator - Version 4.12.1

Version Description

(2019-02-27) = * Added a modal with an optional poll when the plugin is deactivated. * Improved the core plugin's on-boarding process for brand new users. * Fixed the "Sorted" error appearing constantly in the debug log. * The timeout for the truncating posts hook has been extended. * Fixed PHP warnings appearing on WordPress multisite. * Fixed PHP notice appearing on Feed Items page. * Fixed strict standards notice appearing on settings import.

Download this release

Release Info

Developer markzahra
Plugin Icon 128x128 WP RSS Aggregator
Version 4.12.1
Comparing to
See all releases

Code changes from version 4.12 to 4.12.1

Files changed (268) hide show
  1. css/beacon.css +9 -0
  2. css/intro.min.css +1 -1
  3. css/plugins.min.css +1 -0
  4. css/src/intro/steps.scss +16 -5
  5. css/src/plugins/form.scss +48 -0
  6. css/src/plugins/index.scss +25 -0
  7. css/src/plugins/modal.scss +173 -0
  8. css/src/update/index.scss +83 -0
  9. css/update.min.css +1 -0
  10. images/light-line-logo.png +0 -0
  11. images/wp-rss-aggregator-support-beacon.png +0 -0
  12. includes/Aventura/Wprss/Core/Licensing/Manager.php +1 -1
  13. includes/Aventura/Wprss/Core/Model/BulkSourceImport/ArrayImporter.php +5 -5
  14. includes/Aventura/Wprss/Core/Model/Regex/AbstractRegex.php +4 -3
  15. includes/admin-activate.php +38 -0
  16. includes/admin-addons.php +0 -2
  17. includes/admin-ajax-notice.php +3 -1
  18. includes/admin-debugging.php +3 -3
  19. includes/admin-help.php +48 -2
  20. includes/admin-import-export.php +1 -3
  21. includes/{admin-intro.php → admin-intro-page.php} +44 -66
  22. includes/admin-options.php +0 -2
  23. includes/admin-plugins.php +117 -0
  24. includes/admin-update-page.php +133 -0
  25. includes/admin.php +43 -0
  26. includes/custom-feed.php +3 -7
  27. includes/custom-post-types.php +2 -1
  28. includes/feed-importing.php +0 -2
  29. includes/licensing.php +33 -0
  30. includes/opml-importer.php +3 -3
  31. includes/roles-capabilities.php +2 -2
  32. includes/scripts.php +13 -0
  33. includes/secure-reset.php +3 -1
  34. includes/twig.php +2 -2
  35. js/beacon.min.js +5 -0
  36. js/intro.min.js +1 -6
  37. js/plugins.min.js +1 -0
  38. js/src/intro/Wizard.vue +58 -20
  39. js/src/intro/copy.js +37 -0
  40. js/src/plugins/Modal.vue +114 -0
  41. js/src/plugins/PluginDisablePoll.vue +112 -0
  42. js/src/plugins/SerializedForm.vue +89 -0
  43. js/src/plugins/index.js +10 -0
  44. js/update.min.js +1 -0
  45. js/wpra-manifest.min.js +1 -0
  46. js/wpra-vendor.min.js +12 -0
  47. readme.txt +78 -64
  48. templates/admin-update-page.twig +76 -0
  49. vendor/autoload.php +1 -1
  50. vendor/composer/ClassLoader.php +2 -2
  51. vendor/composer/autoload_real.php +7 -7
  52. vendor/composer/autoload_static.php +4 -4
  53. vendor/composer/installed.json +13 -13
  54. vendor/symfony/polyfill-ctype/LICENSE +1 -1
  55. vendor/symfony/polyfill-ctype/composer.json +1 -1
  56. vendor/twig/twig/.php_cs.dist +4 -2
  57. vendor/twig/twig/.travis.yml +0 -1
  58. vendor/twig/twig/CHANGELOG +2 -2
  59. vendor/twig/twig/composer.json +1 -4
  60. vendor/twig/twig/doc/advanced.rst +127 -88
  61. vendor/twig/twig/doc/advanced_legacy.rst +45 -45
  62. vendor/twig/twig/doc/api.rst +55 -55
  63. vendor/twig/twig/doc/deprecated.rst +54 -54
  64. vendor/twig/twig/doc/filters/date.rst +4 -4
  65. vendor/twig/twig/doc/filters/escape.rst +2 -2
  66. vendor/twig/twig/doc/filters/join.rst +2 -2
  67. vendor/twig/twig/doc/filters/number_format.rst +2 -2
  68. vendor/twig/twig/doc/functions/date.rst +2 -2
  69. vendor/twig/twig/doc/functions/dump.rst +3 -3
  70. vendor/twig/twig/doc/functions/include.rst +2 -2
  71. vendor/twig/twig/doc/functions/template_from_string.rst +3 -3
  72. vendor/twig/twig/doc/installation.rst +1 -1
  73. vendor/twig/twig/doc/internals.rst +24 -24
  74. vendor/twig/twig/doc/intro.rst +6 -6
  75. vendor/twig/twig/doc/recipes.rst +35 -35
  76. vendor/twig/twig/doc/tags/extends.rst +1 -1
  77. vendor/twig/twig/doc/tags/filter.rst +2 -2
  78. vendor/twig/twig/doc/tags/include.rst +27 -3
  79. vendor/twig/twig/doc/tags/set.rst +1 -1
  80. vendor/twig/twig/doc/templates.rst +3 -1
  81. vendor/twig/twig/ext/twig/php_twig.h +1 -1
  82. vendor/twig/twig/ext/twig/twig.c +14 -14
  83. vendor/twig/twig/lib/Twig/Autoloader.php +1 -1
  84. vendor/twig/twig/lib/Twig/BaseNodeVisitor.php +15 -11
  85. vendor/twig/twig/lib/Twig/Cache/Filesystem.php +11 -9
  86. vendor/twig/twig/lib/Twig/Cache/Null.php +3 -1
  87. vendor/twig/twig/lib/Twig/Compiler.php +14 -12
  88. vendor/twig/twig/lib/Twig/ContainerRuntimeLoader.php +2 -1
  89. vendor/twig/twig/lib/Twig/Environment.php +205 -176
  90. vendor/twig/twig/lib/Twig/Error.php +18 -15
  91. vendor/twig/twig/lib/Twig/Error/Loader.php +7 -5
  92. vendor/twig/twig/lib/Twig/Error/Runtime.php +3 -1
  93. vendor/twig/twig/lib/Twig/Error/Syntax.php +5 -3
  94. vendor/twig/twig/lib/Twig/ExpressionParser.php +163 -139
  95. vendor/twig/twig/lib/Twig/Extension.php +6 -3
  96. vendor/twig/twig/lib/Twig/Extension/Core.php +328 -338
  97. vendor/twig/twig/lib/Twig/Extension/Debug.php +9 -5
  98. vendor/twig/twig/lib/Twig/Extension/Escaper.php +12 -7
  99. vendor/twig/twig/lib/Twig/Extension/GlobalsInterface.php +1 -1
  100. vendor/twig/twig/lib/Twig/Extension/InitRuntimeInterface.php +1 -1
  101. vendor/twig/twig/lib/Twig/Extension/Optimizer.php +5 -2
  102. vendor/twig/twig/lib/Twig/Extension/Profiler.php +10 -6
  103. vendor/twig/twig/lib/Twig/Extension/Sandbox.php +11 -6
  104. vendor/twig/twig/lib/Twig/Extension/Staging.php +7 -3
  105. vendor/twig/twig/lib/Twig/Extension/StringLoader.php +9 -8
  106. vendor/twig/twig/lib/Twig/ExtensionInterface.php +13 -6
  107. vendor/twig/twig/lib/Twig/FactoryRuntimeLoader.php +3 -1
  108. vendor/twig/twig/lib/Twig/FileExtensionEscapingStrategy.php +1 -1
  109. vendor/twig/twig/lib/Twig/Filter.php +4 -2
  110. vendor/twig/twig/lib/Twig/Filter/Method.php +4 -2
  111. vendor/twig/twig/lib/Twig/FilterInterface.php +3 -1
  112. vendor/twig/twig/lib/Twig/Function.php +4 -2
  113. vendor/twig/twig/lib/Twig/Function/Method.php +4 -2
  114. vendor/twig/twig/lib/Twig/FunctionInterface.php +3 -1
  115. vendor/twig/twig/lib/Twig/Lexer.php +45 -39
  116. vendor/twig/twig/lib/Twig/LexerInterface.php +8 -4
  117. vendor/twig/twig/lib/Twig/Loader/Array.php +11 -7
  118. vendor/twig/twig/lib/Twig/Loader/Chain.php +29 -23
  119. vendor/twig/twig/lib/Twig/Loader/Filesystem.php +25 -21
  120. vendor/twig/twig/lib/Twig/Loader/String.php +7 -4
  121. vendor/twig/twig/lib/Twig/LoaderInterface.php +5 -3
  122. vendor/twig/twig/lib/Twig/Markup.php +2 -2
  123. vendor/twig/twig/lib/Twig/Node.php +20 -17
  124. vendor/twig/twig/lib/Twig/Node/AutoEscape.php +5 -2
  125. vendor/twig/twig/lib/Twig/Node/Block.php +5 -2
  126. vendor/twig/twig/lib/Twig/Node/BlockReference.php +6 -2
  127. vendor/twig/twig/lib/Twig/Node/Body.php +3 -1
  128. vendor/twig/twig/lib/Twig/Node/CheckSecurity.php +11 -8
  129. vendor/twig/twig/lib/Twig/Node/Deprecated.php +9 -4
  130. vendor/twig/twig/lib/Twig/Node/Do.php +7 -3
  131. vendor/twig/twig/lib/Twig/Node/Embed.php +9 -4
  132. vendor/twig/twig/lib/Twig/Node/Expression.php +3 -1
  133. vendor/twig/twig/lib/Twig/Node/Expression/Array.php +11 -6
  134. vendor/twig/twig/lib/Twig/Node/Expression/AssignName.php +5 -2
  135. vendor/twig/twig/lib/Twig/Node/Expression/Binary.php +7 -3
  136. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Add.php +6 -2
  137. vendor/twig/twig/lib/Twig/Node/Expression/Binary/And.php +6 -2
  138. vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php +6 -2
  139. vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php +6 -2
  140. vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php +6 -2
  141. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Concat.php +6 -2
  142. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Div.php +6 -2
  143. vendor/twig/twig/lib/Twig/Node/Expression/Binary/EndsWith.php +7 -3
  144. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Equal.php +6 -2
  145. vendor/twig/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php +7 -3
  146. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Greater.php +6 -2
  147. vendor/twig/twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php +6 -2
  148. vendor/twig/twig/lib/Twig/Node/Expression/Binary/In.php +7 -3
  149. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Less.php +6 -2
  150. vendor/twig/twig/lib/Twig/Node/Expression/Binary/LessEqual.php +6 -2
  151. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Matches.php +7 -3
  152. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mod.php +6 -2
  153. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mul.php +6 -2
  154. vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotEqual.php +6 -2
  155. vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotIn.php +7 -3
  156. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Or.php +6 -2
  157. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Power.php +7 -3
  158. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Range.php +7 -3
  159. vendor/twig/twig/lib/Twig/Node/Expression/Binary/StartsWith.php +7 -3
  160. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Sub.php +6 -2
  161. vendor/twig/twig/lib/Twig/Node/Expression/BlockReference.php +10 -6
  162. vendor/twig/twig/lib/Twig/Node/Expression/Call.php +43 -34
  163. vendor/twig/twig/lib/Twig/Node/Expression/Conditional.php +7 -3
  164. vendor/twig/twig/lib/Twig/Node/Expression/Constant.php +6 -2
  165. vendor/twig/twig/lib/Twig/Node/Expression/ExtensionReference.php +5 -2
  166. vendor/twig/twig/lib/Twig/Node/Expression/Filter.php +11 -5
  167. vendor/twig/twig/lib/Twig/Node/Expression/Filter/Default.php +17 -10
  168. vendor/twig/twig/lib/Twig/Node/Expression/Function.php +9 -4
  169. vendor/twig/twig/lib/Twig/Node/Expression/GetAttr.php +10 -5
  170. vendor/twig/twig/lib/Twig/Node/Expression/MethodCall.php +10 -4
  171. vendor/twig/twig/lib/Twig/Node/Expression/Name.php +6 -2
  172. vendor/twig/twig/lib/Twig/Node/Expression/NullCoalesce.php +16 -6
  173. vendor/twig/twig/lib/Twig/Node/Expression/Parent.php +5 -2
  174. vendor/twig/twig/lib/Twig/Node/Expression/TempName.php +6 -2
  175. vendor/twig/twig/lib/Twig/Node/Expression/Test.php +10 -5
  176. vendor/twig/twig/lib/Twig/Node/Expression/Test/Constant.php +8 -7
  177. vendor/twig/twig/lib/Twig/Node/Expression/Test/Defined.php +25 -17
  178. vendor/twig/twig/lib/Twig/Node/Expression/Test/Divisibleby.php +5 -4
  179. vendor/twig/twig/lib/Twig/Node/Expression/Test/Even.php +5 -4
  180. vendor/twig/twig/lib/Twig/Node/Expression/Test/Null.php +5 -4
  181. vendor/twig/twig/lib/Twig/Node/Expression/Test/Odd.php +5 -4
  182. vendor/twig/twig/lib/Twig/Node/Expression/Test/Sameas.php +5 -2
  183. vendor/twig/twig/lib/Twig/Node/Expression/Unary.php +7 -3
  184. vendor/twig/twig/lib/Twig/Node/Expression/Unary/Neg.php +6 -2
  185. vendor/twig/twig/lib/Twig/Node/Expression/Unary/Not.php +6 -2
  186. vendor/twig/twig/lib/Twig/Node/Expression/Unary/Pos.php +6 -2
  187. vendor/twig/twig/lib/Twig/Node/Flush.php +5 -2
  188. vendor/twig/twig/lib/Twig/Node/For.php +13 -6
  189. vendor/twig/twig/lib/Twig/Node/ForLoop.php +5 -2
  190. vendor/twig/twig/lib/Twig/Node/If.php +6 -3
  191. vendor/twig/twig/lib/Twig/Node/Import.php +9 -4
  192. vendor/twig/twig/lib/Twig/Node/Include.php +11 -6
  193. vendor/twig/twig/lib/Twig/Node/Macro.php +11 -7
  194. vendor/twig/twig/lib/Twig/Node/Module.php +70 -45
  195. vendor/twig/twig/lib/Twig/Node/Print.php +8 -3
  196. vendor/twig/twig/lib/Twig/Node/Sandbox.php +6 -3
  197. vendor/twig/twig/lib/Twig/Node/SandboxedPrint.php +11 -6
  198. vendor/twig/twig/lib/Twig/Node/Set.php +15 -9
  199. vendor/twig/twig/lib/Twig/Node/SetTemp.php +5 -2
  200. vendor/twig/twig/lib/Twig/Node/Spaceless.php +5 -2
  201. vendor/twig/twig/lib/Twig/Node/Text.php +6 -2
  202. vendor/twig/twig/lib/Twig/Node/With.php +7 -4
  203. vendor/twig/twig/lib/Twig/NodeInterface.php +4 -2
  204. vendor/twig/twig/lib/Twig/NodeTraverser.php +7 -5
  205. vendor/twig/twig/lib/Twig/NodeVisitor/Escaper.php +39 -25
  206. vendor/twig/twig/lib/Twig/NodeVisitor/Optimizer.php +55 -36
  207. vendor/twig/twig/lib/Twig/NodeVisitor/SafeAnalysis.php +28 -15
  208. vendor/twig/twig/lib/Twig/NodeVisitor/Sandbox.php +22 -11
  209. vendor/twig/twig/lib/Twig/NodeVisitorInterface.php +4 -2
  210. vendor/twig/twig/lib/Twig/Parser.php +65 -45
  211. vendor/twig/twig/lib/Twig/ParserInterface.php +7 -3
  212. vendor/twig/twig/lib/Twig/Profiler/Dumper/Base.php +8 -6
  213. vendor/twig/twig/lib/Twig/Profiler/Dumper/Blackfire.php +5 -3
  214. vendor/twig/twig/lib/Twig/Profiler/Dumper/Html.php +8 -5
  215. vendor/twig/twig/lib/Twig/Profiler/Dumper/Text.php +7 -4
  216. vendor/twig/twig/lib/Twig/Profiler/Node/EnterProfile.php +6 -3
  217. vendor/twig/twig/lib/Twig/Profiler/Node/LeaveProfile.php +5 -2
  218. vendor/twig/twig/lib/Twig/Profiler/NodeVisitor/Profiler.php +25 -14
  219. vendor/twig/twig/lib/Twig/Profiler/Profile.php +2 -2
  220. vendor/twig/twig/lib/Twig/Sandbox/SecurityError.php +3 -1
  221. vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFilterError.php +4 -2
  222. vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFunctionError.php +4 -2
  223. vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedMethodError.php +4 -2
  224. vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedPropertyError.php +4 -2
  225. vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedTagError.php +4 -2
  226. vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicy.php +23 -15
  227. vendor/twig/twig/lib/Twig/SimpleFilter.php +5 -3
  228. vendor/twig/twig/lib/Twig/SimpleFunction.php +5 -3
  229. vendor/twig/twig/lib/Twig/SimpleTest.php +1 -1
  230. vendor/twig/twig/lib/Twig/SourceContextLoaderInterface.php +5 -2
  231. vendor/twig/twig/lib/Twig/Template.php +58 -50
  232. vendor/twig/twig/lib/Twig/TemplateInterface.php +3 -1
  233. vendor/twig/twig/lib/Twig/TemplateWrapper.php +11 -7
  234. vendor/twig/twig/lib/Twig/Test/IntegrationTestCase.php +30 -20
  235. vendor/twig/twig/lib/Twig/Test/Method.php +4 -2
  236. vendor/twig/twig/lib/Twig/Test/NodeTestCase.php +9 -5
  237. vendor/twig/twig/lib/Twig/Token.php +5 -5
  238. vendor/twig/twig/lib/Twig/TokenParser.php +5 -2
  239. vendor/twig/twig/lib/Twig/TokenParser/AutoEscape.php +27 -23
  240. vendor/twig/twig/lib/Twig/TokenParser/Block.php +21 -15
  241. vendor/twig/twig/lib/Twig/TokenParser/Deprecated.php +10 -9
  242. vendor/twig/twig/lib/Twig/TokenParser/Do.php +8 -4
  243. vendor/twig/twig/lib/Twig/TokenParser/Embed.php +19 -13
  244. vendor/twig/twig/lib/Twig/TokenParser/Extends.php +9 -7
  245. vendor/twig/twig/lib/Twig/TokenParser/Filter.php +18 -13
  246. vendor/twig/twig/lib/Twig/TokenParser/Flush.php +8 -4
  247. vendor/twig/twig/lib/Twig/TokenParser/For.php +38 -30
  248. vendor/twig/twig/lib/Twig/TokenParser/From.php +14 -10
  249. vendor/twig/twig/lib/Twig/TokenParser/If.php +23 -19
  250. vendor/twig/twig/lib/Twig/TokenParser/Import.php +10 -7
  251. vendor/twig/twig/lib/Twig/TokenParser/Include.php +12 -10
  252. vendor/twig/twig/lib/Twig/TokenParser/Macro.php +18 -14
  253. vendor/twig/twig/lib/Twig/TokenParser/Sandbox.php +20 -15
  254. vendor/twig/twig/lib/Twig/TokenParser/Set.php +17 -19
  255. vendor/twig/twig/lib/Twig/TokenParser/Spaceless.php +13 -12
  256. vendor/twig/twig/lib/Twig/TokenParser/Use.php +21 -17
  257. vendor/twig/twig/lib/Twig/TokenParser/With.php +12 -8
  258. vendor/twig/twig/lib/Twig/TokenParserBroker.php +11 -9
  259. vendor/twig/twig/lib/Twig/TokenParserBrokerInterface.php +4 -2
  260. vendor/twig/twig/lib/Twig/TokenParserInterface.php +7 -3
  261. vendor/twig/twig/lib/Twig/TokenStream.php +19 -15
  262. vendor/twig/twig/lib/Twig/Util/DeprecationCollector.php +14 -9
  263. vendor/twig/twig/test/Twig/Tests/Cache/FilesystemTest.php +13 -11
  264. vendor/twig/twig/test/Twig/Tests/CompilerTest.php +4 -1
  265. vendor/twig/twig/test/Twig/Tests/ContainerRuntimeLoaderTest.php +5 -3
  266. vendor/twig/twig/test/Twig/Tests/CustomExtensionTest.php +8 -5
  267. vendor/twig/twig/test/Twig/Tests/EnvironmentTest.php +93 -76
  268. vendor/twig/twig/test/Twig/Tests/ErrorTest.php +14 -7
css/beacon.css ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ #HSBeaconFabButton {
2
+ bottom: 16px !important;
3
+ right: 20px !important;
4
+ }
5
+
6
+ #HSBeaconContainerFrame {
7
+ bottom: 86px !important;
8
+ right: 20px !important;
9
+ }
css/intro.min.css CHANGED
@@ -1 +1 @@
1
- .wrpa-expander{will-change:height;transform:translateZ(0);backface-visibility:hidden;perspective:1000px}.expand-enter-active,.expand-leave-active{transition:height .35s ease;overflow:hidden}.expand-enter,.expand-leave-to{height:0}.fade-enter,.fade-leave-to{opacity:0}.fade-enter-active,.fade-leave-active{transition:opacity .3s ease}.slide-up-enter{transform:translateY(10px);opacity:0}.slide-up-leave-to{transform:translateY(-10px);opacity:0}.slide-up-enter-active,.slide-up-leave-active{transition:all .3s ease}.slide-down-enter{transform:translateY(-10px);opacity:0}.slide-down-leave-to{transform:translateY(10px);opacity:0}.slide-down-enter-active,.slide-down-leave-active{transition:all .3s ease}.wpra-expander__title{cursor:pointer;user-select:none}.wpra-expander__title span{opacity:.5;vertical-align:bottom;transition:transform .3s ease}.wpra-expander__content{padding:0 .5rem;opacity:0;transition:opacity .3s ease}.wpra-expander--expanded .wpra-expander__content{opacity:1}.wpra-expander--expanded .wpra-expander__title span{transform:rotate(180deg)}[v-cloak] .vcloak--visible{display:block}[v-cloak] .vcloak--hidden{display:none}.vcloak--visible{min-height:60px;display:none}.loading-container{position:relative}.loading-container:before{display:block;content:"";position:absolute;left:calc(50% - 20px);top:calc(50% - 20px);box-sizing:border-box;height:40px;width:40px;border:0 solid #d0d0d0;border-radius:50%;box-shadow:inset 0 -12px 0 16px #d0d0d0;animation:rotate 1s infinite linear;z-index:3}.loading-container:after{display:block;content:"";position:absolute;z-index:2;background-color:hsla(0,0%,95%,.5);width:100%;height:100%;left:0;top:0}.loading-container--white:after{background-color:#fff}.loading-button{pointer-events:none;position:relative}.loading-button:before{display:block;content:"";position:absolute;left:calc(50% - 8px);top:calc(50% - 8px);box-sizing:border-box;height:16px;width:16px;border:0 solid #fff;border-radius:50%;box-shadow:inset 0 -4px 0 6px #fff;animation:rotate 1s infinite linear;z-index:3}.loading-button:after{display:block;content:"";position:absolute;z-index:2;background-color:inherit;width:100%;height:100%;left:0;top:0}.button-default.loading-button:before{box-shadow:inset 0 -4px 0 6px #6f6f6f}.loading-inline{display:inline-block;pointer-events:none;position:relative}.loading-inline:before{display:block;content:"";position:absolute;left:calc(50% + 1px);top:calc(50% - 11px);box-sizing:border-box;height:14px;width:14px;border:0 solid #d0d0d0;border-radius:50%;box-shadow:inset 0 -3px 0 5px #d0d0d0;animation:rotate 1s infinite linear;z-index:3}.loading-inline:after{display:block;content:"";position:absolute;z-index:2;background-color:inherit;width:100%;height:100%;left:0;top:0}@keyframes rotate{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.wpra-wizard-head{display:flex;padding-bottom:1.5rem;padding-top:.75rem}.wpra-wizard-head__logo{flex-shrink:0}.wpra-wizard-head__logo img{width:57px}.wpra-wizard-head__copy{flex-grow:1;padding-left:1rem;display:flex;flex-direction:column;justify-content:center}.wpra-wizard-head__title{font-size:1.25rem;font-weight:500;padding-bottom:12px}.wpra-wizard-head__subtitle{font-size:1rem;opacity:.85}.wpra-cols{display:flex;margin:0 -.5rem;border-top:2px solid rgba(0,0,0,.05);padding-top:1.45rem}.wpra-cols-title{font-weight:400;font-size:1rem;padding-bottom:1rem}@media (max-width:50em){.wpra-cols{flex-wrap:wrap}}.wpra-cols .col{flex-basis:50%;padding:0 .5rem}@media (max-width:50em){.wpra-cols .col{flex-basis:100%;padding-bottom:1rem}}.wpra-cols .col img{max-width:100%}.wpra-cols .col p{font-size:14px;line-height:1.6}.wpra-cols .col p:first-child{margin-top:0}.wpra-feed-input{width:26rem;padding:6px 10px;max-width:100%}.wpra-feedback{display:flex}.wpra-feedback__photo{flex-shrink:0}.wpra-feedback__photo img{width:70px;border-radius:100%}.wpra-feedback__copy{padding-left:.5rem;flex-grow:1}.wpra-feedback__text{font-size:1rem;font-family:Georgia,serif;font-style:italic;line-height:1.5}.wpra-feedback__rating{padding:.25rem 0 .45rem}.wpra-feedback__rating span{color:#f8ca29}.wpra-feedback__by{opacity:.85}.wpra-feedback__by a{color:#617181}.wpra-demo-photo{margin-bottom:1rem;border-radius:4px;border:1px solid rgba(0,0,0,.15)}.wpra-feed-items{padding-left:.5rem;margin-bottom:1rem;border-left:4px solid #ff792b}.wpra-feed-items .wpra-feed-item{padding:.75rem}.wpra-feed-items .wpra-feed-item__link{padding-bottom:4px}.step-items{display:flex;position:relative;flex-direction:column;align-items:flex-end}.step-items .step-progress{position:absolute;width:3px;height:0;background-color:#00b479;left:17.5px;top:0;transition:height .3s ease;z-index:-1}.step-items .step-progress--1{height:50%}.step-items .step-progress--2{height:100%}@media (max-width:50em){.step-items .step-progress{display:none}}@media (max-width:50em){.step-items{padding:.625rem;flex-direction:row;align-items:flex-start}}.step-items .step-item{font-size:16px;width:15rem;margin-bottom:2.25rem;display:flex;background-color:#f1f1f1}.step-items .step-item:last-child{margin-bottom:0}@media (max-width:50em){.step-items .step-item{flex-direction:column;margin-bottom:0;align-items:center}}.step-items .step-item_active,.step-items .step-item_active .step-item__info,.step-items .step-item_active .step-item__status{opacity:1}@media (max-width:50em){.step-items .step-item_active{flex-grow:1}}.step-items .step-item__description{font-size:14px}.step-items .step-item__info{display:flex;align-items:center;padding-left:.75rem;opacity:.5}@media (max-width:50em){.step-items .step-item__info{padding-left:0;padding-top:.3rem;display:none}}.step-items .step-item__status{width:35px;height:35px;border-radius:50%;border:2px dashed rgba(0,0,0,.5);flex-shrink:0;opacity:.5;text-align:center;font-size:1.25rem;line-height:2.375rem;color:#00b479}.step-items .step-item__status span{display:block;margin:0!important;width:100%;line-height:35px;font-size:26px}.step-items .step-item_completed{opacity:1}.step-items .step-item_completed .step-item__status{border-style:solid;border-color:#00b479;opacity:1}.step-items .step-item_completed .step-item__status span{position:relative}.step-items .step-item_completed .step-item__info{opacity:.5}.wizard{width:100%;margin-left:1rem}@media (max-width:50em){.wizard{margin-left:0}}.wizard ol{margin-left:1.5rem;line-height:1.5;font-size:13px}.wizard ol ul{margin-bottom:1rem}.wizard .form-group{display:flex;align-items:center}@media (max-width:50em){.wizard .form-group{display:block;align-items:unset}.wizard .form-group input{margin-bottom:8px}}.wizard .form-group input{flex-shrink:0}.wizard .form-group .warning-icon{padding-left:4px;color:#ee5a65}.wizard .form-group a{flex-shrink:0;margin-left:6px}.wizard .button-clear{background-color:transparent;border:none;cursor:pointer;height:30px;line-height:28px;padding:0 12px 2px;vertical-align:baseline;opacity:.55}.wizard .button-clear:hover{opacity:.8}.wizard .button{vertical-align:baseline!important}.wizard .pad{display:flex}.wizard .pad-item--grow{flex-grow:1}.wizard .pad-item--no-shrink{flex-shrink:0}.wizard .wpra-success{padding-right:1rem;font-size:14px}.wizard_content{padding:1rem;font-size:14px;max-width:42rem;min-height:16rem;padding-top:12px}@media (max-width:50em){.wizard_content{padding:0}}.wizard-holder{width:100%;position:relative;display:flex}@media (max-width:50em){.wizard-holder{flex-direction:column}}.wizard-holder .connect-steps{flex-shrink:0;max-width:450px;padding:1rem}@media (max-width:50em){.wizard-holder .connect-steps{max-width:100%;flex-basis:auto;padding:.5rem}}.wizard-holder .wizard{flex-grow:1}.wizard_text{padding:0 0 25px;max-width:480px;font-size:14px}.wizard_more{user-select:none;display:inline-block;color:rgba(0,0,0,.5);font-size:12px;margin-top:20px}.wizard_more:hover{cursor:pointer;text-decoration:underline}.wizard_hello{font-size:18px;margin:15px 0 10px}.wizard_hello img{height:26px;vertical-align:sub;margin-right:3px}.wizard_button{min-width:137px;margin:0 .3rem 1rem}.wizard_buttons{margin:0 -.5rem;display:flex}@media (max-width:50em){.wizard_buttons{flex-direction:row;flex-wrap:wrap}}.wizard_network{padding:0 .5rem;margin-bottom:.35rem}.wizard_network .button{min-width:145px;text-align:center}.wizard_network .button i{margin-left:4px}.wizard_network .button-transparent{margin-bottom:10px}.wizard_network-icon{width:50px;height:50px;border-radius:100%;background-color:hsla(0,0%,7%,.05);margin:0 auto .8rem}.wizard_network-icon i{font-size:22px;line-height:50px}.wizard_list{padding:10px 0;display:flex;flex-wrap:wrap;margin:0 -.3125rem;max-width:49rem}.wizard_item{padding:5px;margin:5px;border:1px solid rgba(0,0,0,.05);display:flex;width:31%;align-items:center;vertical-align:middle;border-radius:4px;text-align:left}@media (max-width:50em){.wizard_item{width:100%;margin:0;margin-bottom:.625rem}}.wizard_item .description{font-size:12px;color:rgba(0,0,0,.75);margin-top:2px}.wizard_item .account-item_picture{float:none;margin-right:10px;flex-shrink:0}.wizard_info{max-width:20rem;text-align:left}.wizard_info .form-group{margin-bottom:1rem}.wizard_label{font-size:1rem;padding-top:.2rem;padding-bottom:.75rem}.wrpa-shortcode .wrpa-shortcode-form{display:inline-block;padding:4px 8px;border-radius:4px;background-color:rgba(0,0,0,.05);cursor:pointer;margin-right:4px}.wrpa-shortcode .wrpa-shortcode-form .wrpa-shortcode-form__shortcode{display:inline-block}.wrpa-shortcode .wrpa-shortcode-form .wrpa-shortcode-form__button{display:inline-block;opacity:.65;font-size:11px;font-style:italic;padding-right:3px}.connect_progress{position:absolute;left:calc(50% - 22px);top:30px}.connect_progress:after{clear:both;display:block;content:""}.connect_progress-point{display:block;float:left;margin-left:5px;width:8px;height:8px;border-radius:100%;background-color:rgba(26,83,230,.3)}.connect_progress-point__active{border:1px solid #1a53e6}.connect_progress-point__done{background-color:#1a53e6}.connect-actions{width:100%;max-width:42rem;border-top:2px solid rgba(0,0,0,.05);padding:1rem 0}.connect-actions .button{margin:0}@media (max-width:50em){.connect-actions{padding-bottom:2rem}}.connect-actions .fa-animated{font-size:2rem;color:rgba(26,83,230,.65);vertical-align:middle;margin-right:5px}@keyframes moveRightLeftLoop{0%{transform:translateX(-10px)}50%{transform:translateX(0)}to{transform:translateX(-10px)}}.moveRightLeftLoop{animation-iteration-count:infinite;animation-name:moveRightLeftLoop;animation-duration:1s}
1
+ .wrpa-expander{will-change:height;transform:translateZ(0);backface-visibility:hidden;perspective:1000px}.expand-enter-active,.expand-leave-active{transition:height .35s ease;overflow:hidden}.expand-enter,.expand-leave-to{height:0}.fade-enter,.fade-leave-to{opacity:0}.fade-enter-active,.fade-leave-active{transition:opacity .3s ease}.slide-up-enter{transform:translateY(10px);opacity:0}.slide-up-leave-to{transform:translateY(-10px);opacity:0}.slide-up-enter-active,.slide-up-leave-active{transition:all .3s ease}.slide-down-enter{transform:translateY(-10px);opacity:0}.slide-down-leave-to{transform:translateY(10px);opacity:0}.slide-down-enter-active,.slide-down-leave-active{transition:all .3s ease}.wpra-expander__title{cursor:pointer;user-select:none}.wpra-expander__title span{opacity:.5;vertical-align:bottom;transition:transform .3s ease}.wpra-expander__content{padding:0 .5rem;opacity:0;transition:opacity .3s ease}.wpra-expander--expanded .wpra-expander__content{opacity:1}.wpra-expander--expanded .wpra-expander__title span{transform:rotate(180deg)}[v-cloak] .vcloak--visible{display:block}[v-cloak] .vcloak--hidden{display:none}.vcloak--visible{min-height:60px;display:none}.loading-container{position:relative}.loading-container:before{display:block;content:"";position:absolute;left:calc(50% - 20px);top:calc(50% - 20px);box-sizing:border-box;height:40px;width:40px;border:0 solid #d0d0d0;border-radius:50%;box-shadow:inset 0 -12px 0 16px #d0d0d0;animation:rotate 1s infinite linear;z-index:3}.loading-container:after{display:block;content:"";position:absolute;z-index:2;background-color:hsla(0,0%,95%,.5);width:100%;height:100%;left:0;top:0}.loading-container--white:after{background-color:#fff}.loading-button{pointer-events:none;position:relative}.loading-button:before{display:block;content:"";position:absolute;left:calc(50% - 8px);top:calc(50% - 8px);box-sizing:border-box;height:16px;width:16px;border:0 solid #fff;border-radius:50%;box-shadow:inset 0 -4px 0 6px #fff;animation:rotate 1s infinite linear;z-index:3}.loading-button:after{display:block;content:"";position:absolute;z-index:2;background-color:inherit;width:100%;height:100%;left:0;top:0}.button-default.loading-button:before{box-shadow:inset 0 -4px 0 6px #6f6f6f}.loading-inline{display:inline-block;pointer-events:none;position:relative}.loading-inline:before{display:block;content:"";position:absolute;left:calc(50% + 1px);top:calc(50% - 11px);box-sizing:border-box;height:14px;width:14px;border:0 solid #d0d0d0;border-radius:50%;box-shadow:inset 0 -3px 0 5px #d0d0d0;animation:rotate 1s infinite linear;z-index:3}.loading-inline:after{display:block;content:"";position:absolute;z-index:2;background-color:inherit;width:100%;height:100%;left:0;top:0}@keyframes rotate{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.wpra-wizard-head{display:flex;padding-bottom:1.5rem;padding-top:.75rem}.wpra-wizard-head__logo{flex-shrink:0}.wpra-wizard-head__logo img{width:57px}.wpra-wizard-head__copy{flex-grow:1;padding-left:1rem;display:flex;flex-direction:column;justify-content:center}.wpra-wizard-head__title{font-size:1.25rem;font-weight:500;padding-bottom:12px}.wpra-wizard-head__subtitle{font-size:1rem;opacity:.85}.wpra-cols{display:flex;margin:0 -.5rem;border-top:2px solid rgba(0,0,0,.05);padding-top:1.45rem}.wpra-cols-title{font-weight:400;font-size:1rem;padding-bottom:1rem}@media (max-width:50em){.wpra-cols{flex-wrap:wrap}}.wpra-cols .col{flex-basis:50%;padding:0 .5rem}@media (max-width:50em){.wpra-cols .col{flex-basis:100%;padding-bottom:1rem}}.wpra-cols .col img{max-width:100%}.wpra-cols .col p{font-size:14px;line-height:1.6}.wpra-cols .col p:first-child{margin-top:0}.wpra-feed-input{width:26rem;padding:6px 10px;max-width:100%}.wpra-feedback{display:flex}.wpra-feedback__photo{flex-shrink:0}.wpra-feedback__photo img{width:70px;border-radius:100%}.wpra-feedback__copy{padding-left:.5rem;flex-grow:1}.wpra-feedback__text{font-size:1rem;font-family:Georgia,serif;font-style:italic;line-height:1.5}.wpra-feedback__rating{padding:.25rem 0 .45rem}.wpra-feedback__rating span{color:#f8ca29}.wpra-feedback__by{opacity:.85}.wpra-feedback__by a{color:#617181}.wpra-demo-photo{margin-bottom:1rem;border-radius:4px;border:1px solid rgba(0,0,0,.15)}.wpra-feed-items{padding-left:.5rem;margin-bottom:1rem;border-left:4px solid #ff792b}.wpra-feed-items .wpra-feed-item{padding:.75rem}.wpra-feed-items .wpra-feed-item__link{padding-bottom:4px}.step-items{display:flex;position:relative;flex-direction:column;align-items:flex-end}.step-items .step-progress{position:absolute;width:3px;height:0;background-color:#00b479;left:17.5px;top:0;transition:height .3s ease;z-index:-1}.step-items .step-progress--1{height:50%}.step-items .step-progress--2{height:100%}@media (max-width:50em){.step-items .step-progress{display:none}}@media (max-width:50em){.step-items{padding:.625rem;flex-direction:row;align-items:flex-start}}.step-items .step-item{font-size:16px;width:15rem;margin-bottom:2.25rem;display:flex;background-color:#f1f1f1}.step-items .step-item:last-child{margin-bottom:0}@media (max-width:50em){.step-items .step-item{flex-direction:column;margin-bottom:0;align-items:center}}.step-items .step-item_active,.step-items .step-item_active .step-item__info,.step-items .step-item_active .step-item__status{opacity:1}@media (max-width:50em){.step-items .step-item_active{flex-grow:1}}.step-items .step-item__description{font-size:14px}.step-items .step-item__info{display:flex;align-items:center;padding-left:.75rem;opacity:.5}@media (max-width:50em){.step-items .step-item__info{padding-left:0;padding-top:.3rem;display:none}}.step-items .step-item__status{width:35px;height:35px;border-radius:50%;border:2px dashed rgba(0,0,0,.5);flex-shrink:0;opacity:.5;text-align:center;font-size:1.25rem;line-height:2.375rem;color:#00b479}.step-items .step-item__status span{display:block;margin:0!important;width:100%;line-height:35px;font-size:26px}.step-items .step-item_completed{opacity:1}.step-items .step-item_completed .step-item__status{border-style:solid;border-color:#00b479;opacity:1}.step-items .step-item_completed .step-item__status span{position:relative}.step-items .step-item_completed .step-item__info{opacity:.5}.wizard{width:100%;margin-left:1rem}@media (max-width:50em){.wizard{margin-left:0}}.wizard ol{margin-left:1.5rem;line-height:1.5;font-size:13px}.wizard ol ul{margin-bottom:1rem}.wizard .form-group{display:flex;align-items:center}@media (max-width:50em){.wizard .form-group{display:block;align-items:unset}.wizard .form-group input{margin-bottom:8px}}.wizard .form-group input{flex-shrink:0}.wizard .form-group .warning-icon{padding-left:4px;color:#ee5a65}.wizard .form-group a{flex-shrink:0;margin-left:6px}.wizard .button-clear{background-color:transparent;border:none;cursor:pointer;height:30px;line-height:28px;padding:0 12px 2px;vertical-align:baseline;opacity:.55}.wizard .button-clear:hover{opacity:.8}.wizard .button{vertical-align:baseline!important}.wizard .pad{display:flex}.wizard .pad-item--grow{flex-grow:1}.wizard .pad-item--no-shrink{flex-shrink:0}.wizard .wpra-success{padding-right:1rem;font-size:14px}.wizard_content{padding:1rem;font-size:14px;max-width:42rem;min-height:16rem;padding-top:12px}@media (max-width:50em){.wizard_content{padding:0}}.wizard-holder{width:100%;position:relative;display:flex}@media (max-width:50em){.wizard-holder{flex-direction:column}}.wizard-holder .connect-steps{flex-shrink:0;max-width:450px;padding:1rem}@media (max-width:50em){.wizard-holder .connect-steps{max-width:100%;flex-basis:auto;padding:.5rem}}.wizard-holder .wizard{flex-grow:1}.wizard_text{padding:0 0 25px;max-width:480px;font-size:14px}.wizard_more{user-select:none;display:inline-block;color:rgba(0,0,0,.5);font-size:12px;margin-top:20px}.wizard_more:hover{cursor:pointer;text-decoration:underline}.wizard_hello{font-size:18px;margin:15px 0 10px}.wizard_hello img{height:26px;vertical-align:sub;margin-right:3px}.wizard_button{min-width:137px;margin:0 .3rem 1rem}.wizard_buttons{margin:0 -.5rem;display:flex}@media (max-width:50em){.wizard_buttons{flex-direction:row;flex-wrap:wrap}}.wizard_network{padding:0 .5rem;margin-bottom:.35rem}.wizard_network .button{min-width:145px;text-align:center}.wizard_network .button i{margin-left:4px}.wizard_network .button-transparent{margin-bottom:10px}.wizard_network-icon{width:50px;height:50px;border-radius:100%;background-color:hsla(0,0%,7%,.05);margin:0 auto .8rem}.wizard_network-icon i{font-size:22px;line-height:50px}.wizard_list{padding:10px 0;display:flex;flex-wrap:wrap;margin:0 -.3125rem;max-width:49rem}.wizard_item{padding:5px;margin:5px;border:1px solid rgba(0,0,0,.05);display:flex;width:31%;align-items:center;vertical-align:middle;border-radius:4px;text-align:left}@media (max-width:50em){.wizard_item{width:100%;margin:0;margin-bottom:.625rem}}.wizard_item .description{font-size:12px;color:rgba(0,0,0,.75);margin-top:2px}.wizard_item .account-item_picture{float:none;margin-right:10px;flex-shrink:0}.wizard_info{max-width:20rem;text-align:left}.wizard_info .form-group{margin-bottom:1rem}.wizard_label{font-size:1rem;padding-top:.2rem;padding-bottom:.75rem}.wrpa-shortcode{display:flex}.wrpa-shortcode-form,.wrpa-shortcode-preview{padding-bottom:10px;padding-right:75px;flex-basis:50%}.wrpa-shortcode-form .wrpa-shortcode-label,.wrpa-shortcode-preview .wrpa-shortcode-label{font-size:1rem;padding-bottom:12px;line-height:1.5}.wrpa-shortcode-form .button.loading-button:before,.wrpa-shortcode-preview .button.loading-button:before{box-shadow:inset 0 -4px 0 6px #797979!important}.wrpa-shortcode .wrpa-shortcode-form{cursor:pointer}.wrpa-shortcode .wrpa-shortcode-form .wrpa-shortcode-form__shortcode{display:inline-block}.wrpa-shortcode .wrpa-shortcode-form .wrpa-shortcode-form__button{display:inline-block;opacity:.65;font-size:11px;font-style:italic;padding-right:3px}.connect_progress{position:absolute;left:calc(50% - 22px);top:30px}.connect_progress:after{clear:both;display:block;content:""}.connect_progress-point{display:block;float:left;margin-left:5px;width:8px;height:8px;border-radius:100%;background-color:rgba(26,83,230,.3)}.connect_progress-point__active{border:1px solid #1a53e6}.connect_progress-point__done{background-color:#1a53e6}.connect-actions{width:100%;max-width:42rem;border-top:2px solid rgba(0,0,0,.05);padding:1rem 0}.connect-actions .button{margin:0}@media (max-width:50em){.connect-actions{padding-bottom:2rem}}.connect-actions .fa-animated{font-size:2rem;color:rgba(26,83,230,.65);vertical-align:middle;margin-right:5px}@keyframes moveRightLeftLoop{0%{transform:translateX(-10px)}50%{transform:translateX(0)}to{transform:translateX(-10px)}}.moveRightLeftLoop{animation-iteration-count:infinite;animation-name:moveRightLeftLoop;animation-duration:1s}
css/plugins.min.css ADDED
@@ -0,0 +1 @@
 
1
+ [v-cloak] .vcloak--visible{display:block}[v-cloak] .vcloak--hidden{display:none}.vcloak--visible{min-height:60px;display:none}.loading-container{position:relative}.loading-container:before{display:block;content:"";position:absolute;left:calc(50% - 20px);top:calc(50% - 20px);box-sizing:border-box;height:40px;width:40px;border:0 solid #d0d0d0;border-radius:50%;box-shadow:inset 0 -12px 0 16px #d0d0d0;animation:rotate 1s infinite linear;z-index:3}.loading-container:after{display:block;content:"";position:absolute;z-index:2;background-color:hsla(0,0%,95%,.5);width:100%;height:100%;left:0;top:0}.loading-container--white:after{background-color:#fff}.loading-button{pointer-events:none;position:relative}.loading-button:before{display:block;content:"";position:absolute;left:calc(50% - 8px);top:calc(50% - 8px);box-sizing:border-box;height:16px;width:16px;border:0 solid #fff;border-radius:50%;box-shadow:inset 0 -4px 0 6px #fff;animation:rotate 1s infinite linear;z-index:3}.loading-button:after{display:block;content:"";position:absolute;z-index:2;background-color:inherit;width:100%;height:100%;left:0;top:0}.button-default.loading-button:before{box-shadow:inset 0 -4px 0 6px #6f6f6f}.loading-inline{display:inline-block;pointer-events:none;position:relative}.loading-inline:before{display:block;content:"";position:absolute;left:calc(50% + 1px);top:calc(50% - 11px);box-sizing:border-box;height:14px;width:14px;border:0 solid #d0d0d0;border-radius:50%;box-shadow:inset 0 -3px 0 5px #d0d0d0;animation:rotate 1s infinite linear;z-index:3}.loading-inline:after{display:block;content:"";position:absolute;z-index:2;background-color:inherit;width:100%;height:100%;left:0;top:0}@keyframes rotate{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.modal{position:fixed;background-color:rgba(0,0,0,.65);width:100%;height:100%;left:0;top:0;z-index:9999;overflow-y:auto}.modal-opened{overflow:hidden}.modal__body{width:100%;max-width:30rem;margin:5rem auto;background-color:#fff;border-radius:4px}.modal__body--no-content-padding .modal__content{padding:0}.modal__body--wide{max-width:50rem}.modal__header{padding:.5rem 1rem;font-size:20px;font-weight:700;line-height:1.5;border-bottom:1px solid #eee}.modal__header.invisible-header{border:none;font-size:unset;font-weight:unset;padding-top:12px!important}.modal__header.invisible-header h3{margin-top:0;line-height:1.5;margin-bottom:0}.modal__header.invisible-header p{margin-top:.25rem;font-size:14px;opacity:.6;margin-bottom:0}.modal__header.invisible-header+.modal__content{padding-top:6px!important}.modal__header-buttons{font-weight:400}.modal__close{opacity:.5;cursor:pointer}.modal__close:hover{opacity:.8}.modal--right{float:right}.modal__content{padding:1rem}.modal__footer{padding:1rem;border-top:1px solid #eee;text-align:right}.modal__footer .button{display:inline-block!important;margin-left:4px!important}.modal__footer .footer-confirm{margin:0;padding:0;display:flex;align-items:center}.modal__footer .footer-confirm__buttons{flex-shrink:0}.modal__footer .footer-confirm__buttons--left{margin-right:auto;flex-grow:1;text-align:left}.modal__footer .footer-confirm__message{margin-right:auto}.modal__footer .footer-confirm__message.__right{flex-grow:1;padding-right:10px;text-align:right}.modal-transition-enter,.modal-transition-leave-to{opacity:0}.modal-transition-enter .modal__body,.modal-transition-leave-to .modal__body{opacity:0;transform:scaleX(.8) scaleY(.7)}.modal-transition-enter-active,.modal-transition-leave-active{transition:opacity .25s ease-out}.modal-transition-enter-active .modal__body,.modal-transition-leave-active .modal__body{transition:all .25s cubic-bezier(.665,1.65,0,.845)}.button-clear{border:none!important;background:transparent!important;box-shadow:none!important}.form-check{padding:4px 0}.form-check input{width:auto!important;margin:0 4px 0 0}.form-check input,.form-check label{display:inline-block!important}.form-group{padding-bottom:8px}.form-group label{display:block}.form-group>label{margin-bottom:2px}.form-group input,.form-group textarea{display:block;width:100%}.form-group:last-child{padding-bottom:0}.form-group p:first-child{margin-top:0}.form-group p:last-child{margin-bottom:0}.form-group .error{margin:0!important}.wpra-plugin-disable-poll__logo img{max-height:40px}
css/src/intro/steps.scss CHANGED
@@ -545,13 +545,24 @@ $primary-color: #1a53e6;
545
  }
546
 
547
  .wrpa-shortcode {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
548
  .wrpa-shortcode-form {
549
- display: inline-block;
550
- padding: 4px 8px;
551
- border-radius: 4px;
552
- background-color: $deep-gray;
553
  cursor: pointer;
554
- margin-right: 4px;
555
  .wrpa-shortcode-form__shortcode {
556
  display: inline-block;
557
  }
545
  }
546
 
547
  .wrpa-shortcode {
548
+ display: flex;
549
+ &-form, &-preview {
550
+ padding-bottom: 10px;
551
+ padding-right: 75px;
552
+ flex-basis: 50%;
553
+ .wrpa-shortcode-label {
554
+ font-size: 1rem;
555
+ padding-bottom: 12px;
556
+ line-height: 1.5;
557
+ }
558
+ .button.loading-button {
559
+ &::before {
560
+ box-shadow: inset 0 -4px 0 6px #797979 !important;
561
+ }
562
+ }
563
+ }
564
  .wrpa-shortcode-form {
 
 
 
 
565
  cursor: pointer;
 
566
  .wrpa-shortcode-form__shortcode {
567
  display: inline-block;
568
  }
css/src/plugins/form.scss ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .form {
2
+ &-check {
3
+ input {
4
+ display: inline-block !important;
5
+ width: auto !important;
6
+ margin: 0 4px 0 0;
7
+ }
8
+ label {
9
+ display: inline-block !important;
10
+ }
11
+ padding: 4px 0;
12
+ }
13
+ &-group {
14
+ padding-bottom: 8px;
15
+ label {
16
+ display: block;
17
+ }
18
+ & > label {
19
+ margin-bottom: 2px;
20
+ }
21
+ input, textarea {
22
+ display: block;
23
+ width: 100%;
24
+ }
25
+ &:last-child {
26
+ padding-bottom: 0;
27
+ }
28
+ p {
29
+ &:first-child {
30
+ margin-top: 0;
31
+ }
32
+ &:last-child {
33
+ margin-bottom: 0;
34
+ }
35
+ }
36
+ .error {
37
+ margin: 0 !important;
38
+ }
39
+ }
40
+ }
41
+
42
+ .wpra-plugin-disable-poll {
43
+ &__logo {
44
+ img {
45
+ max-height: 40px;
46
+ }
47
+ }
48
+ }
css/src/plugins/index.scss ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ $white: #fff;
2
+ $radius: 4px;
3
+
4
+ @mixin breakpoint($point) {
5
+ @if $point == desktop {
6
+ @media (min-width: 70em) { @content ; }
7
+ }
8
+ @else if $point == laptop {
9
+ @media (min-width: 64em) { @content ; }
10
+ }
11
+ @else if $point == tablet {
12
+ @media (max-width: 50em) { @content ; }
13
+ }
14
+ @else if $point == phablet {
15
+ @media (min-width: 37.5em) { @content ; }
16
+ }
17
+ @else if $point == mobileonly {
18
+ @media (max-width: 37.5em) { @content ; }
19
+
20
+ }
21
+ }
22
+
23
+ @import "./../intro/loading";
24
+ @import "modal";
25
+ @import "form";
css/src/plugins/modal.scss ADDED
@@ -0,0 +1,173 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .modal {
2
+ &-opened {
3
+ overflow: hidden;
4
+ }
5
+
6
+ position: fixed;
7
+ background-color: rgba(0, 0, 0, 0.65);
8
+ width: 100%;
9
+ height: 100%;
10
+ left: 0;
11
+ top: 0;
12
+ z-index: 9999;
13
+ overflow-y: auto;
14
+
15
+ @include breakpoint(mobile) {
16
+ z-index: 100000;
17
+ }
18
+
19
+ &__body {
20
+ width: 100%;
21
+ max-width: 30rem;
22
+ margin: 5rem auto;
23
+
24
+ background-color: $white;
25
+ border-radius: $radius;
26
+
27
+ &--no-content-padding {
28
+ .modal__content {
29
+ padding: 0;
30
+ }
31
+ }
32
+
33
+ &--wide {
34
+ max-width: 50rem;
35
+ }
36
+
37
+ @include breakpoint(mobile) {
38
+ min-height: 100vh;
39
+ margin: 0;
40
+ border-radius: 0;
41
+ }
42
+ }
43
+
44
+ &__header {
45
+ padding: .5rem 1rem;
46
+ font-size: 20px;
47
+ font-weight: bold;
48
+ line-height: 1.5;
49
+ border-bottom: 1px solid #eee;
50
+
51
+ &.invisible-header {
52
+ border: none;
53
+ font-size: unset;
54
+ font-weight: unset;
55
+ padding-top: 12px !important;
56
+ h3 {
57
+ margin-top: 0;
58
+ line-height: 1.5;
59
+ margin-bottom: 0;
60
+ }
61
+ p {
62
+ margin-top: .25rem;
63
+ font-size: 14px;
64
+ opacity: .6;
65
+ margin-bottom: 0;
66
+ }
67
+ & + .modal__content {
68
+ padding-top: 6px !important;
69
+ }
70
+ }
71
+
72
+ @include breakpoint(mobile) {
73
+ position: relative;
74
+
75
+ .modal--right {
76
+ position: absolute;
77
+ top: 0;
78
+ padding: 6px 1rem 0 1rem;
79
+ right: 0;
80
+ background-color: white;
81
+ }
82
+ }
83
+
84
+ &-buttons {
85
+ font-weight: normal;
86
+ }
87
+ }
88
+
89
+ &__close {
90
+ opacity: .5;
91
+ cursor: pointer;
92
+ &:hover {
93
+ opacity: .8;
94
+ }
95
+ }
96
+
97
+ &--right {
98
+ float: right;
99
+ }
100
+
101
+ &__content {
102
+ padding: 1rem;
103
+ }
104
+
105
+ &__footer {
106
+ padding: 1rem;
107
+ border-top: 1px solid #eee;
108
+ text-align: right;
109
+
110
+ .button {
111
+ display: inline-block !important;
112
+ margin-left: 4px !important;
113
+ }
114
+ .footer-confirm {
115
+ margin: 0;
116
+ padding: 0;
117
+ display: flex;
118
+ align-items: center;
119
+
120
+ @include breakpoint(mobile) {
121
+ display: block;
122
+ &__message {
123
+ padding-right: 0;
124
+ padding-bottom: 10px;
125
+ }
126
+ }
127
+
128
+ &__buttons {
129
+ flex-shrink: 0;
130
+
131
+ &--left {
132
+ margin-right: auto;
133
+ flex-grow: 1;
134
+ text-align: left;
135
+ }
136
+ }
137
+
138
+ &__message {
139
+ margin-right: auto;
140
+ &.__right {
141
+ flex-grow: 1;
142
+ padding-right: 10px;
143
+ text-align: right;
144
+ }
145
+ }
146
+ }
147
+ }
148
+ }
149
+
150
+ .modal-transition {
151
+ &-enter, &-leave-to {
152
+ opacity: 0;
153
+
154
+ .modal__body {
155
+ opacity: 0;
156
+ transform: scaleX(.8) scaleY(.7);
157
+ }
158
+ }
159
+
160
+ &-enter-active, &-leave-active {
161
+ transition: opacity 0.25s ease-out;
162
+
163
+ .modal__body {
164
+ transition: all .25s cubic-bezier(.665,1.65,0,.845);
165
+ }
166
+ }
167
+ }
168
+
169
+ .button-clear {
170
+ border: none !important;
171
+ background: transparent !important;
172
+ box-shadow: none !important;
173
+ }
css/src/update/index.scss ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+
3
+ .wrap--wpra-update {
4
+ padding-top: 1rem;
5
+ width: 100%;
6
+ max-width: 880px;
7
+ margin: 0 auto;
8
+ }
9
+
10
+ .wpra-text-center {
11
+ text-align: center;
12
+ }
13
+
14
+ .wpra-updates {
15
+ list-style: unset;
16
+ padding: 0 1.25rem;
17
+ }
18
+
19
+ .wpra-inline-form {
20
+ display: flex;
21
+ align-items: baseline;
22
+
23
+ button {
24
+ margin-right: 12px !important;
25
+ }
26
+
27
+ small {
28
+ font-size: 12px;
29
+ opacity: .75;
30
+ }
31
+ }
32
+
33
+
34
+ .wpra-update-head__title {
35
+ font-size: 24px;
36
+ font-weight: 500;
37
+ padding: 1.5rem 0 1.5rem;
38
+ }
39
+
40
+ .wpra-update__logo img {
41
+ width: 56px;
42
+ }
43
+
44
+ .button-icon span {
45
+ vertical-align: baseline;
46
+ margin-right: -7px;
47
+ opacity: .6;
48
+ font-size: 16px;
49
+ top: 4px;
50
+ position: relative;
51
+ }
52
+
53
+ .wpra-links {
54
+ padding-top: .5rem;
55
+ }
56
+
57
+ .wpra-update-head__link {
58
+ font-size: 1rem;
59
+ padding-bottom: 1.5rem;
60
+ }
61
+
62
+ .wpra-update-feature {
63
+ display: flex;
64
+ }
65
+
66
+ .wpra-update-feature__text h3 {
67
+ margin-top: 8px;
68
+ }
69
+
70
+ .wpra-update-feature__image {
71
+ width: 55rem;
72
+ overflow: hidden;
73
+ position: relative;
74
+ margin: -11px -12px -23px 0;
75
+
76
+ img {
77
+ max-height: 29rem;
78
+ position: absolute;
79
+ bottom: 12px;
80
+ right: 12px;
81
+ filter: drop-shadow(0px 2px 3px rgba(0,0,0,.125));
82
+ }
83
+ }
css/update.min.css ADDED
@@ -0,0 +1 @@
 
1
+ .wrap--wpra-update{padding-top:1rem;width:100%;max-width:880px;margin:0 auto}.wpra-text-center{text-align:center}.wpra-updates{list-style:unset;padding:0 1.25rem}.wpra-inline-form{display:flex;align-items:baseline}.wpra-inline-form button{margin-right:12px!important}.wpra-inline-form small{font-size:12px;opacity:.75}.wpra-update-head__title{font-size:24px;font-weight:500;padding:1.5rem 0}.wpra-update__logo img{width:56px}.button-icon span{vertical-align:baseline;margin-right:-7px;opacity:.6;font-size:16px;top:4px;position:relative}.wpra-links{padding-top:.5rem}.wpra-update-head__link{font-size:1rem;padding-bottom:1.5rem}.wpra-update-feature{display:flex}.wpra-update-feature__text h3{margin-top:8px}.wpra-update-feature__image{width:55rem;overflow:hidden;position:relative;margin:-11px -12px -23px 0}.wpra-update-feature__image img{max-height:29rem;position:absolute;bottom:12px;right:12px;filter:drop-shadow(0 2px 3px rgba(0,0,0,.125))}
images/light-line-logo.png ADDED
Binary file
images/wp-rss-aggregator-support-beacon.png ADDED
Binary file
includes/Aventura/Wprss/Core/Licensing/Manager.php CHANGED
@@ -439,7 +439,7 @@ class Manager {
439
  $data = $this->sendApiRequest( $addonId, $action, $return );
440
  $status = is_object( $data ) ? $data->license : $data;
441
 
442
- return ( in_array($status, ['invalid', 'item_name_mismatch', 'failed']) )
443
  ? $this->sendApiRequest( $addonId . static::LIFETIME_ADDON_ID_SUFFIX, $action, $return )
444
  : $data;
445
  }
439
  $data = $this->sendApiRequest( $addonId, $action, $return );
440
  $status = is_object( $data ) ? $data->license : $data;
441
 
442
+ return ( in_array($status, array('invalid', 'item_name_mismatch', 'failed')) )
443
  ? $this->sendApiRequest( $addonId . static::LIFETIME_ADDON_ID_SUFFIX, $action, $return )
444
  : $data;
445
  }
includes/Aventura/Wprss/Core/Model/BulkSourceImport/ArrayImporter.php CHANGED
@@ -38,16 +38,16 @@ class ArrayImporter extends AbstractWpImporter implements ImporterInterface
38
  protected function _inputToSourcesList($input)
39
  {
40
  if (!is_array($input)) {
41
- return [];
42
  }
43
 
44
- $sources = [];
45
  foreach ($input as $k => $v) {
46
- $sources[] = [
47
  ImporterInterface::SK_URL => $k,
48
  ImporterInterface::SK_TITLE => $v,
49
- 'status' => 'publish'
50
- ];
51
  }
52
 
53
  return $sources;
38
  protected function _inputToSourcesList($input)
39
  {
40
  if (!is_array($input)) {
41
+ return array();
42
  }
43
 
44
+ $sources = array();
45
  foreach ($input as $k => $v) {
46
+ $sources[] = array(
47
  ImporterInterface::SK_URL => $k,
48
  ImporterInterface::SK_TITLE => $v,
49
+ 'status' => 'publish',
50
+ );
51
  }
52
 
53
  return $sources;
includes/Aventura/Wprss/Core/Model/Regex/AbstractRegex.php CHANGED
@@ -35,9 +35,10 @@ class AbstractRegex extends Core\Model\ModelAbstract
35
  }
36
 
37
  $string = (array)$string;
38
- return array_map(function ($string) use ($delimiter) {
 
39
  if (is_array($string)) {
40
- return $this->quoteAll($string, $delimiter);
41
  }
42
  return preg_quote($string, $delimiter);
43
  }, $string);
@@ -108,4 +109,4 @@ class AbstractRegex extends Core\Model\ModelAbstract
108
  {
109
  return preg_match($pattern, $subject, $matches, $flags, $offset);
110
  }
111
- }
35
  }
36
 
37
  $string = (array)$string;
38
+ $self = $this;
39
+ return array_map(function ($string) use ($delimiter, $self) {
40
  if (is_array($string)) {
41
+ return $self->quoteAll($string, $delimiter);
42
  }
43
  return preg_quote($string, $delimiter);
44
  }, $string);
109
  {
110
  return preg_match($pattern, $subject, $matches, $flags, $offset);
111
  }
112
+ }
includes/admin-activate.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if (wprss_can_use_twig()) {
4
+ /* The introduction page module */
5
+ require_once(WPRSS_INC . 'admin-intro-page.php');
6
+ /* The update page module */
7
+ require_once(WPRSS_INC . 'admin-update-page.php');
8
+ }
9
+
10
+ /**
11
+ * Detects an activation and redirects the user to the correct page (intro or update).
12
+ *
13
+ * @since 4.12.1
14
+ */
15
+ add_action('admin_init', function () {
16
+ // Continue only if during an activation redirect
17
+ if (!get_transient('_wprss_activation_redirect')) {
18
+ return;
19
+ }
20
+
21
+ // Delete the redirect transient
22
+ delete_transient('_wprss_activation_redirect');
23
+
24
+ // Continue only if activating from a non-network site and not bulk activating plugins
25
+ if (is_network_admin() || isset($_GET['activate-multi'])) {
26
+ return;
27
+ }
28
+
29
+ if (wprss_should_do_intro_page()) {
30
+ wp_safe_redirect(wprss_get_intro_page_url());
31
+ return;
32
+ }
33
+
34
+ if (wprss_should_do_update_page()) {
35
+ wp_safe_redirect(wprss_get_update_page_url());
36
+ return;
37
+ }
38
+ });
includes/admin-addons.php CHANGED
@@ -12,8 +12,6 @@
12
 
13
  ?>
14
  <div class="wrap">
15
- <?php screen_icon( 'wprss-aggregator' ); ?>
16
-
17
  <h2><?php _e( 'More Features With Our Premium Add-Ons', WPRSS_TEXT_DOMAIN ); ?></h2>
18
  <p><?php echo sprintf(__( 'The following <a href="%1$s" target="_blank">add-ons</a> are available to increase the functionality of the WP RSS Aggregator plugin.', WPRSS_TEXT_DOMAIN ), 'https://www.wprssaggregator.com/extensions') ?></p>
19
  <p><?php echo sprintf(__(
12
 
13
  ?>
14
  <div class="wrap">
 
 
15
  <h2><?php _e( 'More Features With Our Premium Add-Ons', WPRSS_TEXT_DOMAIN ); ?></h2>
16
  <p><?php echo sprintf(__( 'The following <a href="%1$s" target="_blank">add-ons</a> are available to increase the functionality of the WP RSS Aggregator plugin.', WPRSS_TEXT_DOMAIN ), 'https://www.wprssaggregator.com/extensions') ?></p>
17
  <p><?php echo sprintf(__(
includes/admin-ajax-notice.php CHANGED
@@ -1267,7 +1267,9 @@ function wprss_is_wprss_page() {
1267
  'wprss-debugging',
1268
  'wprss-addons',
1269
  'wprss-welcome',
1270
- 'wprss-help'
 
 
1271
  ));
1272
 
1273
  $is_wprss_post = in_array($postType, $wprss_post_types, true);
1267
  'wprss-debugging',
1268
  'wprss-addons',
1269
  'wprss-welcome',
1270
+ 'wprss-help',
1271
+ 'wpra-intro',
1272
+ 'wpra-update',
1273
  ));
1274
 
1275
  $is_wprss_post = in_array($postType, $wprss_post_types, true);
includes/admin-debugging.php CHANGED
@@ -246,8 +246,6 @@ use Aventura\Wprss\Core\Model\AdminAjaxNotice\NoticeInterface;
246
  ?>
247
 
248
  <div class="wrap">
249
- <?php screen_icon( 'wprss-aggregator' ); ?>
250
-
251
  <h2><?php _e( 'Debugging', WPRSS_TEXT_DOMAIN ); ?></h2>
252
  <?php
253
  if ( isset( $_GET['debug_message'] )) {//&& ( check_admin_referer( 'wprss-delete-import-feed-items' ) || check_admin_referer( 'wprss-update-feed-items' ) ) ) {
@@ -375,7 +373,9 @@ use Aventura\Wprss\Core\Model\AdminAjaxNotice\NoticeInterface;
375
  'wprss_settings_notices',
376
  'wprss_addon_notices',
377
  'wprss_pwsv',
378
- 'wprss_db_version'
 
 
379
  )
380
  );
381
  // Delete the settings
246
  ?>
247
 
248
  <div class="wrap">
 
 
249
  <h2><?php _e( 'Debugging', WPRSS_TEXT_DOMAIN ); ?></h2>
250
  <?php
251
  if ( isset( $_GET['debug_message'] )) {//&& ( check_admin_referer( 'wprss-delete-import-feed-items' ) || check_admin_referer( 'wprss-update-feed-items' ) ) ) {
373
  'wprss_settings_notices',
374
  'wprss_addon_notices',
375
  'wprss_pwsv',
376
+ 'wprss_db_version',
377
+ WPRSS_INTRO_DID_INTRO_OPTION,
378
+ WPRSS_UPDATE_PAGE_PREV_VERSION_OPTION
379
  )
380
  );
381
  // Delete the settings
includes/admin-help.php CHANGED
@@ -2,6 +2,17 @@
2
 
3
  use Aventura\Wprss\Core\Licensing\License\Status as License_Status;
4
 
 
 
 
 
 
 
 
 
 
 
 
5
  /**
6
  * Build the Help page
7
  *
@@ -11,8 +22,6 @@
11
  ?>
12
 
13
  <div class="wrap">
14
- <?php screen_icon( 'wprss-aggregator' ); ?>
15
-
16
  <h2><?php _e( 'Help & Support', WPRSS_TEXT_DOMAIN ); ?></h2>
17
  <h3><?php _e( 'Documentation', WPRSS_TEXT_DOMAIN ) ?></h3>
18
  <?php
@@ -46,10 +55,47 @@
46
  wprss_free_help_display();
47
  }
48
  ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  </div>
50
  <?php
51
  }
52
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
 
54
  /**
55
  * Print the premium help section, linking to the contact us page on the site.
2
 
3
  use Aventura\Wprss\Core\Licensing\License\Status as License_Status;
4
 
5
+ /**
6
+ * Checks if the HS becaon is enabled or not.
7
+ *
8
+ * @since 4.12.1
9
+ *
10
+ * @return bool True if enabled, false if not.
11
+ */
12
+ function wprss_is_help_beacon_enabled() {
13
+ return (int) get_option('wprss_hs_beacon_enabled', 0) === 1;
14
+ }
15
+
16
  /**
17
  * Build the Help page
18
  *
22
  ?>
23
 
24
  <div class="wrap">
 
 
25
  <h2><?php _e( 'Help & Support', WPRSS_TEXT_DOMAIN ); ?></h2>
26
  <h3><?php _e( 'Documentation', WPRSS_TEXT_DOMAIN ) ?></h3>
27
  <?php
55
  wprss_free_help_display();
56
  }
57
  ?>
58
+ <h3><?php _e( 'Built-in Help Beacon', WPRSS_TEXT_DOMAIN ) ?></h3>
59
+ <form method="POST">
60
+ <p>
61
+ <?php _e('The help beacon is an interactive button that appears on the bottom-right section of WP RSS Aggregator admin pages.', WPRSS_TEXT_DOMAIN); ?>
62
+ <?php _e('It provides access to our documentation and (if you have a valid license for any of our add-ons) you can also contact our support team directly.', WPRSS_TEXT_DOMAIN); ?>
63
+ </p>
64
+ <p>
65
+ <?php _e('The beacon tracks what pages you were on before clicking it. This helps it provide relevant help results and also helps the support team better understand the problem you are facing.', WPRSS_TEXT_DOMAIN); ?>
66
+ <?php _e('The beacon only works on WP RSS Aggregator admin pages and does not track your mouse clicks and keyboard input.', WPRSS_TEXT_DOMAIN); ?>
67
+ </p>
68
+ <?php if (wprss_is_help_beacon_enabled()): ?>
69
+ <p><?php _e('The support beacon is currently <b>enabled</b>.', WPRSS_TEXT_DOMAIN); ?></p>
70
+ <button type="submit" name="wprss_hs_beacon_enabled" value="0" class="button button-secondary">
71
+ <?php _e('Disable support beacon', WPRSS_TEXT_DOMAIN); ?>
72
+ </button>
73
+ <?php else: ?>
74
+ <p><?php _e('By enabling the help beacon, you are consenting to this data collection.', WPRSS_TEXT_DOMAIN); ?></p>
75
+ <button type="submit" name="wprss_hs_beacon_enabled" value="1" class="button button-primary">
76
+ <?php _e('Enable support beacon', WPRSS_TEXT_DOMAIN); ?>
77
+ </button>
78
+ <?php endif; ?>
79
+
80
+ <?php wp_nonce_field('wprss_hs_beacon_enabled'); ?>
81
+ </form>
82
  </div>
83
  <?php
84
  }
85
 
86
+ // Handler to update the HS beacon enabled option
87
+ add_action('init', function () {
88
+ if (!is_admin()) {
89
+ return;
90
+ }
91
+
92
+ $enabled = filter_input(INPUT_POST, 'wprss_hs_beacon_enabled', FILTER_VALIDATE_INT);
93
+
94
+ if ($enabled !== null) {
95
+ check_admin_referer('wprss_hs_beacon_enabled');
96
+ update_option('wprss_hs_beacon_enabled', $enabled);
97
+ }
98
+ });
99
 
100
  /**
101
  * Print the premium help section, linking to the contact us page on the site.
includes/admin-import-export.php CHANGED
@@ -160,8 +160,6 @@ use Aventura\Wprss\Core\Model\BulkSourceImport\ServiceProvider;
160
  function wprss_import_export_settings_page_display() {
161
  if ( !isset( $_POST['export'] ) ) { ?>
162
  <div class="wrap">
163
- <?php screen_icon( 'wprss-aggregator' ); ?>
164
-
165
  <!-- Bulk Add -->
166
  <h2><?php _e( 'Bulk Feed Import', WPRSS_TEXT_DOMAIN ); ?></h2>
167
  <p><?php _e( 'Import multiple feed sources at once, by entering the name and URLs of your feeds below.', WPRSS_TEXT_DOMAIN ); ?></p>
@@ -221,4 +219,4 @@ add_filter(\WPRSS_EVENT_PREFIX .'core_container_init', function(WritableContaine
221
  'event_prefix' => \WPRSS_EVENT_PREFIX,
222
  ));
223
  $container->register($serviceProvider);
224
- });
160
  function wprss_import_export_settings_page_display() {
161
  if ( !isset( $_POST['export'] ) ) { ?>
162
  <div class="wrap">
 
 
163
  <!-- Bulk Add -->
164
  <h2><?php _e( 'Bulk Feed Import', WPRSS_TEXT_DOMAIN ); ?></h2>
165
  <p><?php _e( 'Import multiple feed sources at once, by entering the name and URLs of your feeds below.', WPRSS_TEXT_DOMAIN ); ?></p>
219
  'event_prefix' => \WPRSS_EVENT_PREFIX,
220
  ));
221
  $container->register($serviceProvider);
222
+ });
includes/{admin-intro.php → admin-intro-page.php} RENAMED
@@ -17,30 +17,6 @@ define('WPRSS_INTRO_FEED_URL_PARAM', 'wprss_intro_feed_url');
17
  define('WPRSS_INTRO_SHORTCODE_PAGE_OPTION', 'wprss_intro_shortcode_page');
18
  define('WPRSS_INTRO_SHORTCODE_PAGE_PREVIEW_PARAM', 'wprss_preview_shortcode_page');
19
 
20
- /**
21
- * Detects an activation and redirects the user to the intro page.
22
- *
23
- * @since [*next-version*]
24
- */
25
- add_action('admin_init', function () {
26
- // Continue only if during an activation redirect
27
- if (!get_transient('_wprss_activation_redirect')) {
28
- return;
29
- }
30
-
31
- // Delete the redirect transient
32
- delete_transient('_wprss_activation_redirect');
33
-
34
- // Continue only if activating from a non-network site and not bulk activating plugins
35
- if (is_network_admin() || isset($_GET['activate-multi'])) {
36
- return;
37
- }
38
-
39
- if (wprss_should_do_intro()) {
40
- wp_safe_redirect(wprss_get_intro_page_url());
41
- }
42
- });
43
-
44
  /**
45
  * Registers the introduction page.
46
  *
@@ -51,9 +27,9 @@ add_action('admin_menu', function () {
51
  null,
52
  __('Welcome to WP RSS Aggregator'),
53
  __('Welcome to WP RSS Aggregator'),
54
- 'read',
55
  WPRSS_INTRO_PAGE_SLUG,
56
- 'wpra_render_intro_page'
57
  );
58
  });
59
 
@@ -66,13 +42,15 @@ add_action('admin_menu', function () {
66
  * @throws Twig_Error_Runtime
67
  * @throws Twig_Error_Syntax
68
  */
69
- function wpra_render_intro_page()
70
  {
71
- wp_enqueue_script('intro-wizard', WPRSS_JS . 'intro.min.js', [], '0.1', true);
 
 
72
  wp_enqueue_style('intro-wizard', WPRSS_CSS . 'intro.min.css');
73
 
74
  $nonce = wp_create_nonce(WPRSS_INTRO_NONCE_NAME);
75
- wp_localize_script('intro-wizard', 'wprssWizardConfig', [
76
  'previewUrl' => admin_url('admin.php?wprss_preview_shortcode_page=1&nonce=' . $nonce),
77
  'feedListUrl' => admin_url('edit.php?post_type=wprss_feed'),
78
  'addOnsUrl' => 'https://www.wprssaggregator.com/plugins/?utm_source=core_plugin&utm_medium=onboarding_wizard&utm_campaign=onboarding_wizard_addons_button&utm_content=addons_button',
@@ -80,19 +58,19 @@ function wpra_render_intro_page()
80
  'demoImageUrl' => WPRSS_IMG . 'welcome-page/demo.png',
81
  'feedbackUrl' => 'https://wordpress.org/support/topic/does-everything-i-need-16/',
82
  'knowledgeBaseUrl' => 'https://kb.wprssaggregator.com/',
83
- 'feedEndpoint' => [
84
  'url' => admin_url('admin-ajax.php'),
85
- 'defaultPayload' => [
86
  'action' => 'wprss_create_intro_feed',
87
  'nonce' => $nonce,
88
- ],
89
- ],
90
- ]);
91
 
92
- echo wprss_render_template('admin-intro-page.twig', [
93
  'title' => 'Welcome to WP RSS Aggregator 👋',
94
  'subtitle' => 'Follow these introductory steps to get started with WP RSS Aggregator.',
95
- ]);
96
  }
97
 
98
  /**
@@ -103,9 +81,9 @@ function wpra_render_intro_page()
103
  add_action('wp_ajax_wprss_set_intro_step', function () {
104
  check_ajax_referer(WPRSS_INTRO_NONCE_NAME, 'nonce');
105
  if (!current_user_can('manage_options')) {
106
- wp_die('', '', [
107
  'response' => 403,
108
- ]);
109
  }
110
 
111
  $step = filter_input(INPUT_POST, WPRSS_INTRO_STEP_POST_PARAM, FILTER_VALIDATE_INT);
@@ -117,9 +95,9 @@ add_action('wp_ajax_wprss_set_intro_step', function () {
117
  }
118
 
119
  wprss_set_intro_step($step);
120
- wprss_ajax_success_response([
121
  'wprss_intro_step' => $step,
122
- ]);
123
  });
124
 
125
  /**
@@ -130,9 +108,9 @@ add_action('wp_ajax_wprss_set_intro_step', function () {
130
  add_action('wp_ajax_wprss_create_intro_feed', function () {
131
  check_ajax_referer(WPRSS_INTRO_NONCE_NAME, 'nonce');
132
  if (!current_user_can('manage_options')) {
133
- wp_die('', '', [
134
  'response' => 403,
135
- ]);
136
  }
137
 
138
  $url = filter_input(INPUT_POST, WPRSS_INTRO_FEED_URL_PARAM, FILTER_VALIDATE_URL);
@@ -149,11 +127,11 @@ add_action('wp_ajax_wprss_create_intro_feed', function () {
149
  }
150
 
151
  try {
152
- wp_schedule_single_event(time(), 'wprss_create_intro_feed_source', [$url]);
153
  $items = wprss_preview_feed_items($url);
154
- $data = [
155
  'feed_items' => $items,
156
- ];
157
  wprss_set_intro_done(true);
158
  wprss_ajax_success_response($data);
159
  } catch (Exception $e) {
@@ -175,9 +153,9 @@ add_action('init', function () {
175
 
176
  check_admin_referer(WPRSS_INTRO_NONCE_NAME, 'nonce');
177
  if (!current_user_can('manage_options')) {
178
- wp_die('', '', [
179
  'response' => 403,
180
- ]);
181
  }
182
 
183
  try {
@@ -219,15 +197,15 @@ function wprss_preview_feed_items($url, $max = 10)
219
  }
220
 
221
  $count = 0;
222
- $results = [];
223
  foreach ($items as $item) {
224
  /* @var $item SimplePie_Item */
225
- $results[] = [
226
  'title' => $item->get_title(),
227
  'permalink' => $item->get_permalink(),
228
  'date' => $item->get_date(get_option('date_format')),
229
  'author' => $item->get_author()->name,
230
- ];
231
 
232
  if ($count++ > $max) {
233
  break;
@@ -263,15 +241,15 @@ function wprss_create_intro_feed_source($url)
263
  }
264
 
265
  // Update the existing feed source with a new generated name and new URL
266
- wp_update_post([
267
  'ID' => $feedId,
268
  'post_title' => wprss_feed_source_name_from_url($url),
269
  'post_status' => 'publish',
270
- 'meta_input' => [
271
  'wprss_url' => $url,
272
  'wprss_limit' => WPRSS_INTRO_FEED_LIMIT
273
- ]
274
- ]);
275
 
276
  // Re-import the items for this feed
277
  wprss_delete_feed_items($feedId);
@@ -294,7 +272,7 @@ function wprss_create_intro_feed_source($url)
294
  function wprss_create_feed_source_with_url($url)
295
  {
296
  $name = wprss_feed_source_name_from_url($url);
297
- $result = wprss_import_feed_sources_array([$url => $name]);
298
 
299
  if (empty($result)) {
300
  throw new Exception(
@@ -385,12 +363,12 @@ function wprss_create_shortcode_page($title = null, $status = 'draft')
385
  ? _x('Feeds', 'default name of shortcode page', WPRSS_TEXT_DOMAIN)
386
  : $title;
387
 
388
- $id = wp_insert_post([
389
  'post_type' => 'page',
390
  'post_title' => $title,
391
  'post_content' => '[wp-rss-aggregator]',
392
- 'post_status' => $status
393
- ]);
394
 
395
  if (is_wp_error($id)) {
396
  throw new Exception($id->get_error_message(), $id->get_error_code());
@@ -443,9 +421,9 @@ function wprss_get_intro_page_url()
443
  *
444
  * @return bool True if the introduction should be shown, false if not.
445
  */
446
- function wprss_should_do_intro()
447
  {
448
- return wprss_is_new_user() && intval(get_option(WPRSS_INTRO_DID_INTRO_OPTION, 0)) !== 1 && wprss_can_use_twig();
449
  }
450
 
451
  /**
@@ -483,14 +461,14 @@ function wprss_is_new_user()
483
  * @param array $data Optional data to send.
484
  * @param int $status Optional HTTP status code of the response.
485
  */
486
- function wprss_ajax_success_response($data = [], $status = 200)
487
  {
488
- echo json_encode([
489
  'success' => true,
490
  'error' => '',
491
  'data' => $data,
492
  'status' => $status,
493
- ]);
494
  wp_die();
495
  }
496
 
@@ -504,11 +482,11 @@ function wprss_ajax_success_response($data = [], $status = 200)
504
  */
505
  function wprss_ajax_error_response($message, $status = 400)
506
  {
507
- echo json_encode([
508
  'success' => false,
509
  'error' => $message,
510
- 'data' => [],
511
  'status' => $status,
512
- ]);
513
  wp_die();
514
  }
17
  define('WPRSS_INTRO_SHORTCODE_PAGE_OPTION', 'wprss_intro_shortcode_page');
18
  define('WPRSS_INTRO_SHORTCODE_PAGE_PREVIEW_PARAM', 'wprss_preview_shortcode_page');
19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  /**
21
  * Registers the introduction page.
22
  *
27
  null,
28
  __('Welcome to WP RSS Aggregator'),
29
  __('Welcome to WP RSS Aggregator'),
30
+ 'manage_options',
31
  WPRSS_INTRO_PAGE_SLUG,
32
+ 'wprss_render_intro_page'
33
  );
34
  });
35
 
42
  * @throws Twig_Error_Runtime
43
  * @throws Twig_Error_Syntax
44
  */
45
+ function wprss_render_intro_page()
46
  {
47
+ wprss_update_previous_update_page_version();
48
+
49
+ wprss_plugin_enqueue_app_scripts('intro-wizard', WPRSS_JS . 'intro.min.js', array(), '0.1', true);
50
  wp_enqueue_style('intro-wizard', WPRSS_CSS . 'intro.min.css');
51
 
52
  $nonce = wp_create_nonce(WPRSS_INTRO_NONCE_NAME);
53
+ wp_localize_script('intro-wizard', 'wprssWizardConfig', array(
54
  'previewUrl' => admin_url('admin.php?wprss_preview_shortcode_page=1&nonce=' . $nonce),
55
  'feedListUrl' => admin_url('edit.php?post_type=wprss_feed'),
56
  'addOnsUrl' => 'https://www.wprssaggregator.com/plugins/?utm_source=core_plugin&utm_medium=onboarding_wizard&utm_campaign=onboarding_wizard_addons_button&utm_content=addons_button',
58
  'demoImageUrl' => WPRSS_IMG . 'welcome-page/demo.png',
59
  'feedbackUrl' => 'https://wordpress.org/support/topic/does-everything-i-need-16/',
60
  'knowledgeBaseUrl' => 'https://kb.wprssaggregator.com/',
61
+ 'feedEndpoint' => array(
62
  'url' => admin_url('admin-ajax.php'),
63
+ 'defaultPayload' => array(
64
  'action' => 'wprss_create_intro_feed',
65
  'nonce' => $nonce,
66
+ ),
67
+ ),
68
+ ));
69
 
70
+ echo wprss_render_template('admin-intro-page.twig', array(
71
  'title' => 'Welcome to WP RSS Aggregator 👋',
72
  'subtitle' => 'Follow these introductory steps to get started with WP RSS Aggregator.',
73
+ ));
74
  }
75
 
76
  /**
81
  add_action('wp_ajax_wprss_set_intro_step', function () {
82
  check_ajax_referer(WPRSS_INTRO_NONCE_NAME, 'nonce');
83
  if (!current_user_can('manage_options')) {
84
+ wp_die('', '', array(
85
  'response' => 403,
86
+ ));
87
  }
88
 
89
  $step = filter_input(INPUT_POST, WPRSS_INTRO_STEP_POST_PARAM, FILTER_VALIDATE_INT);
95
  }
96
 
97
  wprss_set_intro_step($step);
98
+ wprss_ajax_success_response(array(
99
  'wprss_intro_step' => $step,
100
+ ));
101
  });
102
 
103
  /**
108
  add_action('wp_ajax_wprss_create_intro_feed', function () {
109
  check_ajax_referer(WPRSS_INTRO_NONCE_NAME, 'nonce');
110
  if (!current_user_can('manage_options')) {
111
+ wp_die('', '', array(
112
  'response' => 403,
113
+ ));
114
  }
115
 
116
  $url = filter_input(INPUT_POST, WPRSS_INTRO_FEED_URL_PARAM, FILTER_VALIDATE_URL);
127
  }
128
 
129
  try {
130
+ wp_schedule_single_event(time(), 'wprss_create_intro_feed_source', array($url));
131
  $items = wprss_preview_feed_items($url);
132
+ $data = array(
133
  'feed_items' => $items,
134
+ );
135
  wprss_set_intro_done(true);
136
  wprss_ajax_success_response($data);
137
  } catch (Exception $e) {
153
 
154
  check_admin_referer(WPRSS_INTRO_NONCE_NAME, 'nonce');
155
  if (!current_user_can('manage_options')) {
156
+ wp_die('', '', array(
157
  'response' => 403,
158
+ ));
159
  }
160
 
161
  try {
197
  }
198
 
199
  $count = 0;
200
+ $results = array();
201
  foreach ($items as $item) {
202
  /* @var $item SimplePie_Item */
203
+ $results[] = array(
204
  'title' => $item->get_title(),
205
  'permalink' => $item->get_permalink(),
206
  'date' => $item->get_date(get_option('date_format')),
207
  'author' => $item->get_author()->name,
208
+ );
209
 
210
  if ($count++ > $max) {
211
  break;
241
  }
242
 
243
  // Update the existing feed source with a new generated name and new URL
244
+ wp_update_post(array(
245
  'ID' => $feedId,
246
  'post_title' => wprss_feed_source_name_from_url($url),
247
  'post_status' => 'publish',
248
+ 'meta_input' => array(
249
  'wprss_url' => $url,
250
  'wprss_limit' => WPRSS_INTRO_FEED_LIMIT
251
+ )
252
+ ));
253
 
254
  // Re-import the items for this feed
255
  wprss_delete_feed_items($feedId);
272
  function wprss_create_feed_source_with_url($url)
273
  {
274
  $name = wprss_feed_source_name_from_url($url);
275
+ $result = wprss_import_feed_sources_array(array($url => $name));
276
 
277
  if (empty($result)) {
278
  throw new Exception(
363
  ? _x('Feeds', 'default name of shortcode page', WPRSS_TEXT_DOMAIN)
364
  : $title;
365
 
366
+ $id = wp_insert_post(array(
367
  'post_type' => 'page',
368
  'post_title' => $title,
369
  'post_content' => '[wp-rss-aggregator]',
370
+ 'post_status' => $status,
371
+ ));
372
 
373
  if (is_wp_error($id)) {
374
  throw new Exception($id->get_error_message(), $id->get_error_code());
421
  *
422
  * @return bool True if the introduction should be shown, false if not.
423
  */
424
+ function wprss_should_do_intro_page()
425
  {
426
+ return wprss_is_new_user() && intval(get_option(WPRSS_INTRO_DID_INTRO_OPTION, 0)) !== 1 && current_user_can('manage_options');
427
  }
428
 
429
  /**
461
  * @param array $data Optional data to send.
462
  * @param int $status Optional HTTP status code of the response.
463
  */
464
+ function wprss_ajax_success_response($data = array(), $status = 200)
465
  {
466
+ echo json_encode(array(
467
  'success' => true,
468
  'error' => '',
469
  'data' => $data,
470
  'status' => $status,
471
+ ));
472
  wp_die();
473
  }
474
 
482
  */
483
  function wprss_ajax_error_response($message, $status = 400)
484
  {
485
+ echo json_encode(array(
486
  'success' => false,
487
  'error' => $message,
488
+ 'data' => array(),
489
  'status' => $status,
490
+ ));
491
  wp_die();
492
  }
includes/admin-options.php CHANGED
@@ -355,8 +355,6 @@
355
  function wprss_settings_page_display() {
356
  ?>
357
  <div class="wrap">
358
- <?php screen_icon( 'wprss-aggregator' ); ?>
359
-
360
  <h2><?php _e( 'WP RSS Aggregator Settings', WPRSS_TEXT_DOMAIN ); ?></h2>
361
 
362
  <?php settings_errors(); ?>
355
  function wprss_settings_page_display() {
356
  ?>
357
  <div class="wrap">
 
 
358
  <h2><?php _e( 'WP RSS Aggregator Settings', WPRSS_TEXT_DOMAIN ); ?></h2>
359
 
360
  <?php settings_errors(); ?>
includes/admin-plugins.php ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if (!defined('ABSPATH')) {
4
+ die;
5
+ }
6
+
7
+ /**
8
+ * Adds deactivate poll application on plugin's page.
9
+ *
10
+ * @since 4.12.1
11
+ */
12
+ add_action('admin_init', function () {
13
+ $page = trim($_SERVER["REQUEST_URI"], '/');
14
+ $isPluginsPage = strpos($page, 'plugins.php') !== false;
15
+
16
+ if (!$isPluginsPage) {
17
+ return;
18
+ }
19
+
20
+ add_action('admin_footer', function () {
21
+ wprss_plugin_enqueue_app_scripts('wpra-plugins', WPRSS_JS . 'plugins.min.js', array(), '0.1', true);
22
+ wp_enqueue_style('wpra-plugins', WPRSS_CSS . 'plugins.min.css');
23
+
24
+ $addons = wprss_find_installed_addon_names();
25
+ $addons = array_fill_keys($addons, 1);
26
+
27
+ wp_localize_script('wpra-plugins', 'WrpaDisablePoll', array(
28
+ 'image' => WPRSS_IMG,
29
+ 'url' => 'https://hooks.zapier.com/hooks/catch/305784/puf5uf/',
30
+ 'model' => array(
31
+ 'reason' => 'Other',
32
+ 'follow_up' => null,
33
+ 'date' => date('j M Y'),
34
+ 'addons' => $addons,
35
+ ),
36
+ 'form' => array(
37
+ array(
38
+ 'label' => '',
39
+ 'type' => 'radio',
40
+ 'name' => 'reason',
41
+ 'options' =>
42
+ array(
43
+ array(
44
+ 'value' => 'I no longer need the plugin',
45
+ 'label' => __('I no longer need the plugin', WPRSS_TEXT_DOMAIN),
46
+ ),
47
+ array(
48
+ 'value' => 'I found a better alternative',
49
+ 'label' => __('I found a better alternative', WPRSS_TEXT_DOMAIN),
50
+ ),
51
+ array(
52
+ 'value' => 'I couldn\'t get the plugin to work',
53
+ 'label' => __('I couldn\'t get the plugin to work', WPRSS_TEXT_DOMAIN),
54
+ ),
55
+ array(
56
+ 'value' => 'I\'m temporarily deactivating the plugin, but I\'ll be back',
57
+ 'label' => __('I\'m temporarily deactivating the plugin, but I\'ll be back', WPRSS_TEXT_DOMAIN),
58
+ ),
59
+ array(
60
+ 'value' => 'I have a WP RSS Aggregator add-on',
61
+ 'label' => __('I have a WP RSS Aggregator add-on', WPRSS_TEXT_DOMAIN),
62
+ ),
63
+ array(
64
+ 'value' => 'Other',
65
+ 'label' => __('Other', WPRSS_TEXT_DOMAIN),
66
+ ),
67
+ ),
68
+ ),
69
+ array(
70
+ 'label' => __('Would you mind sharing its name?', WPRSS_TEXT_DOMAIN),
71
+ 'type' => 'textarea',
72
+ 'name' => 'follow_up',
73
+ 'condition' =>
74
+ array(
75
+ 'field' => 'reason',
76
+ 'operator' => '=',
77
+ 'value' => 'I found a better alternative',
78
+ ),
79
+ ),
80
+ array(
81
+ 'type' => 'content',
82
+ 'label' => __('Have you <a target="_blank" href="https://wordpress.org/support/plugin/wp-rss-aggregator/">contacted our support team</a> or checked out our <a href="https://kb.wprssaggregator.com/" target="_blank">Knowledge Base</a>?', WPRSS_TEXT_DOMAIN),
83
+ 'condition' =>
84
+ array(
85
+ 'field' => 'reason',
86
+ 'operator' => '=',
87
+ 'value' => 'I couldn\'t get the plugin to work',
88
+ ),
89
+ ),
90
+ array(
91
+ 'type' => 'content',
92
+ 'className' => 'error',
93
+ 'label' => __('This core plugin is required for all our premium add-ons. Please don\'t deactivate it if you currently have premium add-ons installed and activated.', WPRSS_TEXT_DOMAIN),
94
+ 'condition' =>
95
+ array(
96
+ 'field' => 'reason',
97
+ 'operator' => '=',
98
+ 'value' => 'I have a WP RSS Aggregator add-on',
99
+ ),
100
+ ),
101
+ array(
102
+ 'label' => __('Please share your reason...', WPRSS_TEXT_DOMAIN),
103
+ 'type' => 'textarea',
104
+ 'name' => 'follow_up',
105
+ 'condition' =>
106
+ array(
107
+ 'field' => 'reason',
108
+ 'operator' => '=',
109
+ 'value' => 'Other',
110
+ ),
111
+ ),
112
+ )
113
+ ));
114
+
115
+ echo '<div id="wpra-plugins-app"></div>';
116
+ });
117
+ });
includes/admin-update-page.php ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ define('WPRSS_UPDATE_PAGE_SLUG', 'wpra-update');
4
+ define('WPRSS_UPDATE_PAGE_PREV_VERSION_OPTION', 'wprss_prev_update_page_version');
5
+
6
+ /**
7
+ * Registers the update page.
8
+ *
9
+ * @since 4.12.1
10
+ */
11
+ add_action('admin_menu', function () {
12
+ add_submenu_page(
13
+ null,
14
+ __('Thank you for updating WP RSS Aggregator', WPRSS_TEXT_DOMAIN),
15
+ __('Thank you for updating WP RSS Aggregator', WPRSS_TEXT_DOMAIN),
16
+ 'manage_options',
17
+ WPRSS_UPDATE_PAGE_SLUG,
18
+ 'wprss_render_update_page'
19
+ );
20
+ });
21
+
22
+ /**
23
+ * Renders the update page.
24
+ *
25
+ * @since 4.12.1
26
+ *
27
+ * @throws Twig_Error_Loader
28
+ * @throws Twig_Error_Runtime
29
+ * @throws Twig_Error_Syntax
30
+ */
31
+ function wprss_render_update_page()
32
+ {
33
+ wprss_update_previous_update_page_version();
34
+
35
+ wp_enqueue_style('update-page', WPRSS_CSS . 'update.min.css');
36
+
37
+ echo wprss_render_template('admin-update-page.twig', array(
38
+ 'title' => __('What\'s new in WP RSS Aggregator?', WPRSS_TEXT_DOMAIN),
39
+ 'version' => WPRSS_VERSION,
40
+ 'beacon_nonce_field' => wp_nonce_field('wprss_hs_beacon_enabled'),
41
+ 'beacon_enabled' => wprss_is_help_beacon_enabled(),
42
+ 'url' => array(
43
+ 'main' => admin_url('edit.php?post_type=wprss_feed'),
44
+ 'website' => 'https://www.wprssaggregator.com/',
45
+ 'support' => 'https://www.wprssaggregator.com/contact/',
46
+ 'kb' => 'https://kb.wprssaggregator.com/',
47
+ ),
48
+ 'path' => array(
49
+ 'images' => WPRSS_IMG,
50
+ ),
51
+ ));
52
+ }
53
+
54
+ /**
55
+ * Retrieves the URL of the update page.
56
+ *
57
+ * @since 4.12.1
58
+ *
59
+ * @return string
60
+ */
61
+ function wprss_get_update_page_url()
62
+ {
63
+ return menu_page_url(WPRSS_UPDATE_PAGE_SLUG, false);
64
+ }
65
+
66
+ /**
67
+ * Checks whether the update should be shown or not, based on whether the user is new and previously had an older
68
+ * version of the plugin.
69
+ *
70
+ * @since 4.12.1
71
+ *
72
+ * @return bool True if the update page should be shown, false if not.
73
+ */
74
+ function wprss_should_do_update_page()
75
+ {
76
+ return !wprss_is_new_user() && current_user_can('manage_options') && wprss_user_had_previous_version();
77
+ }
78
+
79
+ /**
80
+ * Checks whether the user had a previous version of WP RSS Aggregator.
81
+ *
82
+ * @since 4.12.1
83
+ *
84
+ * @return mixed
85
+ */
86
+ function wprss_user_had_previous_version()
87
+ {
88
+ $previous = wprss_get_previous_update_page_version();
89
+ $is_newer = version_compare(WPRSS_VERSION, $previous, '>');
90
+
91
+ return $is_newer;
92
+ }
93
+
94
+ /**
95
+ * Updates the previous update page version to the current plugin version.
96
+ *
97
+ * @since 4.12.1
98
+ */
99
+ function wprss_update_previous_update_page_version()
100
+ {
101
+ update_option(WPRSS_UPDATE_PAGE_PREV_VERSION_OPTION, WPRSS_VERSION);
102
+ }
103
+
104
+ /**
105
+ * Retrieves the previous update page version seen by the user, if at all.
106
+ *
107
+ * @since 4.12.1
108
+ *
109
+ * @return string The version string, or '0.0.0' if the user is new nad has not used WPRA before.
110
+ */
111
+ function wprss_get_previous_update_page_version()
112
+ {
113
+ wprss_migrate_welcome_page_to_update_page();
114
+
115
+ return get_option(WPRSS_UPDATE_PAGE_PREV_VERSION_OPTION, '0.0.0');
116
+ }
117
+
118
+ /**
119
+ * Migrates the previously used "welcome screen" version DB option.
120
+ *
121
+ * @since 4.12.1
122
+ */
123
+ function wprss_migrate_welcome_page_to_update_page()
124
+ {
125
+ // Get the previous welcome screen version - for when the page was called the "welcome screen"
126
+ $pwsv = get_option('wprss_pwsv', null);
127
+
128
+ // If the option exists, move it to the new option
129
+ if ($pwsv !== null) {
130
+ update_option(WPRSS_UPDATE_PAGE_PREV_VERSION_OPTION, $pwsv);
131
+ delete_option('wprss_pwsv');
132
+ }
133
+ }
includes/admin.php CHANGED
@@ -115,3 +115,46 @@
115
  }
116
  return $action_links;
117
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
  }
116
  return $action_links;
117
  }
118
+
119
+ /**
120
+ * Function for registering application's scripts that depends on advanced libraries.
121
+ * It will enqueue manifest and vendor scripts, which contains all required logic
122
+ * for bootstrapping application and dependencies.
123
+ *
124
+ * Use only for Vue-related apps that use Webpack for being built.
125
+ *
126
+ * @since 4.12.1
127
+ *
128
+ * @param $handle
129
+ * @param string $src
130
+ * @param array $deps
131
+ * @param bool $ver
132
+ * @param bool $in_footer
133
+ */
134
+ function wprss_plugin_enqueue_app_scripts( $handle, $src = '', $deps = array(), $ver = false, $in_footer = false ) {
135
+ /*
136
+ * Manifest file holds function used for bootstrapping and ordered
137
+ * loading of dependencies and application.
138
+ */
139
+ wp_enqueue_script('wpra-manifest', WPRSS_JS . 'wpra-manifest.min.js', array(), '0.1', true);
140
+
141
+ /*
142
+ * Vendor file holds all common dependencies for "compilable" applications.
143
+ *
144
+ * For example, `intro` pages application's and plugin's page application's files
145
+ * holds only logic for that particular application. Common dependencies like Vue
146
+ * live in this file and loaded before that application.
147
+ */
148
+ wp_enqueue_script('wpra-vendor', WPRSS_JS . 'wpra-vendor.min.js', array(
149
+ 'wpra-manifest'
150
+ ), '0.1', true);
151
+
152
+ /*
153
+ * Enqueue requested script.
154
+ */
155
+ $deps = array_merge(array(
156
+ 'wpra-manifest',
157
+ 'wpra-vendor',
158
+ ), $deps);
159
+ wp_enqueue_script($handle, $src, $deps, $ver, $in_footer);
160
+ }
includes/custom-feed.php CHANGED
@@ -13,13 +13,9 @@
13
  * @since 3.3
14
  */
15
  function wprss_addfeed_add_feed() {
16
- $general_settings = get_option( 'wprss_settings_general', 'wprss' );
17
- if ( !empty( $general_settings ) && isset( $general_settings['custom_feed_url'] ) && !empty( $general_settings['custom_feed_url'] ) ) {
18
- $url = $general_settings['custom_feed_url'];
19
- }
20
- else {
21
- $url = $general_settings['custom_feed_url'] = 'wprss';
22
- update_option( 'wprss_settings_general', $general_settings );
23
  }
24
 
25
  // Add the feed
13
  * @since 3.3
14
  */
15
  function wprss_addfeed_add_feed() {
16
+ $url = wprss_get_general_setting('custom_feed_url');
17
+ if (empty($url)) {
18
+ $url = 'wprss';
 
 
 
 
19
  }
20
 
21
  // Add the feed
includes/custom-post-types.php CHANGED
@@ -99,7 +99,8 @@ define('WPRSS_POST_TYPE_FEED_SOURCE', 'wprss_feed');
99
  'slug' => 'feed-items',
100
  'with_front' => false,
101
  ),
102
- 'capability_type' => 'feed_source',
 
103
  'labels' => $labels
104
  )
105
  );
99
  'slug' => 'feed-items',
100
  'with_front' => false,
101
  ),
102
+ 'capability_type' => 'feed_item',
103
+ 'map_meta_cap' => true,
104
  'labels' => $labels
105
  )
106
  );
includes/feed-importing.php CHANGED
@@ -745,8 +745,6 @@
745
  usort($items, function ($itemA, $itemB) use ($comparators, $feedSource) {
746
  return wprss_items_sort_compare_items($itemA, $itemB, $comparators, $feedSource);
747
  });
748
-
749
- wprss_log_obj( 'Sorted', NULL, WPRSS_LOG_LEVEL_INFO );
750
  } catch (\InvalidArgumentException $e) {
751
  wprss_log( 'Error was encountered while sorting items; list remains unsorted', NULL, WPRSS_LOG_LEVEL_WARNING );
752
  }
745
  usort($items, function ($itemA, $itemB) use ($comparators, $feedSource) {
746
  return wprss_items_sort_compare_items($itemA, $itemB, $comparators, $feedSource);
747
  });
 
 
748
  } catch (\InvalidArgumentException $e) {
749
  wprss_log( 'Error was encountered while sorting items; list remains unsorted', NULL, WPRSS_LOG_LEVEL_WARNING );
750
  }
includes/licensing.php CHANGED
@@ -59,6 +59,39 @@ function wprss_get_addons($noCache = false) {
59
  : $addons;
60
  }
61
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  /**
63
  * Hooks the licensing system into WordPress.
64
  */
59
  : $addons;
60
  }
61
 
62
+ /**
63
+ * Finds all WPRA addons installed, even if they are deactivated.
64
+ *
65
+ * @since 4.12.1
66
+ *
67
+ * @return array An array of WordPress plugin info arrays.
68
+ */
69
+ function wprss_find_installed_addons()
70
+ {
71
+ $all_plugins = get_plugins();
72
+ $addons = array();
73
+ foreach ($all_plugins as $plugin_path => $plugin) {
74
+ if ($plugin_path !== WPRSS_FILE_CONSTANT && strpos($plugin['Name'], 'WP RSS Aggregator - ') === 0) {
75
+ $addons[$plugin_path] = $plugin;
76
+ }
77
+ }
78
+ return $addons;
79
+ }
80
+
81
+ /**
82
+ * Retrieves the names of the installed addons, even if they are deactivated.
83
+ *
84
+ * @since 4.12.1
85
+ *
86
+ * @return string[] A list of the names of installed addons.
87
+ */
88
+ function wprss_find_installed_addon_names()
89
+ {
90
+ return array_map(function ($plugin_info) {
91
+ return substr($plugin_info['Name'], strlen('WP RSS Aggregator - '));
92
+ }, wprss_find_installed_addons());
93
+ }
94
+
95
  /**
96
  * Hooks the licensing system into WordPress.
97
  */
includes/opml-importer.php CHANGED
@@ -60,9 +60,9 @@
60
  */
61
  public function opml_import() {
62
  // Show the Icon and Title
63
- ?><div class="wrap"><?php
64
- screen_icon();
65
- ?><h2><?php _e( 'Import OPML', WPRSS_TEXT_DOMAIN ) ?></h2><?php
66
 
67
  // Get the current step from URL query string
68
  $step = empty( $_GET['step'] ) ? 0 : (int) $_GET['step'];
60
  */
61
  public function opml_import() {
62
  // Show the Icon and Title
63
+ ?>
64
+ <div class="wrap">
65
+ <h2><?php _e( 'Import OPML', WPRSS_TEXT_DOMAIN ) ?></h2><?php
66
 
67
  // Get the current step from URL query string
68
  $step = empty( $_GET['step'] ) ? 0 : (int) $_GET['step'];
includes/roles-capabilities.php CHANGED
@@ -45,7 +45,7 @@
45
  function wprss_get_core_caps() {
46
  $capabilities = array();
47
 
48
- $capability_types = array( 'feed', 'feed_source' );
49
 
50
  foreach ( $capability_types as $capability_type ) {
51
  $capabilities[ $capability_type ] = array(
@@ -104,4 +104,4 @@
104
  }
105
  }
106
  }
107
- }
45
  function wprss_get_core_caps() {
46
  $capabilities = array();
47
 
48
+ $capability_types = array( 'feed', 'feed_item' );
49
 
50
  foreach ( $capability_types as $capability_type ) {
51
  $capabilities[ $capability_type ] = array(
104
  }
105
  }
106
  }
107
+ }
includes/scripts.php CHANGED
@@ -5,6 +5,8 @@
5
  * @package WPRSSAggregator
6
  */
7
 
 
 
8
  add_action( 'init', 'wprss_register_scripts', 9 );
9
  function wprss_register_scripts()
10
  {
@@ -71,6 +73,11 @@
71
  'sent-error' => sprintf(__('There was an error sending the form. Please use the <a href="%s">contact form on our site.</a>', WPRSS_TEXT_DOMAIN), esc_attr('https://www.wprssaggregator.com/contact/')),
72
  'sent-ok' => __("Your message has been sent and we'll send you a confirmation e-mail when we receive it.", WPRSS_TEXT_DOMAIN)
73
  ));
 
 
 
 
 
74
  }
75
 
76
 
@@ -156,6 +163,11 @@
156
  wp_enqueue_script( 'wprss-admin-help' );
157
  }
158
 
 
 
 
 
 
159
  do_action('wprss_admin_exclusive_scripts_styles');
160
  }
161
 
@@ -214,5 +226,6 @@
214
  wp_register_style( 'wprss-admin-editor-styles', WPRSS_CSS . 'admin-editor.css', array(), $version );
215
  wp_register_style( 'wprss-admin-tracking-styles', WPRSS_CSS . 'admin-tracking-styles.css', array(), $version );
216
  wp_register_style( 'wprss-admin-general-styles', WPRSS_CSS . 'admin-general-styles.css', array(), $version );
 
217
  wp_register_style( 'jquery-style', 'https://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css', array(), $version );
218
  }
5
  * @package WPRSSAggregator
6
  */
7
 
8
+ use Aventura\Wprss\Core\Licensing\License\Status as License_Status;
9
+
10
  add_action( 'init', 'wprss_register_scripts', 9 );
11
  function wprss_register_scripts()
12
  {
73
  'sent-error' => sprintf(__('There was an error sending the form. Please use the <a href="%s">contact form on our site.</a>', WPRSS_TEXT_DOMAIN), esc_attr('https://www.wprssaggregator.com/contact/')),
74
  'sent-ok' => __("Your message has been sent and we'll send you a confirmation e-mail when we receive it.", WPRSS_TEXT_DOMAIN)
75
  ));
76
+
77
+ wp_register_script( 'wprss-hs-beacon-js', WPRSS_JS . 'beacon.min.js', array(), $version );
78
+ wp_localize_script( 'wprss-hs-beacon-js', 'WprssHelpBeaconConfig', array (
79
+ 'premiumSupport' => ( wprss_licensing_get_manager()->licenseWithStatusExists( License_Status::VALID ) )
80
+ ));
81
  }
82
 
83
 
163
  wp_enqueue_script( 'wprss-admin-help' );
164
  }
165
 
166
+ if (wprss_is_help_beacon_enabled()) {
167
+ wp_enqueue_script('wprss-hs-beacon-js');
168
+ wp_enqueue_style('wprss-hs-beacon-css');
169
+ }
170
+
171
  do_action('wprss_admin_exclusive_scripts_styles');
172
  }
173
 
226
  wp_register_style( 'wprss-admin-editor-styles', WPRSS_CSS . 'admin-editor.css', array(), $version );
227
  wp_register_style( 'wprss-admin-tracking-styles', WPRSS_CSS . 'admin-tracking-styles.css', array(), $version );
228
  wp_register_style( 'wprss-admin-general-styles', WPRSS_CSS . 'admin-general-styles.css', array(), $version );
229
+ wp_register_style( 'wprss-hs-beacon-css', WPRSS_CSS, 'beacon.css', array(), $version );
230
  wp_register_style( 'jquery-style', 'https://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css', array(), $version );
231
  }
includes/secure-reset.php CHANGED
@@ -45,6 +45,8 @@
45
  delete_option( 'wprss_addon_notices' );
46
  delete_option( 'wprss_settings_notices' );
47
  delete_option( 'wprss_pwsv' );
 
 
48
  }
49
 
50
  // Deactivate the plugin
@@ -53,4 +55,4 @@
53
  deactivate_plugins( WPRSS_FILE_CONSTANT, TRUE );
54
  }
55
 
56
- }
45
  delete_option( 'wprss_addon_notices' );
46
  delete_option( 'wprss_settings_notices' );
47
  delete_option( 'wprss_pwsv' );
48
+ delete_option( WPRSS_UPDATE_PAGE_PREV_VERSION_OPTION );
49
+ delete_option( WPRSS_INTRO_DID_INTRO_OPTION );
50
  }
51
 
52
  // Deactivate the plugin
55
  deactivate_plugins( WPRSS_FILE_CONSTANT, TRUE );
56
  }
57
 
58
+ }
includes/twig.php CHANGED
@@ -10,7 +10,7 @@ define('WPRSS_TWIG_MIN_PHP_VERSION', '5.4.0');
10
  /**
11
  * Returns whether twig can be used.
12
  *
13
- * @since [*next-version*]
14
  *
15
  * @return bool True if twig can be used, false if not.
16
  */
@@ -33,7 +33,7 @@ function wprss_twig()
33
  if ($twig === null) {
34
  $options = array();
35
 
36
- if (defined('WP_DEBUG') && WP_DEBUG) {
37
  $options['cache'] = get_temp_dir() . 'wprss/twig-cache';
38
  }
39
 
10
  /**
11
  * Returns whether twig can be used.
12
  *
13
+ * @since 4.12.1
14
  *
15
  * @return bool True if twig can be used, false if not.
16
  */
33
  if ($twig === null) {
34
  $options = array();
35
 
36
+ if (!defined('WP_DEBUG') || !WP_DEBUG) {
37
  $options['cache'] = get_temp_dir() . 'wprss/twig-cache';
38
  }
39
 
js/beacon.min.js ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ !function(e,t,n){function a(){var e=t.getElementsByTagName("script")[0],n=t.createElement("script");n.type="text/javascript",n.async=!0,n.src="https://beacon-v2.helpscout.net",e.parentNode.insertBefore(n,e)}if(e.Beacon=n=function(t,n,a){e.Beacon.readyQueue.push({method:t,options:n,data:a})},n.readyQueue=[],"complete"===t.readyState)return a();e.attachEvent?e.attachEvent("onload",a):e.addEventListener("load",a,!1)}(window,document,window.Beacon||function(){});
2
+ window.Beacon('init', 'af457a55-16ed-412d-95e9-c84417562092');
3
+ window.Beacon('config', {
4
+ messagingEnabled: WprssHelpBeaconConfig.premiumSupport
5
+ });
js/intro.min.js CHANGED
@@ -1,6 +1 @@
1
- !function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var n=t();for(var r in n)("object"==typeof exports?exports:e)[r]=n[r]}}("undefined"!=typeof self?self:this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=1)}([function(e,t){var n;n=function(){return this}();try{n=n||Function("return this")()||(0,eval)("this")}catch(e){"object"==typeof window&&(n=window)}e.exports=n},function(e,t,n){"use strict";function r(e,t,n,r,i,o,a,s){var c="function"==typeof e?e.options:e;t&&(c.render=t,c.staticRenderFns=n,c._compiled=!0),r&&(c.functional=!0),o&&(c._scopeId="data-v-"+o);var u;if(a?(u=function(e){e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,e||"undefined"==typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),i&&i.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(a)},c._ssrRegister=u):i&&(u=s?function(){i.call(this,this.$root.$options.shadowRoot)}:i),u)if(c.functional){c._injectStyles=u;var l=c.render;c.render=function(e,t){return u.call(t),l(e,t)}}else{var f=c.beforeCreate;c.beforeCreate=f?[].concat(f,u):[u]}return{exports:e,options:c}}function i(e,t){for(var n=(arguments.length>2&&void 0!==arguments[2]&&arguments[2],new FormData),r=Object.keys(t),i=Array.isArray(r),o=0,r=i?r:r[Symbol.iterator]();;){var a;if(i){if(o>=r.length)break;a=r[o++]}else{if(o=r.next(),o.done)break;a=o.value}var s=a;n.set(s,t[s])}return fetch(e,{method:"post",body:n}).then(function(e){return e.json()}).then(function(e){if(200!==e.status)throw e;return e})}function o(e){return e&&DataView.prototype.isPrototypeOf(e)}function a(e){if("string"!=typeof e&&(e=String(e)),/[^a-z0-9\-#$%&'*+.^_`|~]/i.test(e))throw new TypeError("Invalid character in header field name");return e.toLowerCase()}function s(e){return"string"!=typeof e&&(e=String(e)),e}function c(e){var t={next:function(){var t=e.shift();return{done:void 0===t,value:t}}};return H.iterable&&(t[Symbol.iterator]=function(){return t}),t}function u(e){this.map={},e instanceof u?e.forEach(function(e,t){this.append(t,e)},this):Array.isArray(e)?e.forEach(function(e){this.append(e[0],e[1])},this):e&&Object.getOwnPropertyNames(e).forEach(function(t){this.append(t,e[t])},this)}function l(e){if(e.bodyUsed)return Promise.reject(new TypeError("Already read"));e.bodyUsed=!0}function f(e){return new Promise(function(t,n){e.onload=function(){t(e.result)},e.onerror=function(){n(e.error)}})}function d(e){var t=new FileReader,n=f(t);return t.readAsArrayBuffer(e),n}function p(e){var t=new FileReader,n=f(t);return t.readAsText(e),n}function v(e){for(var t=new Uint8Array(e),n=new Array(t.length),r=0;r<t.length;r++)n[r]=String.fromCharCode(t[r]);return n.join("")}function h(e){if(e.slice)return e.slice(0);var t=new Uint8Array(e.byteLength);return t.set(new Uint8Array(e)),t.buffer}function m(){return this.bodyUsed=!1,this._initBody=function(e){this._bodyInit=e,e?"string"==typeof e?this._bodyText=e:H.blob&&Blob.prototype.isPrototypeOf(e)?this._bodyBlob=e:H.formData&&FormData.prototype.isPrototypeOf(e)?this._bodyFormData=e:H.searchParams&&URLSearchParams.prototype.isPrototypeOf(e)?this._bodyText=e.toString():H.arrayBuffer&&H.blob&&o(e)?(this._bodyArrayBuffer=h(e.buffer),this._bodyInit=new Blob([this._bodyArrayBuffer])):H.arrayBuffer&&(ArrayBuffer.prototype.isPrototypeOf(e)||V(e))?this._bodyArrayBuffer=h(e):this._bodyText=e=Object.prototype.toString.call(e):this._bodyText="",this.headers.get("content-type")||("string"==typeof e?this.headers.set("content-type","text/plain;charset=UTF-8"):this._bodyBlob&&this._bodyBlob.type?this.headers.set("content-type",this._bodyBlob.type):H.searchParams&&URLSearchParams.prototype.isPrototypeOf(e)&&this.headers.set("content-type","application/x-www-form-urlencoded;charset=UTF-8"))},H.blob&&(this.blob=function(){var e=l(this);if(e)return e;if(this._bodyBlob)return Promise.resolve(this._bodyBlob);if(this._bodyArrayBuffer)return Promise.resolve(new Blob([this._bodyArrayBuffer]));if(this._bodyFormData)throw new Error("could not read FormData body as blob");return Promise.resolve(new Blob([this._bodyText]))},this.arrayBuffer=function(){return this._bodyArrayBuffer?l(this)||Promise.resolve(this._bodyArrayBuffer):this.blob().then(d)}),this.text=function(){var e=l(this);if(e)return e;if(this._bodyBlob)return p(this._bodyBlob);if(this._bodyArrayBuffer)return Promise.resolve(v(this._bodyArrayBuffer));if(this._bodyFormData)throw new Error("could not read FormData body as text");return Promise.resolve(this._bodyText)},H.formData&&(this.formData=function(){return this.text().then(_)}),this.json=function(){return this.text().then(JSON.parse)},this}function y(e){var t=e.toUpperCase();return q.indexOf(t)>-1?t:e}function g(e,t){t=t||{};var n=t.body;if(e instanceof g){if(e.bodyUsed)throw new TypeError("Already read");this.url=e.url,this.credentials=e.credentials,t.headers||(this.headers=new u(e.headers)),this.method=e.method,this.mode=e.mode,this.signal=e.signal,n||null==e._bodyInit||(n=e._bodyInit,e.bodyUsed=!0)}else this.url=String(e);if(this.credentials=t.credentials||this.credentials||"same-origin",!t.headers&&this.headers||(this.headers=new u(t.headers)),this.method=y(t.method||this.method||"GET"),this.mode=t.mode||this.mode||null,this.signal=t.signal||this.signal,this.referrer=null,("GET"===this.method||"HEAD"===this.method)&&n)throw new TypeError("Body not allowed for GET or HEAD requests");this._initBody(n)}function _(e){var t=new FormData;return e.trim().split("&").forEach(function(e){if(e){var n=e.split("="),r=n.shift().replace(/\+/g," "),i=n.join("=").replace(/\+/g," ");t.append(decodeURIComponent(r),decodeURIComponent(i))}}),t}function b(e){var t=new u;return e.replace(/\r?\n[\t ]+/g," ").split(/\r?\n/).forEach(function(e){var n=e.split(":"),r=n.shift().trim();if(r){var i=n.join(":").trim();t.append(r,i)}}),t}function w(e,t){t||(t={}),this.type="default",this.status=void 0===t.status?200:t.status,this.ok=this.status>=200&&this.status<300,this.statusText="statusText"in t?t.statusText:"OK",this.headers=new u(t.headers),this.url=t.url||"",this._initBody(e)}function C(e,t){return new Promise(function(n,r){function i(){a.abort()}var o=new g(e,t);if(o.signal&&o.signal.aborted)return r(new W("Aborted","AbortError"));var a=new XMLHttpRequest;a.onload=function(){var e={status:a.status,statusText:a.statusText,headers:b(a.getAllResponseHeaders()||"")};e.url="responseURL"in a?a.responseURL:e.headers.get("X-Request-URL");var t="response"in a?a.response:a.responseText;n(new w(t,e))},a.onerror=function(){r(new TypeError("Network request failed"))},a.ontimeout=function(){r(new TypeError("Network request failed"))},a.onabort=function(){r(new W("Aborted","AbortError"))},a.open(o.method,o.url,!0),"include"===o.credentials?a.withCredentials=!0:"omit"===o.credentials&&(a.withCredentials=!1),"responseType"in a&&H.blob&&(a.responseType="blob"),o.headers.forEach(function(e,t){a.setRequestHeader(t,e)}),o.signal&&(o.signal.addEventListener("abort",i),a.onreadystatechange=function(){4===a.readyState&&o.signal.removeEventListener("abort",i)}),a.send(void 0===o._bodyInit?null:o._bodyInit)})}Object.defineProperty(t,"__esModule",{value:!0});var x=n(3),$=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"wizard-holder animated fadeIn"},[n("div",{staticClass:"connect-steps"},[n("div",{staticClass:"step-items"},[n("div",{staticClass:"step-progress",class:"step-progress--"+e.activeScreenIndex}),e._v(" "),e._l(e.screens,function(t,r){return n("div",{staticClass:"step-item",class:{"step-item_active":e.active(t.id),"step-item_completed":t.completed()&&r<e.activeScreenIndex}},[n("div",{staticClass:"step-item__status"},[t.completed()&&r<e.activeScreenIndex?n("span",{staticClass:"dashicons dashicons-yes"}):e._e()]),e._v(" "),n("div",{staticClass:"step-item__info"},[n("div",{staticClass:"step-item__title"},[e._v(e._s(t.title))]),e._v(" "),t.description?n("div",{staticClass:"step-item__description"},[e._v(e._s(t.description))]):e._e()])])})],2)]),e._v(" "),n("div",{staticClass:"wizard"},[n("transition",{attrs:{name:e.transition,mode:"out-in"}},[e.active("feed")?n("div",{key:e.activeScreen,staticClass:"wizard_content"},[n("div",{staticClass:"wizard_hello"},[e._v("\n Enter your first RSS Feed URL\n ")]),e._v(" "),n("form",{staticClass:"wizard_info",attrs:{id:"feedForm"},on:{submit:function(t){return t.preventDefault(),e.next(t)}}},[n("div",{staticClass:"form-group"},[n("input",{directives:[{name:"model",rawName:"v-model",value:e.form.feedSourceUrl,expression:"form.feedSourceUrl"}],staticClass:"wpra-feed-input",attrs:{type:"text",placeholder:"https://www.sourcedomain.com/feed/"},domProps:{value:e.form.feedSourceUrl},on:{input:function(t){t.target.composing||e.$set(e.form,"feedSourceUrl",t.target.value)}}}),e._v(" "),e.isFeedError?n("span",{staticClass:"dashicons dashicons-warning warning-icon"}):e._e(),e._v(" "),e.isFeedError?n("a",{attrs:{href:e.validateLink,target:"_blank"}},[e._v("Validate feed")]):e._e()])]),e._v(" "),e.isFeedError?n("div",{staticClass:"wizard_error"},[n("p",[e._v("This RSS feed URL appears to be invalid. Here are a couple of things you can try:")]),e._v(" "),n("ol",[n("li",[e._v('Check whether the URL you entered is the correct one by trying one of the options when clicking on "How do I find an RSS feed URL?" below.')]),e._v(" "),n("li",[e._v("\n Test out this other RSS feed URL to make sure the plugin is working correctly - https://www.wpmayor.com/feed/ - If it works, you may "),n("a",{attrs:{href:e.supportUrl,target:"_blank"}},[e._v("contact us here")]),e._v(" to help you with your source.\n ")]),e._v(" "),n("li",[e._v("Test the URL's validity by W3C standards, the standards we use in our plugins, using the “Validate feed” link above.")])])]):e._e(),e._v(" "),n("expander",{attrs:{title:"How do I find an RSS feed URL?"}},[n("p",[e._v("WP RSS Aggregator fetches feed items through RSS feeds. Almost every website in the world provides an RSS feed. Here's how to find it:")]),e._v(" "),n("p",[e._v("Option 1: Add /feed to the website's homepage URL ")]),e._v(" "),n("p",[e._v("Many sites have their RSS feed at the same URL. For instance, if the website's URL is www.thiswebsite.com, then the RSS feed could be at www.thiswebsite.com/feed.")]),e._v(" "),n("p",[e._v("Option 2: Look for the RSS share icon")]),e._v(" "),n("p",[e._v("Many websites have share icons on their pages for Facebook, Twitter and more. Many times, there will also be an orange RSS icon. Click on that to access the RSS feed URL.")]),e._v(" "),n("p",[e._v("Option 3: Browser RSS Auto-Discovery")]),e._v(" "),n("p",[e._v("Most browsers either include an RSS auto-discovery tool by default or they allow you to add extensions for it. Firefox shows an RSS icon above the website, in the address bar, which you can click on directly. Chrome offers extensions such as this one.")]),e._v(" "),n("p",[e._v("Option 4: Look at the Page Source")]),e._v(" "),n("p",[e._v('When on any page of the website you\'re looking to import feed items from, right click and press "View Page Source". Once the new window opens, use the “Find” feature (Ctrl-F on PC, Command-F on Mac) and search for " RSS". This should take you to a line that reads like this (or similar):')]),e._v(" "),n("p",[n("code",[e._v('\n <link rel="alternate" type="application/rss+xml" title="RSS Feed" href="https://www.sourcedomain.com/feed/" />\n ')])]),e._v(" "),n("p",[e._v("The RSS feed’s URL is found between the quotes after href=. In the above case, it would be https://www.sourcedomain.com/feed/.")]),e._v(" "),n("p",[n("a",{attrs:{href:e.knowledgeBaseUrl,target:"_blank"}},[e._v("Browse our Knowledge Base for more information.")])])])],1):e._e(),e._v(" "),e.active("feedItems")?n("div",{key:e.activeScreen,staticClass:"wizard_content"},[n("div",{staticClass:"wizard_hello"},[e._v("\n Latest feed items from your selected feed source:\n ")]),e._v(" "),n("div",{staticClass:"wpra-feed-items"},e._l(e.feed.items,function(t){return n("div",{staticClass:"wpra-feed-item"},[n("div",{staticClass:"wpra-feed-item__link"},[n("a",{attrs:{href:t.permalink,target:"_blank"}},[e._v(e._s(t.title))])]),e._v(" "),n("div",{staticClass:"wpra-feed-item__info"},[e._v("\n Published on "+e._s(t.date)+" | By "+e._s(t.author)+"\n ")])])}),0),e._v(" "),n("div",{staticClass:"wizard_label"},[e._v("\n Copy and paste this shortcode to any page or post to display the full list:\n ")]),e._v(" "),n("div",{staticClass:"wrpa-shortcode"},[n("div",{staticClass:"wrpa-shortcode-form",on:{click:function(t){e.copyToClipboard()}}},[n("input",{ref:"selected",staticClass:"wrpa-shortcode-form__shortcode",attrs:{type:"text",readonly:"",value:"[wp-rss-aggregator]"}}),e._v(" "),n("div",{staticClass:"wrpa-shortcode-form__button"},[e._v("\n Ctrl+C or CMD+C to copy\n ")])]),e._v("\n OR\n "),n("a",{attrs:{href:e.previewUrl,target:"_blank"}},[e._v("Preview the feed items on a new page")])])]):e._e(),e._v(" "),e.active("finish")?n("div",{key:e.activeScreen,staticClass:"wizard_content"},[n("div",{staticClass:"wizard_hello"},[e._v("\n You’ve successfully set up your first feed source 😄\n ")]),e._v(" "),n("div",{staticClass:"wpra-cols-title"},[e._v("\n Do more with WP RSS Aggregator - here is what we did at CryptoHeadlines.com.\n ")]),e._v(" "),n("div",{staticClass:"wpra-cols"},[n("div",{staticClass:"col"},[n("p",[e._v("CryptoHeadlines.com displays latest news, Youtube videos, podcasts, jobs and more from the Cryptocurrency industry.")]),e._v(" "),n("p",[e._v("It uses Feed to Post to import articles, Youtube videos, and podcast links.")]),e._v(" "),n("p",[e._v("Full Text RSS Feeds is used to fetch the full content of the job listings to present more information to the potential applicant.")]),e._v(" "),n("p",[e._v("Keyword Filtering is used to filter out content that contains profanity and keywords or phrases deemed as inappropriate.")]),e._v(" "),n("div",{staticStyle:{"margin-bottom":".5rem"}},[n("a",{staticClass:"button",attrs:{href:e.addOnsUrl,target:"_blank"}},[e._v("\n Browse Add-ons ⭐️\n ")])]),e._v(" "),n("div",[n("a",{staticStyle:{"font-size":".9em"},attrs:{href:e.supportUrl,target:"_blank"}},[e._v("Contact support for more information.")])])]),e._v(" "),n("div",{staticClass:"col"},[n("img",{staticClass:"img wpra-demo-photo",attrs:{src:e.demoImageUrl}}),e._v(" "),n("div",{staticClass:"wpra-feedback"},[n("div",{staticClass:"wpra-feedback__copy"},[n("div",{staticClass:"wpra-feedback__text"},[e._v("\n This plugin has made my life a lot easier, and the support has been great as well.\n ")]),e._v(" "),n("div",{staticClass:"wpra-feedback__rating"},[n("span",{staticClass:"dashicons dashicons-star-filled"}),e._v(" "),n("span",{staticClass:"dashicons dashicons-star-filled"}),e._v(" "),n("span",{staticClass:"dashicons dashicons-star-filled"}),e._v(" "),n("span",{staticClass:"dashicons dashicons-star-filled"}),e._v(" "),n("span",{staticClass:"dashicons dashicons-star-filled"})]),e._v(" "),n("div",{staticClass:"wpra-feedback__by"},[n("a",{attrs:{href:e.feedbackUrl,target:"_blank"}},[e._v("\n Review by officeinnovator\n ")])])])])])])]):e._e()]),e._v(" "),n("div",{staticClass:"connect-actions pad"},[n("div",{staticClass:"pad-item--grow"},[e.active("finish")?e._e():n("button",{staticClass:"button-clear",on:{click:e.finish}},[e._v("\n Skip the introduction\n ")])]),e._v(" "),n("div",{staticClass:"pad-item--no-shrink"},[e.isBackAvailable?n("button",{staticClass:"button-clear",on:{click:e.back}},[e._v("\n Back\n ")]):e._e(),e._v(" "),n("button",{staticClass:"button button-primary button-large",class:{"loading-button":e.isLoading},on:{click:e.next}},[e._v("\n "+e._s(e.active("finish")?"Continue to Plugin":"Next")+"\n ")])])])],1)])},k=[],S=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"wpra-expander",class:{"wpra-expander--expanded":e.isExpanded}},[n("div",{staticClass:"wpra-expander__title",on:{click:function(t){e.isExpanded=!e.isExpanded}}},[e._v("\n "+e._s(e.title)+"\n "),n("span",{staticClass:"dashicons dashicons-arrow-down-alt2"})]),e._v(" "),n("transition-expand",[e.isExpanded?n("div",[n("div",{staticClass:"wpra-expander__content"},[e._t("default")],2)]):e._e()])],1)},A=[],T={name:"TransitionExpand",functional:!0,render:function(e,t){return e("transition",{props:{name:"expand"},on:{afterEnter:function(e){e.style.height="auto"},enter:function(e){var t=getComputedStyle(e),n=t.width;e.style.width=n,e.style.position="absolute",e.style.visibility="hidden",e.style.height="auto";var r=getComputedStyle(e),i=r.height;e.style.width=null,e.style.position=null,e.style.visibility=null,e.style.height=0,getComputedStyle(e).height,setTimeout(function(){e.style.height=i})},leave:function(e){var t=getComputedStyle(e),n=t.height;e.style.height=n,getComputedStyle(e).height,setTimeout(function(){e.style.height=0})}}},t.children)}},O=T,E=r(O,void 0,void 0,!1,null,null,null);E.options.__file="TransitionExpand.vue";var I=E.exports,L={data:function(){return{isExpanded:this.defaultExpanded}},props:{title:{},defaultExpanded:{value:!1}},components:{TransitionExpand:I}},j=L,P=r(j,S,A,!1,null,null,null);P.options.__file="Expander.vue";var R=P.exports,N=function(e){return e},D=window.wprssWizardConfig,U={data:function(){var e=this;return{prevHeight:0,screens:[{id:"feed",title:N("Add feed source URL"),description:!1,next:this.submitFeed,completed:function(){return e.feed.items.length},entered:function(){e.focusOnInput("feed")}},{id:"feedItems",title:N("Display feed items"),description:!1,next:this.continueItems,entered:function(){setTimeout(function(){e.copyToClipboard()},400)},completed:function(){return e.feed.items.length&&e.itemsPassed}},{id:"finish",title:N("Complete introduction"),description:!1,next:this.completeIntroduction,completed:function(){return e.feed.items.length&&e.itemsPassed}}],transition:"slide-up",activeScreen:"feed",form:{feedSourceUrl:null},itemsPassed:!1,stepLoading:!1,isLoading:!1,isFeedError:!1,feed:{items:[]},previewUrl:D.previewUrl,addOnsUrl:D.addOnsUrl,supportUrl:D.supportUrl,demoImageUrl:D.demoImageUrl,feedbackUrl:D.feedbackUrl,knowledgeBaseUrl:D.knowledgeBaseUrl}},computed:{validateLink:function(){return"https://validator.w3.org/feed/check.cgi?url="+encodeURI(this.form.feedSourceUrl)},activeScreenIndex:function(){var e=this;return this.screens.findIndex(function(t){return t.id===e.activeScreen})},currentScreen:function(){var e=this;return this.screens.find(function(t){return t.id===e.activeScreen})},actionCompleted:function(){return this.currentScreen.completed()},isBackAvailable:function(){return this.activeScreenIndex>0&&this.activeScreenIndex<this.screens.length}},mounted:function(){this.onScreenEnter()},methods:{submitFeed:function(){var e=this,t=Object.assign(D.feedEndpoint.defaultPayload,{wprss_intro_feed_url:this.form.feedSourceUrl});return this.isLoading=!0,this.isFeedError=!1,i(D.feedEndpoint.url,t).then(function(t){return e.feed.items=t.data.feed_items.slice(0,3),e.isLoading=!1,{}}).catch(function(t){throw e.isLoading=!1,e.isFeedError=!0,t})},continueItems:function(){return this.itemsPassed=!0,Promise.resolve({})},completeIntroduction:function(){return Promise.resolve({})},next:function(){var e=this;this.transition="slide-up";var t=this.currentScreen.next?this.currentScreen.next:function(){return Promise.resolve(!1)};this.stepLoading=!0,t().then(function(t){e.stepLoading=!1},function(e){throw e}).then(function(){var t=e.activeScreenIndex+1;t>=e.screens.length?e.finish():(e.activeScreen=e.screens[t].id,e.onScreenEnter())}).catch(function(e){console.error(e)})},onScreenEnter:function(){var e=this;this.$nextTick(function(){e.currentScreen.entered&&e.currentScreen.entered()})},focusOnInput:function(e){if(!this.$refs[e]||!this.$refs[e].focus)return!1;this.$refs[e].focus()},back:function(){this.transition="slide-down",this.activeScreen=this.screens[this.activeScreenIndex-1].id},finish:function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],t=function(){return window.location.href=D.feedListUrl};if(e)return void(confirm("Are you sure you want to skip the introduction?")&&t());t()},active:function(e){return this.activeScreen===e},copyToClipboard:function(){try{this.$refs.selected.focus(),this.$refs.selected.select()}catch(e){console.error(e)}}},components:{Expander:R}},F=U,M=r(F,$,k,!1,null,null,null);M.options.__file="Wizard.vue";var B=M.exports,H={searchParams:"URLSearchParams"in self,iterable:"Symbol"in self&&"iterator"in Symbol,blob:"FileReader"in self&&"Blob"in self&&function(){try{return new Blob,!0}catch(e){return!1}}(),formData:"FormData"in self,arrayBuffer:"ArrayBuffer"in self};if(H.arrayBuffer)var z=["[object Int8Array]","[object Uint8Array]","[object Uint8ClampedArray]","[object Int16Array]","[object Uint16Array]","[object Int32Array]","[object Uint32Array]","[object Float32Array]","[object Float64Array]"],V=ArrayBuffer.isView||function(e){return e&&z.indexOf(Object.prototype.toString.call(e))>-1};u.prototype.append=function(e,t){e=a(e),t=s(t);var n=this.map[e];this.map[e]=n?n+", "+t:t},u.prototype.delete=function(e){delete this.map[a(e)]},u.prototype.get=function(e){return e=a(e),this.has(e)?this.map[e]:null},u.prototype.has=function(e){return this.map.hasOwnProperty(a(e))},u.prototype.set=function(e,t){this.map[a(e)]=s(t)},u.prototype.forEach=function(e,t){for(var n in this.map)this.map.hasOwnProperty(n)&&e.call(t,this.map[n],n,this)},u.prototype.keys=function(){var e=[];return this.forEach(function(t,n){e.push(n)}),c(e)},u.prototype.values=function(){var e=[];return this.forEach(function(t){e.push(t)}),c(e)},u.prototype.entries=function(){var e=[];return this.forEach(function(t,n){e.push([n,t])}),c(e)},H.iterable&&(u.prototype[Symbol.iterator]=u.prototype.entries);var q=["DELETE","GET","HEAD","OPTIONS","POST","PUT"];g.prototype.clone=function(){return new g(this,{body:this._bodyInit})},m.call(g.prototype),m.call(w.prototype),w.prototype.clone=function(){return new w(this._bodyInit,{status:this.status,statusText:this.statusText,headers:new u(this.headers),url:this.url})},w.error=function(){var e=new w(null,{status:0,statusText:""});return e.type="error",e};var K=[301,302,303,307,308];w.redirect=function(e,t){if(-1===K.indexOf(t))throw new RangeError("Invalid status code");return new w(null,{status:t,headers:{location:e}})};var W=self.DOMException;try{new W}catch(e){W=function(e,t){this.message=e,this.name=t;var n=Error(e);this.stack=n.stack},W.prototype=Object.create(Error.prototype),W.prototype.constructor=W}C.polyfill=!0,self.fetch||(self.fetch=C,self.Headers=u,self.Request=g,self.Response=w),n(2),new x.a({el:"#wpra-wizard-app",template:"<Wizard/>",components:{Wizard:B}})},function(e,t){},function(e,t,n){"use strict";(function(e,n){function r(e){return void 0===e||null===e}function i(e){return void 0!==e&&null!==e}function o(e){return!0===e}function a(e){return!1===e}function s(e){return"string"==typeof e||"number"==typeof e||"symbol"==typeof e||"boolean"==typeof e}function c(e){return null!==e&&"object"==typeof e}function u(e){return"[object Object]"===fo.call(e)}function l(e){return"[object RegExp]"===fo.call(e)}function f(e){var t=parseFloat(String(e));return t>=0&&Math.floor(t)===t&&isFinite(e)}function d(e){return null==e?"":"object"==typeof e?JSON.stringify(e,null,2):String(e)}function p(e){var t=parseFloat(e);return isNaN(t)?e:t}function v(e,t){for(var n=Object.create(null),r=e.split(","),i=0;i<r.length;i++)n[r[i]]=!0;return t?function(e){return n[e.toLowerCase()]}:function(e){return n[e]}}function h(e,t){if(e.length){var n=e.indexOf(t);if(n>-1)return e.splice(n,1)}}function m(e,t){return ho.call(e,t)}function y(e){var t=Object.create(null);return function(n){return t[n]||(t[n]=e(n))}}function g(e,t){function n(n){var r=arguments.length;return r?r>1?e.apply(t,arguments):e.call(t,n):e.call(t)}return n._length=e.length,n}function _(e,t){return e.bind(t)}function b(e,t){t=t||0;for(var n=e.length-t,r=new Array(n);n--;)r[n]=e[n+t];return r}function w(e,t){for(var n in t)e[n]=t[n];return e}function C(e){for(var t={},n=0;n<e.length;n++)e[n]&&w(t,e[n]);return t}function x(e,t,n){}function $(e,t){if(e===t)return!0;var n=c(e),r=c(t);if(!n||!r)return!n&&!r&&String(e)===String(t);try{var i=Array.isArray(e),o=Array.isArray(t);if(i&&o)return e.length===t.length&&e.every(function(e,n){return $(e,t[n])});if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();if(i||o)return!1;var a=Object.keys(e),s=Object.keys(t);return a.length===s.length&&a.every(function(n){return $(e[n],t[n])})}catch(e){return!1}}function k(e,t){for(var n=0;n<e.length;n++)if($(e[n],t))return n;return-1}function S(e){var t=!1;return function(){t||(t=!0,e.apply(this,arguments))}}function A(e){var t=(e+"").charCodeAt(0);return 36===t||95===t}function T(e,t,n,r){Object.defineProperty(e,t,{value:n,enumerable:!!r,writable:!0,configurable:!0})}function O(e){if(!To.test(e)){var t=e.split(".");return function(e){for(var n=0;n<t.length;n++){if(!e)return;e=e[t[n]]}return e}}}function E(e){return"function"==typeof e&&/native code/.test(e.toString())}function I(e){Go.push(e),Jo.target=e}function L(){Go.pop(),Jo.target=Go[Go.length-1]}function j(e){return new Xo(void 0,void 0,void 0,String(e))}function P(e){var t=new Xo(e.tag,e.data,e.children&&e.children.slice(),e.text,e.elm,e.context,e.componentOptions,e.asyncFactory);return t.ns=e.ns,t.isStatic=e.isStatic,t.key=e.key,t.isComment=e.isComment,t.fnContext=e.fnContext,t.fnOptions=e.fnOptions,t.fnScopeId=e.fnScopeId,t.asyncMeta=e.asyncMeta,t.isCloned=!0,t}function R(e){na=e}function N(e,t){e.__proto__=t}function D(e,t,n){for(var r=0,i=n.length;r<i;r++){var o=n[r];T(e,o,t[o])}}function U(e,t){if(c(e)&&!(e instanceof Xo)){var n;return m(e,"__ob__")&&e.__ob__ instanceof ra?n=e.__ob__:na&&!zo()&&(Array.isArray(e)||u(e))&&Object.isExtensible(e)&&!e._isVue&&(n=new ra(e)),t&&n&&n.vmCount++,n}}function F(e,t,n,r,i){var o=new Jo,a=Object.getOwnPropertyDescriptor(e,t);if(!a||!1!==a.configurable){var s=a&&a.get,c=a&&a.set;s&&!c||2!==arguments.length||(n=e[t]);var u=!i&&U(n);Object.defineProperty(e,t,{enumerable:!0,configurable:!0,get:function(){var t=s?s.call(e):n;return Jo.target&&(o.depend(),u&&(u.dep.depend(),Array.isArray(t)&&H(t))),t},set:function(t){var r=s?s.call(e):n;t===r||t!==t&&r!==r||s&&!c||(c?c.call(e,t):n=t,u=!i&&U(t),o.notify())}})}}function M(e,t,n){if(Array.isArray(e)&&f(t))return e.length=Math.max(e.length,t),e.splice(t,1,n),n;if(t in e&&!(t in Object.prototype))return e[t]=n,n;var r=e.__ob__;return e._isVue||r&&r.vmCount?n:r?(F(r.value,t,n),r.dep.notify(),n):(e[t]=n,n)}function B(e,t){if(Array.isArray(e)&&f(t))return void e.splice(t,1);var n=e.__ob__;e._isVue||n&&n.vmCount||m(e,t)&&(delete e[t],n&&n.dep.notify())}function H(e){for(var t=void 0,n=0,r=e.length;n<r;n++)t=e[n],t&&t.__ob__&&t.__ob__.dep.depend(),Array.isArray(t)&&H(t)}function z(e,t){if(!t)return e;for(var n,r,i,o=Object.keys(t),a=0;a<o.length;a++)n=o[a],r=e[n],i=t[n],m(e,n)?r!==i&&u(r)&&u(i)&&z(r,i):M(e,n,i);return e}function V(e,t,n){return n?function(){var r="function"==typeof t?t.call(n,n):t,i="function"==typeof e?e.call(n,n):e;return r?z(r,i):i}:t?e?function(){return z("function"==typeof t?t.call(this,this):t,"function"==typeof e?e.call(this,this):e)}:t:e}function q(e,t){var n=t?e?e.concat(t):Array.isArray(t)?t:[t]:e;return n?K(n):n}function K(e){for(var t=[],n=0;n<e.length;n++)-1===t.indexOf(e[n])&&t.push(e[n]);return t}function W(e,t,n,r){var i=Object.create(e||null);return t?w(i,t):i}function J(e,t){var n=e.props;if(n){var r,i,o,a={};if(Array.isArray(n))for(r=n.length;r--;)"string"==typeof(i=n[r])&&(o=yo(i),a[o]={type:null});else if(u(n))for(var s in n)i=n[s],o=yo(s),a[o]=u(i)?i:{type:i};e.props=a}}function G(e,t){var n=e.inject;if(n){var r=e.inject={};if(Array.isArray(n))for(var i=0;i<n.length;i++)r[n[i]]={from:n[i]};else if(u(n))for(var o in n){var a=n[o];r[o]=u(a)?w({from:o},a):{from:a}}}}function X(e){var t=e.directives;if(t)for(var n in t){var r=t[n];"function"==typeof r&&(t[n]={bind:r,update:r})}}function Z(e,t,n){function r(r){var i=ia[r]||sa;s[r]=i(e[r],t[r],n,r)}if("function"==typeof t&&(t=t.options),J(t,n),G(t,n),X(t),!t._base&&(t.extends&&(e=Z(e,t.extends,n)),t.mixins))for(var i=0,o=t.mixins.length;i<o;i++)e=Z(e,t.mixins[i],n);var a,s={};for(a in e)r(a);for(a in t)m(e,a)||r(a);return s}function Y(e,t,n,r){if("string"==typeof n){var i=e[t];if(m(i,n))return i[n];var o=yo(n);if(m(i,o))return i[o];var a=go(o);return m(i,a)?i[a]:i[n]||i[o]||i[a]}}function Q(e,t,n,r){var i=t[e],o=!m(n,e),a=n[e],s=re(Boolean,i.type);if(s>-1)if(o&&!m(i,"default"))a=!1;else if(""===a||a===bo(e)){var c=re(String,i.type);(c<0||s<c)&&(a=!0)}if(void 0===a){a=ee(r,i,e);var u=na;R(!0),U(a),R(u)}return a}function ee(e,t,n){if(m(t,"default")){var r=t.default;return e&&e.$options.propsData&&void 0===e.$options.propsData[n]&&void 0!==e._props[n]?e._props[n]:"function"==typeof r&&"Function"!==te(t.type)?r.call(e):r}}function te(e){var t=e&&e.toString().match(/^\s*function (\w+)/);return t?t[1]:""}function ne(e,t){return te(e)===te(t)}function re(e,t){if(!Array.isArray(t))return ne(t,e)?0:-1;for(var n=0,r=t.length;n<r;n++)if(ne(t[n],e))return n;return-1}function ie(e,t,n){if(t)for(var r=t;r=r.$parent;){var i=r.$options.errorCaptured;if(i)for(var o=0;o<i.length;o++)try{var a=!1===i[o].call(r,e,t,n);if(a)return}catch(e){oe(e,r,"errorCaptured hook")}}oe(e,t,n)}function oe(e,t,n){if(Ao.errorHandler)try{return Ao.errorHandler.call(null,e,t,n)}catch(e){ae(e,null,"config.errorHandler")}ae(e,t,n)}function ae(e,t,n){if(!Eo&&!Io||"undefined"==typeof console)throw e;console.error(e)}function se(){ua=!1;var e=ca.slice(0);ca.length=0;for(var t=0;t<e.length;t++)e[t]()}function ce(e){return e._withTask||(e._withTask=function(){la=!0;try{return e.apply(null,arguments)}finally{la=!1}})}function ue(e,t){var n;if(ca.push(function(){if(e)try{e.call(t)}catch(e){ie(e,t,"nextTick")}else n&&n(t)}),ua||(ua=!0,la?aa():oa()),!e&&"undefined"!=typeof Promise)return new Promise(function(e){n=e})}function le(e){fe(e,ha),ha.clear()}function fe(e,t){var n,r,i=Array.isArray(e);if(!(!i&&!c(e)||Object.isFrozen(e)||e instanceof Xo)){if(e.__ob__){var o=e.__ob__.dep.id;if(t.has(o))return;t.add(o)}if(i)for(n=e.length;n--;)fe(e[n],t);else for(r=Object.keys(e),n=r.length;n--;)fe(e[r[n]],t)}}function de(e){function t(){var e=arguments,n=t.fns;if(!Array.isArray(n))return n.apply(null,arguments);for(var r=n.slice(),i=0;i<r.length;i++)r[i].apply(null,e)}return t.fns=e,t}function pe(e,t,n,i,a,s){var c,u,l,f;for(c in e)u=e[c],l=t[c],f=ma(c),r(u)||(r(l)?(r(u.fns)&&(u=e[c]=de(u)),o(f.once)&&(u=e[c]=a(f.name,u,f.capture)),n(f.name,u,f.capture,f.passive,f.params)):u!==l&&(l.fns=u,e[c]=l));for(c in t)r(e[c])&&(f=ma(c),i(f.name,t[c],f.capture))}function ve(e,t,n){function a(){n.apply(this,arguments),h(s.fns,a)}e instanceof Xo&&(e=e.data.hook||(e.data.hook={}));var s,c=e[t];r(c)?s=de([a]):i(c.fns)&&o(c.merged)?(s=c,s.fns.push(a)):s=de([c,a]),s.merged=!0,e[t]=s}function he(e,t,n){var o=t.options.props;if(!r(o)){var a={},s=e.attrs,c=e.props;if(i(s)||i(c))for(var u in o){var l=bo(u);me(a,c,u,l,!0)||me(a,s,u,l,!1)}return a}}function me(e,t,n,r,o){if(i(t)){if(m(t,n))return e[n]=t[n],o||delete t[n],!0;if(m(t,r))return e[n]=t[r],o||delete t[r],!0}return!1}function ye(e){for(var t=0;t<e.length;t++)if(Array.isArray(e[t]))return Array.prototype.concat.apply([],e);return e}function ge(e){return s(e)?[j(e)]:Array.isArray(e)?be(e):void 0}function _e(e){return i(e)&&i(e.text)&&a(e.isComment)}function be(e,t){var n,a,c,u,l=[];for(n=0;n<e.length;n++)a=e[n],r(a)||"boolean"==typeof a||(c=l.length-1,u=l[c],Array.isArray(a)?a.length>0&&(a=be(a,(t||"")+"_"+n),_e(a[0])&&_e(u)&&(l[c]=j(u.text+a[0].text),a.shift()),l.push.apply(l,a)):s(a)?_e(u)?l[c]=j(u.text+a):""!==a&&l.push(j(a)):_e(a)&&_e(u)?l[c]=j(u.text+a.text):(o(e._isVList)&&i(a.tag)&&r(a.key)&&i(t)&&(a.key="__vlist"+t+"_"+n+"__"),l.push(a)));return l}function we(e,t){return(e.__esModule||qo&&"Module"===e[Symbol.toStringTag])&&(e=e.default),c(e)?t.extend(e):e}function Ce(e,t,n,r,i){var o=Yo();return o.asyncFactory=e,o.asyncMeta={data:t,context:n,children:r,tag:i},o}function xe(e,t,n){if(o(e.error)&&i(e.errorComp))return e.errorComp;if(i(e.resolved))return e.resolved;if(o(e.loading)&&i(e.loadingComp))return e.loadingComp;if(!i(e.contexts)){var a=e.contexts=[n],s=!0,u=function(e){for(var t=0,n=a.length;t<n;t++)a[t].$forceUpdate();e&&(a.length=0)},l=S(function(n){e.resolved=we(n,t),s?a.length=0:u(!0)}),f=S(function(t){i(e.errorComp)&&(e.error=!0,u(!0))}),d=e(l,f);return c(d)&&("function"==typeof d.then?r(e.resolved)&&d.then(l,f):i(d.component)&&"function"==typeof d.component.then&&(d.component.then(l,f),i(d.error)&&(e.errorComp=we(d.error,t)),i(d.loading)&&(e.loadingComp=we(d.loading,t),0===d.delay?e.loading=!0:setTimeout(function(){r(e.resolved)&&r(e.error)&&(e.loading=!0,u(!1))},d.delay||200)),i(d.timeout)&&setTimeout(function(){r(e.resolved)&&f(null)},d.timeout))),s=!1,e.loading?e.loadingComp:e.resolved}e.contexts.push(n)}function $e(e){return e.isComment&&e.asyncFactory}function ke(e){if(Array.isArray(e))for(var t=0;t<e.length;t++){var n=e[t];if(i(n)&&(i(n.componentOptions)||$e(n)))return n}}function Se(e){e._events=Object.create(null),e._hasHookEvent=!1;var t=e.$options._parentListeners;t&&Ee(e,t)}function Ae(e,t){va.$on(e,t)}function Te(e,t){va.$off(e,t)}function Oe(e,t){var n=va;return function r(){null!==t.apply(null,arguments)&&n.$off(e,r)}}function Ee(e,t,n){va=e,pe(t,n||{},Ae,Te,Oe,e),va=void 0}function Ie(e,t){var n={};if(!e)return n;for(var r=0,i=e.length;r<i;r++){var o=e[r],a=o.data;if(a&&a.attrs&&a.attrs.slot&&delete a.attrs.slot,o.context!==t&&o.fnContext!==t||!a||null==a.slot)(n.default||(n.default=[])).push(o);else{var s=a.slot,c=n[s]||(n[s]=[]);"template"===o.tag?c.push.apply(c,o.children||[]):c.push(o)}}for(var u in n)n[u].every(Le)&&delete n[u];return n}function Le(e){return e.isComment&&!e.asyncFactory||" "===e.text}function je(e,t){t=t||{};for(var n=0;n<e.length;n++)Array.isArray(e[n])?je(e[n],t):t[e[n].key]=e[n].fn;return t}function Pe(e){var t=ya;return ya=e,function(){ya=t}}function Re(e){var t=e.$options,n=t.parent;if(n&&!t.abstract){for(;n.$options.abstract&&n.$parent;)n=n.$parent;n.$children.push(e)}e.$parent=n,e.$root=n?n.$root:e,e.$children=[],e.$refs={},e._watcher=null,e._inactive=null,e._directInactive=!1,e._isMounted=!1,e._isDestroyed=!1,e._isBeingDestroyed=!1}function Ne(e,t,n){e.$el=t,e.$options.render||(e.$options.render=Yo),Be(e,"beforeMount");var r;return r=function(){e._update(e._render(),n)},new ka(e,r,x,{before:function(){e._isMounted&&!e._isDestroyed&&Be(e,"beforeUpdate")}},!0),n=!1,null==e.$vnode&&(e._isMounted=!0,Be(e,"mounted")),e}function De(e,t,n,r,i){var o=!!(i||e.$options._renderChildren||r.data.scopedSlots||e.$scopedSlots!==lo);if(e.$options._parentVnode=r,e.$vnode=r,e._vnode&&(e._vnode.parent=r),e.$options._renderChildren=i,e.$attrs=r.data.attrs||lo,e.$listeners=n||lo,t&&e.$options.props){R(!1);for(var a=e._props,s=e.$options._propKeys||[],c=0;c<s.length;c++){var u=s[c],l=e.$options.props;a[u]=Q(u,l,t,e)}R(!0),e.$options.propsData=t}n=n||lo;var f=e.$options._parentListeners;e.$options._parentListeners=n,Ee(e,n,f),o&&(e.$slots=Ie(i,r.context),e.$forceUpdate())}function Ue(e){for(;e&&(e=e.$parent);)if(e._inactive)return!0;return!1}function Fe(e,t){if(t){if(e._directInactive=!1,Ue(e))return}else if(e._directInactive)return;if(e._inactive||null===e._inactive){e._inactive=!1;for(var n=0;n<e.$children.length;n++)Fe(e.$children[n]);Be(e,"activated")}}function Me(e,t){if(!(t&&(e._directInactive=!0,Ue(e))||e._inactive)){e._inactive=!0;for(var n=0;n<e.$children.length;n++)Me(e.$children[n]);Be(e,"deactivated")}}function Be(e,t){I();var n=e.$options[t];if(n)for(var r=0,i=n.length;r<i;r++)try{n[r].call(e)}catch(n){ie(n,e,t+" hook")}e._hasHookEvent&&e.$emit("hook:"+t),L()}function He(){xa=ga.length=_a.length=0,ba={},wa=Ca=!1}function ze(){Ca=!0;var e,t;for(ga.sort(function(e,t){return e.id-t.id}),xa=0;xa<ga.length;xa++)e=ga[xa],e.before&&e.before(),t=e.id,ba[t]=null,e.run();var n=_a.slice(),r=ga.slice();He(),Ke(n),Ve(r),Vo&&Ao.devtools&&Vo.emit("flush")}function Ve(e){for(var t=e.length;t--;){var n=e[t],r=n.vm;r._watcher===n&&r._isMounted&&!r._isDestroyed&&Be(r,"updated")}}function qe(e){e._inactive=!1,_a.push(e)}function Ke(e){for(var t=0;t<e.length;t++)e[t]._inactive=!0,Fe(e[t],!0)}function We(e){var t=e.id;if(null==ba[t]){if(ba[t]=!0,Ca){for(var n=ga.length-1;n>xa&&ga[n].id>e.id;)n--;ga.splice(n+1,0,e)}else ga.push(e);wa||(wa=!0,ue(ze))}}function Je(e,t,n){Sa.get=function(){return this[t][n]},Sa.set=function(e){this[t][n]=e},Object.defineProperty(e,n,Sa)}function Ge(e){e._watchers=[];var t=e.$options;t.props&&Xe(e,t.props),t.methods&&rt(e,t.methods),t.data?Ze(e):U(e._data={},!0),t.computed&&Qe(e,t.computed),t.watch&&t.watch!==Uo&&it(e,t.watch)}function Xe(e,t){var n=e.$options.propsData||{},r=e._props={},i=e.$options._propKeys=[];!e.$parent||R(!1);for(var o in t)!function(o){i.push(o);var a=Q(o,t,n,e);F(r,o,a),o in e||Je(e,"_props",o)}(o);R(!0)}function Ze(e){var t=e.$options.data;t=e._data="function"==typeof t?Ye(t,e):t||{},u(t)||(t={});for(var n=Object.keys(t),r=e.$options.props,i=(e.$options.methods,n.length);i--;){var o=n[i];r&&m(r,o)||A(o)||Je(e,"_data",o)}U(t,!0)}function Ye(e,t){I();try{return e.call(t,t)}catch(e){return ie(e,t,"data()"),{}}finally{L()}}function Qe(e,t){var n=e._computedWatchers=Object.create(null),r=zo();for(var i in t){var o=t[i],a="function"==typeof o?o:o.get;r||(n[i]=new ka(e,a||x,x,Aa)),i in e||et(e,i,o)}}function et(e,t,n){var r=!zo();"function"==typeof n?(Sa.get=r?tt(t):nt(n),Sa.set=x):(Sa.get=n.get?r&&!1!==n.cache?tt(t):nt(n.get):x,Sa.set=n.set||x),Object.defineProperty(e,t,Sa)}function tt(e){return function(){var t=this._computedWatchers&&this._computedWatchers[e];if(t)return t.dirty&&t.evaluate(),Jo.target&&t.depend(),t.value}}function nt(e){return function(){return e.call(this,this)}}function rt(e,t){e.$options.props;for(var n in t)e[n]="function"!=typeof t[n]?x:wo(t[n],e)}function it(e,t){for(var n in t){var r=t[n];if(Array.isArray(r))for(var i=0;i<r.length;i++)ot(e,n,r[i]);else ot(e,n,r)}}function ot(e,t,n,r){return u(n)&&(r=n,n=n.handler),"string"==typeof n&&(n=e[n]),e.$watch(t,n,r)}function at(e){var t=e.$options.provide;t&&(e._provided="function"==typeof t?t.call(e):t)}function st(e){var t=ct(e.$options.inject,e);t&&(R(!1),Object.keys(t).forEach(function(n){F(e,n,t[n])}),R(!0))}function ct(e,t){if(e){for(var n=Object.create(null),r=qo?Reflect.ownKeys(e).filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}):Object.keys(e),i=0;i<r.length;i++){for(var o=r[i],a=e[o].from,s=t;s;){if(s._provided&&m(s._provided,a)){n[o]=s._provided[a];break}s=s.$parent}if(!s&&"default"in e[o]){var c=e[o].default;n[o]="function"==typeof c?c.call(t):c}}return n}}function ut(e,t){var n,r,o,a,s;if(Array.isArray(e)||"string"==typeof e)for(n=new Array(e.length),r=0,o=e.length;r<o;r++)n[r]=t(e[r],r);else if("number"==typeof e)for(n=new Array(e),r=0;r<e;r++)n[r]=t(r+1,r);else if(c(e))for(a=Object.keys(e),n=new Array(a.length),r=0,o=a.length;r<o;r++)s=a[r],n[r]=t(e[s],s,r);return i(n)||(n=[]),n._isVList=!0,n}function lt(e,t,n,r){var i,o=this.$scopedSlots[e];o?(n=n||{},r&&(n=w(w({},r),n)),i=o(n)||t):i=this.$slots[e]||t;var a=n&&n.slot;return a?this.$createElement("template",{slot:a},i):i}function ft(e){return Y(this.$options,"filters",e,!0)||xo}function dt(e,t){return Array.isArray(e)?-1===e.indexOf(t):e!==t}function pt(e,t,n,r,i){var o=Ao.keyCodes[t]||n;return i&&r&&!Ao.keyCodes[t]?dt(i,r):o?dt(o,e):r?bo(r)!==t:void 0}function vt(e,t,n,r,i){if(n&&c(n)){Array.isArray(n)&&(n=C(n));var o;for(var a in n)!function(a){if("class"===a||"style"===a||vo(a))o=e;else{var s=e.attrs&&e.attrs.type;o=r||Ao.mustUseProp(t,s,a)?e.domProps||(e.domProps={}):e.attrs||(e.attrs={})}var c=yo(a);a in o||c in o||(o[a]=n[a],!i)||((e.on||(e.on={}))["update:"+c]=function(e){n[a]=e})}(a)}return e}function ht(e,t){var n=this._staticTrees||(this._staticTrees=[]),r=n[e];return r&&!t?r:(r=n[e]=this.$options.staticRenderFns[e].call(this._renderProxy,null,this),yt(r,"__static__"+e,!1),r)}function mt(e,t,n){return yt(e,"__once__"+t+(n?"_"+n:""),!0),e}function yt(e,t,n){if(Array.isArray(e))for(var r=0;r<e.length;r++)e[r]&&"string"!=typeof e[r]&&gt(e[r],t+"_"+r,n);else gt(e,t,n)}function gt(e,t,n){e.isStatic=!0,e.key=t,e.isOnce=n}function _t(e,t){if(t&&u(t)){var n=e.on=e.on?w({},e.on):{};for(var r in t){var i=n[r],o=t[r];n[r]=i?[].concat(i,o):o}}return e}function bt(e){e._o=mt,e._n=p,e._s=d,e._l=ut,e._t=lt,e._q=$,e._i=k,e._m=ht,e._f=ft,e._k=pt,e._b=vt,e._v=j,e._e=Yo,e._u=je,e._g=_t}function wt(e,t,n,r,i){var a,s=i.options;m(r,"_uid")?(a=Object.create(r),a._original=r):(a=r,r=r._original);var c=o(s._compiled),u=!c;this.data=e,this.props=t,this.children=n,this.parent=r,this.listeners=e.on||lo,this.injections=ct(s.inject,r),this.slots=function(){return Ie(n,r)},c&&(this.$options=s,this.$slots=this.slots(),this.$scopedSlots=e.scopedSlots||lo),s._scopeId?this._c=function(e,t,n,i){var o=Et(a,e,t,n,i,u);return o&&!Array.isArray(o)&&(o.fnScopeId=s._scopeId,o.fnContext=r),o}:this._c=function(e,t,n,r){return Et(a,e,t,n,r,u)}}function Ct(e,t,n,r,o){var a=e.options,s={},c=a.props;if(i(c))for(var u in c)s[u]=Q(u,c,t||lo);else i(n.attrs)&&$t(s,n.attrs),i(n.props)&&$t(s,n.props);var l=new wt(n,s,o,r,e),f=a.render.call(null,l._c,l);if(f instanceof Xo)return xt(f,n,l.parent,a,l);if(Array.isArray(f)){for(var d=ge(f)||[],p=new Array(d.length),v=0;v<d.length;v++)p[v]=xt(d[v],n,l.parent,a,l);return p}}function xt(e,t,n,r,i){var o=P(e);return o.fnContext=n,o.fnOptions=r,t.slot&&((o.data||(o.data={})).slot=t.slot),o}function $t(e,t){for(var n in t)e[yo(n)]=t[n]}function kt(e,t,n,a,s){if(!r(e)){var u=n.$options._base;if(c(e)&&(e=u.extend(e)),"function"==typeof e){var l;if(r(e.cid)&&(l=e,void 0===(e=xe(l,u,n))))return Ce(l,t,n,a,s);t=t||{},Nt(e),i(t.model)&&Ot(e.options,t);var f=he(t,e,s);if(o(e.options.functional))return Ct(e,f,t,n,a);var d=t.on;if(t.on=t.nativeOn,o(e.options.abstract)){var p=t.slot;t={},p&&(t.slot=p)}At(t);var v=e.options.name||s;return new Xo("vue-component-"+e.cid+(v?"-"+v:""),t,void 0,void 0,void 0,n,{Ctor:e,propsData:f,listeners:d,tag:s,children:a},l)}}}function St(e,t){var n={_isComponent:!0,_parentVnode:e,parent:t},r=e.data.inlineTemplate;return i(r)&&(n.render=r.render,n.staticRenderFns=r.staticRenderFns),new e.componentOptions.Ctor(n)}function At(e){for(var t=e.hook||(e.hook={}),n=0;n<Oa.length;n++){var r=Oa[n],i=t[r],o=Ta[r];i===o||i&&i._merged||(t[r]=i?Tt(o,i):o)}}function Tt(e,t){var n=function(n,r){e(n,r),t(n,r)};return n._merged=!0,n}function Ot(e,t){var n=e.model&&e.model.prop||"value",r=e.model&&e.model.event||"input";(t.props||(t.props={}))[n]=t.model.value;var o=t.on||(t.on={}),a=o[r],s=t.model.callback;i(a)?(Array.isArray(a)?-1===a.indexOf(s):a!==s)&&(o[r]=[s].concat(a)):o[r]=s}function Et(e,t,n,r,i,a){return(Array.isArray(n)||s(n))&&(i=r,r=n,n=void 0),o(a)&&(i=Ia),It(e,t,n,r,i)}function It(e,t,n,r,o){if(i(n)&&i(n.__ob__))return Yo();if(i(n)&&i(n.is)&&(t=n.is),!t)return Yo();Array.isArray(r)&&"function"==typeof r[0]&&(n=n||{},n.scopedSlots={default:r[0]},r.length=0),o===Ia?r=ge(r):o===Ea&&(r=ye(r));var a,s;if("string"==typeof t){var c;s=e.$vnode&&e.$vnode.ns||Ao.getTagNamespace(t),a=Ao.isReservedTag(t)?new Xo(Ao.parsePlatformTagName(t),n,r,void 0,void 0,e):n&&n.pre||!i(c=Y(e.$options,"components",t))?new Xo(t,n,r,void 0,void 0,e):kt(c,n,e,r,t)}else a=kt(t,n,e,r);return Array.isArray(a)?a:i(a)?(i(s)&&Lt(a,s),i(n)&&jt(n),a):Yo()}function Lt(e,t,n){if(e.ns=t,"foreignObject"===e.tag&&(t=void 0,n=!0),i(e.children))for(var a=0,s=e.children.length;a<s;a++){var c=e.children[a];i(c.tag)&&(r(c.ns)||o(n)&&"svg"!==c.tag)&&Lt(c,t,n)}}function jt(e){c(e.style)&&le(e.style),c(e.class)&&le(e.class)}function Pt(e){e._vnode=null,e._staticTrees=null;var t=e.$options,n=e.$vnode=t._parentVnode,r=n&&n.context;e.$slots=Ie(t._renderChildren,r),e.$scopedSlots=lo,e._c=function(t,n,r,i){return Et(e,t,n,r,i,!1)},e.$createElement=function(t,n,r,i){return Et(e,t,n,r,i,!0)};var i=n&&n.data;F(e,"$attrs",i&&i.attrs||lo,null,!0),F(e,"$listeners",t._parentListeners||lo,null,!0)}function Rt(e,t){var n=e.$options=Object.create(e.constructor.options),r=t._parentVnode;n.parent=t.parent,n._parentVnode=r;var i=r.componentOptions;n.propsData=i.propsData,n._parentListeners=i.listeners,n._renderChildren=i.children,n._componentTag=i.tag,t.render&&(n.render=t.render,n.staticRenderFns=t.staticRenderFns)}function Nt(e){var t=e.options;if(e.super){var n=Nt(e.super);if(n!==e.superOptions){e.superOptions=n;var r=Dt(e);r&&w(e.extendOptions,r),t=e.options=Z(n,e.extendOptions),t.name&&(t.components[t.name]=e)}}return t}function Dt(e){var t,n=e.options,r=e.sealedOptions;for(var i in n)n[i]!==r[i]&&(t||(t={}),t[i]=n[i]);return t}function Ut(e){this._init(e)}function Ft(e){e.use=function(e){var t=this._installedPlugins||(this._installedPlugins=[]);if(t.indexOf(e)>-1)return this;var n=b(arguments,1);return n.unshift(this),"function"==typeof e.install?e.install.apply(e,n):"function"==typeof e&&e.apply(null,n),t.push(e),this}}function Mt(e){e.mixin=function(e){return this.options=Z(this.options,e),this}}function Bt(e){e.cid=0;var t=1;e.extend=function(e){e=e||{};var n=this,r=n.cid,i=e._Ctor||(e._Ctor={});if(i[r])return i[r];var o=e.name||n.options.name,a=function(e){this._init(e)};return a.prototype=Object.create(n.prototype),a.prototype.constructor=a,a.cid=t++,a.options=Z(n.options,e),a.super=n,a.options.props&&Ht(a),a.options.computed&&zt(a),a.extend=n.extend,a.mixin=n.mixin,a.use=n.use,ko.forEach(function(e){a[e]=n[e]}),o&&(a.options.components[o]=a),a.superOptions=n.options,a.extendOptions=e,a.sealedOptions=w({},a.options),i[r]=a,a}}function Ht(e){var t=e.options.props;for(var n in t)Je(e.prototype,"_props",n)}function zt(e){var t=e.options.computed;for(var n in t)et(e.prototype,n,t[n])}function Vt(e){ko.forEach(function(t){e[t]=function(e,n){return n?("component"===t&&u(n)&&(n.name=n.name||e,n=this.options._base.extend(n)),"directive"===t&&"function"==typeof n&&(n={bind:n,update:n}),this.options[t+"s"][e]=n,n):this.options[t+"s"][e]}})}function qt(e){return e&&(e.Ctor.options.name||e.tag)}function Kt(e,t){return Array.isArray(e)?e.indexOf(t)>-1:"string"==typeof e?e.split(",").indexOf(t)>-1:!!l(e)&&e.test(t)}function Wt(e,t){var n=e.cache,r=e.keys,i=e._vnode;for(var o in n){var a=n[o];if(a){var s=qt(a.componentOptions);s&&!t(s)&&Jt(n,o,r,i)}}}function Jt(e,t,n,r){var i=e[t];!i||r&&i.tag===r.tag||i.componentInstance.$destroy(),e[t]=null,h(n,t)}function Gt(e){for(var t=e.data,n=e,r=e;i(r.componentInstance);)(r=r.componentInstance._vnode)&&r.data&&(t=Xt(r.data,t));for(;i(n=n.parent);)n&&n.data&&(t=Xt(t,n.data));return Zt(t.staticClass,t.class)}function Xt(e,t){return{staticClass:Yt(e.staticClass,t.staticClass),class:i(e.class)?[e.class,t.class]:t.class}}function Zt(e,t){return i(e)||i(t)?Yt(e,Qt(t)):""}function Yt(e,t){return e?t?e+" "+t:e:t||""}function Qt(e){return Array.isArray(e)?en(e):c(e)?tn(e):"string"==typeof e?e:""}function en(e){for(var t,n="",r=0,o=e.length;r<o;r++)i(t=Qt(e[r]))&&""!==t&&(n&&(n+=" "),n+=t);return n}function tn(e){var t="";for(var n in e)e[n]&&(t&&(t+=" "),t+=n);return t}function nn(e){return ns(e)?"svg":"math"===e?"math":void 0}function rn(e){if(!Eo)return!0;if(is(e))return!1;if(e=e.toLowerCase(),null!=os[e])return os[e];var t=document.createElement(e);return e.indexOf("-")>-1?os[e]=t.constructor===window.HTMLUnknownElement||t.constructor===window.HTMLElement:os[e]=/HTMLUnknownElement/.test(t.toString())}function on(e){if("string"==typeof e){return document.querySelector(e)||document.createElement("div")}return e}function an(e,t){var n=document.createElement(e);return"select"!==e?n:(t.data&&t.data.attrs&&void 0!==t.data.attrs.multiple&&n.setAttribute("multiple","multiple"),n)}function sn(e,t){return document.createElementNS(es[e],t)}function cn(e){return document.createTextNode(e)}function un(e){return document.createComment(e)}function ln(e,t,n){e.insertBefore(t,n)}function fn(e,t){e.removeChild(t)}function dn(e,t){e.appendChild(t)}function pn(e){return e.parentNode}function vn(e){return e.nextSibling}function hn(e){return e.tagName}function mn(e,t){e.textContent=t}function yn(e,t){e.setAttribute(t,"")}function gn(e,t){var n=e.data.ref;if(i(n)){var r=e.context,o=e.componentInstance||e.elm,a=r.$refs;t?Array.isArray(a[n])?h(a[n],o):a[n]===o&&(a[n]=void 0):e.data.refInFor?Array.isArray(a[n])?a[n].indexOf(o)<0&&a[n].push(o):a[n]=[o]:a[n]=o}}function _n(e,t){return e.key===t.key&&(e.tag===t.tag&&e.isComment===t.isComment&&i(e.data)===i(t.data)&&bn(e,t)||o(e.isAsyncPlaceholder)&&e.asyncFactory===t.asyncFactory&&r(t.asyncFactory.error))}function bn(e,t){if("input"!==e.tag)return!0;var n,r=i(n=e.data)&&i(n=n.attrs)&&n.type,o=i(n=t.data)&&i(n=n.attrs)&&n.type;return r===o||as(r)&&as(o)}function wn(e,t,n){var r,o,a={};for(r=t;r<=n;++r)o=e[r].key,i(o)&&(a[o]=r);return a}function Cn(e,t){(e.data.directives||t.data.directives)&&xn(e,t)}function xn(e,t){var n,r,i,o=e===us,a=t===us,s=$n(e.data.directives,e.context),c=$n(t.data.directives,t.context),u=[],l=[];for(n in c)r=s[n],i=c[n],r?(i.oldValue=r.value,Sn(i,"update",t,e),i.def&&i.def.componentUpdated&&l.push(i)):(Sn(i,"bind",t,e),i.def&&i.def.inserted&&u.push(i));if(u.length){var f=function(){for(var n=0;n<u.length;n++)Sn(u[n],"inserted",t,e)};o?ve(t,"insert",f):f()}if(l.length&&ve(t,"postpatch",function(){for(var n=0;n<l.length;n++)Sn(l[n],"componentUpdated",t,e)}),!o)for(n in s)c[n]||Sn(s[n],"unbind",e,e,a)}function $n(e,t){var n=Object.create(null);if(!e)return n;var r,i;for(r=0;r<e.length;r++)i=e[r],i.modifiers||(i.modifiers=ds),n[kn(i)]=i,i.def=Y(t.$options,"directives",i.name,!0);return n}function kn(e){return e.rawName||e.name+"."+Object.keys(e.modifiers||{}).join(".")}function Sn(e,t,n,r,i){var o=e.def&&e.def[t];if(o)try{o(n.elm,e,n,r,i)}catch(r){ie(r,n.context,"directive "+e.name+" "+t+" hook")}}function An(e,t){var n=t.componentOptions;if(!(i(n)&&!1===n.Ctor.options.inheritAttrs||r(e.data.attrs)&&r(t.data.attrs))){var o,a,s=t.elm,c=e.data.attrs||{},u=t.data.attrs||{};i(u.__ob__)&&(u=t.data.attrs=w({},u));for(o in u)a=u[o],c[o]!==a&&Tn(s,o,a);(Po||No)&&u.value!==c.value&&Tn(s,"value",u.value);for(o in c)r(u[o])&&(Za(o)?s.removeAttributeNS(Xa,Ya(o)):Ja(o)||s.removeAttribute(o))}}function Tn(e,t,n){e.tagName.indexOf("-")>-1?On(e,t,n):Ga(t)?Qa(n)?e.removeAttribute(t):(n="allowfullscreen"===t&&"EMBED"===e.tagName?"true":t,e.setAttribute(t,n)):Ja(t)?e.setAttribute(t,Qa(n)||"false"===n?"false":"true"):Za(t)?Qa(n)?e.removeAttributeNS(Xa,Ya(t)):e.setAttributeNS(Xa,t,n):On(e,t,n)}function On(e,t,n){if(Qa(n))e.removeAttribute(t);else{if(Po&&!Ro&&("TEXTAREA"===e.tagName||"INPUT"===e.tagName)&&"placeholder"===t&&!e.__ieph){var r=function(t){t.stopImmediatePropagation(),e.removeEventListener("input",r)};e.addEventListener("input",r),e.__ieph=!0}e.setAttribute(t,n)}}function En(e,t){var n=t.elm,o=t.data,a=e.data;if(!(r(o.staticClass)&&r(o.class)&&(r(a)||r(a.staticClass)&&r(a.class)))){var s=Gt(t),c=n._transitionClasses;i(c)&&(s=Yt(s,Qt(c))),s!==n._prevClass&&(n.setAttribute("class",s),n._prevClass=s)}}function In(e){function t(){(a||(a=[])).push(e.slice(v,i).trim()),v=i+1}var n,r,i,o,a,s=!1,c=!1,u=!1,l=!1,f=0,d=0,p=0,v=0;for(i=0;i<e.length;i++)if(r=n,n=e.charCodeAt(i),s)39===n&&92!==r&&(s=!1);else if(c)34===n&&92!==r&&(c=!1);else if(u)96===n&&92!==r&&(u=!1);else if(l)47===n&&92!==r&&(l=!1);else if(124!==n||124===e.charCodeAt(i+1)||124===e.charCodeAt(i-1)||f||d||p){switch(n){case 34:c=!0;break;case 39:s=!0;break;case 96:u=!0;break;case 40:p++;break;case 41:p--;break;case 91:d++;break;case 93:d--;break;case 123:f++;break;case 125:f--}if(47===n){for(var h=i-1,m=void 0;h>=0&&" "===(m=e.charAt(h));h--);m&&ms.test(m)||(l=!0)}}else void 0===o?(v=i+1,o=e.slice(0,i).trim()):t();if(void 0===o?o=e.slice(0,i).trim():0!==v&&t(),a)for(i=0;i<a.length;i++)o=Ln(o,a[i]);return o}function Ln(e,t){var n=t.indexOf("(");if(n<0)return'_f("'+t+'")('+e+")";var r=t.slice(0,n),i=t.slice(n+1);return'_f("'+r+'")('+e+(")"!==i?","+i:i)}function jn(e){console.error("[Vue compiler]: "+e)}function Pn(e,t){return e?e.map(function(e){return e[t]}).filter(function(e){return e}):[]}function Rn(e,t,n){(e.props||(e.props=[])).push({name:t,value:n}),e.plain=!1}function Nn(e,t,n){(e.attrs||(e.attrs=[])).push({name:t,value:n}),e.plain=!1}function Dn(e,t,n){e.attrsMap[t]=n,e.attrsList.push({name:t,value:n})}function Un(e,t,n,r,i,o){(e.directives||(e.directives=[])).push({name:t,rawName:n,value:r,arg:i,modifiers:o}),e.plain=!1}function Fn(e,t,n,r,i,o){r=r||lo,"click"===t&&(r.right?(t="contextmenu",delete r.right):r.middle&&(t="mouseup")),r.capture&&(delete r.capture,t="!"+t),r.once&&(delete r.once,t="~"+t),r.passive&&(delete r.passive,t="&"+t);var a;r.native?(delete r.native,a=e.nativeEvents||(e.nativeEvents={})):a=e.events||(e.events={});var s={value:n.trim()};r!==lo&&(s.modifiers=r);var c=a[t];Array.isArray(c)?i?c.unshift(s):c.push(s):a[t]=c?i?[s,c]:[c,s]:s,e.plain=!1}function Mn(e,t,n){var r=Bn(e,":"+t)||Bn(e,"v-bind:"+t);if(null!=r)return In(r);if(!1!==n){var i=Bn(e,t);if(null!=i)return JSON.stringify(i)}}function Bn(e,t,n){var r;if(null!=(r=e.attrsMap[t]))for(var i=e.attrsList,o=0,a=i.length;o<a;o++)if(i[o].name===t){i.splice(o,1);break}return n&&delete e.attrsMap[t],r}function Hn(e,t,n){var r=n||{},i=r.number,o=r.trim,a="$$v";o&&(a="(typeof $$v === 'string'? $$v.trim(): $$v)"),i&&(a="_n("+a+")");var s=zn(t,a);e.model={value:"("+t+")",expression:JSON.stringify(t),callback:"function ($$v) {"+s+"}"}}function zn(e,t){var n=Vn(e);return null===n.key?e+"="+t:"$set("+n.exp+", "+n.key+", "+t+")"}function Vn(e){if(e=e.trim(),Na=e.length,e.indexOf("[")<0||e.lastIndexOf("]")<Na-1)return Fa=e.lastIndexOf("."),Fa>-1?{exp:e.slice(0,Fa),key:'"'+e.slice(Fa+1)+'"'}:{exp:e,key:null};for(Da=e,Fa=Ma=Ba=0;!Kn();)Ua=qn(),Wn(Ua)?Gn(Ua):91===Ua&&Jn(Ua);return{exp:e.slice(0,Ma),key:e.slice(Ma+1,Ba)}}function qn(){return Da.charCodeAt(++Fa)}function Kn(){return Fa>=Na}function Wn(e){return 34===e||39===e}function Jn(e){var t=1;for(Ma=Fa;!Kn();)if(e=qn(),Wn(e))Gn(e);else if(91===e&&t++,93===e&&t--,0===t){Ba=Fa;break}}function Gn(e){for(var t=e;!Kn()&&(e=qn())!==t;);}function Xn(e,t,n){Ha=n;var r=t.value,i=t.modifiers,o=e.tag,a=e.attrsMap.type;if(e.component)return Hn(e,r,i),!1;if("select"===o)Qn(e,r,i);else if("input"===o&&"checkbox"===a)Zn(e,r,i);else if("input"===o&&"radio"===a)Yn(e,r,i);else if("input"===o||"textarea"===o)er(e,r,i);else if(!Ao.isReservedTag(o))return Hn(e,r,i),!1;return!0}function Zn(e,t,n){var r=n&&n.number,i=Mn(e,"value")||"null",o=Mn(e,"true-value")||"true",a=Mn(e,"false-value")||"false";Rn(e,"checked","Array.isArray("+t+")?_i("+t+","+i+")>-1"+("true"===o?":("+t+")":":_q("+t+","+o+")")),Fn(e,"change","var $$a="+t+",$$el=$event.target,$$c=$$el.checked?("+o+"):("+a+");if(Array.isArray($$a)){var $$v="+(r?"_n("+i+")":i)+",$$i=_i($$a,$$v);if($$el.checked){$$i<0&&("+zn(t,"$$a.concat([$$v])")+")}else{$$i>-1&&("+zn(t,"$$a.slice(0,$$i).concat($$a.slice($$i+1))")+")}}else{"+zn(t,"$$c")+"}",null,!0)}function Yn(e,t,n){var r=n&&n.number,i=Mn(e,"value")||"null";i=r?"_n("+i+")":i,Rn(e,"checked","_q("+t+","+i+")"),Fn(e,"change",zn(t,i),null,!0)}function Qn(e,t,n){var r=n&&n.number,i='Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = "_value" in o ? o._value : o.value;return '+(r?"_n(val)":"val")+"})",o="var $$selectedVal = "+i+";";o=o+" "+zn(t,"$event.target.multiple ? $$selectedVal : $$selectedVal[0]"),Fn(e,"change",o,null,!0)}function er(e,t,n){var r=e.attrsMap.type,i=n||{},o=i.lazy,a=i.number,s=i.trim,c=!o&&"range"!==r,u=o?"change":"range"===r?ys:"input",l="$event.target.value";s&&(l="$event.target.value.trim()"),a&&(l="_n("+l+")");var f=zn(t,l);c&&(f="if($event.target.composing)return;"+f),Rn(e,"value","("+t+")"),Fn(e,u,f,null,!0),(s||a)&&Fn(e,"blur","$forceUpdate()")}function tr(e){if(i(e[ys])){var t=Po?"change":"input";e[t]=[].concat(e[ys],e[t]||[]),delete e[ys]}i(e[gs])&&(e.change=[].concat(e[gs],e.change||[]),delete e[gs])}function nr(e,t,n){var r=za;return function i(){null!==t.apply(null,arguments)&&ir(e,i,n,r)}}function rr(e,t,n,r){t=ce(t),za.addEventListener(e,t,Fo?{capture:n,passive:r}:n)}function ir(e,t,n,r){(r||za).removeEventListener(e,t._withTask||t,n)}function or(e,t){if(!r(e.data.on)||!r(t.data.on)){var n=t.data.on||{},i=e.data.on||{};za=t.elm,tr(n),pe(n,i,rr,ir,nr,t.context),za=void 0}}function ar(e,t){if(!r(e.data.domProps)||!r(t.data.domProps)){var n,o,a=t.elm,s=e.data.domProps||{},c=t.data.domProps||{};i(c.__ob__)&&(c=t.data.domProps=w({},c));for(n in s)r(c[n])&&(a[n]="");for(n in c){if(o=c[n],"textContent"===n||"innerHTML"===n){if(t.children&&(t.children.length=0),o===s[n])continue;1===a.childNodes.length&&a.removeChild(a.childNodes[0])}if("value"===n){a._value=o;var u=r(o)?"":String(o);sr(a,u)&&(a.value=u)}else a[n]=o}}}function sr(e,t){return!e.composing&&("OPTION"===e.tagName||cr(e,t)||ur(e,t))}function cr(e,t){var n=!0;try{n=document.activeElement!==e}catch(e){}return n&&e.value!==t}function ur(e,t){var n=e.value,r=e._vModifiers;if(i(r)){if(r.lazy)return!1;if(r.number)return p(n)!==p(t);if(r.trim)return n.trim()!==t.trim()}return n!==t}function lr(e){var t=fr(e.style);return e.staticStyle?w(e.staticStyle,t):t}function fr(e){return Array.isArray(e)?C(e):"string"==typeof e?ws(e):e}function dr(e,t){var n,r={};if(t)for(var i=e;i.componentInstance;)(i=i.componentInstance._vnode)&&i.data&&(n=lr(i.data))&&w(r,n);(n=lr(e.data))&&w(r,n);for(var o=e;o=o.parent;)o.data&&(n=lr(o.data))&&w(r,n);return r}function pr(e,t){var n=t.data,o=e.data;if(!(r(n.staticStyle)&&r(n.style)&&r(o.staticStyle)&&r(o.style))){var a,s,c=t.elm,u=o.staticStyle,l=o.normalizedStyle||o.style||{},f=u||l,d=fr(t.data.style)||{};t.data.normalizedStyle=i(d.__ob__)?w({},d):d;var p=dr(t,!0);for(s in f)r(p[s])&&$s(c,s,"");for(s in p)(a=p[s])!==f[s]&&$s(c,s,null==a?"":a)}}function vr(e,t){if(t&&(t=t.trim()))if(e.classList)t.indexOf(" ")>-1?t.split(Ts).forEach(function(t){return e.classList.add(t)}):e.classList.add(t);else{var n=" "+(e.getAttribute("class")||"")+" ";n.indexOf(" "+t+" ")<0&&e.setAttribute("class",(n+t).trim())}}function hr(e,t){if(t&&(t=t.trim()))if(e.classList)t.indexOf(" ")>-1?t.split(Ts).forEach(function(t){return e.classList.remove(t)}):e.classList.remove(t),e.classList.length||e.removeAttribute("class");else{for(var n=" "+(e.getAttribute("class")||"")+" ",r=" "+t+" ";n.indexOf(r)>=0;)n=n.replace(r," ");n=n.trim(),n?e.setAttribute("class",n):e.removeAttribute("class")}}function mr(e){if(e){if("object"==typeof e){var t={};return!1!==e.css&&w(t,Os(e.name||"v")),w(t,e),t}return"string"==typeof e?Os(e):void 0}}function yr(e){Ds(function(){Ds(e)})}function gr(e,t){var n=e._transitionClasses||(e._transitionClasses=[]);n.indexOf(t)<0&&(n.push(t),vr(e,t))}function _r(e,t){e._transitionClasses&&h(e._transitionClasses,t),hr(e,t)}function br(e,t,n){var r=wr(e,t),i=r.type,o=r.timeout,a=r.propCount;if(!i)return n();var s=i===Is?Ps:Ns,c=0,u=function(){e.removeEventListener(s,l),n()},l=function(t){t.target===e&&++c>=a&&u()};setTimeout(function(){c<a&&u()},o+1),e.addEventListener(s,l)}function wr(e,t){var n,r=window.getComputedStyle(e),i=(r[js+"Delay"]||"").split(", "),o=(r[js+"Duration"]||"").split(", "),a=Cr(i,o),s=(r[Rs+"Delay"]||"").split(", "),c=(r[Rs+"Duration"]||"").split(", "),u=Cr(s,c),l=0,f=0;return t===Is?a>0&&(n=Is,l=a,f=o.length):t===Ls?u>0&&(n=Ls,l=u,f=c.length):(l=Math.max(a,u),n=l>0?a>u?Is:Ls:null,f=n?n===Is?o.length:c.length:0),{type:n,timeout:l,propCount:f,hasTransform:n===Is&&Us.test(r[js+"Property"])}}function Cr(e,t){for(;e.length<t.length;)e=e.concat(e);return Math.max.apply(null,t.map(function(t,n){return xr(t)+xr(e[n])}))}function xr(e){return 1e3*Number(e.slice(0,-1).replace(",","."))}function $r(e,t){var n=e.elm;i(n._leaveCb)&&(n._leaveCb.cancelled=!0,n._leaveCb());var o=mr(e.data.transition);if(!r(o)&&!i(n._enterCb)&&1===n.nodeType){for(var a=o.css,s=o.type,u=o.enterClass,l=o.enterToClass,f=o.enterActiveClass,d=o.appearClass,v=o.appearToClass,h=o.appearActiveClass,m=o.beforeEnter,y=o.enter,g=o.afterEnter,_=o.enterCancelled,b=o.beforeAppear,w=o.appear,C=o.afterAppear,x=o.appearCancelled,$=o.duration,k=ya,A=ya.$vnode;A&&A.parent;)A=A.parent,k=A.context;var T=!k._isMounted||!e.isRootInsert;if(!T||w||""===w){var O=T&&d?d:u,E=T&&h?h:f,I=T&&v?v:l,L=T?b||m:m,j=T&&"function"==typeof w?w:y,P=T?C||g:g,R=T?x||_:_,N=p(c($)?$.enter:$),D=!1!==a&&!Ro,U=Ar(j),F=n._enterCb=S(function(){D&&(_r(n,I),_r(n,E)),F.cancelled?(D&&_r(n,O),R&&R(n)):P&&P(n),n._enterCb=null});e.data.show||ve(e,"insert",function(){var t=n.parentNode,r=t&&t._pending&&t._pending[e.key];r&&r.tag===e.tag&&r.elm._leaveCb&&r.elm._leaveCb(),j&&j(n,F)}),L&&L(n),D&&(gr(n,O),gr(n,E),yr(function(){_r(n,O),F.cancelled||(gr(n,I),U||(Sr(N)?setTimeout(F,N):br(n,s,F)))})),e.data.show&&(t&&t(),j&&j(n,F)),D||U||F()}}}function kr(e,t){function n(){x.cancelled||(!e.data.show&&o.parentNode&&((o.parentNode._pending||(o.parentNode._pending={}))[e.key]=e),v&&v(o),b&&(gr(o,l),gr(o,d),yr(function(){_r(o,l),x.cancelled||(gr(o,f),w||(Sr(C)?setTimeout(x,C):br(o,u,x)))})),h&&h(o,x),b||w||x())}var o=e.elm;i(o._enterCb)&&(o._enterCb.cancelled=!0,o._enterCb());var a=mr(e.data.transition);if(r(a)||1!==o.nodeType)return t();if(!i(o._leaveCb)){var s=a.css,u=a.type,l=a.leaveClass,f=a.leaveToClass,d=a.leaveActiveClass,v=a.beforeLeave,h=a.leave,m=a.afterLeave,y=a.leaveCancelled,g=a.delayLeave,_=a.duration,b=!1!==s&&!Ro,w=Ar(h),C=p(c(_)?_.leave:_),x=o._leaveCb=S(function(){o.parentNode&&o.parentNode._pending&&(o.parentNode._pending[e.key]=null),b&&(_r(o,f),_r(o,d)),x.cancelled?(b&&_r(o,l),y&&y(o)):(t(),m&&m(o)),o._leaveCb=null});g?g(n):n()}}function Sr(e){return"number"==typeof e&&!isNaN(e)}function Ar(e){if(r(e))return!1;var t=e.fns;return i(t)?Ar(Array.isArray(t)?t[0]:t):(e._length||e.length)>1}function Tr(e,t){!0!==t.data.show&&$r(t)}function Or(e,t,n){Er(e,t,n),(Po||No)&&setTimeout(function(){Er(e,t,n)},0)}function Er(e,t,n){var r=t.value,i=e.multiple;if(!i||Array.isArray(r)){for(var o,a,s=0,c=e.options.length;s<c;s++)if(a=e.options[s],i)o=k(r,Lr(a))>-1,a.selected!==o&&(a.selected=o);else if($(Lr(a),r))return void(e.selectedIndex!==s&&(e.selectedIndex=s));i||(e.selectedIndex=-1)}}function Ir(e,t){return t.every(function(t){return!$(t,e)})}function Lr(e){return"_value"in e?e._value:e.value}function jr(e){e.target.composing=!0}function Pr(e){e.target.composing&&(e.target.composing=!1,Rr(e.target,"input"))}function Rr(e,t){var n=document.createEvent("HTMLEvents");n.initEvent(t,!0,!0),e.dispatchEvent(n)}function Nr(e){return!e.componentInstance||e.data&&e.data.transition?e:Nr(e.componentInstance._vnode)}function Dr(e){var t=e&&e.componentOptions;return t&&t.Ctor.options.abstract?Dr(ke(t.children)):e}function Ur(e){var t={},n=e.$options;for(var r in n.propsData)t[r]=e[r];var i=n._parentListeners;for(var o in i)t[yo(o)]=i[o];return t}function Fr(e,t){if(/\d-keep-alive$/.test(t.tag))return e("keep-alive",{props:t.componentOptions.propsData})}function Mr(e){for(;e=e.parent;)if(e.data.transition)return!0}function Br(e,t){return t.key===e.key&&t.tag===e.tag}function Hr(e){e.elm._moveCb&&e.elm._moveCb(),e.elm._enterCb&&e.elm._enterCb()}function zr(e){e.data.newPos=e.elm.getBoundingClientRect()}function Vr(e){var t=e.data.pos,n=e.data.newPos,r=t.left-n.left,i=t.top-n.top;if(r||i){e.data.moved=!0;var o=e.elm.style;o.transform=o.WebkitTransform="translate("+r+"px,"+i+"px)",o.transitionDuration="0s"}}function qr(e,t){var n=t?pc(t):fc;if(n.test(e)){for(var r,i,o,a=[],s=[],c=n.lastIndex=0;r=n.exec(e);){(i=r.index)>c&&(s.push(o=e.slice(c,i)),a.push(JSON.stringify(o)));var u=In(r[1].trim());a.push("_s("+u+")"),s.push({"@binding":u}),c=i+r[0].length}return c<e.length&&(s.push(o=e.slice(c)),a.push(JSON.stringify(o))),{expression:a.join("+"),tokens:s}}}function Kr(e,t){var n=(t.warn,Bn(e,"class"));n&&(e.staticClass=JSON.stringify(n));var r=Mn(e,"class",!1);r&&(e.classBinding=r)}function Wr(e){var t="";return e.staticClass&&(t+="staticClass:"+e.staticClass+","),e.classBinding&&(t+="class:"+e.classBinding+","),t}function Jr(e,t){var n=(t.warn,Bn(e,"style"));n&&(e.staticStyle=JSON.stringify(ws(n)));var r=Mn(e,"style",!1);r&&(e.styleBinding=r)}function Gr(e){var t="";return e.staticStyle&&(t+="staticStyle:"+e.staticStyle+","),e.styleBinding&&(t+="style:("+e.styleBinding+"),"),t}function Xr(e,t){var n=t?jc:Lc;return e.replace(n,function(e){return Ic[e]})}function Zr(e,t){function n(t){l+=t,e=e.substring(t)}function r(e,n,r){var i,s;if(null==n&&(n=l),null==r&&(r=l),e)for(s=e.toLowerCase(),i=a.length-1;i>=0&&a[i].lowerCasedTag!==s;i--);else i=0;if(i>=0){for(var c=a.length-1;c>=i;c--)t.end&&t.end(a[c].tag,n,r);a.length=i,o=i&&a[i-1].tag}else"br"===s?t.start&&t.start(e,[],!0,n,r):"p"===s&&(t.start&&t.start(e,[],!1,n,r),t.end&&t.end(e,n,r))}for(var i,o,a=[],s=t.expectHTML,c=t.isUnaryTag||Co,u=t.canBeLeftOpenTag||Co,l=0;e;){if(i=e,o&&Oc(o)){var f=0,d=o.toLowerCase(),p=Ec[d]||(Ec[d]=new RegExp("([\\s\\S]*?)(</"+d+"[^>]*>)","i")),v=e.replace(p,function(e,n,r){return f=r.length,Oc(d)||"noscript"===d||(n=n.replace(/<!\--([\s\S]*?)-->/g,"$1").replace(/<!\[CDATA\[([\s\S]*?)]]>/g,"$1")),Rc(d,n)&&(n=n.slice(1)),t.chars&&t.chars(n),""});l+=e.length-v.length,e=v,r(d,l-f,l)}else{var h=e.indexOf("<");if(0===h){if(Ac.test(e)){var m=e.indexOf("--\x3e");if(m>=0){t.shouldKeepComment&&t.comment(e.substring(4,m)),n(m+3);continue}}if(Tc.test(e)){var y=e.indexOf("]>");if(y>=0){n(y+2);continue}}var g=e.match(Sc);if(g){n(g[0].length);continue}var _=e.match(kc);if(_){var b=l;n(_[0].length),r(_[1],b,l);continue}var w=function(){var t=e.match(xc);if(t){var r={tagName:t[1],attrs:[],start:l};n(t[0].length);for(var i,o;!(i=e.match($c))&&(o=e.match(bc));)n(o[0].length),r.attrs.push(o);if(i)return r.unarySlash=i[1],n(i[0].length),r.end=l,r}}();if(w){!function(e){var n=e.tagName,i=e.unarySlash;s&&("p"===o&&_c(n)&&r(o),u(n)&&o===n&&r(n));for(var l=c(n)||!!i,f=e.attrs.length,d=new Array(f),p=0;p<f;p++){var v=e.attrs[p],h=v[3]||v[4]||v[5]||"",m="a"===n&&"href"===v[1]?t.shouldDecodeNewlinesForHref:t.shouldDecodeNewlines;d[p]={name:v[1],value:Xr(h,m)}}l||(a.push({tag:n,lowerCasedTag:n.toLowerCase(),attrs:d}),o=n),t.start&&t.start(n,d,l,e.start,e.end)}(w),Rc(w.tagName,e)&&n(1);continue}}var C=void 0,x=void 0,$=void 0;if(h>=0){for(x=e.slice(h);!(kc.test(x)||xc.test(x)||Ac.test(x)||Tc.test(x)||($=x.indexOf("<",1))<0);)h+=$,x=e.slice(h);C=e.substring(0,h),n(h)}h<0&&(C=e,e=""),t.chars&&C&&t.chars(C)}if(e===i){t.chars&&t.chars(e);break}}r()}function Yr(e,t,n){return{type:1,tag:e,attrsList:t,attrsMap:yi(t),parent:n,children:[]}}function Qr(e,t){function n(e){e.pre&&(s=!1),oc(e.tag)&&(c=!1);for(var n=0;n<ic.length;n++)ic[n](e,t)}ec=t.warn||jn,oc=t.isPreTag||Co,ac=t.mustUseProp||Co,sc=t.getTagNamespace||Co,nc=Pn(t.modules,"transformNode"),rc=Pn(t.modules,"preTransformNode"),ic=Pn(t.modules,"postTransformNode"),tc=t.delimiters;var r,i,o=[],a=!1!==t.preserveWhitespace,s=!1,c=!1;return Zr(e,{warn:ec,expectHTML:t.expectHTML,isUnaryTag:t.isUnaryTag,canBeLeftOpenTag:t.canBeLeftOpenTag,shouldDecodeNewlines:t.shouldDecodeNewlines,shouldDecodeNewlinesForHref:t.shouldDecodeNewlinesForHref,shouldKeepComment:t.comments,start:function(e,a,u){var l=i&&i.ns||sc(e);Po&&"svg"===l&&(a=bi(a));var f=Yr(e,a,i);l&&(f.ns=l),_i(f)&&!zo()&&(f.forbidden=!0);for(var d=0;d<rc.length;d++)f=rc[d](f,t)||f;if(s||(ei(f),f.pre&&(s=!0)),oc(f.tag)&&(c=!0),s?ti(f):f.processed||(oi(f),si(f),fi(f),ni(f,t)),r?o.length||r.if&&(f.elseif||f.else)&&li(r,{exp:f.elseif,block:f}):r=f,i&&!f.forbidden)if(f.elseif||f.else)ci(f,i);else if(f.slotScope){i.plain=!1;var p=f.slotTarget||'"default"';(i.scopedSlots||(i.scopedSlots={}))[p]=f}else i.children.push(f),f.parent=i;u?n(f):(i=f,o.push(f))},end:function(){var e=o[o.length-1],t=e.children[e.children.length-1];t&&3===t.type&&" "===t.text&&!c&&e.children.pop(),o.length-=1,i=o[o.length-1],n(e)},chars:function(e){if(i&&(!Po||"textarea"!==i.tag||i.attrsMap.placeholder!==e)){var t=i.children;if(e=c||e.trim()?gi(i)?e:Vc(e):a&&t.length?" ":""){var n;!s&&" "!==e&&(n=qr(e,tc))?t.push({type:2,expression:n.expression,tokens:n.tokens,text:e}):" "===e&&t.length&&" "===t[t.length-1].text||t.push({type:3,text:e})}}},comment:function(e){i.children.push({type:3,text:e,isComment:!0})}}),r}function ei(e){null!=Bn(e,"v-pre")&&(e.pre=!0)}function ti(e){var t=e.attrsList.length;if(t)for(var n=e.attrs=new Array(t),r=0;r<t;r++)n[r]={name:e.attrsList[r].name,value:JSON.stringify(e.attrsList[r].value)};else e.pre||(e.plain=!0)}function ni(e,t){ri(e),e.plain=!e.key&&!e.attrsList.length,ii(e),di(e),pi(e);for(var n=0;n<nc.length;n++)e=nc[n](e,t)||e;vi(e)}function ri(e){var t=Mn(e,"key");t&&(e.key=t)}function ii(e){var t=Mn(e,"ref");t&&(e.ref=t,e.refInFor=hi(e))}function oi(e){var t;if(t=Bn(e,"v-for")){var n=ai(t);n&&w(e,n)}}function ai(e){var t=e.match(Uc);if(t){var n={};n.for=t[2].trim();var r=t[1].trim().replace(Mc,""),i=r.match(Fc);return i?(n.alias=r.replace(Fc,"").trim(),n.iterator1=i[1].trim(),i[2]&&(n.iterator2=i[2].trim())):n.alias=r,n}}function si(e){var t=Bn(e,"v-if");if(t)e.if=t,li(e,{exp:t,block:e});else{null!=Bn(e,"v-else")&&(e.else=!0);var n=Bn(e,"v-else-if");n&&(e.elseif=n)}}function ci(e,t){var n=ui(t.children);n&&n.if&&li(n,{exp:e.elseif,block:e})}function ui(e){for(var t=e.length;t--;){if(1===e[t].type)return e[t];e.pop()}}function li(e,t){e.ifConditions||(e.ifConditions=[]),e.ifConditions.push(t)}function fi(e){null!=Bn(e,"v-once")&&(e.once=!0)}function di(e){if("slot"===e.tag)e.slotName=Mn(e,"name");else{var t;"template"===e.tag?(t=Bn(e,"scope"),e.slotScope=t||Bn(e,"slot-scope")):(t=Bn(e,"slot-scope"))&&(e.slotScope=t);var n=Mn(e,"slot");n&&(e.slotTarget='""'===n?'"default"':n,"template"===e.tag||e.slotScope||Nn(e,"slot",n))}}function pi(e){var t;(t=Mn(e,"is"))&&(e.component=t),null!=Bn(e,"inline-template")&&(e.inlineTemplate=!0)}function vi(e){var t,n,r,i,o,a,s,c=e.attrsList;for(t=0,n=c.length;t<n;t++)if(r=i=c[t].name,o=c[t].value,Dc.test(r))if(e.hasBindings=!0,a=mi(r),a&&(r=r.replace(zc,"")),Hc.test(r))r=r.replace(Hc,""),o=In(o),s=!1,a&&(a.prop&&(s=!0,"innerHtml"===(r=yo(r))&&(r="innerHTML")),a.camel&&(r=yo(r)),a.sync&&Fn(e,"update:"+yo(r),zn(o,"$event"))),s||!e.component&&ac(e.tag,e.attrsMap.type,r)?Rn(e,r,o):Nn(e,r,o);else if(Nc.test(r))r=r.replace(Nc,""),Fn(e,r,o,a,!1,ec);else{r=r.replace(Dc,"");var u=r.match(Bc),l=u&&u[1];l&&(r=r.slice(0,-(l.length+1))),Un(e,r,i,o,l,a)}else Nn(e,r,JSON.stringify(o)),!e.component&&"muted"===r&&ac(e.tag,e.attrsMap.type,r)&&Rn(e,r,"true")}function hi(e){for(var t=e;t;){if(void 0!==t.for)return!0;t=t.parent}return!1}function mi(e){var t=e.match(zc);if(t){var n={};return t.forEach(function(e){n[e.slice(1)]=!0}),n}}function yi(e){for(var t={},n=0,r=e.length;n<r;n++)t[e[n].name]=e[n].value;return t}function gi(e){return"script"===e.tag||"style"===e.tag}function _i(e){return"style"===e.tag||"script"===e.tag&&(!e.attrsMap.type||"text/javascript"===e.attrsMap.type)}function bi(e){for(var t=[],n=0;n<e.length;n++){var r=e[n];qc.test(r.name)||(r.name=r.name.replace(Kc,""),t.push(r))}return t}function wi(e,t){if("input"===e.tag){var n=e.attrsMap;if(!n["v-model"])return;var r;if((n[":type"]||n["v-bind:type"])&&(r=Mn(e,"type")),n.type||r||!n["v-bind"]||(r="("+n["v-bind"]+").type"),r){var i=Bn(e,"v-if",!0),o=i?"&&("+i+")":"",a=null!=Bn(e,"v-else",!0),s=Bn(e,"v-else-if",!0),c=Ci(e);oi(c),Dn(c,"type","checkbox"),ni(c,t),c.processed=!0,c.if="("+r+")==='checkbox'"+o,li(c,{exp:c.if,block:c});var u=Ci(e);Bn(u,"v-for",!0),Dn(u,"type","radio"),ni(u,t),li(c,{exp:"("+r+")==='radio'"+o,block:u});var l=Ci(e);return Bn(l,"v-for",!0),Dn(l,":type",r),ni(l,t),li(c,{exp:i,block:l}),a?c.else=!0:s&&(c.elseif=s),c}}}function Ci(e){return Yr(e.tag,e.attrsList.slice(),e.parent)}function xi(e,t){t.value&&Rn(e,"textContent","_s("+t.value+")")}function $i(e,t){t.value&&Rn(e,"innerHTML","_s("+t.value+")")}function ki(e,t){e&&(cc=Zc(t.staticKeys||""),uc=t.isReservedTag||Co,Ai(e),Ti(e,!1))}function Si(e){return v("type,tag,attrsList,attrsMap,plain,parent,children,attrs"+(e?","+e:""))}function Ai(e){if(e.static=Oi(e),1===e.type){if(!uc(e.tag)&&"slot"!==e.tag&&null==e.attrsMap["inline-template"])return;for(var t=0,n=e.children.length;t<n;t++){var r=e.children[t];Ai(r),r.static||(e.static=!1)}if(e.ifConditions)for(var i=1,o=e.ifConditions.length;i<o;i++){var a=e.ifConditions[i].block;Ai(a),a.static||(e.static=!1)}}}function Ti(e,t){if(1===e.type){if((e.static||e.once)&&(e.staticInFor=t),e.static&&e.children.length&&(1!==e.children.length||3!==e.children[0].type))return void(e.staticRoot=!0);if(e.staticRoot=!1,e.children)for(var n=0,r=e.children.length;n<r;n++)Ti(e.children[n],t||!!e.for);if(e.ifConditions)for(var i=1,o=e.ifConditions.length;i<o;i++)Ti(e.ifConditions[i].block,t)}}function Oi(e){return 2!==e.type&&(3===e.type||!(!e.pre&&(e.hasBindings||e.if||e.for||po(e.tag)||!uc(e.tag)||Ei(e)||!Object.keys(e).every(cc))))}function Ei(e){for(;e.parent;){if(e=e.parent,"template"!==e.tag)return!1;if(e.for)return!0}return!1}function Ii(e,t){var n=t?"nativeOn:{":"on:{";for(var r in e)n+='"'+r+'":'+Li(r,e[r])+",";return n.slice(0,-1)+"}"}function Li(e,t){if(!t)return"function(){}";if(Array.isArray(t))return"["+t.map(function(t){return Li(e,t)}).join(",")+"]";var n=Qc.test(t.value),r=Yc.test(t.value);if(t.modifiers){var i="",o="",a=[];for(var s in t.modifiers)if(ru[s])o+=ru[s],eu[s]&&a.push(s);else if("exact"===s){var c=t.modifiers;o+=nu(["ctrl","shift","alt","meta"].filter(function(e){return!c[e]}).map(function(e){return"$event."+e+"Key"}).join("||"))}else a.push(s);return a.length&&(i+=ji(a)),o&&(i+=o),"function($event){"+i+(n?"return "+t.value+"($event)":r?"return ("+t.value+")($event)":t.value)+"}"}return n||r?t.value:"function($event){"+t.value+"}"}function ji(e){return"if(!('button' in $event)&&"+e.map(Pi).join("&&")+")return null;"}function Pi(e){var t=parseInt(e,10);if(t)return"$event.keyCode!=="+t;var n=eu[e],r=tu[e];return"_k($event.keyCode,"+JSON.stringify(e)+","+JSON.stringify(n)+",$event.key,"+JSON.stringify(r)+")"}function Ri(e,t){e.wrapListeners=function(e){return"_g("+e+","+t.value+")"}}function Ni(e,t){e.wrapData=function(n){return"_b("+n+",'"+e.tag+"',"+t.value+","+(t.modifiers&&t.modifiers.prop?"true":"false")+(t.modifiers&&t.modifiers.sync?",true":"")+")"}}function Di(e,t){var n=new ou(t);return{render:"with(this){return "+(e?Ui(e,n):'_c("div")')+"}",staticRenderFns:n.staticRenderFns}}function Ui(e,t){if(e.parent&&(e.pre=e.pre||e.parent.pre),e.staticRoot&&!e.staticProcessed)return Fi(e,t);if(e.once&&!e.onceProcessed)return Mi(e,t);if(e.for&&!e.forProcessed)return zi(e,t);if(e.if&&!e.ifProcessed)return Bi(e,t);if("template"!==e.tag||e.slotTarget||t.pre){if("slot"===e.tag)return no(e,t);var n;if(e.component)n=ro(e.component,e,t);else{var r;(!e.plain||e.pre&&t.maybeComponent(e))&&(r=Vi(e,t));var i=e.inlineTemplate?null:Xi(e,t,!0);n="_c('"+e.tag+"'"+(r?","+r:"")+(i?","+i:"")+")"}for(var o=0;o<t.transforms.length;o++)n=t.transforms[o](e,n);return n}return Xi(e,t)||"void 0"}function Fi(e,t){e.staticProcessed=!0;var n=t.pre;return e.pre&&(t.pre=e.pre),t.staticRenderFns.push("with(this){return "+Ui(e,t)+"}"),t.pre=n,"_m("+(t.staticRenderFns.length-1)+(e.staticInFor?",true":"")+")"}function Mi(e,t){if(e.onceProcessed=!0,e.if&&!e.ifProcessed)return Bi(e,t);if(e.staticInFor){for(var n="",r=e.parent;r;){if(r.for){n=r.key;break}r=r.parent}return n?"_o("+Ui(e,t)+","+t.onceId+++","+n+")":Ui(e,t)}return Fi(e,t)}function Bi(e,t,n,r){return e.ifProcessed=!0,Hi(e.ifConditions.slice(),t,n,r)}function Hi(e,t,n,r){function i(e){return n?n(e,t):e.once?Mi(e,t):Ui(e,t)}if(!e.length)return r||"_e()";var o=e.shift();return o.exp?"("+o.exp+")?"+i(o.block)+":"+Hi(e,t,n,r):""+i(o.block)}function zi(e,t,n,r){var i=e.for,o=e.alias,a=e.iterator1?","+e.iterator1:"",s=e.iterator2?","+e.iterator2:"";return e.forProcessed=!0,(r||"_l")+"(("+i+"),function("+o+a+s+"){return "+(n||Ui)(e,t)+"})"}function Vi(e,t){var n="{",r=qi(e,t);r&&(n+=r+","),e.key&&(n+="key:"+e.key+","),e.ref&&(n+="ref:"+e.ref+","),e.refInFor&&(n+="refInFor:true,"),e.pre&&(n+="pre:true,"),e.component&&(n+='tag:"'+e.tag+'",');for(var i=0;i<t.dataGenFns.length;i++)n+=t.dataGenFns[i](e);if(e.attrs&&(n+="attrs:{"+io(e.attrs)+"},"),e.props&&(n+="domProps:{"+io(e.props)+"},"),e.events&&(n+=Ii(e.events,!1)+","),e.nativeEvents&&(n+=Ii(e.nativeEvents,!0)+","),e.slotTarget&&!e.slotScope&&(n+="slot:"+e.slotTarget+","),e.scopedSlots&&(n+=Wi(e.scopedSlots,t)+","),e.model&&(n+="model:{value:"+e.model.value+",callback:"+e.model.callback+",expression:"+e.model.expression+"},"),e.inlineTemplate){var o=Ki(e,t);o&&(n+=o+",")}return n=n.replace(/,$/,"")+"}",e.wrapData&&(n=e.wrapData(n)),e.wrapListeners&&(n=e.wrapListeners(n)),n}function qi(e,t){var n=e.directives;if(n){var r,i,o,a,s="directives:[",c=!1;for(r=0,i=n.length;r<i;r++){o=n[r],a=!0;var u=t.directives[o.name];u&&(a=!!u(e,o,t.warn)),a&&(c=!0,s+='{name:"'+o.name+'",rawName:"'+o.rawName+'"'+(o.value?",value:("+o.value+"),expression:"+JSON.stringify(o.value):"")+(o.arg?',arg:"'+o.arg+'"':"")+(o.modifiers?",modifiers:"+JSON.stringify(o.modifiers):"")+"},")}return c?s.slice(0,-1)+"]":void 0}}function Ki(e,t){var n=e.children[0];if(1===n.type){var r=Di(n,t.options);return"inlineTemplate:{render:function(){"+r.render+"},staticRenderFns:["+r.staticRenderFns.map(function(e){return"function(){"+e+"}"}).join(",")+"]}"}}function Wi(e,t){return"scopedSlots:_u(["+Object.keys(e).map(function(n){return Ji(n,e[n],t)}).join(",")+"])"}function Ji(e,t,n){return t.for&&!t.forProcessed?Gi(e,t,n):"{key:"+e+",fn:function("+String(t.slotScope)+"){return "+("template"===t.tag?t.if?"("+t.if+")?"+(Xi(t,n)||"undefined")+":undefined":Xi(t,n)||"undefined":Ui(t,n))+"}}"}function Gi(e,t,n){var r=t.for,i=t.alias,o=t.iterator1?","+t.iterator1:"",a=t.iterator2?","+t.iterator2:"";return t.forProcessed=!0,"_l(("+r+"),function("+i+o+a+"){return "+Ji(e,t,n)+"})"}function Xi(e,t,n,r,i){var o=e.children;if(o.length){var a=o[0];if(1===o.length&&a.for&&"template"!==a.tag&&"slot"!==a.tag){var s=n?t.maybeComponent(a)?",1":",0":"";return""+(r||Ui)(a,t)+s}var c=n?Zi(o,t.maybeComponent):0,u=i||Qi;return"["+o.map(function(e){return u(e,t)}).join(",")+"]"+(c?","+c:"")}}function Zi(e,t){for(var n=0,r=0;r<e.length;r++){var i=e[r];if(1===i.type){if(Yi(i)||i.ifConditions&&i.ifConditions.some(function(e){return Yi(e.block)})){n=2;break}(t(i)||i.ifConditions&&i.ifConditions.some(function(e){return t(e.block)}))&&(n=1)}}return n}function Yi(e){return void 0!==e.for||"template"===e.tag||"slot"===e.tag}function Qi(e,t){return 1===e.type?Ui(e,t):3===e.type&&e.isComment?to(e):eo(e)}function eo(e){return"_v("+(2===e.type?e.expression:oo(JSON.stringify(e.text)))+")"}function to(e){return"_e("+JSON.stringify(e.text)+")"}function no(e,t){var n=e.slotName||'"default"',r=Xi(e,t),i="_t("+n+(r?","+r:""),o=e.attrs&&"{"+e.attrs.map(function(e){return yo(e.name)+":"+e.value}).join(",")+"}",a=e.attrsMap["v-bind"];return!o&&!a||r||(i+=",null"),o&&(i+=","+o),a&&(i+=(o?"":",null")+","+a),i+")"}function ro(e,t,n){var r=t.inlineTemplate?null:Xi(t,n,!0);return"_c("+e+","+Vi(t,n)+(r?","+r:"")+")"}function io(e){for(var t="",n=0;n<e.length;n++){var r=e[n];t+='"'+r.name+'":'+oo(r.value)+","}return t.slice(0,-1)}function oo(e){return e.replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029")}function ao(e,t){try{return new Function(e)}catch(n){return t.push({err:n,code:e}),x}}function so(e){var t=Object.create(null);return function(n,r,i){r=w({},r),r.warn,delete r.warn;var o=r.delimiters?String(r.delimiters)+n:n;if(t[o])return t[o];var a=e(n,r),s={},c=[];return s.render=ao(a.render,c),s.staticRenderFns=a.staticRenderFns.map(function(e){return ao(e,c)}),t[o]=s}}function co(e){return lc=lc||document.createElement("div"),lc.innerHTML=e?'<a href="\n"/>':'<div a="\n"/>',lc.innerHTML.indexOf("&#10;")>0}function uo(e){if(e.outerHTML)return e.outerHTML;var t=document.createElement("div");return t.appendChild(e.cloneNode(!0)),t.innerHTML}/*!
2
- * Vue.js v2.5.22
3
- * (c) 2014-2019 Evan You
4
- * Released under the MIT License.
5
- */
6
- var lo=Object.freeze({}),fo=Object.prototype.toString,po=v("slot,component",!0),vo=v("key,ref,slot,slot-scope,is"),ho=Object.prototype.hasOwnProperty,mo=/-(\w)/g,yo=y(function(e){return e.replace(mo,function(e,t){return t?t.toUpperCase():""})}),go=y(function(e){return e.charAt(0).toUpperCase()+e.slice(1)}),_o=/\B([A-Z])/g,bo=y(function(e){return e.replace(_o,"-$1").toLowerCase()}),wo=Function.prototype.bind?_:g,Co=function(e,t,n){return!1},xo=function(e){return e},$o="data-server-rendered",ko=["component","directive","filter"],So=["beforeCreate","created","beforeMount","mounted","beforeUpdate","updated","beforeDestroy","destroyed","activated","deactivated","errorCaptured"],Ao={optionMergeStrategies:Object.create(null),silent:!1,productionTip:!1,devtools:!1,performance:!1,errorHandler:null,warnHandler:null,ignoredElements:[],keyCodes:Object.create(null),isReservedTag:Co,isReservedAttr:Co,isUnknownElement:Co,getTagNamespace:x,parsePlatformTagName:xo,mustUseProp:Co,async:!0,_lifecycleHooks:So},To=/[^\w.$]/,Oo="__proto__"in{},Eo="undefined"!=typeof window,Io="undefined"!=typeof WXEnvironment&&!!WXEnvironment.platform,Lo=Io&&WXEnvironment.platform.toLowerCase(),jo=Eo&&window.navigator.userAgent.toLowerCase(),Po=jo&&/msie|trident/.test(jo),Ro=jo&&jo.indexOf("msie 9.0")>0,No=jo&&jo.indexOf("edge/")>0,Do=(jo&&jo.indexOf("android"),jo&&/iphone|ipad|ipod|ios/.test(jo)||"ios"===Lo),Uo=(jo&&/chrome\/\d+/.test(jo),{}.watch),Fo=!1;if(Eo)try{var Mo={};Object.defineProperty(Mo,"passive",{get:function(){Fo=!0}}),window.addEventListener("test-passive",null,Mo)}catch(e){}var Bo,Ho,zo=function(){return void 0===Bo&&(Bo=!Eo&&!Io&&void 0!==e&&e.process&&"server"===e.process.env.VUE_ENV),Bo},Vo=Eo&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__,qo="undefined"!=typeof Symbol&&E(Symbol)&&"undefined"!=typeof Reflect&&E(Reflect.ownKeys);Ho="undefined"!=typeof Set&&E(Set)?Set:function(){function e(){this.set=Object.create(null)}return e.prototype.has=function(e){return!0===this.set[e]},e.prototype.add=function(e){this.set[e]=!0},e.prototype.clear=function(){this.set=Object.create(null)},e}();var Ko=x,Wo=0,Jo=function(){this.id=Wo++,this.subs=[]};Jo.prototype.addSub=function(e){this.subs.push(e)},Jo.prototype.removeSub=function(e){h(this.subs,e)},Jo.prototype.depend=function(){Jo.target&&Jo.target.addDep(this)},Jo.prototype.notify=function(){for(var e=this.subs.slice(),t=0,n=e.length;t<n;t++)e[t].update()},Jo.target=null;var Go=[],Xo=function(e,t,n,r,i,o,a,s){this.tag=e,this.data=t,this.children=n,this.text=r,this.elm=i,this.ns=void 0,this.context=o,this.fnContext=void 0,this.fnOptions=void 0,this.fnScopeId=void 0,this.key=t&&t.key,this.componentOptions=a,this.componentInstance=void 0,this.parent=void 0,this.raw=!1,this.isStatic=!1,this.isRootInsert=!0,this.isComment=!1,this.isCloned=!1,this.isOnce=!1,this.asyncFactory=s,this.asyncMeta=void 0,this.isAsyncPlaceholder=!1},Zo={child:{configurable:!0}};Zo.child.get=function(){return this.componentInstance},Object.defineProperties(Xo.prototype,Zo);var Yo=function(e){void 0===e&&(e="");var t=new Xo;return t.text=e,t.isComment=!0,t},Qo=Array.prototype,ea=Object.create(Qo);["push","pop","shift","unshift","splice","sort","reverse"].forEach(function(e){var t=Qo[e];T(ea,e,function(){for(var n=[],r=arguments.length;r--;)n[r]=arguments[r];var i,o=t.apply(this,n),a=this.__ob__;switch(e){case"push":case"unshift":i=n;break;case"splice":i=n.slice(2)}return i&&a.observeArray(i),a.dep.notify(),o})});var ta=Object.getOwnPropertyNames(ea),na=!0,ra=function(e){this.value=e,this.dep=new Jo,this.vmCount=0,T(e,"__ob__",this),Array.isArray(e)?(Oo?N(e,ea):D(e,ea,ta),this.observeArray(e)):this.walk(e)};ra.prototype.walk=function(e){for(var t=Object.keys(e),n=0;n<t.length;n++)F(e,t[n])},ra.prototype.observeArray=function(e){for(var t=0,n=e.length;t<n;t++)U(e[t])};var ia=Ao.optionMergeStrategies;ia.data=function(e,t,n){return n?V(e,t,n):t&&"function"!=typeof t?e:V(e,t)},So.forEach(function(e){ia[e]=q}),ko.forEach(function(e){ia[e+"s"]=W}),ia.watch=function(e,t,n,r){if(e===Uo&&(e=void 0),t===Uo&&(t=void 0),!t)return Object.create(e||null);if(!e)return t;var i={};w(i,e);for(var o in t){var a=i[o],s=t[o];a&&!Array.isArray(a)&&(a=[a]),i[o]=a?a.concat(s):Array.isArray(s)?s:[s]}return i},ia.props=ia.methods=ia.inject=ia.computed=function(e,t,n,r){if(!e)return t;var i=Object.create(null);return w(i,e),t&&w(i,t),i},ia.provide=V;var oa,aa,sa=function(e,t){return void 0===t?e:t},ca=[],ua=!1,la=!1;if(void 0!==n&&E(n))aa=function(){n(se)};else if("undefined"==typeof MessageChannel||!E(MessageChannel)&&"[object MessageChannelConstructor]"!==MessageChannel.toString())aa=function(){setTimeout(se,0)};else{var fa=new MessageChannel,da=fa.port2;fa.port1.onmessage=se,aa=function(){da.postMessage(1)}}if("undefined"!=typeof Promise&&E(Promise)){var pa=Promise.resolve();oa=function(){pa.then(se),Do&&setTimeout(x)}}else oa=aa;var va,ha=new Ho,ma=y(function(e){var t="&"===e.charAt(0);e=t?e.slice(1):e;var n="~"===e.charAt(0);e=n?e.slice(1):e;var r="!"===e.charAt(0);return e=r?e.slice(1):e,{name:e,once:n,capture:r,passive:t}}),ya=null,ga=[],_a=[],ba={},wa=!1,Ca=!1,xa=0,$a=0,ka=function(e,t,n,r,i){this.vm=e,i&&(e._watcher=this),e._watchers.push(this),r?(this.deep=!!r.deep,this.user=!!r.user,this.lazy=!!r.lazy,this.sync=!!r.sync,this.before=r.before):this.deep=this.user=this.lazy=this.sync=!1,this.cb=n,this.id=++$a,this.active=!0,this.dirty=this.lazy,this.deps=[],this.newDeps=[],this.depIds=new Ho,this.newDepIds=new Ho,this.expression="","function"==typeof t?this.getter=t:(this.getter=O(t),this.getter||(this.getter=x)),this.value=this.lazy?void 0:this.get()};ka.prototype.get=function(){I(this);var e,t=this.vm;try{e=this.getter.call(t,t)}catch(e){if(!this.user)throw e;ie(e,t,'getter for watcher "'+this.expression+'"')}finally{this.deep&&le(e),L(),this.cleanupDeps()}return e},ka.prototype.addDep=function(e){var t=e.id;this.newDepIds.has(t)||(this.newDepIds.add(t),this.newDeps.push(e),this.depIds.has(t)||e.addSub(this))},ka.prototype.cleanupDeps=function(){for(var e=this.deps.length;e--;){var t=this.deps[e];this.newDepIds.has(t.id)||t.removeSub(this)}var n=this.depIds;this.depIds=this.newDepIds,this.newDepIds=n,this.newDepIds.clear(),n=this.deps,this.deps=this.newDeps,this.newDeps=n,this.newDeps.length=0},ka.prototype.update=function(){this.lazy?this.dirty=!0:this.sync?this.run():We(this)},ka.prototype.run=function(){if(this.active){var e=this.get();if(e!==this.value||c(e)||this.deep){var t=this.value;if(this.value=e,this.user)try{this.cb.call(this.vm,e,t)}catch(e){ie(e,this.vm,'callback for watcher "'+this.expression+'"')}else this.cb.call(this.vm,e,t)}}},ka.prototype.evaluate=function(){this.value=this.get(),this.dirty=!1},ka.prototype.depend=function(){for(var e=this.deps.length;e--;)this.deps[e].depend()},ka.prototype.teardown=function(){if(this.active){this.vm._isBeingDestroyed||h(this.vm._watchers,this);for(var e=this.deps.length;e--;)this.deps[e].removeSub(this);this.active=!1}};var Sa={enumerable:!0,configurable:!0,get:x,set:x},Aa={lazy:!0};bt(wt.prototype);var Ta={init:function(e,t){if(e.componentInstance&&!e.componentInstance._isDestroyed&&e.data.keepAlive){var n=e;Ta.prepatch(n,n)}else(e.componentInstance=St(e,ya)).$mount(t?e.elm:void 0,t)},prepatch:function(e,t){var n=t.componentOptions;De(t.componentInstance=e.componentInstance,n.propsData,n.listeners,t,n.children)},insert:function(e){var t=e.context,n=e.componentInstance;n._isMounted||(n._isMounted=!0,Be(n,"mounted")),e.data.keepAlive&&(t._isMounted?qe(n):Fe(n,!0))},destroy:function(e){var t=e.componentInstance;t._isDestroyed||(e.data.keepAlive?Me(t,!0):t.$destroy())}},Oa=Object.keys(Ta),Ea=1,Ia=2,La=0;!function(e){e.prototype._init=function(e){var t=this;t._uid=La++,t._isVue=!0,e&&e._isComponent?Rt(t,e):t.$options=Z(Nt(t.constructor),e||{},t),t._renderProxy=t,t._self=t,Re(t),Se(t),Pt(t),Be(t,"beforeCreate"),st(t),Ge(t),at(t),Be(t,"created"),t.$options.el&&t.$mount(t.$options.el)}}(Ut),function(e){var t={};t.get=function(){return this._data};var n={};n.get=function(){return this._props},Object.defineProperty(e.prototype,"$data",t),Object.defineProperty(e.prototype,"$props",n),e.prototype.$set=M,e.prototype.$delete=B,e.prototype.$watch=function(e,t,n){var r=this;if(u(t))return ot(r,e,t,n);n=n||{},n.user=!0;var i=new ka(r,e,t,n);if(n.immediate)try{t.call(r,i.value)}catch(e){ie(e,r,'callback for immediate watcher "'+i.expression+'"')}return function(){i.teardown()}}}(Ut),function(e){var t=/^hook:/;e.prototype.$on=function(e,n){var r=this;if(Array.isArray(e))for(var i=0,o=e.length;i<o;i++)r.$on(e[i],n);else(r._events[e]||(r._events[e]=[])).push(n),t.test(e)&&(r._hasHookEvent=!0);return r},e.prototype.$once=function(e,t){function n(){r.$off(e,n),t.apply(r,arguments)}var r=this;return n.fn=t,r.$on(e,n),r},e.prototype.$off=function(e,t){var n=this;if(!arguments.length)return n._events=Object.create(null),n;if(Array.isArray(e)){for(var r=0,i=e.length;r<i;r++)n.$off(e[r],t);return n}var o=n._events[e];if(!o)return n;if(!t)return n._events[e]=null,n;for(var a,s=o.length;s--;)if((a=o[s])===t||a.fn===t){o.splice(s,1);break}return n},e.prototype.$emit=function(e){var t=this,n=t._events[e];if(n){n=n.length>1?b(n):n;for(var r=b(arguments,1),i=0,o=n.length;i<o;i++)try{n[i].apply(t,r)}catch(n){ie(n,t,'event handler for "'+e+'"')}}return t}}(Ut),function(e){e.prototype._update=function(e,t){var n=this,r=n.$el,i=n._vnode,o=Pe(n);n._vnode=e,n.$el=i?n.__patch__(i,e):n.__patch__(n.$el,e,t,!1),o(),r&&(r.__vue__=null),n.$el&&(n.$el.__vue__=n),n.$vnode&&n.$parent&&n.$vnode===n.$parent._vnode&&(n.$parent.$el=n.$el)},e.prototype.$forceUpdate=function(){var e=this;e._watcher&&e._watcher.update()},e.prototype.$destroy=function(){var e=this;if(!e._isBeingDestroyed){Be(e,"beforeDestroy"),e._isBeingDestroyed=!0;var t=e.$parent;!t||t._isBeingDestroyed||e.$options.abstract||h(t.$children,e),e._watcher&&e._watcher.teardown();for(var n=e._watchers.length;n--;)e._watchers[n].teardown();e._data.__ob__&&e._data.__ob__.vmCount--,e._isDestroyed=!0,e.__patch__(e._vnode,null),Be(e,"destroyed"),e.$off(),e.$el&&(e.$el.__vue__=null),e.$vnode&&(e.$vnode.parent=null)}}}(Ut),function(e){bt(e.prototype),e.prototype.$nextTick=function(e){return ue(e,this)},e.prototype._render=function(){var e=this,t=e.$options,n=t.render,r=t._parentVnode;r&&(e.$scopedSlots=r.data.scopedSlots||lo),e.$vnode=r;var i;try{i=n.call(e._renderProxy,e.$createElement)}catch(t){ie(t,e,"render"),i=e._vnode}return i instanceof Xo||(i=Yo()),i.parent=r,i}}(Ut);var ja=[String,RegExp,Array],Pa={name:"keep-alive",abstract:!0,props:{include:ja,exclude:ja,max:[String,Number]},created:function(){this.cache=Object.create(null),this.keys=[]},destroyed:function(){for(var e in this.cache)Jt(this.cache,e,this.keys)},mounted:function(){var e=this;this.$watch("include",function(t){Wt(e,function(e){return Kt(t,e)})}),this.$watch("exclude",function(t){Wt(e,function(e){return!Kt(t,e)})})},render:function(){var e=this.$slots.default,t=ke(e),n=t&&t.componentOptions;if(n){var r=qt(n),i=this,o=i.include,a=i.exclude;if(o&&(!r||!Kt(o,r))||a&&r&&Kt(a,r))return t;var s=this,c=s.cache,u=s.keys,l=null==t.key?n.Ctor.cid+(n.tag?"::"+n.tag:""):t.key;c[l]?(t.componentInstance=c[l].componentInstance,h(u,l),u.push(l)):(c[l]=t,u.push(l),this.max&&u.length>parseInt(this.max)&&Jt(c,u[0],u,this._vnode)),t.data.keepAlive=!0}return t||e&&e[0]}},Ra={KeepAlive:Pa};!function(e){var t={};t.get=function(){return Ao},Object.defineProperty(e,"config",t),e.util={warn:Ko,extend:w,mergeOptions:Z,defineReactive:F},e.set=M,e.delete=B,e.nextTick=ue,e.options=Object.create(null),ko.forEach(function(t){e.options[t+"s"]=Object.create(null)}),e.options._base=e,w(e.options.components,Ra),Ft(e),Mt(e),Bt(e),Vt(e)}(Ut),Object.defineProperty(Ut.prototype,"$isServer",{get:zo}),Object.defineProperty(Ut.prototype,"$ssrContext",{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Object.defineProperty(Ut,"FunctionalRenderContext",{value:wt}),Ut.version="2.5.22";var Na,Da,Ua,Fa,Ma,Ba,Ha,za,Va,qa=v("style,class"),Ka=v("input,textarea,option,select,progress"),Wa=function(e,t,n){return"value"===n&&Ka(e)&&"button"!==t||"selected"===n&&"option"===e||"checked"===n&&"input"===e||"muted"===n&&"video"===e},Ja=v("contenteditable,draggable,spellcheck"),Ga=v("allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,defaultchecked,defaultmuted,defaultselected,defer,disabled,enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,translate,truespeed,typemustmatch,visible"),Xa="http://www.w3.org/1999/xlink",Za=function(e){return":"===e.charAt(5)&&"xlink"===e.slice(0,5)},Ya=function(e){return Za(e)?e.slice(6,e.length):""},Qa=function(e){return null==e||!1===e},es={svg:"http://www.w3.org/2000/svg",math:"http://www.w3.org/1998/Math/MathML"},ts=v("html,body,base,head,link,meta,style,title,address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,s,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,output,progress,select,textarea,details,dialog,menu,menuitem,summary,content,element,shadow,template,blockquote,iframe,tfoot"),ns=v("svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,font-face,foreignObject,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view",!0),rs=function(e){return"pre"===e},is=function(e){return ts(e)||ns(e)},os=Object.create(null),as=v("text,number,password,search,email,tel,url"),ss=Object.freeze({createElement:an,createElementNS:sn,createTextNode:cn,createComment:un,insertBefore:ln,removeChild:fn,appendChild:dn,parentNode:pn,nextSibling:vn,tagName:hn,setTextContent:mn,setStyleScope:yn}),cs={create:function(e,t){gn(t)},update:function(e,t){e.data.ref!==t.data.ref&&(gn(e,!0),gn(t))},destroy:function(e){gn(e,!0)}},us=new Xo("",{},[]),ls=["create","activate","update","remove","destroy"],fs={create:Cn,update:Cn,destroy:function(e){Cn(e,us)}},ds=Object.create(null),ps=[cs,fs],vs={create:An,update:An},hs={create:En,update:En},ms=/[\w).+\-_$\]]/,ys="__r",gs="__c",_s={create:or,update:or},bs={create:ar,update:ar},ws=y(function(e){var t={},n=/;(?![^(]*\))/g,r=/:(.+)/;return e.split(n).forEach(function(e){if(e){var n=e.split(r);n.length>1&&(t[n[0].trim()]=n[1].trim())}}),t}),Cs=/^--/,xs=/\s*!important$/,$s=function(e,t,n){if(Cs.test(t))e.style.setProperty(t,n);else if(xs.test(n))e.style.setProperty(t,n.replace(xs,""),"important");else{var r=Ss(t);if(Array.isArray(n))for(var i=0,o=n.length;i<o;i++)e.style[r]=n[i];else e.style[r]=n}},ks=["Webkit","Moz","ms"],Ss=y(function(e){if(Va=Va||document.createElement("div").style,"filter"!==(e=yo(e))&&e in Va)return e;for(var t=e.charAt(0).toUpperCase()+e.slice(1),n=0;n<ks.length;n++){var r=ks[n]+t;if(r in Va)return r}}),As={create:pr,update:pr},Ts=/\s+/,Os=y(function(e){return{enterClass:e+"-enter",enterToClass:e+"-enter-to",enterActiveClass:e+"-enter-active",leaveClass:e+"-leave",leaveToClass:e+"-leave-to",leaveActiveClass:e+"-leave-active"}}),Es=Eo&&!Ro,Is="transition",Ls="animation",js="transition",Ps="transitionend",Rs="animation",Ns="animationend";Es&&(void 0===window.ontransitionend&&void 0!==window.onwebkittransitionend&&(js="WebkitTransition",Ps="webkitTransitionEnd"),void 0===window.onanimationend&&void 0!==window.onwebkitanimationend&&(Rs="WebkitAnimation",Ns="webkitAnimationEnd"));var Ds=Eo?window.requestAnimationFrame?window.requestAnimationFrame.bind(window):setTimeout:function(e){return e()},Us=/\b(transform|all)(,|$)/,Fs=Eo?{create:Tr,activate:Tr,remove:function(e,t){!0!==e.data.show?kr(e,t):t()}}:{},Ms=[vs,hs,_s,bs,As,Fs],Bs=Ms.concat(ps),Hs=function(e){function t(e){return new Xo(I.tagName(e).toLowerCase(),{},[],void 0,e)}function n(e,t){function n(){0==--n.listeners&&a(e)}return n.listeners=t,n}function a(e){var t=I.parentNode(e);i(t)&&I.removeChild(t,e)}function c(e,t,n,r,a,s,c){if(i(e.elm)&&i(s)&&(e=s[c]=P(e)),e.isRootInsert=!a,!u(e,t,n,r)){var l=e.data,f=e.children,v=e.tag;i(v)?(e.elm=e.ns?I.createElementNS(e.ns,v):I.createElement(v,e),y(e),p(e,f,t),i(l)&&m(e,t),d(n,e.elm,r)):o(e.isComment)?(e.elm=I.createComment(e.text),d(n,e.elm,r)):(e.elm=I.createTextNode(e.text),d(n,e.elm,r))}}function u(e,t,n,r){var a=e.data;if(i(a)){var s=i(e.componentInstance)&&a.keepAlive;if(i(a=a.hook)&&i(a=a.init)&&a(e,!1),i(e.componentInstance))return l(e,t),d(n,e.elm,r),o(s)&&f(e,t,n,r),!0}}function l(e,t){i(e.data.pendingInsert)&&(t.push.apply(t,e.data.pendingInsert),e.data.pendingInsert=null),e.elm=e.componentInstance.$el,h(e)?(m(e,t),y(e)):(gn(e),t.push(e))}function f(e,t,n,r){for(var o,a=e;a.componentInstance;)if(a=a.componentInstance._vnode,i(o=a.data)&&i(o=o.transition)){for(o=0;o<O.activate.length;++o)O.activate[o](us,a);t.push(a);break}d(n,e.elm,r)}function d(e,t,n){i(e)&&(i(n)?I.parentNode(n)===e&&I.insertBefore(e,t,n):I.appendChild(e,t))}function p(e,t,n){if(Array.isArray(t))for(var r=0;r<t.length;++r)c(t[r],n,e.elm,null,!0,t,r);else s(e.text)&&I.appendChild(e.elm,I.createTextNode(String(e.text)))}function h(e){for(;e.componentInstance;)e=e.componentInstance._vnode;return i(e.tag)}function m(e,t){for(var n=0;n<O.create.length;++n)O.create[n](us,e);A=e.data.hook,i(A)&&(i(A.create)&&A.create(us,e),i(A.insert)&&t.push(e))}function y(e){var t;if(i(t=e.fnScopeId))I.setStyleScope(e.elm,t);else for(var n=e;n;)i(t=n.context)&&i(t=t.$options._scopeId)&&I.setStyleScope(e.elm,t),n=n.parent;i(t=ya)&&t!==e.context&&t!==e.fnContext&&i(t=t.$options._scopeId)&&I.setStyleScope(e.elm,t)}function g(e,t,n,r,i,o){for(;r<=i;++r)c(n[r],o,e,t,!1,n,r)}function _(e){var t,n,r=e.data;if(i(r))for(i(t=r.hook)&&i(t=t.destroy)&&t(e),t=0;t<O.destroy.length;++t)O.destroy[t](e);if(i(t=e.children))for(n=0;n<e.children.length;++n)_(e.children[n])}function b(e,t,n,r){for(;n<=r;++n){var o=t[n];i(o)&&(i(o.tag)?(w(o),_(o)):a(o.elm))}}function w(e,t){if(i(t)||i(e.data)){var r,o=O.remove.length+1;for(i(t)?t.listeners+=o:t=n(e.elm,o),i(r=e.componentInstance)&&i(r=r._vnode)&&i(r.data)&&w(r,t),r=0;r<O.remove.length;++r)O.remove[r](e,t);i(r=e.data.hook)&&i(r=r.remove)?r(e,t):t()}else a(e.elm)}function C(e,t,n,o,a){for(var s,u,l,f,d=0,p=0,v=t.length-1,h=t[0],m=t[v],y=n.length-1,_=n[0],w=n[y],C=!a;d<=v&&p<=y;)r(h)?h=t[++d]:r(m)?m=t[--v]:_n(h,_)?($(h,_,o,n,p),h=t[++d],_=n[++p]):_n(m,w)?($(m,w,o,n,y),m=t[--v],w=n[--y]):_n(h,w)?($(h,w,o,n,y),C&&I.insertBefore(e,h.elm,I.nextSibling(m.elm)),h=t[++d],w=n[--y]):_n(m,_)?($(m,_,o,n,p),C&&I.insertBefore(e,m.elm,h.elm),m=t[--v],_=n[++p]):(r(s)&&(s=wn(t,d,v)),u=i(_.key)?s[_.key]:x(_,t,d,v),r(u)?c(_,o,e,h.elm,!1,n,p):(l=t[u],_n(l,_)?($(l,_,o,n,p),t[u]=void 0,C&&I.insertBefore(e,l.elm,h.elm)):c(_,o,e,h.elm,!1,n,p)),_=n[++p]);d>v?(f=r(n[y+1])?null:n[y+1].elm,g(e,f,n,p,y,o)):p>y&&b(e,t,d,v)}function x(e,t,n,r){for(var o=n;o<r;o++){var a=t[o];if(i(a)&&_n(e,a))return o}}function $(e,t,n,a,s,c){if(e!==t){i(t.elm)&&i(a)&&(t=a[s]=P(t));var u=t.elm=e.elm;if(o(e.isAsyncPlaceholder))return void(i(t.asyncFactory.resolved)?S(e.elm,t,n):t.isAsyncPlaceholder=!0);if(o(t.isStatic)&&o(e.isStatic)&&t.key===e.key&&(o(t.isCloned)||o(t.isOnce)))return void(t.componentInstance=e.componentInstance);var l,f=t.data;i(f)&&i(l=f.hook)&&i(l=l.prepatch)&&l(e,t);var d=e.children,p=t.children;if(i(f)&&h(t)){for(l=0;l<O.update.length;++l)O.update[l](e,t);i(l=f.hook)&&i(l=l.update)&&l(e,t)}r(t.text)?i(d)&&i(p)?d!==p&&C(u,d,p,n,c):i(p)?(i(e.text)&&I.setTextContent(u,""),g(u,null,p,0,p.length-1,n)):i(d)?b(u,d,0,d.length-1):i(e.text)&&I.setTextContent(u,""):e.text!==t.text&&I.setTextContent(u,t.text),i(f)&&i(l=f.hook)&&i(l=l.postpatch)&&l(e,t)}}function k(e,t,n){if(o(n)&&i(e.parent))e.parent.data.pendingInsert=t;else for(var r=0;r<t.length;++r)t[r].data.hook.insert(t[r])}function S(e,t,n,r){var a,s=t.tag,c=t.data,u=t.children;if(r=r||c&&c.pre,t.elm=e,o(t.isComment)&&i(t.asyncFactory))return t.isAsyncPlaceholder=!0,!0;if(i(c)&&(i(a=c.hook)&&i(a=a.init)&&a(t,!0),i(a=t.componentInstance)))return l(t,n),!0;if(i(s)){if(i(u))if(e.hasChildNodes())if(i(a=c)&&i(a=a.domProps)&&i(a=a.innerHTML)){if(a!==e.innerHTML)return!1}else{for(var f=!0,d=e.firstChild,v=0;v<u.length;v++){if(!d||!S(d,u[v],n,r)){f=!1;break}d=d.nextSibling}if(!f||d)return!1}else p(t,u,n);if(i(c)){var h=!1;for(var y in c)if(!L(y)){h=!0,m(t,n);break}!h&&c.class&&le(c.class)}}else e.data!==t.text&&(e.data=t.text);return!0}var A,T,O={},E=e.modules,I=e.nodeOps;for(A=0;A<ls.length;++A)for(O[ls[A]]=[],T=0;T<E.length;++T)i(E[T][ls[A]])&&O[ls[A]].push(E[T][ls[A]]);var L=v("attrs,class,staticClass,staticStyle,key");return function(e,n,a,s){if(r(n))return void(i(e)&&_(e));var u=!1,l=[];if(r(e))u=!0,c(n,l);else{var f=i(e.nodeType);if(!f&&_n(e,n))$(e,n,l,null,null,s);else{if(f){if(1===e.nodeType&&e.hasAttribute($o)&&(e.removeAttribute($o),a=!0),o(a)&&S(e,n,l))return k(n,l,!0),e;e=t(e)}var d=e.elm,p=I.parentNode(d);if(c(n,l,d._leaveCb?null:p,I.nextSibling(d)),i(n.parent))for(var v=n.parent,m=h(n);v;){for(var y=0;y<O.destroy.length;++y)O.destroy[y](v);if(v.elm=n.elm,m){for(var g=0;g<O.create.length;++g)O.create[g](us,v);var w=v.data.hook.insert;if(w.merged)for(var C=1;C<w.fns.length;C++)w.fns[C]()}else gn(v);v=v.parent}i(p)?b(p,[e],0,0):i(e.tag)&&_(e)}}return k(n,l,u),n.elm}}({nodeOps:ss,modules:Bs});Ro&&document.addEventListener("selectionchange",function(){var e=document.activeElement;e&&e.vmodel&&Rr(e,"input")});var zs={inserted:function(e,t,n,r){"select"===n.tag?(r.elm&&!r.elm._vOptions?ve(n,"postpatch",function(){zs.componentUpdated(e,t,n)}):Or(e,t,n.context),e._vOptions=[].map.call(e.options,Lr)):("textarea"===n.tag||as(e.type))&&(e._vModifiers=t.modifiers,t.modifiers.lazy||(e.addEventListener("compositionstart",jr),e.addEventListener("compositionend",Pr),e.addEventListener("change",Pr),Ro&&(e.vmodel=!0)))},componentUpdated:function(e,t,n){if("select"===n.tag){Or(e,t,n.context);var r=e._vOptions,i=e._vOptions=[].map.call(e.options,Lr);i.some(function(e,t){return!$(e,r[t])})&&(e.multiple?t.value.some(function(e){return Ir(e,i)}):t.value!==t.oldValue&&Ir(t.value,i))&&Rr(e,"change")}}},Vs={bind:function(e,t,n){var r=t.value;n=Nr(n);var i=n.data&&n.data.transition,o=e.__vOriginalDisplay="none"===e.style.display?"":e.style.display;r&&i?(n.data.show=!0,$r(n,function(){e.style.display=o})):e.style.display=r?o:"none"},update:function(e,t,n){var r=t.value;!r!=!t.oldValue&&(n=Nr(n),n.data&&n.data.transition?(n.data.show=!0,r?$r(n,function(){e.style.display=e.__vOriginalDisplay}):kr(n,function(){e.style.display="none"})):e.style.display=r?e.__vOriginalDisplay:"none")},unbind:function(e,t,n,r,i){i||(e.style.display=e.__vOriginalDisplay)}},qs={model:zs,show:Vs},Ks={name:String,appear:Boolean,css:Boolean,mode:String,type:String,enterClass:String,leaveClass:String,enterToClass:String,leaveToClass:String,enterActiveClass:String,leaveActiveClass:String,appearClass:String,appearActiveClass:String,appearToClass:String,duration:[Number,String,Object]},Ws=function(e){return e.tag||$e(e)},Js=function(e){return"show"===e.name},Gs={name:"transition",props:Ks,abstract:!0,render:function(e){var t=this,n=this.$slots.default;if(n&&(n=n.filter(Ws),n.length)){var r=this.mode,i=n[0];if(Mr(this.$vnode))return i;var o=Dr(i);if(!o)return i;if(this._leaving)return Fr(e,i);var a="__transition-"+this._uid+"-";o.key=null==o.key?o.isComment?a+"comment":a+o.tag:s(o.key)?0===String(o.key).indexOf(a)?o.key:a+o.key:o.key;var c=(o.data||(o.data={})).transition=Ur(this),u=this._vnode,l=Dr(u);if(o.data.directives&&o.data.directives.some(Js)&&(o.data.show=!0),l&&l.data&&!Br(o,l)&&!$e(l)&&(!l.componentInstance||!l.componentInstance._vnode.isComment)){var f=l.data.transition=w({},c);if("out-in"===r)return this._leaving=!0,ve(f,"afterLeave",function(){t._leaving=!1,t.$forceUpdate()}),Fr(e,i);if("in-out"===r){if($e(o))return u;var d,p=function(){d()};ve(c,"afterEnter",p),ve(c,"enterCancelled",p),ve(f,"delayLeave",function(e){d=e})}}return i}}},Xs=w({tag:String,moveClass:String},Ks);delete Xs.mode;var Zs={props:Xs,beforeMount:function(){var e=this,t=this._update;this._update=function(n,r){var i=Pe(e);e.__patch__(e._vnode,e.kept,!1,!0),e._vnode=e.kept,i(),t.call(e,n,r)}},render:function(e){for(var t=this.tag||this.$vnode.data.tag||"span",n=Object.create(null),r=this.prevChildren=this.children,i=this.$slots.default||[],o=this.children=[],a=Ur(this),s=0;s<i.length;s++){var c=i[s];c.tag&&null!=c.key&&0!==String(c.key).indexOf("__vlist")&&(o.push(c),n[c.key]=c,(c.data||(c.data={})).transition=a)}if(r){for(var u=[],l=[],f=0;f<r.length;f++){var d=r[f];d.data.transition=a,d.data.pos=d.elm.getBoundingClientRect(),n[d.key]?u.push(d):l.push(d)}this.kept=e(t,null,u),this.removed=l}return e(t,null,o)},updated:function(){var e=this.prevChildren,t=this.moveClass||(this.name||"v")+"-move";e.length&&this.hasMove(e[0].elm,t)&&(e.forEach(Hr),e.forEach(zr),e.forEach(Vr),this._reflow=document.body.offsetHeight,e.forEach(function(e){if(e.data.moved){var n=e.elm,r=n.style;gr(n,t),r.transform=r.WebkitTransform=r.transitionDuration="",n.addEventListener(Ps,n._moveCb=function e(r){r&&r.target!==n||r&&!/transform$/.test(r.propertyName)||(n.removeEventListener(Ps,e),n._moveCb=null,_r(n,t))})}}))},methods:{hasMove:function(e,t){if(!Es)return!1;if(this._hasMove)return this._hasMove;var n=e.cloneNode();e._transitionClasses&&e._transitionClasses.forEach(function(e){hr(n,e)}),vr(n,t),n.style.display="none",this.$el.appendChild(n);var r=wr(n);return this.$el.removeChild(n),this._hasMove=r.hasTransform}}},Ys={Transition:Gs,TransitionGroup:Zs};Ut.config.mustUseProp=Wa,Ut.config.isReservedTag=is,Ut.config.isReservedAttr=qa,Ut.config.getTagNamespace=nn,Ut.config.isUnknownElement=rn,w(Ut.options.directives,qs),w(Ut.options.components,Ys),Ut.prototype.__patch__=Eo?Hs:x,Ut.prototype.$mount=function(e,t){return e=e&&Eo?on(e):void 0,Ne(this,e,t)},Eo&&setTimeout(function(){Ao.devtools&&Vo&&Vo.emit("init",Ut)},0);var Qs,ec,tc,nc,rc,ic,oc,ac,sc,cc,uc,lc,fc=/\{\{((?:.|\r?\n)+?)\}\}/g,dc=/[-.*+?^${}()|[\]\/\\]/g,pc=y(function(e){var t=e[0].replace(dc,"\\$&"),n=e[1].replace(dc,"\\$&");return new RegExp(t+"((?:.|\\n)+?)"+n,"g")}),vc={staticKeys:["staticClass"],transformNode:Kr,genData:Wr},hc={staticKeys:["staticStyle"],transformNode:Jr,genData:Gr},mc={decode:function(e){return Qs=Qs||document.createElement("div"),Qs.innerHTML=e,Qs.textContent}},yc=v("area,base,br,col,embed,frame,hr,img,input,isindex,keygen,link,meta,param,source,track,wbr"),gc=v("colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr,source"),_c=v("address,article,aside,base,blockquote,body,caption,col,colgroup,dd,details,dialog,div,dl,dt,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,legend,li,menuitem,meta,optgroup,option,param,rp,rt,source,style,summary,tbody,td,tfoot,th,thead,title,tr,track"),bc=/^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/,wc="[a-zA-Z_][\\w\\-\\.]*",Cc="((?:"+wc+"\\:)?"+wc+")",xc=new RegExp("^<"+Cc),$c=/^\s*(\/?)>/,kc=new RegExp("^<\\/"+Cc+"[^>]*>"),Sc=/^<!DOCTYPE [^>]+>/i,Ac=/^<!\--/,Tc=/^<!\[/,Oc=v("script,style,textarea",!0),Ec={},Ic={"&lt;":"<","&gt;":">","&quot;":'"',"&amp;":"&","&#10;":"\n","&#9;":"\t"},Lc=/&(?:lt|gt|quot|amp);/g,jc=/&(?:lt|gt|quot|amp|#10|#9);/g,Pc=v("pre,textarea",!0),Rc=function(e,t){return e&&Pc(e)&&"\n"===t[0]},Nc=/^@|^v-on:/,Dc=/^v-|^@|^:/,Uc=/([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/,Fc=/,([^,\}\]]*)(?:,([^,\}\]]*))?$/,Mc=/^\(|\)$/g,Bc=/:(.*)$/,Hc=/^:|^v-bind:/,zc=/\.[^.]+/g,Vc=y(mc.decode),qc=/^xmlns:NS\d+/,Kc=/^NS\d+:/,Wc={preTransformNode:wi},Jc=[vc,hc,Wc],Gc={model:Xn,text:xi,html:$i},Xc={expectHTML:!0,modules:Jc,directives:Gc,isPreTag:rs,isUnaryTag:yc,mustUseProp:Wa,canBeLeftOpenTag:gc,isReservedTag:is,getTagNamespace:nn,staticKeys:function(e){return e.reduce(function(e,t){return e.concat(t.staticKeys||[])},[]).join(",")}(Jc)},Zc=y(Si),Yc=/^([\w$_]+|\([^)]*?\))\s*=>|^function\s*\(/,Qc=/^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/,eu={esc:27,tab:9,enter:13,space:32,up:38,left:37,right:39,down:40,delete:[8,46]},tu={esc:["Esc","Escape"],tab:"Tab",enter:"Enter",space:[" ","Spacebar"],up:["Up","ArrowUp"],left:["Left","ArrowLeft"],right:["Right","ArrowRight"],down:["Down","ArrowDown"],delete:["Backspace","Delete","Del"]},nu=function(e){return"if("+e+")return null;"},ru={stop:"$event.stopPropagation();",prevent:"$event.preventDefault();",self:nu("$event.target !== $event.currentTarget"),ctrl:nu("!$event.ctrlKey"),shift:nu("!$event.shiftKey"),alt:nu("!$event.altKey"),meta:nu("!$event.metaKey"),left:nu("'button' in $event && $event.button !== 0"),middle:nu("'button' in $event && $event.button !== 1"),right:nu("'button' in $event && $event.button !== 2")},iu={on:Ri,bind:Ni,cloak:x},ou=function(e){this.options=e,this.warn=e.warn||jn,this.transforms=Pn(e.modules,"transformCode"),this.dataGenFns=Pn(e.modules,"genData"),this.directives=w(w({},iu),e.directives);var t=e.isReservedTag||Co;this.maybeComponent=function(e){return!(t(e.tag)&&!e.component)},this.onceId=0,this.staticRenderFns=[],this.pre=!1},au=(new RegExp("\\b"+"do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,super,throw,while,yield,delete,export,import,return,switch,default,extends,finally,continue,debugger,function,arguments".split(",").join("\\b|\\b")+"\\b"),new RegExp("\\b"+"delete,typeof,void".split(",").join("\\s*\\([^\\)]*\\)|\\b")+"\\s*\\([^\\)]*\\)"),function(e){return function(t){function n(n,r){var i=Object.create(t),o=[],a=[];if(i.warn=function(e,t){(t?a:o).push(e)},r){r.modules&&(i.modules=(t.modules||[]).concat(r.modules)),r.directives&&(i.directives=w(Object.create(t.directives||null),r.directives));for(var s in r)"modules"!==s&&"directives"!==s&&(i[s]=r[s])}var c=e(n,i);return c.errors=o,c.tips=a,c}return{compile:n,compileToFunctions:so(n)}}}(function(e,t){var n=Qr(e.trim(),t);!1!==t.optimize&&ki(n,t);var r=Di(n,t);return{ast:n,render:r.render,staticRenderFns:r.staticRenderFns}})),su=au(Xc),cu=(su.compile,su.compileToFunctions),uu=!!Eo&&co(!1),lu=!!Eo&&co(!0),fu=y(function(e){var t=on(e);return t&&t.innerHTML}),du=Ut.prototype.$mount;Ut.prototype.$mount=function(e,t){if((e=e&&on(e))===document.body||e===document.documentElement)return this;var n=this.$options;if(!n.render){var r=n.template;if(r)if("string"==typeof r)"#"===r.charAt(0)&&(r=fu(r));else{if(!r.nodeType)return this;r=r.innerHTML}else e&&(r=uo(e));if(r){var i=cu(r,{shouldDecodeNewlines:uu,shouldDecodeNewlinesForHref:lu,delimiters:n.delimiters,comments:n.comments},this),o=i.render,a=i.staticRenderFns;n.render=o,n.staticRenderFns=a}}return du.call(this,e,t)},Ut.compile=cu,t.a=Ut}).call(t,n(0),n(4).setImmediate)},function(e,t,n){(function(e){function r(e,t){this._id=e,this._clearFn=t}var i=void 0!==e&&e||"undefined"!=typeof self&&self||window,o=Function.prototype.apply;t.setTimeout=function(){return new r(o.call(setTimeout,i,arguments),clearTimeout)},t.setInterval=function(){return new r(o.call(setInterval,i,arguments),clearInterval)},t.clearTimeout=t.clearInterval=function(e){e&&e.close()},r.prototype.unref=r.prototype.ref=function(){},r.prototype.close=function(){this._clearFn.call(i,this._id)},t.enroll=function(e,t){clearTimeout(e._idleTimeoutId),e._idleTimeout=t},t.unenroll=function(e){clearTimeout(e._idleTimeoutId),e._idleTimeout=-1},t._unrefActive=t.active=function(e){clearTimeout(e._idleTimeoutId);var t=e._idleTimeout;t>=0&&(e._idleTimeoutId=setTimeout(function(){e._onTimeout&&e._onTimeout()},t))},n(5),t.setImmediate="undefined"!=typeof self&&self.setImmediate||void 0!==e&&e.setImmediate||this&&this.setImmediate,t.clearImmediate="undefined"!=typeof self&&self.clearImmediate||void 0!==e&&e.clearImmediate||this&&this.clearImmediate}).call(t,n(0))},function(e,t,n){(function(e,t){!function(e,n){"use strict";function r(e){"function"!=typeof e&&(e=new Function(""+e));for(var t=new Array(arguments.length-1),n=0;n<t.length;n++)t[n]=arguments[n+1];var r={callback:e,args:t};return u[c]=r,s(c),c++}function i(e){delete u[e]}function o(e){var t=e.callback,r=e.args;switch(r.length){case 0:t();break;case 1:t(r[0]);break;case 2:t(r[0],r[1]);break;case 3:t(r[0],r[1],r[2]);break;default:t.apply(n,r)}}function a(e){if(l)setTimeout(a,0,e);else{var t=u[e];if(t){l=!0;try{o(t)}finally{i(e),l=!1}}}}if(!e.setImmediate){var s,c=1,u={},l=!1,f=e.document,d=Object.getPrototypeOf&&Object.getPrototypeOf(e);d=d&&d.setTimeout?d:e,"[object process]"==={}.toString.call(e.process)?function(){s=function(e){t.nextTick(function(){a(e)})}}():function(){if(e.postMessage&&!e.importScripts){var t=!0,n=e.onmessage;return e.onmessage=function(){t=!1},e.postMessage("","*"),e.onmessage=n,t}}()?function(){var t="setImmediate$"+Math.random()+"$",n=function(n){n.source===e&&"string"==typeof n.data&&0===n.data.indexOf(t)&&a(+n.data.slice(t.length))};e.addEventListener?e.addEventListener("message",n,!1):e.attachEvent("onmessage",n),s=function(n){e.postMessage(t+n,"*")}}():e.MessageChannel?function(){var e=new MessageChannel;e.port1.onmessage=function(e){a(e.data)},s=function(t){e.port2.postMessage(t)}}():f&&"onreadystatechange"in f.createElement("script")?function(){var e=f.documentElement;s=function(t){var n=f.createElement("script");n.onreadystatechange=function(){a(t),n.onreadystatechange=null,e.removeChild(n),n=null},e.appendChild(n)}}():function(){s=function(e){setTimeout(a,0,e)}}(),d.setImmediate=r,d.clearImmediate=i}}("undefined"==typeof self?void 0===e?this:e:self)}).call(t,n(0),n(6))},function(e,t){function n(){throw new Error("setTimeout has not been defined")}function r(){throw new Error("clearTimeout has not been defined")}function i(e){if(l===setTimeout)return setTimeout(e,0);if((l===n||!l)&&setTimeout)return l=setTimeout,setTimeout(e,0);try{return l(e,0)}catch(t){try{return l.call(null,e,0)}catch(t){return l.call(this,e,0)}}}function o(e){if(f===clearTimeout)return clearTimeout(e);if((f===r||!f)&&clearTimeout)return f=clearTimeout,clearTimeout(e);try{return f(e)}catch(t){try{return f.call(null,e)}catch(t){return f.call(this,e)}}}function a(){h&&p&&(h=!1,p.length?v=p.concat(v):m=-1,v.length&&s())}function s(){if(!h){var e=i(a);h=!0;for(var t=v.length;t;){for(p=v,v=[];++m<t;)p&&p[m].run();m=-1,t=v.length}p=null,h=!1,o(e)}}function c(e,t){this.fun=e,this.array=t}function u(){}var l,f,d=e.exports={};!function(){try{l="function"==typeof setTimeout?setTimeout:n}catch(e){l=n}try{f="function"==typeof clearTimeout?clearTimeout:r}catch(e){f=r}}();var p,v=[],h=!1,m=-1;d.nextTick=function(e){var t=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];v.push(new c(e,t)),1!==v.length||h||i(s)},c.prototype.run=function(){this.fun.apply(null,this.array)},d.title="browser",d.browser=!0,d.env={},d.argv=[],d.version="",d.versions={},d.on=u,d.addListener=u,d.once=u,d.off=u,d.removeListener=u,d.removeAllListeners=u,d.emit=u,d.prependListener=u,d.prependOnceListener=u,d.listeners=function(e){return[]},d.binding=function(e){throw new Error("process.binding is not supported")},d.cwd=function(){return"/"},d.chdir=function(e){throw new Error("process.chdir is not supported")},d.umask=function(){return 0}}])});
1
+ !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.WPRA=t():e.WPRA=t()}("undefined"!=typeof self?self:this,function(){return webpackJsonpWPRA([2],{11:function(e,t,i){"use strict";function s(e,t){for(var i=(arguments.length>2&&void 0!==arguments[2]&&arguments[2],new FormData),s=Object.keys(t),n=Array.isArray(s),r=0,s=n?s:s[Symbol.iterator]();;){var a;if(n){if(r>=s.length)break;a=s[r++]}else{if(r=s.next(),r.done)break;a=r.value}var o=a;i.set(o,t[o])}return fetch(e,{method:"post",body:i}).then(function(e){return e.json()}).then(function(e){if(200!==e.status)throw e;return e})}function n(e){if(!navigator.clipboard)return void g(e);navigator.clipboard.writeText(e).then(function(){},function(e){console.error("Async: Could not copy text: ",e)})}Object.defineProperty(t,"__esModule",{value:!0});var r=i(4),a=function(){var e=this,t=e.$createElement,i=e._self._c||t;return i("div",{staticClass:"wizard-holder animated fadeIn"},[i("div",{staticClass:"connect-steps"},[i("div",{staticClass:"step-items"},[i("div",{staticClass:"step-progress",class:"step-progress--"+e.activeScreenIndex}),e._v(" "),e._l(e.screens,function(t,s){return i("div",{staticClass:"step-item",class:{"step-item_active":e.active(t.id),"step-item_completed":t.completed()&&s<e.activeScreenIndex}},[i("div",{staticClass:"step-item__status"},[t.completed()&&s<e.activeScreenIndex?i("span",{staticClass:"dashicons dashicons-yes"}):e._e()]),e._v(" "),i("div",{staticClass:"step-item__info"},[i("div",{staticClass:"step-item__title"},[e._v(e._s(t.title))]),e._v(" "),t.description?i("div",{staticClass:"step-item__description"},[e._v(e._s(t.description))]):e._e()])])})],2)]),e._v(" "),i("div",{staticClass:"wizard"},[i("transition",{attrs:{name:e.transition,mode:"out-in"}},[e.active("feed")?i("div",{key:e.activeScreen,staticClass:"wizard_content"},[i("div",{staticClass:"wizard_hello"},[e._v("\n Enter your first RSS Feed URL\n ")]),e._v(" "),i("form",{staticClass:"wizard_info",attrs:{id:"feedForm"},on:{submit:function(t){return t.preventDefault(),e.next(t)}}},[i("div",{staticClass:"form-group"},[i("input",{directives:[{name:"model",rawName:"v-model",value:e.form.feedSourceUrl,expression:"form.feedSourceUrl"}],staticClass:"wpra-feed-input",attrs:{type:"text",placeholder:"https://www.sourcedomain.com/feed/"},domProps:{value:e.form.feedSourceUrl},on:{input:function(t){t.target.composing||e.$set(e.form,"feedSourceUrl",t.target.value)}}}),e._v(" "),e.isFeedError?i("span",{staticClass:"dashicons dashicons-warning warning-icon"}):e._e(),e._v(" "),e.isFeedError?i("a",{attrs:{href:e.validateLink,target:"_blank"}},[e._v("Validate feed")]):e._e()])]),e._v(" "),e.isFeedError?i("div",{staticClass:"wizard_error"},[i("p",[e._v("This RSS feed URL appears to be invalid. Here are a couple of things you can try:")]),e._v(" "),i("ol",[i("li",[e._v('Check whether the URL you entered is the correct one by trying one of the options when clicking on "How do I find an RSS feed URL?" below.')]),e._v(" "),i("li",[e._v("\n Test out this other RSS feed URL to make sure the plugin is working correctly - https://www.wpmayor.com/feed/ - If it works, you may "),i("a",{attrs:{href:e.supportUrl,target:"_blank"}},[e._v("contact us here")]),e._v(" to help you with your source.\n ")]),e._v(" "),i("li",[e._v("Test the URL's validity by W3C standards, the standards we use in our plugins, using the “Validate feed” link above.")])])]):e._e(),e._v(" "),i("expander",{attrs:{title:"How do I find an RSS feed URL?"}},[i("p",[e._v("WP RSS Aggregator fetches feed items through RSS feeds. Almost every website in the world provides an RSS feed. Here's how to find it:")]),e._v(" "),i("p",[e._v("Option 1: Add /feed to the website's homepage URL ")]),e._v(" "),i("p",[e._v("Many sites have their RSS feed at the same URL. For instance, if the website's URL is www.thiswebsite.com, then the RSS feed could be at www.thiswebsite.com/feed.")]),e._v(" "),i("p",[e._v("Option 2: Look for the RSS share icon")]),e._v(" "),i("p",[e._v("Many websites have share icons on their pages for Facebook, Twitter and more. Many times, there will also be an orange RSS icon. Click on that to access the RSS feed URL.")]),e._v(" "),i("p",[e._v("Option 3: Browser RSS Auto-Discovery")]),e._v(" "),i("p",[e._v("Most browsers either include an RSS auto-discovery tool by default or they allow you to add extensions for it. Firefox shows an RSS icon above the website, in the address bar, which you can click on directly. Chrome offers extensions such as this one.")]),e._v(" "),i("p",[e._v("Option 4: Look at the Page Source")]),e._v(" "),i("p",[e._v('When on any page of the website you\'re looking to import feed items from, right click and press "View Page Source". Once the new window opens, use the “Find” feature (Ctrl-F on PC, Command-F on Mac) and search for " RSS". This should take you to a line that reads like this (or similar):')]),e._v(" "),i("p",[i("code",[e._v('\n <link rel="alternate" type="application/rss+xml" title="RSS Feed" href="https://www.sourcedomain.com/feed/" />\n ')])]),e._v(" "),i("p",[e._v("The RSS feed’s URL is found between the quotes after href=. In the above case, it would be https://www.sourcedomain.com/feed/.")]),e._v(" "),i("p",[i("a",{attrs:{href:e.knowledgeBaseUrl,target:"_blank"}},[e._v("Browse our Knowledge Base for more information.")])])])],1):e._e(),e._v(" "),e.active("feedItems")?i("div",{key:e.activeScreen,staticClass:"wizard_content"},[i("div",{staticClass:"wizard_hello"},[e._v("\n Latest feed items from your selected feed source:\n ")]),e._v(" "),i("div",{staticClass:"wpra-feed-items"},e._l(e.feed.items,function(t){return i("div",{staticClass:"wpra-feed-item"},[i("div",{staticClass:"wpra-feed-item__link"},[i("a",{attrs:{href:t.permalink,target:"_blank"}},[e._v(e._s(t.title))])]),e._v(" "),i("div",{staticClass:"wpra-feed-item__info"},[t.date||t.author?[t.date?[e._v("\n Published on "+e._s(t.date)+"\n ")]:e._e(),e._v(" "),t.date&&t.author?[e._v("|")]:e._e(),e._v(" "),t.author?[e._v("\n By "+e._s(t.author)+"\n ")]:e._e()]:e._e()],2)])}),0),e._v(" "),i("div",{staticClass:"wrpa-shortcode"},[i("div",{staticClass:"wrpa-shortcode-preview"},[i("div",{staticClass:"wrpa-shortcode-label"},[e._v("\n Create a draft page to preview these feed items on your site:\n ")]),e._v(" "),i("a",{staticClass:"button",class:{"button-primary":e.isPrepared,"loading-button":e.isPreparing},attrs:{href:e.previewUrl,target:"_blank"},on:{click:e.preparePreview}},[e._v("\n "+e._s(e.isPrepared?"Preview the Page":"Create Draft Page")+"\n ")])]),e._v(" "),i("div",{staticClass:"wrpa-shortcode-form",on:{click:function(t){return e.copyToClipboard()}}},[i("div",{staticClass:"wrpa-shortcode-label"},[e._v("\n Copy the shortcode to any page or post on your site:\n ")]),e._v(" "),i("input",{ref:"selected",staticClass:"wrpa-shortcode-form__shortcode",attrs:{type:"text",readonly:"",value:"[wp-rss-aggregator]"}}),e._v(" "),i("div",{staticClass:"wrpa-shortcode-form__button"},[e._v("\n "+e._s(e.isCopied?"Copied!":"Click to copy")+"\n ")])])])]):e._e(),e._v(" "),e.active("finish")?i("div",{key:e.activeScreen,staticClass:"wizard_content"},[i("div",{staticClass:"wizard_hello"},[e._v("\n You’ve successfully set up your first feed source 😄\n ")]),e._v(" "),i("div",{staticClass:"wpra-cols-title"},[e._v("\n Do more with WP RSS Aggregator - here is what we did at CryptoHeadlines.com.\n ")]),e._v(" "),i("div",{staticClass:"wpra-cols"},[i("div",{staticClass:"col"},[i("p",[e._v("CryptoHeadlines.com displays latest news, Youtube videos, podcasts, jobs and more from the Cryptocurrency industry.")]),e._v(" "),i("p",[e._v("It uses Feed to Post to import articles, Youtube videos, and podcast links.")]),e._v(" "),i("p",[e._v("Full Text RSS Feeds is used to fetch the full content of the job listings to present more information to the potential applicant.")]),e._v(" "),i("p",[e._v("Keyword Filtering is used to filter out content that contains profanity and keywords or phrases deemed as inappropriate.")]),e._v(" "),i("div",{staticStyle:{"margin-bottom":".5rem"}},[i("a",{staticClass:"button",attrs:{href:e.addOnsUrl,target:"_blank"}},[e._v("\n Browse Add-ons ⭐️\n ")])]),e._v(" "),i("div",[i("a",{staticStyle:{"font-size":".9em"},attrs:{href:e.supportUrl,target:"_blank"}},[e._v("Contact support for more information.")])])]),e._v(" "),i("div",{staticClass:"col"},[i("img",{staticClass:"img wpra-demo-photo",attrs:{src:e.demoImageUrl}}),e._v(" "),i("div",{staticClass:"wpra-feedback"},[i("div",{staticClass:"wpra-feedback__copy"},[i("div",{staticClass:"wpra-feedback__text"},[e._v("\n This plugin has made my life a lot easier, and the support has been great as well.\n ")]),e._v(" "),i("div",{staticClass:"wpra-feedback__rating"},[i("span",{staticClass:"dashicons dashicons-star-filled"}),e._v(" "),i("span",{staticClass:"dashicons dashicons-star-filled"}),e._v(" "),i("span",{staticClass:"dashicons dashicons-star-filled"}),e._v(" "),i("span",{staticClass:"dashicons dashicons-star-filled"}),e._v(" "),i("span",{staticClass:"dashicons dashicons-star-filled"})]),e._v(" "),i("div",{staticClass:"wpra-feedback__by"},[i("a",{attrs:{href:e.feedbackUrl,target:"_blank"}},[e._v("\n Review by officeinnovator\n ")])])])])])])]):e._e()]),e._v(" "),i("div",{staticClass:"connect-actions pad"},[i("div",{staticClass:"pad-item--grow"},[e.active("finish")?e._e():i("button",{staticClass:"button-clear",on:{click:e.finish}},[e._v("\n Skip the introduction\n ")])]),e._v(" "),i("div",{staticClass:"pad-item--no-shrink"},[e.isBackAvailable?i("button",{staticClass:"button-clear",on:{click:e.back}},[e._v("\n Back\n ")]):e._e(),e._v(" "),i("button",{staticClass:"button button-primary button-large",class:{"loading-button":e.isLoading},on:{click:e.next}},[e._v("\n "+e._s(e.active("finish")?"Continue to Plugin":"Next")+"\n ")])])])],1)])},o=[],d=function(){var e=this,t=e.$createElement,i=e._self._c||t;return i("div",{staticClass:"wpra-expander",class:{"wpra-expander--expanded":e.isExpanded}},[i("div",{staticClass:"wpra-expander__title",on:{click:function(t){e.isExpanded=!e.isExpanded}}},[e._v("\n "+e._s(e.title)+"\n "),i("span",{staticClass:"dashicons dashicons-arrow-down-alt2"})]),e._v(" "),i("transition-expand",[e.isExpanded?i("div",[i("div",{staticClass:"wpra-expander__content"},[e._t("default")],2)]):e._e()])],1)},c=[],l={name:"TransitionExpand",functional:!0,render:function(e,t){return e("transition",{props:{name:"expand"},on:{afterEnter:function(e){e.style.height="auto"},enter:function(e){var t=getComputedStyle(e),i=t.width;e.style.width=i,e.style.position="absolute",e.style.visibility="hidden",e.style.height="auto";var s=getComputedStyle(e),n=s.height;e.style.width=null,e.style.position=null,e.style.visibility=null,e.style.height=0,getComputedStyle(e).height,setTimeout(function(){e.style.height=n})},leave:function(e){var t=getComputedStyle(e),i=t.height;e.style.height=i,getComputedStyle(e).height,setTimeout(function(){e.style.height=0})}}},t.children)}},u=l,p=i(1),f=Object(p.a)(u,void 0,void 0,!1,null,null,null),v=f.exports,h={data:function(){return{isExpanded:this.defaultExpanded}},props:{title:{},defaultExpanded:{value:!1}},components:{TransitionExpand:v}},_=h,m=Object(p.a)(_,d,c,!1,null,null,null),w=m.exports,g=function(e){var t=document.createElement("textarea");t.value=e,document.body.appendChild(t),t.focus(),t.select();try{document.execCommand("copy")}catch(e){console.error("Fallback: Oops, unable to copy",e)}document.body.removeChild(t)},y=function(e){return e},b=window.wprssWizardConfig,C={data:function(){var e=this;return{prevHeight:0,screens:[{id:"feed",title:y("Add feed source URL"),description:!1,next:this.submitFeed,completed:function(){return e.feed.items.length},entered:function(){e.focusOnInput("feed")}},{id:"feedItems",title:y("Display feed items"),description:!1,next:this.continueItems,completed:function(){return e.feed.items.length&&e.itemsPassed}},{id:"finish",title:y("Complete introduction"),description:!1,next:this.completeIntroduction,completed:function(){return e.feed.items.length&&e.itemsPassed}}],isCopied:!1,isPreparing:!1,isPrepared:!1,transition:"slide-up",activeScreen:"feed",form:{feedSourceUrl:null},itemsPassed:!1,stepLoading:!1,isLoading:!1,isFeedError:!1,feed:{items:[]},previewUrl:b.previewUrl,addOnsUrl:b.addOnsUrl,supportUrl:b.supportUrl,demoImageUrl:b.demoImageUrl,feedbackUrl:b.feedbackUrl,knowledgeBaseUrl:b.knowledgeBaseUrl}},computed:{validateLink:function(){return"https://validator.w3.org/feed/check.cgi?url="+encodeURI(this.form.feedSourceUrl)},activeScreenIndex:function(){var e=this;return this.screens.findIndex(function(t){return t.id===e.activeScreen})},currentScreen:function(){var e=this;return this.screens.find(function(t){return t.id===e.activeScreen})},actionCompleted:function(){return this.currentScreen.completed()},isBackAvailable:function(){return this.activeScreenIndex>0&&this.activeScreenIndex<this.screens.length}},mounted:function(){this.onScreenEnter()},methods:{preparePreview:function(e){var t=this;if(this.isPreparing)return void e.preventDefault();this.isPrepared||(e.preventDefault(),this.isPreparing=!0,fetch(this.previewUrl).then(function(){t.isPreparing=!1,t.isPrepared=!0}))},submitFeed:function(){var e=this,t=Object.assign(b.feedEndpoint.defaultPayload,{wprss_intro_feed_url:this.form.feedSourceUrl});return this.isLoading=!0,this.isFeedError=!1,s(b.feedEndpoint.url,t).then(function(t){return e.feed.items=t.data.feed_items.slice(0,3),e.isLoading=!1,{}}).catch(function(t){throw e.isLoading=!1,e.isFeedError=!0,t})},continueItems:function(){return this.itemsPassed=!0,Promise.resolve({})},completeIntroduction:function(){return Promise.resolve({})},next:function(){var e=this;this.transition="slide-up";var t=this.currentScreen.next?this.currentScreen.next:function(){return Promise.resolve(!1)};this.stepLoading=!0,t().then(function(t){e.stepLoading=!1},function(e){throw e}).then(function(){var t=e.activeScreenIndex+1;t>=e.screens.length?e.finish():(e.activeScreen=e.screens[t].id,e.onScreenEnter())}).catch(function(e){console.error(e)})},onScreenEnter:function(){var e=this;this.$nextTick(function(){e.currentScreen.entered&&e.currentScreen.entered()})},focusOnInput:function(e){if(!this.$refs[e]||!this.$refs[e].focus)return!1;this.$refs[e].focus()},back:function(){this.transition="slide-down",this.activeScreen=this.screens[this.activeScreenIndex-1].id},finish:function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],t=function(){return window.location.href=b.feedListUrl};if(e)return void(confirm("Are you sure you want to skip the introduction?")&&t());t()},active:function(e){return this.activeScreen===e},copyToClipboard:function(){var e=this;this.isCopied||(n("[wp-rss-aggregator]"),this.isCopied=!0,setTimeout(function(){e.isCopied=!1},1e3))}},components:{Expander:w}},S=C,k=Object(p.a)(S,a,o,!1,null,null,null),x=k.exports;i(15),i(12),new r.a({el:"#wpra-wizard-app",template:"<Wizard/>",components:{Wizard:x}})},12:function(e,t){}},[11])});
 
 
 
 
 
js/plugins.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.WPRA=t():e.WPRA=t()}("undefined"!=typeof self?self:this,function(){return webpackJsonpWPRA([1],{16:function(e,t,o){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var a=o(4),n=function(){var e=this,t=e.$createElement,o=e._self._c||t;return o("div",{staticClass:"wpra-plugin-disable-poll"},[o("modal",{attrs:{active:e.isModalVisible,"header-class":"invisible-header"},on:{close:e.closeModal}},[o("div",{attrs:{slot:"header"},slot:"header"},[o("div",{staticClass:"wpra-plugin-disable-poll__logo"},[o("img",{attrs:{src:e.image("light-line-logo.png"),alt:""}})]),e._v(" "),o("h3",[e._v("\n Do you have a moment to share why you are deactivating WP RSS Aggregator?\n ")]),e._v(" "),o("p",[e._v("\n Your feedback will help us to improve our plugins and service.\n ")])]),e._v(" "),o("div",{attrs:{slot:"body"},slot:"body"},[o("SerializedForm",{attrs:{form:e.form},model:{value:e.model,callback:function(t){e.model=t},expression:"model"}})],1),e._v(" "),o("div",{attrs:{slot:"footer"},slot:"footer"},[o("div",{staticClass:"footer-confirm__buttons"},[o("button",{staticClass:"button button-clear",on:{click:e.deactivate}},[e._v("\n Skip & Deactivate\n ")]),e._v(" "),o("button",{staticClass:"button button-primary",class:{"loading-button":e.isDeactivating},on:{click:e.submit}},[e._v("\n Submit & Deactivate\n ")])])])])],1)},i=[],l=function(){var e=this,t=e.$createElement,o=e._self._c||t;return o("transition",{attrs:{name:"modal-transition"}},[e.active?o("div",{staticClass:"modal",on:{click:function(t){return t.target!==t.currentTarget?null:e.$emit("close")}}},[o("div",{class:["modal__body",this.modalBodyClass]},[o("div",{staticClass:"modal__header",class:e.headerClass},[e._t("header")],2),e._v(" "),o("div",{staticClass:"modal__content"},[e._t("body")],2),e._v(" "),o("div",{staticClass:"modal__footer"},[e._t("footer")],2)])]):e._e()])},s=[],r={props:{active:{type:Boolean},title:{type:String},modalBodyClass:{type:String,default:""},headerClass:{default:function(){return{}}},dialogOpenedClass:{type:String,default:"modal-opened"}},watch:{active:function(e){this.$emit(e?"open":"close")}},mounted:function(){var e=this;this.$on("open",function(){document.querySelector("body").classList.add(e.dialogOpenedClass)}),this.$on("close",function(){document.querySelector("body").classList.remove(e.dialogOpenedClass)})}},d=r,c=o(1),u=Object(c.a)(d,l,s,!1,null,null,null),m=u.exports,v=function(){var e=this,t=e.$createElement,o=e._self._c||t;return o("div",{staticClass:"form"},e._l(e.form,function(t){return e.satisfiesCondition(t)?o("div",{staticClass:"form-group"},["radio"===t.type?[t.label?o("label",{attrs:{for:t.name},domProps:{innerHTML:e._s(t.label)}}):e._e(),e._v(" "),e._l(t.options,function(a,n){return o("div",{staticClass:"form-check"},[o("input",{directives:[{name:"model",rawName:"v-model",value:e.model[t.name],expression:"model[datum.name]"}],attrs:{type:"radio",name:t.name,id:t.name+"_"+n},domProps:{value:a.value,checked:e._q(e.model[t.name],a.value)},on:{change:function(o){return e.$set(e.model,t.name,a.value)}}}),e._v(" "),o("label",{attrs:{for:t.name+"_"+n}},[e._v("\n "+e._s(a.label||a.value)+"\n ")])])})]:e._e(),e._v(" "),"textarea"===t.type?[t.label?o("label",{attrs:{for:t.name},domProps:{innerHTML:e._s(t.label)}}):e._e(),e._v(" "),o("textarea",{directives:[{name:"model",rawName:"v-model",value:e.model[t.name],expression:"model[datum.name]"}],attrs:{id:t.name},domProps:{value:e.model[t.name]},on:{input:function(o){o.target.composing||e.$set(e.model,t.name,o.target.value)}}})]:e._e(),e._v(" "),"content"===t.type?[o("div",{class:t.className},[o("p",{domProps:{innerHTML:e._s(t.label)}})])]:e._e()],2):e._e()}),0)},p=[],f={props:{form:{type:Array},value:{type:Object}},computed:{model:{get:function(){return this.value},set:function(e){this.$emit("input",e)}}},methods:{satisfiesCondition:function(e){if(!e.condition)return!0;var t=this.getConditionFunction(e.condition.operator);return!!t&&t(e.condition.field,e.condition.value)},getConditionFunction:function(e){var t=this,o={"=":function(e,o){return t.model[e]===o}};return o[e]?o[e]:null}}},_=f,b=Object(c.a)(_,v,p,!1,null,null,null),h=b.exports,g=o(18),y=o.n(g),C=document.querySelector('[data-slug="wp-rss-aggregator"] .deactivate a'),P={components:{Modal:m,SerializedForm:h},data:function(){return{isDeactivating:!1,deactivateUrl:null,submitUrl:WrpaDisablePoll.url,model:WrpaDisablePoll.model,form:WrpaDisablePoll.form,isModalVisible:!1}},watch:{"model.reason":function(){this.model.follow_up=null}},mounted:function(){C.addEventListener("click",this.handleDeactivateClick)},methods:{image:function(e){return WrpaDisablePoll.image+e},handleDeactivateClick:function(e){this.isModalVisible||(e.preventDefault(),this.isModalVisible=!0)},closeModal:function(){this.isModalVisible=!1,this.deactivateUrl=null},submit:function(){var e=this;this.isDeactivating=!0,y.a.post(this.submitUrl,this.model,{headers:{"Content-Type":"application/x-www-form-urlencoded"}}).then(function(){e.deactivate()}).finally(function(){e.isDeactivating=!1})},deactivate:function(){C.click()}}},w=P,D=Object(c.a)(w,n,i,!1,null,null,null),k=D.exports;o(17),new a.a({el:"#wpra-plugins-app",template:"<PluginDisablePoll/>",components:{PluginDisablePoll:k}})},17:function(e,t){}},[16])});
js/src/intro/Wizard.vue CHANGED
@@ -76,24 +76,45 @@
76
  <a :href="item.permalink" target="_blank">{{ item.title }}</a>
77
  </div>
78
  <div class="wpra-feed-item__info">
79
- Published on {{ item.date }} | By {{ item.author }}
 
 
 
 
 
 
 
 
80
  </div>
81
  </div>
82
  </div>
83
 
84
- <div class="wizard_label">
85
- Copy and paste this shortcode to any page or post to display the full list:
86
- </div>
87
-
88
  <div class="wrpa-shortcode">
 
 
 
 
 
 
 
 
 
 
 
89
  <div class="wrpa-shortcode-form" @click="copyToClipboard()">
90
- <input class="wrpa-shortcode-form__shortcode" type="text" readonly value="[wp-rss-aggregator]" ref="selected"/>
 
 
 
 
 
 
 
 
91
  <div class="wrpa-shortcode-form__button">
92
- Ctrl+C or CMD+C to copy
93
  </div>
94
  </div>
95
- OR
96
- <a :href="previewUrl" target="_blank">Preview the feed items on a new page</a>
97
  </div>
98
  </div>
99
 
@@ -183,6 +204,7 @@
183
  <script>
184
  import Expander from './Expander'
185
  import { post } from './fetch'
 
186
 
187
  const _ = (str) => str
188
 
@@ -208,11 +230,6 @@
208
  title: _('Display feed items'),
209
  description: false,
210
  next: this.continueItems,
211
- entered: () => {
212
- setTimeout(() => {
213
- this.copyToClipboard()
214
- }, 400)
215
- },
216
  completed: () => {
217
  return this.feed.items.length && this.itemsPassed
218
  }
@@ -225,6 +242,11 @@
225
  return this.feed.items.length && this.itemsPassed
226
  }
227
  }],
 
 
 
 
 
228
  transition: 'slide-up', // 'slide-down',
229
 
230
  activeScreen: 'feed',
@@ -271,6 +293,21 @@
271
  this.onScreenEnter()
272
  },
273
  methods: {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
274
  /**
275
  * Submits first feed step.
276
  *
@@ -386,13 +423,14 @@
386
  },
387
 
388
  copyToClipboard () {
389
- try {
390
- this.$refs.selected.focus()
391
- this.$refs.selected.select()
392
- }
393
- catch (e) {
394
- console.error(e)
395
  }
 
 
 
 
 
396
  }
397
  },
398
  components: {
76
  <a :href="item.permalink" target="_blank">{{ item.title }}</a>
77
  </div>
78
  <div class="wpra-feed-item__info">
79
+ <template v-if="item.date || item.author">
80
+ <template v-if="item.date">
81
+ Published on {{ item.date }}
82
+ </template>
83
+ <template v-if="item.date && item.author">|</template>
84
+ <template v-if="item.author">
85
+ By {{ item.author }}
86
+ </template>
87
+ </template>
88
  </div>
89
  </div>
90
  </div>
91
 
 
 
 
 
92
  <div class="wrpa-shortcode">
93
+ <div class="wrpa-shortcode-preview">
94
+ <div class="wrpa-shortcode-label">
95
+ Create a draft page to preview these feed items on your site:
96
+ </div>
97
+ <a :href="previewUrl" target="_blank" class="button"
98
+ @click="preparePreview"
99
+ :class="{'button-primary': isPrepared, 'loading-button': isPreparing}"
100
+ >
101
+ {{ isPrepared ? 'Preview the Page' : 'Create Draft Page' }}
102
+ </a>
103
+ </div>
104
  <div class="wrpa-shortcode-form" @click="copyToClipboard()">
105
+ <div class="wrpa-shortcode-label">
106
+ Copy the shortcode to any page or post on your site:
107
+ </div>
108
+ <input class="wrpa-shortcode-form__shortcode"
109
+ type="text"
110
+ readonly
111
+ value="[wp-rss-aggregator]"
112
+ ref="selected"
113
+ />
114
  <div class="wrpa-shortcode-form__button">
115
+ {{ isCopied ? 'Copied!' : 'Click to copy' }}
116
  </div>
117
  </div>
 
 
118
  </div>
119
  </div>
120
 
204
  <script>
205
  import Expander from './Expander'
206
  import { post } from './fetch'
207
+ import { copyToClipboard } from './copy'
208
 
209
  const _ = (str) => str
210
 
230
  title: _('Display feed items'),
231
  description: false,
232
  next: this.continueItems,
 
 
 
 
 
233
  completed: () => {
234
  return this.feed.items.length && this.itemsPassed
235
  }
242
  return this.feed.items.length && this.itemsPassed
243
  }
244
  }],
245
+ isCopied: false,
246
+
247
+ isPreparing: false,
248
+ isPrepared: false,
249
+
250
  transition: 'slide-up', // 'slide-down',
251
 
252
  activeScreen: 'feed',
293
  this.onScreenEnter()
294
  },
295
  methods: {
296
+ preparePreview (e) {
297
+ if (this.isPreparing) {
298
+ e.preventDefault()
299
+ return
300
+ }
301
+ if (!this.isPrepared) {
302
+ e.preventDefault()
303
+ this.isPreparing = true
304
+ fetch(this.previewUrl).then(() => {
305
+ this.isPreparing = false
306
+ this.isPrepared = true
307
+ })
308
+ }
309
+ },
310
+
311
  /**
312
  * Submits first feed step.
313
  *
423
  },
424
 
425
  copyToClipboard () {
426
+ if (this.isCopied) {
427
+ return
 
 
 
 
428
  }
429
+ copyToClipboard('[wp-rss-aggregator]')
430
+ this.isCopied = true
431
+ setTimeout(() => {
432
+ this.isCopied = false
433
+ }, 1000)
434
  }
435
  },
436
  components: {
js/src/intro/copy.js ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Helper functions to copy text to clipboard.
3
+ *
4
+ * @see https://stackoverflow.com/questions/400212/how-do-i-copy-to-the-clipboard-in-javascript
5
+ *
6
+ * @param text
7
+ */
8
+
9
+ const fallbackCopyToClipboard = function (text) {
10
+ var textArea = document.createElement('textarea')
11
+ textArea.value = text
12
+ document.body.appendChild(textArea)
13
+ textArea.focus()
14
+ textArea.select()
15
+
16
+ try {
17
+ var successful = document.execCommand('copy')
18
+ var msg = successful ? 'successful' : 'unsuccessful'
19
+ console.log('Fallback: Copying text command was ' + msg)
20
+ } catch (err) {
21
+ console.error('Fallback: Oops, unable to copy', err)
22
+ }
23
+
24
+ document.body.removeChild(textArea)
25
+ }
26
+
27
+ export function copyToClipboard (text) {
28
+ if (!navigator.clipboard) {
29
+ fallbackCopyToClipboard(text)
30
+ return
31
+ }
32
+ navigator.clipboard.writeText(text).then(function () {
33
+ console.log('Async: Copying to clipboard was successful!')
34
+ }, function (err) {
35
+ console.error('Async: Could not copy text: ', err)
36
+ })
37
+ }
js/src/plugins/Modal.vue ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <template>
2
+ <transition name="modal-transition">
3
+ <div class="modal" v-if="active" @click.self="$emit('close')">
4
+ <div :class="['modal__body', this.modalBodyClass]">
5
+ <div class="modal__header" :class="headerClass">
6
+ <slot name="header"></slot>
7
+ </div>
8
+ <div class="modal__content">
9
+ <slot name="body"></slot>
10
+ </div>
11
+ <div class="modal__footer">
12
+ <slot name="footer"></slot>
13
+ </div>
14
+ </div>
15
+ </div>
16
+ </transition>
17
+ </template>
18
+
19
+ <script>
20
+ /**
21
+ * Abstract dialog component, solid foundation for
22
+ * any modals and dialogs that opened over the rest page content.
23
+ *
24
+ * @param Vue
25
+ */
26
+ export default {
27
+ props: {
28
+ /**
29
+ * Determines dialog visibility. This property is passed
30
+ * from outside and cannot be changed inside dialog.
31
+ * Dialog's consumer is responsible for manipulating dialog's visibility.
32
+ *
33
+ * @property {bool}
34
+ */
35
+ active: {
36
+ type: Boolean
37
+ },
38
+
39
+ /**
40
+ * Modal title
41
+ *
42
+ * @property {string}
43
+ */
44
+ title: {
45
+ type: String
46
+ },
47
+
48
+ /**
49
+ * Additional class modifier for modal customization.
50
+ *
51
+ * @property {string}
52
+ */
53
+ modalBodyClass: {
54
+ type: String,
55
+ default: ''
56
+ },
57
+
58
+ /**
59
+ * Additional classes for modal header.
60
+ *
61
+ * @property {object|Array}
62
+ */
63
+ headerClass: {
64
+ default () {
65
+ return {}
66
+ }
67
+ },
68
+
69
+ /**
70
+ * Class that applies to the body and used
71
+ * to prevent body's scroll catch, so long dialog can be scrolled
72
+ * without interfering with body scroll.
73
+ *
74
+ * @property {string}
75
+ */
76
+ dialogOpenedClass: {
77
+ type: String,
78
+ default: 'modal-opened'
79
+ }
80
+ },
81
+
82
+ watch: {
83
+ /**
84
+ * Watch for "active" property change and emit corresponding
85
+ * event when it changed.
86
+ *
87
+ * @param isDialogActive {bool}
88
+ */
89
+ active (isDialogActive) {
90
+ this.$emit(isDialogActive ? 'open' : 'close')
91
+ }
92
+ },
93
+
94
+ mounted () {
95
+ /*
96
+ * Add body "frozen" class to the body when dialog is opened.
97
+ */
98
+ this.$on('open', () => {
99
+ document.querySelector('body')
100
+ .classList
101
+ .add(this.dialogOpenedClass);
102
+ });
103
+
104
+ /*
105
+ * Remove body "frozen" class from the body when dialog is closed.
106
+ */
107
+ this.$on('close', () => {
108
+ document.querySelector('body')
109
+ .classList
110
+ .remove(this.dialogOpenedClass);
111
+ });
112
+ },
113
+ }
114
+ </script>
js/src/plugins/PluginDisablePoll.vue ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <template>
2
+ <div class="wpra-plugin-disable-poll">
3
+ <modal :active="isModalVisible"
4
+ @close="closeModal"
5
+ :header-class="'invisible-header'"
6
+ >
7
+ <div slot="header">
8
+ <div class="wpra-plugin-disable-poll__logo">
9
+ <img :src="image('light-line-logo.png')" alt="">
10
+ </div>
11
+ <h3>
12
+ Do you have a moment to share why you are deactivating WP RSS Aggregator?
13
+ </h3>
14
+ <p>
15
+ Your feedback will help us to improve our plugins and service.
16
+ </p>
17
+ </div>
18
+
19
+ <div slot="body">
20
+ <SerializedForm :form="form" v-model="model"/>
21
+ </div>
22
+
23
+ <div slot="footer">
24
+ <div class="footer-confirm__buttons">
25
+ <button class="button button-clear" @click="deactivate">
26
+ Skip & Deactivate
27
+ </button>
28
+ <button class="button button-primary"
29
+ :class="{'loading-button': isDeactivating}"
30
+ @click="submit">
31
+ Submit & Deactivate
32
+ </button>
33
+ </div>
34
+ </div>
35
+ </modal>
36
+ </div>
37
+ </template>
38
+
39
+ <script>
40
+ import Modal from './Modal'
41
+ import SerializedForm from './SerializedForm'
42
+ import axios from 'axios'
43
+
44
+ /**
45
+ * Selector string for plugin's deactivation link.
46
+ *
47
+ * @type {string}
48
+ */
49
+ const deactivateSelector = '[data-slug="wp-rss-aggregator"] .deactivate a'
50
+ const deactivateLink = document.querySelector(deactivateSelector)
51
+
52
+ export default {
53
+ components: {
54
+ Modal,
55
+ SerializedForm,
56
+ },
57
+ data () {
58
+ return {
59
+ isDeactivating: false,
60
+ deactivateUrl: null,
61
+ submitUrl: WrpaDisablePoll.url,
62
+ model: WrpaDisablePoll.model,
63
+ form: WrpaDisablePoll.form,
64
+ isModalVisible: false
65
+ }
66
+ },
67
+ watch: {
68
+ 'model.reason' () {
69
+ this.model.follow_up = null
70
+ }
71
+ },
72
+ mounted () {
73
+ deactivateLink.addEventListener('click', this.handleDeactivateClick)
74
+ },
75
+ methods: {
76
+ image (path) {
77
+ return WrpaDisablePoll.image + path
78
+ },
79
+
80
+ handleDeactivateClick (e) {
81
+ if (this.isModalVisible) {
82
+ return
83
+ }
84
+
85
+ e.preventDefault()
86
+ this.isModalVisible = true
87
+ },
88
+
89
+ closeModal () {
90
+ this.isModalVisible = false
91
+ this.deactivateUrl = null
92
+ },
93
+
94
+ submit () {
95
+ this.isDeactivating = true
96
+ axios.post(this.submitUrl, this.model, {
97
+ headers: {
98
+ 'Content-Type': 'application/x-www-form-urlencoded'
99
+ }
100
+ }).then(() => {
101
+ this.deactivate()
102
+ }).finally(() => {
103
+ this.isDeactivating = false
104
+ })
105
+ },
106
+
107
+ deactivate () {
108
+ deactivateLink.click()
109
+ }
110
+ }
111
+ }
112
+ </script>
js/src/plugins/SerializedForm.vue ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <template>
2
+ <div class="form">
3
+ <div class="form-group"
4
+ v-for="datum of form"
5
+ v-if="satisfiesCondition(datum)"
6
+ >
7
+ <template v-if="datum.type === 'radio'">
8
+ <label :for="datum.name" v-html="datum.label" v-if="datum.label"></label>
9
+ <div class="form-check" v-for="(radio, $i) of datum.options">
10
+ <input type="radio"
11
+ :name="datum.name"
12
+ :id="datum.name + '_' + $i"
13
+ :value="radio.value"
14
+ v-model="model[datum.name]"
15
+ >
16
+ <label :for="datum.name + '_' + $i">
17
+ {{ radio.label || radio.value }}
18
+ </label>
19
+ </div>
20
+ </template>
21
+
22
+ <template v-if="datum.type === 'textarea'">
23
+ <label :for="datum.name" v-html="datum.label" v-if="datum.label"></label>
24
+ <textarea v-model="model[datum.name]" :id="datum.name"></textarea>
25
+ </template>
26
+
27
+ <template v-if="datum.type === 'content'">
28
+ <div :class="datum.className">
29
+ <p v-html="datum.label"></p>
30
+ </div>
31
+ </template>
32
+ </div>
33
+ </div>
34
+ </template>
35
+
36
+ <script>
37
+ export default {
38
+ props: {
39
+ /*
40
+ * Form, described by object containing information
41
+ * about each field.
42
+ */
43
+ form: {
44
+ type: Array,
45
+ },
46
+
47
+ /*
48
+ * Form model.
49
+ */
50
+ value: {
51
+ type: Object,
52
+ }
53
+ },
54
+ computed: {
55
+ model: {
56
+ get () {
57
+ return this.value
58
+ },
59
+ set (value) {
60
+ this.$emit('input', value)
61
+ }
62
+ }
63
+ },
64
+ methods: {
65
+ satisfiesCondition (datum) {
66
+ if (!datum.condition) {
67
+ return true
68
+ }
69
+ let compareFunction = this.getConditionFunction(datum.condition.operator);
70
+ if (!compareFunction) {
71
+ return false
72
+ }
73
+ return compareFunction(datum.condition.field, datum.condition.value)
74
+ },
75
+
76
+ getConditionFunction (operator) {
77
+ const fns = {
78
+ '=': (field, value) => {
79
+ return this.model[field] === value
80
+ }
81
+ }
82
+ if (!fns[operator]) {
83
+ return null
84
+ }
85
+ return fns[operator]
86
+ }
87
+ }
88
+ }
89
+ </script>
js/src/plugins/index.js ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ require('./../../../css/src/plugins/index.scss')
2
+
3
+ import Vue from 'vue'
4
+ import PluginDisablePoll from './PluginDisablePoll'
5
+
6
+ new Vue({
7
+ el: '#wpra-plugins-app',
8
+ template: '<PluginDisablePoll/>',
9
+ components: { PluginDisablePoll }
10
+ })
js/update.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(e,o){"object"==typeof exports&&"object"==typeof module?module.exports=o():"function"==typeof define&&define.amd?define([],o):"object"==typeof exports?exports.WPRA=o():e.WPRA=o()}("undefined"!=typeof self?self:this,function(){return webpackJsonpWPRA([3],{37:function(e,o){}},[37])});
js/wpra-manifest.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(r){function n(e){if(o[e])return o[e].exports;var t=o[e]={i:e,l:!1,exports:{}};return r[e].call(t.exports,t,t.exports,n),t.l=!0,t.exports}var e=window.webpackJsonpWPRA;window.webpackJsonpWPRA=function(o,u,c){for(var f,i,p,a=0,l=[];a<o.length;a++)i=o[a],t[i]&&l.push(t[i][0]),t[i]=0;for(f in u)Object.prototype.hasOwnProperty.call(u,f)&&(r[f]=u[f]);for(e&&e(o,u,c);l.length;)l.shift()();if(c)for(a=0;a<c.length;a++)p=n(n.s=c[a]);return p};var o={},t={4:0};n.m=r,n.c=o,n.d=function(r,e,o){n.o(r,e)||Object.defineProperty(r,e,{configurable:!1,enumerable:!0,get:o})},n.n=function(r){var e=r&&r.__esModule?function(){return r.default}:function(){return r};return n.d(e,"a",e),e},n.o=function(r,n){return Object.prototype.hasOwnProperty.call(r,n)},n.p="",n.oe=function(r){throw console.error(r),r}}([]);
js/wpra-vendor.min.js ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ webpackJsonpWPRA([0],[function(e,t,n){"use strict";function r(e){return"[object Array]"===A.call(e)}function o(e){return"[object ArrayBuffer]"===A.call(e)}function i(e){return"undefined"!=typeof FormData&&e instanceof FormData}function a(e){return"undefined"!=typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView(e):e&&e.buffer&&e.buffer instanceof ArrayBuffer}function s(e){return"string"==typeof e}function c(e){return"number"==typeof e}function u(e){return void 0===e}function f(e){return null!==e&&"object"==typeof e}function l(e){return"[object Date]"===A.call(e)}function p(e){return"[object File]"===A.call(e)}function d(e){return"[object Blob]"===A.call(e)}function v(e){return"[object Function]"===A.call(e)}function h(e){return f(e)&&v(e.pipe)}function m(e){return"undefined"!=typeof URLSearchParams&&e instanceof URLSearchParams}function y(e){return e.replace(/^\s*/,"").replace(/\s*$/,"")}function g(){return("undefined"==typeof navigator||"ReactNative"!==navigator.product)&&"undefined"!=typeof window&&"undefined"!=typeof document}function b(e,t){if(null!==e&&void 0!==e)if("object"!=typeof e&&(e=[e]),r(e))for(var n=0,o=e.length;n<o;n++)t.call(null,e[n],n,e);else for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&t.call(null,e[i],i,e)}function _(){function e(e,n){"object"==typeof t[n]&&"object"==typeof e?t[n]=_(t[n],e):t[n]=e}for(var t={},n=0,r=arguments.length;n<r;n++)b(arguments[n],e);return t}function w(e,t,n){return b(t,function(t,r){e[r]=n&&"function"==typeof t?x(t,n):t}),e}var x=n(6),$=n(20),A=Object.prototype.toString;e.exports={isArray:r,isArrayBuffer:o,isBuffer:$,isFormData:i,isArrayBufferView:a,isString:s,isNumber:c,isObject:f,isUndefined:u,isDate:l,isFile:p,isBlob:d,isFunction:v,isStream:h,isURLSearchParams:m,isStandardBrowserEnv:g,forEach:b,merge:_,extend:w,trim:y}},function(e,t,n){"use strict";function r(e,t,n,r,o,i,a,s){var c="function"==typeof e?e.options:e;t&&(c.render=t,c.staticRenderFns=n,c._compiled=!0),r&&(c.functional=!0),i&&(c._scopeId="data-v-"+i);var u;if(a?(u=function(e){e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,e||"undefined"==typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),o&&o.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(a)},c._ssrRegister=u):o&&(u=s?function(){o.call(this,this.$root.$options.shadowRoot)}:o),u)if(c.functional){c._injectStyles=u;var f=c.render;c.render=function(e,t){return u.call(t),f(e,t)}}else{var l=c.beforeCreate;c.beforeCreate=l?[].concat(l,u):[u]}return{exports:e,options:c}}t.a=r},function(e,t){var n;n=function(){return this}();try{n=n||Function("return this")()||(0,eval)("this")}catch(e){"object"==typeof window&&(n=window)}e.exports=n},function(e,t,n){"use strict";(function(t){function r(e,t){!o.isUndefined(e)&&o.isUndefined(e["Content-Type"])&&(e["Content-Type"]=t)}var o=n(0),i=n(22),a={"Content-Type":"application/x-www-form-urlencoded"},s={adapter:function(){var e;return"undefined"!=typeof XMLHttpRequest?e=n(7):void 0!==t&&(e=n(7)),e}(),transformRequest:[function(e,t){return i(t,"Content-Type"),o.isFormData(e)||o.isArrayBuffer(e)||o.isBuffer(e)||o.isStream(e)||o.isFile(e)||o.isBlob(e)?e:o.isArrayBufferView(e)?e.buffer:o.isURLSearchParams(e)?(r(t,"application/x-www-form-urlencoded;charset=utf-8"),e.toString()):o.isObject(e)?(r(t,"application/json;charset=utf-8"),JSON.stringify(e)):e}],transformResponse:[function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(e){}return e}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,validateStatus:function(e){return e>=200&&e<300}};s.headers={common:{Accept:"application/json, text/plain, */*"}},o.forEach(["delete","get","head"],function(e){s.headers[e]={}}),o.forEach(["post","put","patch"],function(e){s.headers[e]=o.merge(a)}),e.exports=s}).call(t,n(5))},function(e,t,n){"use strict";(function(e,n){function r(e){return void 0===e||null===e}function o(e){return void 0!==e&&null!==e}function i(e){return!0===e}function a(e){return!1===e}function s(e){return"string"==typeof e||"number"==typeof e||"symbol"==typeof e||"boolean"==typeof e}function c(e){return null!==e&&"object"==typeof e}function u(e){return"[object Object]"===Ci.call(e)}function f(e){return"[object RegExp]"===Ci.call(e)}function l(e){var t=parseFloat(String(e));return t>=0&&Math.floor(t)===t&&isFinite(e)}function p(e){return o(e)&&"function"==typeof e.then&&"function"==typeof e.catch}function d(e){return null==e?"":Array.isArray(e)||u(e)&&e.toString===Ci?JSON.stringify(e,null,2):String(e)}function v(e){var t=parseFloat(e);return isNaN(t)?e:t}function h(e,t){for(var n=Object.create(null),r=e.split(","),o=0;o<r.length;o++)n[r[o]]=!0;return t?function(e){return n[e.toLowerCase()]}:function(e){return n[e]}}function m(e,t){if(e.length){var n=e.indexOf(t);if(n>-1)return e.splice(n,1)}}function y(e,t){return Si.call(e,t)}function g(e){var t=Object.create(null);return function(n){return t[n]||(t[n]=e(n))}}function b(e,t){function n(n){var r=arguments.length;return r?r>1?e.apply(t,arguments):e.call(t,n):e.call(t)}return n._length=e.length,n}function _(e,t){return e.bind(t)}function w(e,t){t=t||0;for(var n=e.length-t,r=new Array(n);n--;)r[n]=e[n+t];return r}function x(e,t){for(var n in t)e[n]=t[n];return e}function $(e){for(var t={},n=0;n<e.length;n++)e[n]&&x(t,e[n]);return t}function A(e,t,n){}function C(e,t){if(e===t)return!0;var n=c(e),r=c(t);if(!n||!r)return!n&&!r&&String(e)===String(t);try{var o=Array.isArray(e),i=Array.isArray(t);if(o&&i)return e.length===t.length&&e.every(function(e,n){return C(e,t[n])});if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();if(o||i)return!1;var a=Object.keys(e),s=Object.keys(t);return a.length===s.length&&a.every(function(n){return C(e[n],t[n])})}catch(e){return!1}}function k(e,t){for(var n=0;n<e.length;n++)if(C(e[n],t))return n;return-1}function T(e){var t=!1;return function(){t||(t=!0,e.apply(this,arguments))}}function S(e){var t=(e+"").charCodeAt(0);return 36===t||95===t}function O(e,t,n,r){Object.defineProperty(e,t,{value:n,enumerable:!!r,writable:!0,configurable:!0})}function E(e){if(!Hi.test(e)){var t=e.split(".");return function(e){for(var n=0;n<t.length;n++){if(!e)return;e=e[t[n]]}return e}}}function j(e){return"function"==typeof e&&/native code/.test(e.toString())}function I(e){fa.push(e),ua.target=e}function L(){fa.pop(),ua.target=fa[fa.length-1]}function N(e){return new la(void 0,void 0,void 0,String(e))}function D(e){var t=new la(e.tag,e.data,e.children&&e.children.slice(),e.text,e.elm,e.context,e.componentOptions,e.asyncFactory);return t.ns=e.ns,t.isStatic=e.isStatic,t.key=e.key,t.isComment=e.isComment,t.fnContext=e.fnContext,t.fnOptions=e.fnOptions,t.fnScopeId=e.fnScopeId,t.asyncMeta=e.asyncMeta,t.isCloned=!0,t}function P(e){ya=e}function R(e,t){e.__proto__=t}function M(e,t,n){for(var r=0,o=n.length;r<o;r++){var i=n[r];O(e,i,t[i])}}function B(e,t){if(c(e)&&!(e instanceof la)){var n;return y(e,"__ob__")&&e.__ob__ instanceof ga?n=e.__ob__:ya&&!oa()&&(Array.isArray(e)||u(e))&&Object.isExtensible(e)&&!e._isVue&&(n=new ga(e)),t&&n&&n.vmCount++,n}}function F(e,t,n,r,o){var i=new ua,a=Object.getOwnPropertyDescriptor(e,t);if(!a||!1!==a.configurable){var s=a&&a.get,c=a&&a.set;s&&!c||2!==arguments.length||(n=e[t]);var u=!o&&B(n);Object.defineProperty(e,t,{enumerable:!0,configurable:!0,get:function(){var t=s?s.call(e):n;return ua.target&&(i.depend(),u&&(u.dep.depend(),Array.isArray(t)&&q(t))),t},set:function(t){var r=s?s.call(e):n;t===r||t!==t&&r!==r||s&&!c||(c?c.call(e,t):n=t,u=!o&&B(t),i.notify())}})}}function U(e,t,n){if(Array.isArray(e)&&l(t))return e.length=Math.max(e.length,t),e.splice(t,1,n),n;if(t in e&&!(t in Object.prototype))return e[t]=n,n;var r=e.__ob__;return e._isVue||r&&r.vmCount?n:r?(F(r.value,t,n),r.dep.notify(),n):(e[t]=n,n)}function H(e,t){if(Array.isArray(e)&&l(t))return void e.splice(t,1);var n=e.__ob__;e._isVue||n&&n.vmCount||y(e,t)&&(delete e[t],n&&n.dep.notify())}function q(e){for(var t=void 0,n=0,r=e.length;n<r;n++)t=e[n],t&&t.__ob__&&t.__ob__.dep.depend(),Array.isArray(t)&&q(t)}function z(e,t){if(!t)return e;for(var n,r,o,i=aa?Reflect.ownKeys(t):Object.keys(t),a=0;a<i.length;a++)"__ob__"!==(n=i[a])&&(r=e[n],o=t[n],y(e,n)?r!==o&&u(r)&&u(o)&&z(r,o):U(e,n,o));return e}function V(e,t,n){return n?function(){var r="function"==typeof t?t.call(n,n):t,o="function"==typeof e?e.call(n,n):e;return r?z(r,o):o}:t?e?function(){return z("function"==typeof t?t.call(this,this):t,"function"==typeof e?e.call(this,this):e)}:t:e}function K(e,t){var n=t?e?e.concat(t):Array.isArray(t)?t:[t]:e;return n?J(n):n}function J(e){for(var t=[],n=0;n<e.length;n++)-1===t.indexOf(e[n])&&t.push(e[n]);return t}function X(e,t,n,r){var o=Object.create(e||null);return t?x(o,t):o}function W(e,t){var n=e.props;if(n){var r,o,i,a={};if(Array.isArray(n))for(r=n.length;r--;)"string"==typeof(o=n[r])&&(i=Ei(o),a[i]={type:null});else if(u(n))for(var s in n)o=n[s],i=Ei(s),a[i]=u(o)?o:{type:o};e.props=a}}function G(e,t){var n=e.inject;if(n){var r=e.inject={};if(Array.isArray(n))for(var o=0;o<n.length;o++)r[n[o]]={from:n[o]};else if(u(n))for(var i in n){var a=n[i];r[i]=u(a)?x({from:i},a):{from:a}}}}function Z(e){var t=e.directives;if(t)for(var n in t){var r=t[n];"function"==typeof r&&(t[n]={bind:r,update:r})}}function Y(e,t,n){function r(r){var o=ba[r]||wa;s[r]=o(e[r],t[r],n,r)}if("function"==typeof t&&(t=t.options),W(t,n),G(t,n),Z(t),!t._base&&(t.extends&&(e=Y(e,t.extends,n)),t.mixins))for(var o=0,i=t.mixins.length;o<i;o++)e=Y(e,t.mixins[o],n);var a,s={};for(a in e)r(a);for(a in t)y(e,a)||r(a);return s}function Q(e,t,n,r){if("string"==typeof n){var o=e[t];if(y(o,n))return o[n];var i=Ei(n);if(y(o,i))return o[i];var a=ji(i);return y(o,a)?o[a]:o[n]||o[i]||o[a]}}function ee(e,t,n,r){var o=t[e],i=!y(n,e),a=n[e],s=oe(Boolean,o.type);if(s>-1)if(i&&!y(o,"default"))a=!1;else if(""===a||a===Li(e)){var c=oe(String,o.type);(c<0||s<c)&&(a=!0)}if(void 0===a){a=te(r,o,e);var u=ya;P(!0),B(a),P(u)}return a}function te(e,t,n){if(y(t,"default")){var r=t.default;return e&&e.$options.propsData&&void 0===e.$options.propsData[n]&&void 0!==e._props[n]?e._props[n]:"function"==typeof r&&"Function"!==ne(t.type)?r.call(e):r}}function ne(e){var t=e&&e.toString().match(/^\s*function (\w+)/);return t?t[1]:""}function re(e,t){return ne(e)===ne(t)}function oe(e,t){if(!Array.isArray(t))return re(t,e)?0:-1;for(var n=0,r=t.length;n<r;n++)if(re(t[n],e))return n;return-1}function ie(e,t,n){I();try{if(t)for(var r=t;r=r.$parent;){var o=r.$options.errorCaptured;if(o)for(var i=0;i<o.length;i++)try{var a=!1===o[i].call(r,e,t,n);if(a)return}catch(e){se(e,r,"errorCaptured hook")}}se(e,t,n)}finally{L()}}function ae(e,t,n,r,o){var i;try{(i=n?e.apply(t,n):e.call(t))&&!i._isVue&&p(i)&&(i=i.catch(function(e){return ie(e,r,o+" (Promise/async)")}))}catch(e){ie(e,r,o)}return i}function se(e,t,n){if(Fi.errorHandler)try{return Fi.errorHandler.call(null,e,t,n)}catch(t){t!==e&&ce(t,null,"config.errorHandler")}ce(e,t,n)}function ce(e,t,n){if(!zi&&!Vi||"undefined"==typeof console)throw e;console.error(e)}function ue(){Aa=!1;var e=$a.slice(0);$a.length=0;for(var t=0;t<e.length;t++)e[t]()}function fe(e,t){var n;if($a.push(function(){if(e)try{e.call(t)}catch(e){ie(e,t,"nextTick")}else n&&n(t)}),Aa||(Aa=!0,_a()),!e&&"undefined"!=typeof Promise)return new Promise(function(e){n=e})}function le(e){pe(e,Oa),Oa.clear()}function pe(e,t){var n,r,o=Array.isArray(e);if(!(!o&&!c(e)||Object.isFrozen(e)||e instanceof la)){if(e.__ob__){var i=e.__ob__.dep.id;if(t.has(i))return;t.add(i)}if(o)for(n=e.length;n--;)pe(e[n],t);else for(r=Object.keys(e),n=r.length;n--;)pe(e[r[n]],t)}}function de(e,t){function n(){var e=arguments,r=n.fns;if(!Array.isArray(r))return ae(r,null,arguments,t,"v-on handler");for(var o=r.slice(),i=0;i<o.length;i++)ae(o[i],null,e,t,"v-on handler")}return n.fns=e,n}function ve(e,t,n,o,a,s){var c,u,f,l;for(c in e)u=e[c],f=t[c],l=Ea(c),r(u)||(r(f)?(r(u.fns)&&(u=e[c]=de(u,s)),i(l.once)&&(u=e[c]=a(l.name,u,l.capture)),n(l.name,u,l.capture,l.passive,l.params)):u!==f&&(f.fns=u,e[c]=f));for(c in t)r(e[c])&&(l=Ea(c),o(l.name,t[c],l.capture))}function he(e,t,n){function a(){n.apply(this,arguments),m(s.fns,a)}e instanceof la&&(e=e.data.hook||(e.data.hook={}));var s,c=e[t];r(c)?s=de([a]):o(c.fns)&&i(c.merged)?(s=c,s.fns.push(a)):s=de([c,a]),s.merged=!0,e[t]=s}function me(e,t,n){var i=t.options.props;if(!r(i)){var a={},s=e.attrs,c=e.props;if(o(s)||o(c))for(var u in i){var f=Li(u);ye(a,c,u,f,!0)||ye(a,s,u,f,!1)}return a}}function ye(e,t,n,r,i){if(o(t)){if(y(t,n))return e[n]=t[n],i||delete t[n],!0;if(y(t,r))return e[n]=t[r],i||delete t[r],!0}return!1}function ge(e){for(var t=0;t<e.length;t++)if(Array.isArray(e[t]))return Array.prototype.concat.apply([],e);return e}function be(e){return s(e)?[N(e)]:Array.isArray(e)?we(e):void 0}function _e(e){return o(e)&&o(e.text)&&a(e.isComment)}function we(e,t){var n,a,c,u,f=[];for(n=0;n<e.length;n++)a=e[n],r(a)||"boolean"==typeof a||(c=f.length-1,u=f[c],Array.isArray(a)?a.length>0&&(a=we(a,(t||"")+"_"+n),_e(a[0])&&_e(u)&&(f[c]=N(u.text+a[0].text),a.shift()),f.push.apply(f,a)):s(a)?_e(u)?f[c]=N(u.text+a):""!==a&&f.push(N(a)):_e(a)&&_e(u)?f[c]=N(u.text+a.text):(i(e._isVList)&&o(a.tag)&&r(a.key)&&o(t)&&(a.key="__vlist"+t+"_"+n+"__"),f.push(a)));return f}function xe(e){var t=e.$options.provide;t&&(e._provided="function"==typeof t?t.call(e):t)}function $e(e){var t=Ae(e.$options.inject,e);t&&(P(!1),Object.keys(t).forEach(function(n){F(e,n,t[n])}),P(!0))}function Ae(e,t){if(e){for(var n=Object.create(null),r=aa?Reflect.ownKeys(e):Object.keys(e),o=0;o<r.length;o++){var i=r[o];if("__ob__"!==i){for(var a=e[i].from,s=t;s;){if(s._provided&&y(s._provided,a)){n[i]=s._provided[a];break}s=s.$parent}if(!s&&"default"in e[i]){var c=e[i].default;n[i]="function"==typeof c?c.call(t):c}}}return n}}function Ce(e,t){if(!e||!e.length)return{};for(var n={},r=0,o=e.length;r<o;r++){var i=e[r],a=i.data;if(a&&a.attrs&&a.attrs.slot&&delete a.attrs.slot,i.context!==t&&i.fnContext!==t||!a||null==a.slot)(n.default||(n.default=[])).push(i);else{var s=a.slot,c=n[s]||(n[s]=[]);"template"===i.tag?c.push.apply(c,i.children||[]):c.push(i)}}for(var u in n)n[u].every(ke)&&delete n[u];return n}function ke(e){return e.isComment&&!e.asyncFactory||" "===e.text}function Te(e,t,n){var r,o=!e||!!e.$stable,i=e&&e.$key;if(e){if(e._normalized)return e._normalized;if(o&&n&&n!==Ai&&i===n.$key&&0===Object.keys(t).length)return n;r={};for(var a in e)e[a]&&"$"!==a[0]&&(r[a]=Se(t,a,e[a]))}else r={};for(var s in t)s in r||(r[s]=Oe(t,s));return e&&Object.isExtensible(e)&&(e._normalized=r),O(r,"$stable",o),O(r,"$key",i),r}function Se(e,t,n){var r=function(){var e=arguments.length?n.apply(null,arguments):n({});return e=e&&"object"==typeof e&&!Array.isArray(e)?[e]:be(e),e&&0===e.length?void 0:e};return n.proxy&&Object.defineProperty(e,t,{get:r,enumerable:!0,configurable:!0}),r}function Oe(e,t){return function(){return e[t]}}function Ee(e,t){var n,r,i,a,s;if(Array.isArray(e)||"string"==typeof e)for(n=new Array(e.length),r=0,i=e.length;r<i;r++)n[r]=t(e[r],r);else if("number"==typeof e)for(n=new Array(e),r=0;r<e;r++)n[r]=t(r+1,r);else if(c(e))if(aa&&e[Symbol.iterator]){n=[];for(var u=e[Symbol.iterator](),f=u.next();!f.done;)n.push(t(f.value,n.length)),f=u.next()}else for(a=Object.keys(e),n=new Array(a.length),r=0,i=a.length;r<i;r++)s=a[r],n[r]=t(e[s],s,r);return o(n)||(n=[]),n._isVList=!0,n}function je(e,t,n,r){var o,i=this.$scopedSlots[e];i?(n=n||{},r&&(n=x(x({},r),n)),o=i(n)||t):o=this.$slots[e]||t;var a=n&&n.slot;return a?this.$createElement("template",{slot:a},o):o}function Ie(e){return Q(this.$options,"filters",e,!0)||Pi}function Le(e,t){return Array.isArray(e)?-1===e.indexOf(t):e!==t}function Ne(e,t,n,r,o){var i=Fi.keyCodes[t]||n;return o&&r&&!Fi.keyCodes[t]?Le(o,r):i?Le(i,e):r?Li(r)!==t:void 0}function De(e,t,n,r,o){if(n&&c(n)){Array.isArray(n)&&(n=$(n));var i;for(var a in n)!function(a){if("class"===a||"style"===a||Ti(a))i=e;else{var s=e.attrs&&e.attrs.type;i=r||Fi.mustUseProp(t,s,a)?e.domProps||(e.domProps={}):e.attrs||(e.attrs={})}var c=Ei(a);a in i||c in i||(i[a]=n[a],!o)||((e.on||(e.on={}))["update:"+c]=function(e){n[a]=e})}(a)}return e}function Pe(e,t){var n=this._staticTrees||(this._staticTrees=[]),r=n[e];return r&&!t?r:(r=n[e]=this.$options.staticRenderFns[e].call(this._renderProxy,null,this),Me(r,"__static__"+e,!1),r)}function Re(e,t,n){return Me(e,"__once__"+t+(n?"_"+n:""),!0),e}function Me(e,t,n){if(Array.isArray(e))for(var r=0;r<e.length;r++)e[r]&&"string"!=typeof e[r]&&Be(e[r],t+"_"+r,n);else Be(e,t,n)}function Be(e,t,n){e.isStatic=!0,e.key=t,e.isOnce=n}function Fe(e,t){if(t&&u(t)){var n=e.on=e.on?x({},e.on):{};for(var r in t){var o=n[r],i=t[r];n[r]=o?[].concat(o,i):i}}return e}function Ue(e,t,n,r){t=t||{$stable:!n};for(var o=0;o<e.length;o++){var i=e[o];Array.isArray(i)?Ue(i,t,n):i&&(i.proxy&&(i.fn.proxy=!0),t[i.key]=i.fn)}return r&&(t.$key=r),t}function He(e,t){for(var n=0;n<t.length;n+=2){var r=t[n];"string"==typeof r&&r&&(e[t[n]]=t[n+1])}return e}function qe(e,t){return"string"==typeof e?t+e:e}function ze(e){e._o=Re,e._n=v,e._s=d,e._l=Ee,e._t=je,e._q=C,e._i=k,e._m=Pe,e._f=Ie,e._k=Ne,e._b=De,e._v=N,e._e=da,e._u=Ue,e._g=Fe,e._d=He,e._p=qe}function Ve(e,t,n,r,o){var a,s=this,c=o.options;y(r,"_uid")?(a=Object.create(r),a._original=r):(a=r,r=r._original);var u=i(c._compiled),f=!u;this.data=e,this.props=t,this.children=n,this.parent=r,this.listeners=e.on||Ai,this.injections=Ae(c.inject,r),this.slots=function(){return s.$slots||Te(e.scopedSlots,s.$slots=Ce(n,r)),s.$slots},Object.defineProperty(this,"scopedSlots",{enumerable:!0,get:function(){return Te(e.scopedSlots,this.slots())}}),u&&(this.$options=c,this.$slots=this.slots(),this.$scopedSlots=Te(e.scopedSlots,this.$slots)),c._scopeId?this._c=function(e,t,n,o){var i=et(a,e,t,n,o,f);return i&&!Array.isArray(i)&&(i.fnScopeId=c._scopeId,i.fnContext=r),i}:this._c=function(e,t,n,r){return et(a,e,t,n,r,f)}}function Ke(e,t,n,r,i){var a=e.options,s={},c=a.props;if(o(c))for(var u in c)s[u]=ee(u,c,t||Ai);else o(n.attrs)&&Xe(s,n.attrs),o(n.props)&&Xe(s,n.props);var f=new Ve(n,s,i,r,e),l=a.render.call(null,f._c,f);if(l instanceof la)return Je(l,n,f.parent,a,f);if(Array.isArray(l)){for(var p=be(l)||[],d=new Array(p.length),v=0;v<p.length;v++)d[v]=Je(p[v],n,f.parent,a,f);return d}}function Je(e,t,n,r,o){var i=D(e);return i.fnContext=n,i.fnOptions=r,t.slot&&((i.data||(i.data={})).slot=t.slot),i}function Xe(e,t){for(var n in t)e[Ei(n)]=t[n]}function We(e,t,n,a,s){if(!r(e)){var u=n.$options._base;if(c(e)&&(e=u.extend(e)),"function"==typeof e){var f;if(r(e.cid)&&(f=e,void 0===(e=st(f,u))))return at(f,t,n,a,s);t=t||{},Ht(e),o(t.model)&&Qe(e.options,t);var l=me(t,e,s);if(i(e.options.functional))return Ke(e,l,t,n,a);var p=t.on;if(t.on=t.nativeOn,i(e.options.abstract)){var d=t.slot;t={},d&&(t.slot=d)}Ze(t);var v=e.options.name||s;return new la("vue-component-"+e.cid+(v?"-"+v:""),t,void 0,void 0,void 0,n,{Ctor:e,propsData:l,listeners:p,tag:s,children:a},f)}}}function Ge(e,t){var n={_isComponent:!0,_parentVnode:e,parent:t},r=e.data.inlineTemplate;return o(r)&&(n.render=r.render,n.staticRenderFns=r.staticRenderFns),new e.componentOptions.Ctor(n)}function Ze(e){for(var t=e.hook||(e.hook={}),n=0;n<La.length;n++){var r=La[n],o=t[r],i=Ia[r];o===i||o&&o._merged||(t[r]=o?Ye(i,o):i)}}function Ye(e,t){var n=function(n,r){e(n,r),t(n,r)};return n._merged=!0,n}function Qe(e,t){var n=e.model&&e.model.prop||"value",r=e.model&&e.model.event||"input";(t.attrs||(t.attrs={}))[n]=t.model.value;var i=t.on||(t.on={}),a=i[r],s=t.model.callback;o(a)?(Array.isArray(a)?-1===a.indexOf(s):a!==s)&&(i[r]=[s].concat(a)):i[r]=s}function et(e,t,n,r,o,a){return(Array.isArray(n)||s(n))&&(o=r,r=n,n=void 0),i(a)&&(o=Da),tt(e,t,n,r,o)}function tt(e,t,n,r,i){if(o(n)&&o(n.__ob__))return da();if(o(n)&&o(n.is)&&(t=n.is),!t)return da();Array.isArray(r)&&"function"==typeof r[0]&&(n=n||{},n.scopedSlots={default:r[0]},r.length=0),i===Da?r=be(r):i===Na&&(r=ge(r));var a,s;if("string"==typeof t){var c;s=e.$vnode&&e.$vnode.ns||Fi.getTagNamespace(t),a=Fi.isReservedTag(t)?new la(Fi.parsePlatformTagName(t),n,r,void 0,void 0,e):n&&n.pre||!o(c=Q(e.$options,"components",t))?new la(t,n,r,void 0,void 0,e):We(c,n,e,r,t)}else a=We(t,n,e,r);return Array.isArray(a)?a:o(a)?(o(s)&&nt(a,s),o(n)&&rt(n),a):da()}function nt(e,t,n){if(e.ns=t,"foreignObject"===e.tag&&(t=void 0,n=!0),o(e.children))for(var a=0,s=e.children.length;a<s;a++){var c=e.children[a];o(c.tag)&&(r(c.ns)||i(n)&&"svg"!==c.tag)&&nt(c,t,n)}}function rt(e){c(e.style)&&le(e.style),c(e.class)&&le(e.class)}function ot(e){e._vnode=null,e._staticTrees=null;var t=e.$options,n=e.$vnode=t._parentVnode,r=n&&n.context;e.$slots=Ce(t._renderChildren,r),e.$scopedSlots=Ai,e._c=function(t,n,r,o){return et(e,t,n,r,o,!1)},e.$createElement=function(t,n,r,o){return et(e,t,n,r,o,!0)};var o=n&&n.data;F(e,"$attrs",o&&o.attrs||Ai,null,!0),F(e,"$listeners",t._parentListeners||Ai,null,!0)}function it(e,t){return(e.__esModule||aa&&"Module"===e[Symbol.toStringTag])&&(e=e.default),c(e)?t.extend(e):e}function at(e,t,n,r,o){var i=da();return i.asyncFactory=e,i.asyncMeta={data:t,context:n,children:r,tag:o},i}function st(e,t){if(i(e.error)&&o(e.errorComp))return e.errorComp;if(o(e.resolved))return e.resolved;if(i(e.loading)&&o(e.loadingComp))return e.loadingComp;var n=Pa;if(!o(e.owners)){var a=e.owners=[n],s=!0,u=function(e){for(var t=0,n=a.length;t<n;t++)a[t].$forceUpdate();e&&(a.length=0)},f=T(function(n){e.resolved=it(n,t),s?a.length=0:u(!0)}),l=T(function(t){o(e.errorComp)&&(e.error=!0,u(!0))}),d=e(f,l);return c(d)&&(p(d)?r(e.resolved)&&d.then(f,l):p(d.component)&&(d.component.then(f,l),o(d.error)&&(e.errorComp=it(d.error,t)),o(d.loading)&&(e.loadingComp=it(d.loading,t),0===d.delay?e.loading=!0:setTimeout(function(){r(e.resolved)&&r(e.error)&&(e.loading=!0,u(!1))},d.delay||200)),o(d.timeout)&&setTimeout(function(){r(e.resolved)&&l(null)},d.timeout))),s=!1,e.loading?e.loadingComp:e.resolved}e.owners.push(n)}function ct(e){return e.isComment&&e.asyncFactory}function ut(e){if(Array.isArray(e))for(var t=0;t<e.length;t++){var n=e[t];if(o(n)&&(o(n.componentOptions)||ct(n)))return n}}function ft(e){e._events=Object.create(null),e._hasHookEvent=!1;var t=e.$options._parentListeners;t&&vt(e,t)}function lt(e,t){ja.$on(e,t)}function pt(e,t){ja.$off(e,t)}function dt(e,t){var n=ja;return function r(){null!==t.apply(null,arguments)&&n.$off(e,r)}}function vt(e,t,n){ja=e,ve(t,n||{},lt,pt,dt,e),ja=void 0}function ht(e){var t=Ra;return Ra=e,function(){Ra=t}}function mt(e){var t=e.$options,n=t.parent;if(n&&!t.abstract){for(;n.$options.abstract&&n.$parent;)n=n.$parent;n.$children.push(e)}e.$parent=n,e.$root=n?n.$root:e,e.$children=[],e.$refs={},e._watcher=null,e._inactive=null,e._directInactive=!1,e._isMounted=!1,e._isDestroyed=!1,e._isBeingDestroyed=!1}function yt(e,t,n){e.$el=t,e.$options.render||(e.$options.render=da),xt(e,"beforeMount");var r;return r=function(){e._update(e._render(),n)},new Ja(e,r,A,{before:function(){e._isMounted&&!e._isDestroyed&&xt(e,"beforeUpdate")}},!0),n=!1,null==e.$vnode&&(e._isMounted=!0,xt(e,"mounted")),e}function gt(e,t,n,r,o){var i=r.data.scopedSlots,a=e.$scopedSlots,s=!!(i&&!i.$stable||a!==Ai&&!a.$stable||i&&e.$scopedSlots.$key!==i.$key),c=!!(o||e.$options._renderChildren||s);if(e.$options._parentVnode=r,e.$vnode=r,e._vnode&&(e._vnode.parent=r),e.$options._renderChildren=o,e.$attrs=r.data.attrs||Ai,e.$listeners=n||Ai,t&&e.$options.props){P(!1);for(var u=e._props,f=e.$options._propKeys||[],l=0;l<f.length;l++){var p=f[l],d=e.$options.props;u[p]=ee(p,d,t,e)}P(!0),e.$options.propsData=t}n=n||Ai;var v=e.$options._parentListeners;e.$options._parentListeners=n,vt(e,n,v),c&&(e.$slots=Ce(o,r.context),e.$forceUpdate())}function bt(e){for(;e&&(e=e.$parent);)if(e._inactive)return!0;return!1}function _t(e,t){if(t){if(e._directInactive=!1,bt(e))return}else if(e._directInactive)return;if(e._inactive||null===e._inactive){e._inactive=!1;for(var n=0;n<e.$children.length;n++)_t(e.$children[n]);xt(e,"activated")}}function wt(e,t){if(!(t&&(e._directInactive=!0,bt(e))||e._inactive)){e._inactive=!0;for(var n=0;n<e.$children.length;n++)wt(e.$children[n]);xt(e,"deactivated")}}function xt(e,t){I();var n=e.$options[t],r=t+" hook";if(n)for(var o=0,i=n.length;o<i;o++)ae(n[o],e,null,e,r);e._hasHookEvent&&e.$emit("hook:"+t),L()}function $t(){qa=Ma.length=Ba.length=0,Fa={},Ua=Ha=!1}function At(){za=Va(),Ha=!0;var e,t;for(Ma.sort(function(e,t){return e.id-t.id}),qa=0;qa<Ma.length;qa++)e=Ma[qa],e.before&&e.before(),t=e.id,Fa[t]=null,e.run();var n=Ba.slice(),r=Ma.slice();$t(),Tt(n),Ct(r),ia&&Fi.devtools&&ia.emit("flush")}function Ct(e){for(var t=e.length;t--;){var n=e[t],r=n.vm;r._watcher===n&&r._isMounted&&!r._isDestroyed&&xt(r,"updated")}}function kt(e){e._inactive=!1,Ba.push(e)}function Tt(e){for(var t=0;t<e.length;t++)e[t]._inactive=!0,_t(e[t],!0)}function St(e){var t=e.id;if(null==Fa[t]){if(Fa[t]=!0,Ha){for(var n=Ma.length-1;n>qa&&Ma[n].id>e.id;)n--;Ma.splice(n+1,0,e)}else Ma.push(e);Ua||(Ua=!0,fe(At))}}function Ot(e,t,n){Xa.get=function(){return this[t][n]},Xa.set=function(e){this[t][n]=e},Object.defineProperty(e,n,Xa)}function Et(e){e._watchers=[];var t=e.$options;t.props&&jt(e,t.props),t.methods&&Mt(e,t.methods),t.data?It(e):B(e._data={},!0),t.computed&&Nt(e,t.computed),t.watch&&t.watch!==Qi&&Bt(e,t.watch)}function jt(e,t){var n=e.$options.propsData||{},r=e._props={},o=e.$options._propKeys=[];!e.$parent||P(!1);for(var i in t)!function(i){o.push(i);var a=ee(i,t,n,e);F(r,i,a),i in e||Ot(e,"_props",i)}(i);P(!0)}function It(e){var t=e.$options.data;t=e._data="function"==typeof t?Lt(t,e):t||{},u(t)||(t={});for(var n=Object.keys(t),r=e.$options.props,o=(e.$options.methods,n.length);o--;){var i=n[o];r&&y(r,i)||S(i)||Ot(e,"_data",i)}B(t,!0)}function Lt(e,t){I();try{return e.call(t,t)}catch(e){return ie(e,t,"data()"),{}}finally{L()}}function Nt(e,t){var n=e._computedWatchers=Object.create(null),r=oa();for(var o in t){var i=t[o],a="function"==typeof i?i:i.get;r||(n[o]=new Ja(e,a||A,A,Wa)),o in e||Dt(e,o,i)}}function Dt(e,t,n){var r=!oa();"function"==typeof n?(Xa.get=r?Pt(t):Rt(n),Xa.set=A):(Xa.get=n.get?r&&!1!==n.cache?Pt(t):Rt(n.get):A,Xa.set=n.set||A),Object.defineProperty(e,t,Xa)}function Pt(e){return function(){var t=this._computedWatchers&&this._computedWatchers[e];if(t)return t.dirty&&t.evaluate(),ua.target&&t.depend(),t.value}}function Rt(e){return function(){return e.call(this,this)}}function Mt(e,t){e.$options.props;for(var n in t)e[n]="function"!=typeof t[n]?A:Ni(t[n],e)}function Bt(e,t){for(var n in t){var r=t[n];if(Array.isArray(r))for(var o=0;o<r.length;o++)Ft(e,n,r[o]);else Ft(e,n,r)}}function Ft(e,t,n,r){return u(n)&&(r=n,n=n.handler),"string"==typeof n&&(n=e[n]),e.$watch(t,n,r)}function Ut(e,t){var n=e.$options=Object.create(e.constructor.options),r=t._parentVnode;n.parent=t.parent,n._parentVnode=r;var o=r.componentOptions;n.propsData=o.propsData,n._parentListeners=o.listeners,n._renderChildren=o.children,n._componentTag=o.tag,t.render&&(n.render=t.render,n.staticRenderFns=t.staticRenderFns)}function Ht(e){var t=e.options;if(e.super){var n=Ht(e.super);if(n!==e.superOptions){e.superOptions=n;var r=qt(e);r&&x(e.extendOptions,r),t=e.options=Y(n,e.extendOptions),t.name&&(t.components[t.name]=e)}}return t}function qt(e){var t,n=e.options,r=e.sealedOptions;for(var o in n)n[o]!==r[o]&&(t||(t={}),t[o]=n[o]);return t}function zt(e){this._init(e)}function Vt(e){e.use=function(e){var t=this._installedPlugins||(this._installedPlugins=[]);if(t.indexOf(e)>-1)return this;var n=w(arguments,1);return n.unshift(this),"function"==typeof e.install?e.install.apply(e,n):"function"==typeof e&&e.apply(null,n),t.push(e),this}}function Kt(e){e.mixin=function(e){return this.options=Y(this.options,e),this}}function Jt(e){e.cid=0;var t=1;e.extend=function(e){e=e||{};var n=this,r=n.cid,o=e._Ctor||(e._Ctor={});if(o[r])return o[r];var i=e.name||n.options.name,a=function(e){this._init(e)};return a.prototype=Object.create(n.prototype),a.prototype.constructor=a,a.cid=t++,a.options=Y(n.options,e),a.super=n,a.options.props&&Xt(a),a.options.computed&&Wt(a),a.extend=n.extend,a.mixin=n.mixin,a.use=n.use,Mi.forEach(function(e){a[e]=n[e]}),i&&(a.options.components[i]=a),a.superOptions=n.options,a.extendOptions=e,a.sealedOptions=x({},a.options),o[r]=a,a}}function Xt(e){var t=e.options.props;for(var n in t)Ot(e.prototype,"_props",n)}function Wt(e){var t=e.options.computed;for(var n in t)Dt(e.prototype,n,t[n])}function Gt(e){Mi.forEach(function(t){e[t]=function(e,n){return n?("component"===t&&u(n)&&(n.name=n.name||e,n=this.options._base.extend(n)),"directive"===t&&"function"==typeof n&&(n={bind:n,update:n}),this.options[t+"s"][e]=n,n):this.options[t+"s"][e]}})}function Zt(e){return e&&(e.Ctor.options.name||e.tag)}function Yt(e,t){return Array.isArray(e)?e.indexOf(t)>-1:"string"==typeof e?e.split(",").indexOf(t)>-1:!!f(e)&&e.test(t)}function Qt(e,t){var n=e.cache,r=e.keys,o=e._vnode;for(var i in n){var a=n[i];if(a){var s=Zt(a.componentOptions);s&&!t(s)&&en(n,i,r,o)}}}function en(e,t,n,r){var o=e[t];!o||r&&o.tag===r.tag||o.componentInstance.$destroy(),e[t]=null,m(n,t)}function tn(e){for(var t=e.data,n=e,r=e;o(r.componentInstance);)(r=r.componentInstance._vnode)&&r.data&&(t=nn(r.data,t));for(;o(n=n.parent);)n&&n.data&&(t=nn(t,n.data));return rn(t.staticClass,t.class)}function nn(e,t){return{staticClass:on(e.staticClass,t.staticClass),class:o(e.class)?[e.class,t.class]:t.class}}function rn(e,t){return o(e)||o(t)?on(e,an(t)):""}function on(e,t){return e?t?e+" "+t:e:t||""}function an(e){return Array.isArray(e)?sn(e):c(e)?cn(e):"string"==typeof e?e:""}function sn(e){for(var t,n="",r=0,i=e.length;r<i;r++)o(t=an(e[r]))&&""!==t&&(n&&(n+=" "),n+=t);return n}function cn(e){var t="";for(var n in e)e[n]&&(t&&(t+=" "),t+=n);return t}function un(e){return $s(e)?"svg":"math"===e?"math":void 0}function fn(e){if(!zi)return!0;if(Cs(e))return!1;if(e=e.toLowerCase(),null!=ks[e])return ks[e];var t=document.createElement(e);return e.indexOf("-")>-1?ks[e]=t.constructor===window.HTMLUnknownElement||t.constructor===window.HTMLElement:ks[e]=/HTMLUnknownElement/.test(t.toString())}function ln(e){if("string"==typeof e){return document.querySelector(e)||document.createElement("div")}return e}function pn(e,t){var n=document.createElement(e);return"select"!==e?n:(t.data&&t.data.attrs&&void 0!==t.data.attrs.multiple&&n.setAttribute("multiple","multiple"),n)}function dn(e,t){return document.createElementNS(ws[e],t)}function vn(e){return document.createTextNode(e)}function hn(e){return document.createComment(e)}function mn(e,t,n){e.insertBefore(t,n)}function yn(e,t){e.removeChild(t)}function gn(e,t){e.appendChild(t)}function bn(e){return e.parentNode}function _n(e){return e.nextSibling}function wn(e){return e.tagName}function xn(e,t){e.textContent=t}function $n(e,t){e.setAttribute(t,"")}function An(e,t){var n=e.data.ref;if(o(n)){var r=e.context,i=e.componentInstance||e.elm,a=r.$refs;t?Array.isArray(a[n])?m(a[n],i):a[n]===i&&(a[n]=void 0):e.data.refInFor?Array.isArray(a[n])?a[n].indexOf(i)<0&&a[n].push(i):a[n]=[i]:a[n]=i}}function Cn(e,t){return e.key===t.key&&(e.tag===t.tag&&e.isComment===t.isComment&&o(e.data)===o(t.data)&&kn(e,t)||i(e.isAsyncPlaceholder)&&e.asyncFactory===t.asyncFactory&&r(t.asyncFactory.error))}function kn(e,t){if("input"!==e.tag)return!0;var n,r=o(n=e.data)&&o(n=n.attrs)&&n.type,i=o(n=t.data)&&o(n=n.attrs)&&n.type;return r===i||Ts(r)&&Ts(i)}function Tn(e,t,n){var r,i,a={};for(r=t;r<=n;++r)i=e[r].key,o(i)&&(a[i]=r);return a}function Sn(e,t){(e.data.directives||t.data.directives)&&On(e,t)}function On(e,t){var n,r,o,i=e===Es,a=t===Es,s=En(e.data.directives,e.context),c=En(t.data.directives,t.context),u=[],f=[];for(n in c)r=s[n],o=c[n],r?(o.oldValue=r.value,o.oldArg=r.arg,In(o,"update",t,e),o.def&&o.def.componentUpdated&&f.push(o)):(In(o,"bind",t,e),o.def&&o.def.inserted&&u.push(o));if(u.length){var l=function(){for(var n=0;n<u.length;n++)In(u[n],"inserted",t,e)};i?he(t,"insert",l):l()}if(f.length&&he(t,"postpatch",function(){for(var n=0;n<f.length;n++)In(f[n],"componentUpdated",t,e)}),!i)for(n in s)c[n]||In(s[n],"unbind",e,e,a)}function En(e,t){var n=Object.create(null);if(!e)return n;var r,o;for(r=0;r<e.length;r++)o=e[r],o.modifiers||(o.modifiers=Ls),n[jn(o)]=o,o.def=Q(t.$options,"directives",o.name,!0);return n}function jn(e){return e.rawName||e.name+"."+Object.keys(e.modifiers||{}).join(".")}function In(e,t,n,r,o){var i=e.def&&e.def[t];if(i)try{i(n.elm,e,n,r,o)}catch(r){ie(r,n.context,"directive "+e.name+" "+t+" hook")}}function Ln(e,t){var n=t.componentOptions;if(!(o(n)&&!1===n.Ctor.options.inheritAttrs||r(e.data.attrs)&&r(t.data.attrs))){var i,a,s=t.elm,c=e.data.attrs||{},u=t.data.attrs||{};o(u.__ob__)&&(u=t.data.attrs=x({},u));for(i in u)a=u[i],c[i]!==a&&Nn(s,i,a);(Xi||Gi)&&u.value!==c.value&&Nn(s,"value",u.value);for(i in c)r(u[i])&&(gs(i)?s.removeAttributeNS(ys,bs(i)):ds(i)||s.removeAttribute(i))}}function Nn(e,t,n){e.tagName.indexOf("-")>-1?Dn(e,t,n):ms(t)?_s(n)?e.removeAttribute(t):(n="allowfullscreen"===t&&"EMBED"===e.tagName?"true":t,e.setAttribute(t,n)):ds(t)?e.setAttribute(t,hs(t,n)):gs(t)?_s(n)?e.removeAttributeNS(ys,bs(t)):e.setAttributeNS(ys,t,n):Dn(e,t,n)}function Dn(e,t,n){if(_s(n))e.removeAttribute(t);else{if(Xi&&!Wi&&"TEXTAREA"===e.tagName&&"placeholder"===t&&""!==n&&!e.__ieph){var r=function(t){t.stopImmediatePropagation(),e.removeEventListener("input",r)};e.addEventListener("input",r),e.__ieph=!0}e.setAttribute(t,n)}}function Pn(e,t){var n=t.elm,i=t.data,a=e.data;if(!(r(i.staticClass)&&r(i.class)&&(r(a)||r(a.staticClass)&&r(a.class)))){var s=tn(t),c=n._transitionClasses;o(c)&&(s=on(s,an(c))),s!==n._prevClass&&(n.setAttribute("class",s),n._prevClass=s)}}function Rn(e){function t(){(a||(a=[])).push(e.slice(v,o).trim()),v=o+1}var n,r,o,i,a,s=!1,c=!1,u=!1,f=!1,l=0,p=0,d=0,v=0;for(o=0;o<e.length;o++)if(r=n,n=e.charCodeAt(o),s)39===n&&92!==r&&(s=!1);else if(c)34===n&&92!==r&&(c=!1);else if(u)96===n&&92!==r&&(u=!1);else if(f)47===n&&92!==r&&(f=!1);else if(124!==n||124===e.charCodeAt(o+1)||124===e.charCodeAt(o-1)||l||p||d){switch(n){case 34:c=!0;break;case 39:s=!0;break;case 96:u=!0;break;case 40:d++;break;case 41:d--;break;case 91:p++;break;case 93:p--;break;case 123:l++;break;case 125:l--}if(47===n){for(var h=o-1,m=void 0;h>=0&&" "===(m=e.charAt(h));h--);m&&Rs.test(m)||(f=!0)}}else void 0===i?(v=o+1,i=e.slice(0,o).trim()):t();if(void 0===i?i=e.slice(0,o).trim():0!==v&&t(),a)for(o=0;o<a.length;o++)i=Mn(i,a[o]);return i}function Mn(e,t){var n=t.indexOf("(");if(n<0)return'_f("'+t+'")('+e+")";var r=t.slice(0,n),o=t.slice(n+1);return'_f("'+r+'")('+e+(")"!==o?","+o:o)}function Bn(e,t){console.error("[Vue compiler]: "+e)}function Fn(e,t){return e?e.map(function(e){return e[t]}).filter(function(e){return e}):[]}function Un(e,t,n,r,o){(e.props||(e.props=[])).push(Zn({name:t,value:n,dynamic:o},r)),e.plain=!1}function Hn(e,t,n,r,o){(o?e.dynamicAttrs||(e.dynamicAttrs=[]):e.attrs||(e.attrs=[])).push(Zn({name:t,value:n,dynamic:o},r)),e.plain=!1}function qn(e,t,n,r){e.attrsMap[t]=n,e.attrsList.push(Zn({name:t,value:n},r))}function zn(e,t,n,r,o,i,a,s){(e.directives||(e.directives=[])).push(Zn({name:t,rawName:n,value:r,arg:o,isDynamicArg:i,modifiers:a},s)),e.plain=!1}function Vn(e,t,n){return n?"_p("+t+',"'+e+'")':e+t}function Kn(e,t,n,r,o,i,a,s){r=r||Ai,r.right?s?t="("+t+")==='click'?'contextmenu':("+t+")":"click"===t&&(t="contextmenu",delete r.right):r.middle&&(s?t="("+t+")==='click'?'mouseup':("+t+")":"click"===t&&(t="mouseup")),r.capture&&(delete r.capture,t=Vn("!",t,s)),r.once&&(delete r.once,t=Vn("~",t,s)),r.passive&&(delete r.passive,t=Vn("&",t,s));var c;r.native?(delete r.native,c=e.nativeEvents||(e.nativeEvents={})):c=e.events||(e.events={});var u=Zn({value:n.trim(),dynamic:s},a);r!==Ai&&(u.modifiers=r);var f=c[t];Array.isArray(f)?o?f.unshift(u):f.push(u):c[t]=f?o?[u,f]:[f,u]:u,e.plain=!1}function Jn(e,t){return e.rawAttrsMap[":"+t]||e.rawAttrsMap["v-bind:"+t]||e.rawAttrsMap[t]}function Xn(e,t,n){var r=Wn(e,":"+t)||Wn(e,"v-bind:"+t);if(null!=r)return Rn(r);if(!1!==n){var o=Wn(e,t);if(null!=o)return JSON.stringify(o)}}function Wn(e,t,n){var r;if(null!=(r=e.attrsMap[t]))for(var o=e.attrsList,i=0,a=o.length;i<a;i++)if(o[i].name===t){o.splice(i,1);break}return n&&delete e.attrsMap[t],r}function Gn(e,t){for(var n=e.attrsList,r=0,o=n.length;r<o;r++){var i=n[r];if(t.test(i.name))return n.splice(r,1),i}}function Zn(e,t){return t&&(null!=t.start&&(e.start=t.start),null!=t.end&&(e.end=t.end)),e}function Yn(e,t,n){var r=n||{},o=r.number,i=r.trim,a="$$v";i&&(a="(typeof $$v === 'string'? $$v.trim(): $$v)"),o&&(a="_n("+a+")");var s=Qn(t,a);e.model={value:"("+t+")",expression:JSON.stringify(t),callback:"function ($$v) {"+s+"}"}}function Qn(e,t){var n=er(e);return null===n.key?e+"="+t:"$set("+n.exp+", "+n.key+", "+t+")"}function er(e){if(e=e.trim(),es=e.length,e.indexOf("[")<0||e.lastIndexOf("]")<es-1)return rs=e.lastIndexOf("."),rs>-1?{exp:e.slice(0,rs),key:'"'+e.slice(rs+1)+'"'}:{exp:e,key:null};for(ts=e,rs=os=is=0;!nr();)ns=tr(),rr(ns)?ir(ns):91===ns&&or(ns);return{exp:e.slice(0,os),key:e.slice(os+1,is)}}function tr(){return ts.charCodeAt(++rs)}function nr(){return rs>=es}function rr(e){return 34===e||39===e}function or(e){var t=1;for(os=rs;!nr();)if(e=tr(),rr(e))ir(e);else if(91===e&&t++,93===e&&t--,0===t){is=rs;break}}function ir(e){for(var t=e;!nr()&&(e=tr())!==t;);}function ar(e,t,n){as=n;var r=t.value,o=t.modifiers,i=e.tag,a=e.attrsMap.type;if(e.component)return Yn(e,r,o),!1;if("select"===i)ur(e,r,o);else if("input"===i&&"checkbox"===a)sr(e,r,o);else if("input"===i&&"radio"===a)cr(e,r,o);else if("input"===i||"textarea"===i)fr(e,r,o);else if(!Fi.isReservedTag(i))return Yn(e,r,o),!1;return!0}function sr(e,t,n){var r=n&&n.number,o=Xn(e,"value")||"null",i=Xn(e,"true-value")||"true",a=Xn(e,"false-value")||"false";Un(e,"checked","Array.isArray("+t+")?_i("+t+","+o+")>-1"+("true"===i?":("+t+")":":_q("+t+","+i+")")),Kn(e,"change","var $$a="+t+",$$el=$event.target,$$c=$$el.checked?("+i+"):("+a+");if(Array.isArray($$a)){var $$v="+(r?"_n("+o+")":o)+",$$i=_i($$a,$$v);if($$el.checked){$$i<0&&("+Qn(t,"$$a.concat([$$v])")+")}else{$$i>-1&&("+Qn(t,"$$a.slice(0,$$i).concat($$a.slice($$i+1))")+")}}else{"+Qn(t,"$$c")+"}",null,!0)}function cr(e,t,n){var r=n&&n.number,o=Xn(e,"value")||"null";o=r?"_n("+o+")":o,Un(e,"checked","_q("+t+","+o+")"),Kn(e,"change",Qn(t,o),null,!0)}function ur(e,t,n){var r=n&&n.number,o='Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = "_value" in o ? o._value : o.value;return '+(r?"_n(val)":"val")+"})",i="var $$selectedVal = "+o+";";i=i+" "+Qn(t,"$event.target.multiple ? $$selectedVal : $$selectedVal[0]"),Kn(e,"change",i,null,!0)}function fr(e,t,n){var r=e.attrsMap.type,o=n||{},i=o.lazy,a=o.number,s=o.trim,c=!i&&"range"!==r,u=i?"change":"range"===r?Ms:"input",f="$event.target.value";s&&(f="$event.target.value.trim()"),a&&(f="_n("+f+")");var l=Qn(t,f);c&&(l="if($event.target.composing)return;"+l),Un(e,"value","("+t+")"),Kn(e,u,l,null,!0),(s||a)&&Kn(e,"blur","$forceUpdate()")}function lr(e){if(o(e[Ms])){var t=Xi?"change":"input";e[t]=[].concat(e[Ms],e[t]||[]),delete e[Ms]}o(e[Bs])&&(e.change=[].concat(e[Bs],e.change||[]),delete e[Bs])}function pr(e,t,n){var r=ss;return function o(){null!==t.apply(null,arguments)&&vr(e,o,n,r)}}function dr(e,t,n,r){if(Fs){var o=za,i=t;t=i._wrapper=function(e){if(e.target===e.currentTarget||e.timeStamp>=o||0===e.timeStamp||e.target.ownerDocument!==document)return i.apply(this,arguments)}}ss.addEventListener(e,t,ea?{capture:n,passive:r}:n)}function vr(e,t,n,r){(r||ss).removeEventListener(e,t._wrapper||t,n)}function hr(e,t){if(!r(e.data.on)||!r(t.data.on)){var n=t.data.on||{},o=e.data.on||{};ss=t.elm,lr(n),ve(n,o,dr,vr,pr,t.context),ss=void 0}}function mr(e,t){if(!r(e.data.domProps)||!r(t.data.domProps)){var n,i,a=t.elm,s=e.data.domProps||{},c=t.data.domProps||{};o(c.__ob__)&&(c=t.data.domProps=x({},c));for(n in s)r(c[n])&&(a[n]="");for(n in c){if(i=c[n],"textContent"===n||"innerHTML"===n){if(t.children&&(t.children.length=0),i===s[n])continue;1===a.childNodes.length&&a.removeChild(a.childNodes[0])}if("value"===n&&"PROGRESS"!==a.tagName){a._value=i;var u=r(i)?"":String(i);yr(a,u)&&(a.value=u)}else if("innerHTML"===n&&$s(a.tagName)&&r(a.innerHTML)){cs=cs||document.createElement("div"),cs.innerHTML="<svg>"+i+"</svg>";for(var f=cs.firstChild;a.firstChild;)a.removeChild(a.firstChild);for(;f.firstChild;)a.appendChild(f.firstChild)}else if(i!==s[n])try{a[n]=i}catch(e){}}}}function yr(e,t){return!e.composing&&("OPTION"===e.tagName||gr(e,t)||br(e,t))}function gr(e,t){var n=!0;try{n=document.activeElement!==e}catch(e){}return n&&e.value!==t}function br(e,t){var n=e.value,r=e._vModifiers;if(o(r)){if(r.number)return v(n)!==v(t);if(r.trim)return n.trim()!==t.trim()}return n!==t}function _r(e){var t=wr(e.style);return e.staticStyle?x(e.staticStyle,t):t}function wr(e){return Array.isArray(e)?$(e):"string"==typeof e?qs(e):e}function xr(e,t){var n,r={};if(t)for(var o=e;o.componentInstance;)(o=o.componentInstance._vnode)&&o.data&&(n=_r(o.data))&&x(r,n);(n=_r(e.data))&&x(r,n);for(var i=e;i=i.parent;)i.data&&(n=_r(i.data))&&x(r,n);return r}function $r(e,t){var n=t.data,i=e.data;if(!(r(n.staticStyle)&&r(n.style)&&r(i.staticStyle)&&r(i.style))){var a,s,c=t.elm,u=i.staticStyle,f=i.normalizedStyle||i.style||{},l=u||f,p=wr(t.data.style)||{};t.data.normalizedStyle=o(p.__ob__)?x({},p):p;var d=xr(t,!0);for(s in l)r(d[s])&&Ks(c,s,"");for(s in d)(a=d[s])!==l[s]&&Ks(c,s,null==a?"":a)}}function Ar(e,t){if(t&&(t=t.trim()))if(e.classList)t.indexOf(" ")>-1?t.split(Gs).forEach(function(t){return e.classList.add(t)}):e.classList.add(t);else{var n=" "+(e.getAttribute("class")||"")+" ";n.indexOf(" "+t+" ")<0&&e.setAttribute("class",(n+t).trim())}}function Cr(e,t){if(t&&(t=t.trim()))if(e.classList)t.indexOf(" ")>-1?t.split(Gs).forEach(function(t){return e.classList.remove(t)}):e.classList.remove(t),e.classList.length||e.removeAttribute("class");else{for(var n=" "+(e.getAttribute("class")||"")+" ",r=" "+t+" ";n.indexOf(r)>=0;)n=n.replace(r," ");n=n.trim(),n?e.setAttribute("class",n):e.removeAttribute("class")}}function kr(e){if(e){if("object"==typeof e){var t={};return!1!==e.css&&x(t,Zs(e.name||"v")),x(t,e),t}return"string"==typeof e?Zs(e):void 0}}function Tr(e){ic(function(){ic(e)})}function Sr(e,t){var n=e._transitionClasses||(e._transitionClasses=[]);n.indexOf(t)<0&&(n.push(t),Ar(e,t))}function Or(e,t){e._transitionClasses&&m(e._transitionClasses,t),Cr(e,t)}function Er(e,t,n){var r=jr(e,t),o=r.type,i=r.timeout,a=r.propCount;if(!o)return n();var s=o===Qs?nc:oc,c=0,u=function(){e.removeEventListener(s,f),n()},f=function(t){t.target===e&&++c>=a&&u()};setTimeout(function(){c<a&&u()},i+1),e.addEventListener(s,f)}function jr(e,t){var n,r=window.getComputedStyle(e),o=(r[tc+"Delay"]||"").split(", "),i=(r[tc+"Duration"]||"").split(", "),a=Ir(o,i),s=(r[rc+"Delay"]||"").split(", "),c=(r[rc+"Duration"]||"").split(", "),u=Ir(s,c),f=0,l=0;return t===Qs?a>0&&(n=Qs,f=a,l=i.length):t===ec?u>0&&(n=ec,f=u,l=c.length):(f=Math.max(a,u),n=f>0?a>u?Qs:ec:null,l=n?n===Qs?i.length:c.length:0),{type:n,timeout:f,propCount:l,hasTransform:n===Qs&&ac.test(r[tc+"Property"])}}function Ir(e,t){for(;e.length<t.length;)e=e.concat(e);return Math.max.apply(null,t.map(function(t,n){return Lr(t)+Lr(e[n])}))}function Lr(e){return 1e3*Number(e.slice(0,-1).replace(",","."))}function Nr(e,t){var n=e.elm;o(n._leaveCb)&&(n._leaveCb.cancelled=!0,n._leaveCb());var i=kr(e.data.transition);if(!r(i)&&!o(n._enterCb)&&1===n.nodeType){for(var a=i.css,s=i.type,u=i.enterClass,f=i.enterToClass,l=i.enterActiveClass,p=i.appearClass,d=i.appearToClass,h=i.appearActiveClass,m=i.beforeEnter,y=i.enter,g=i.afterEnter,b=i.enterCancelled,_=i.beforeAppear,w=i.appear,x=i.afterAppear,$=i.appearCancelled,A=i.duration,C=Ra,k=Ra.$vnode;k&&k.parent;)k=k.parent,C=k.context;var S=!C._isMounted||!e.isRootInsert;if(!S||w||""===w){var O=S&&p?p:u,E=S&&h?h:l,j=S&&d?d:f,I=S?_||m:m,L=S&&"function"==typeof w?w:y,N=S?x||g:g,D=S?$||b:b,P=v(c(A)?A.enter:A),R=!1!==a&&!Wi,M=Rr(L),B=n._enterCb=T(function(){R&&(Or(n,j),Or(n,E)),B.cancelled?(R&&Or(n,O),D&&D(n)):N&&N(n),n._enterCb=null});e.data.show||he(e,"insert",function(){var t=n.parentNode,r=t&&t._pending&&t._pending[e.key];r&&r.tag===e.tag&&r.elm._leaveCb&&r.elm._leaveCb(),L&&L(n,B)}),I&&I(n),R&&(Sr(n,O),Sr(n,E),Tr(function(){Or(n,O),B.cancelled||(Sr(n,j),M||(Pr(P)?setTimeout(B,P):Er(n,s,B)))})),e.data.show&&(t&&t(),L&&L(n,B)),R||M||B()}}}function Dr(e,t){function n(){$.cancelled||(!e.data.show&&i.parentNode&&((i.parentNode._pending||(i.parentNode._pending={}))[e.key]=e),d&&d(i),_&&(Sr(i,f),Sr(i,p),Tr(function(){Or(i,f),$.cancelled||(Sr(i,l),w||(Pr(x)?setTimeout($,x):Er(i,u,$)))})),h&&h(i,$),_||w||$())}var i=e.elm;o(i._enterCb)&&(i._enterCb.cancelled=!0,i._enterCb());var a=kr(e.data.transition);if(r(a)||1!==i.nodeType)return t();if(!o(i._leaveCb)){var s=a.css,u=a.type,f=a.leaveClass,l=a.leaveToClass,p=a.leaveActiveClass,d=a.beforeLeave,h=a.leave,m=a.afterLeave,y=a.leaveCancelled,g=a.delayLeave,b=a.duration,_=!1!==s&&!Wi,w=Rr(h),x=v(c(b)?b.leave:b),$=i._leaveCb=T(function(){i.parentNode&&i.parentNode._pending&&(i.parentNode._pending[e.key]=null),_&&(Or(i,l),Or(i,p)),$.cancelled?(_&&Or(i,f),y&&y(i)):(t(),m&&m(i)),i._leaveCb=null});g?g(n):n()}}function Pr(e){return"number"==typeof e&&!isNaN(e)}function Rr(e){if(r(e))return!1;var t=e.fns;return o(t)?Rr(Array.isArray(t)?t[0]:t):(e._length||e.length)>1}function Mr(e,t){!0!==t.data.show&&Nr(t)}function Br(e,t,n){Fr(e,t,n),(Xi||Gi)&&setTimeout(function(){Fr(e,t,n)},0)}function Fr(e,t,n){var r=t.value,o=e.multiple;if(!o||Array.isArray(r)){for(var i,a,s=0,c=e.options.length;s<c;s++)if(a=e.options[s],o)i=k(r,Hr(a))>-1,a.selected!==i&&(a.selected=i);else if(C(Hr(a),r))return void(e.selectedIndex!==s&&(e.selectedIndex=s));o||(e.selectedIndex=-1)}}function Ur(e,t){return t.every(function(t){return!C(t,e)})}function Hr(e){return"_value"in e?e._value:e.value}function qr(e){e.target.composing=!0}function zr(e){e.target.composing&&(e.target.composing=!1,Vr(e.target,"input"))}function Vr(e,t){var n=document.createEvent("HTMLEvents");n.initEvent(t,!0,!0),e.dispatchEvent(n)}function Kr(e){return!e.componentInstance||e.data&&e.data.transition?e:Kr(e.componentInstance._vnode)}function Jr(e){var t=e&&e.componentOptions;return t&&t.Ctor.options.abstract?Jr(ut(t.children)):e}function Xr(e){var t={},n=e.$options;for(var r in n.propsData)t[r]=e[r];var o=n._parentListeners;for(var i in o)t[Ei(i)]=o[i];return t}function Wr(e,t){if(/\d-keep-alive$/.test(t.tag))return e("keep-alive",{props:t.componentOptions.propsData})}function Gr(e){for(;e=e.parent;)if(e.data.transition)return!0}function Zr(e,t){return t.key===e.key&&t.tag===e.tag}function Yr(e){e.elm._moveCb&&e.elm._moveCb(),e.elm._enterCb&&e.elm._enterCb()}function Qr(e){e.data.newPos=e.elm.getBoundingClientRect()}function eo(e){var t=e.data.pos,n=e.data.newPos,r=t.left-n.left,o=t.top-n.top;if(r||o){e.data.moved=!0;var i=e.elm.style;i.transform=i.WebkitTransform="translate("+r+"px,"+o+"px)",i.transitionDuration="0s"}}function to(e,t){var n=t?Pc(t):Nc;if(n.test(e)){for(var r,o,i,a=[],s=[],c=n.lastIndex=0;r=n.exec(e);){(o=r.index)>c&&(s.push(i=e.slice(c,o)),a.push(JSON.stringify(i)));var u=Rn(r[1].trim());a.push("_s("+u+")"),s.push({"@binding":u}),c=o+r[0].length}return c<e.length&&(s.push(i=e.slice(c)),a.push(JSON.stringify(i))),{expression:a.join("+"),tokens:s}}}function no(e,t){var n=(t.warn,Wn(e,"class"));n&&(e.staticClass=JSON.stringify(n));var r=Xn(e,"class",!1);r&&(e.classBinding=r)}function ro(e){var t="";return e.staticClass&&(t+="staticClass:"+e.staticClass+","),e.classBinding&&(t+="class:"+e.classBinding+","),t}function oo(e,t){var n=(t.warn,Wn(e,"style"));n&&(e.staticStyle=JSON.stringify(qs(n)));var r=Xn(e,"style",!1);r&&(e.styleBinding=r)}function io(e){var t="";return e.staticStyle&&(t+="staticStyle:"+e.staticStyle+","),e.styleBinding&&(t+="style:("+e.styleBinding+"),"),t}function ao(e,t){var n=t?ru:nu;return e.replace(n,function(e){return tu[e]})}function so(e,t){function n(t){f+=t,e=e.substring(t)}function r(e,n,r){var o,s;if(null==n&&(n=f),null==r&&(r=f),e)for(s=e.toLowerCase(),o=a.length-1;o>=0&&a[o].lowerCasedTag!==s;o--);else o=0;if(o>=0){for(var c=a.length-1;c>=o;c--)t.end&&t.end(a[c].tag,n,r);a.length=o,i=o&&a[o-1].tag}else"br"===s?t.start&&t.start(e,[],!0,n,r):"p"===s&&(t.start&&t.start(e,[],!1,n,r),t.end&&t.end(e,n,r))}for(var o,i,a=[],s=t.expectHTML,c=t.isUnaryTag||Di,u=t.canBeLeftOpenTag||Di,f=0;e;){if(o=e,i&&Qc(i)){var l=0,p=i.toLowerCase(),d=eu[p]||(eu[p]=new RegExp("([\\s\\S]*?)(</"+p+"[^>]*>)","i")),v=e.replace(d,function(e,n,r){return l=r.length,Qc(p)||"noscript"===p||(n=n.replace(/<!\--([\s\S]*?)-->/g,"$1").replace(/<!\[CDATA\[([\s\S]*?)]]>/g,"$1")),iu(p,n)&&(n=n.slice(1)),t.chars&&t.chars(n),""});f+=e.length-v.length,e=v,r(p,f-l,f)}else{var h=e.indexOf("<");if(0===h){if(Zc.test(e)){var m=e.indexOf("--\x3e");if(m>=0){t.shouldKeepComment&&t.comment(e.substring(4,m),f,f+m+3),n(m+3);continue}}if(Yc.test(e)){var y=e.indexOf("]>");if(y>=0){n(y+2);continue}}var g=e.match(Gc);if(g){n(g[0].length);continue}var b=e.match(Wc);if(b){var _=f;n(b[0].length),r(b[1],_,f);continue}var w=function(){var t=e.match(Jc);if(t){var r={tagName:t[1],attrs:[],start:f};n(t[0].length);for(var o,i;!(o=e.match(Xc))&&(i=e.match(zc)||e.match(qc));)i.start=f,n(i[0].length),i.end=f,r.attrs.push(i);if(o)return r.unarySlash=o[1],n(o[0].length),r.end=f,r}}();if(w){!function(e){var n=e.tagName,o=e.unarySlash;s&&("p"===i&&Hc(n)&&r(i),u(n)&&i===n&&r(n));for(var f=c(n)||!!o,l=e.attrs.length,p=new Array(l),d=0;d<l;d++){var v=e.attrs[d],h=v[3]||v[4]||v[5]||"",m="a"===n&&"href"===v[1]?t.shouldDecodeNewlinesForHref:t.shouldDecodeNewlines;p[d]={name:v[1],value:ao(h,m)}}f||(a.push({tag:n,lowerCasedTag:n.toLowerCase(),attrs:p,start:e.start,end:e.end}),i=n),t.start&&t.start(n,p,f,e.start,e.end)}(w),iu(w.tagName,e)&&n(1);continue}}var x=void 0,$=void 0,A=void 0;if(h>=0){for($=e.slice(h);!(Wc.test($)||Jc.test($)||Zc.test($)||Yc.test($)||(A=$.indexOf("<",1))<0);)h+=A,$=e.slice(h);x=e.substring(0,h)}h<0&&(x=e),x&&n(x.length),t.chars&&x&&t.chars(x,f-x.length,f)}if(e===o){t.chars&&t.chars(e);break}}r()}function co(e,t,n){return{type:1,tag:e,attrsList:t,attrsMap:Eo(t),rawAttrsMap:{},parent:n,children:[]}}function uo(e,t){function n(e){if(r(e),f||e.processed||(e=po(e,t)),s.length||e===i||i.if&&(e.elseif||e.else)&&wo(i,{exp:e.elseif,block:e}),a&&!e.forbidden)if(e.elseif||e.else)bo(e,a);else{if(e.slotScope){var n=e.slotTarget||'"default"';(a.scopedSlots||(a.scopedSlots={}))[n]=e}a.children.push(e),e.parent=a}e.children=e.children.filter(function(e){return!e.slotScope}),r(e),e.pre&&(f=!1),Tc(e.tag)&&(l=!1);for(var o=0;o<kc.length;o++)kc[o](e,t)}function r(e){if(!l)for(var t;(t=e.children[e.children.length-1])&&3===t.type&&" "===t.text;)e.children.pop()}xc=t.warn||Bn,Tc=t.isPreTag||Di,Sc=t.mustUseProp||Di,Oc=t.getTagNamespace||Di;var o=t.isReservedTag||Di;Ec=function(e){return!!e.component||!o(e.tag)},Ac=Fn(t.modules,"transformNode"),Cc=Fn(t.modules,"preTransformNode"),kc=Fn(t.modules,"postTransformNode"),$c=t.delimiters;var i,a,s=[],c=!1!==t.preserveWhitespace,u=t.whitespace,f=!1,l=!1;return so(e,{warn:xc,expectHTML:t.expectHTML,isUnaryTag:t.isUnaryTag,canBeLeftOpenTag:t.canBeLeftOpenTag,shouldDecodeNewlines:t.shouldDecodeNewlines,shouldDecodeNewlinesForHref:t.shouldDecodeNewlinesForHref,shouldKeepComment:t.comments,outputSourceRange:t.outputSourceRange,start:function(e,r,o,c){var u=a&&a.ns||Oc(e);Xi&&"svg"===u&&(r=Lo(r));var p=co(e,r,a);u&&(p.ns=u),Io(p)&&!oa()&&(p.forbidden=!0);for(var d=0;d<Cc.length;d++)p=Cc[d](p,t)||p;f||(fo(p),p.pre&&(f=!0)),Tc(p.tag)&&(l=!0),f?lo(p):p.processed||(mo(p),go(p),xo(p)),i||(i=p),o?n(p):(a=p,s.push(p))},end:function(e,t,r){var o=s[s.length-1];s.length-=1,a=s[s.length-1],n(o)},chars:function(e,t,n){if(a&&(!Xi||"textarea"!==a.tag||a.attrsMap.placeholder!==e)){var r=a.children;if(e=l||e.trim()?jo(a)?e:gu(e):r.length?u?"condense"===u&&mu.test(e)?"":" ":c?" ":"":""){"condense"===u&&(e=e.replace(yu," "));var o,i;!f&&" "!==e&&(o=to(e,$c))?i={type:2,expression:o.expression,tokens:o.tokens,text:e}:" "===e&&r.length&&" "===r[r.length-1].text||(i={type:3,text:e}),i&&r.push(i)}}},comment:function(e,t,n){if(a){var r={type:3,text:e,isComment:!0};a.children.push(r)}}}),i}function fo(e){null!=Wn(e,"v-pre")&&(e.pre=!0)}function lo(e){var t=e.attrsList,n=t.length;if(n)for(var r=e.attrs=new Array(n),o=0;o<n;o++)r[o]={name:t[o].name,value:JSON.stringify(t[o].value)},null!=t[o].start&&(r[o].start=t[o].start,r[o].end=t[o].end);else e.pre||(e.plain=!0)}function po(e,t){vo(e),e.plain=!e.key&&!e.scopedSlots&&!e.attrsList.length,ho(e),$o(e),Co(e),ko(e);for(var n=0;n<Ac.length;n++)e=Ac[n](e,t)||e;return To(e),e}function vo(e){var t=Xn(e,"key");t&&(e.key=t)}function ho(e){var t=Xn(e,"ref");t&&(e.ref=t,e.refInFor=So(e))}function mo(e){var t;if(t=Wn(e,"v-for")){var n=yo(t);n&&x(e,n)}}function yo(e){var t=e.match(cu);if(t){var n={};n.for=t[2].trim();var r=t[1].trim().replace(fu,""),o=r.match(uu);return o?(n.alias=r.replace(uu,"").trim(),n.iterator1=o[1].trim(),o[2]&&(n.iterator2=o[2].trim())):n.alias=r,n}}function go(e){var t=Wn(e,"v-if");if(t)e.if=t,wo(e,{exp:t,block:e});else{null!=Wn(e,"v-else")&&(e.else=!0);var n=Wn(e,"v-else-if");n&&(e.elseif=n)}}function bo(e,t){var n=_o(t.children);n&&n.if&&wo(n,{exp:e.elseif,block:e})}function _o(e){for(var t=e.length;t--;){if(1===e[t].type)return e[t];e.pop()}}function wo(e,t){e.ifConditions||(e.ifConditions=[]),e.ifConditions.push(t)}function xo(e){null!=Wn(e,"v-once")&&(e.once=!0)}function $o(e){var t;"template"===e.tag?(t=Wn(e,"scope"),e.slotScope=t||Wn(e,"slot-scope")):(t=Wn(e,"slot-scope"))&&(e.slotScope=t);var n=Xn(e,"slot");if(n&&(e.slotTarget='""'===n?'"default"':n,e.slotTargetDynamic=!(!e.attrsMap[":slot"]&&!e.attrsMap["v-bind:slot"]),"template"===e.tag||e.slotScope||Hn(e,"slot",n,Jn(e,"slot"))),"template"===e.tag){var r=Gn(e,hu);if(r){var o=Ao(r),i=o.name,a=o.dynamic;e.slotTarget=i,e.slotTargetDynamic=a,e.slotScope=r.value||bu}}else{var s=Gn(e,hu);if(s){var c=e.scopedSlots||(e.scopedSlots={}),u=Ao(s),f=u.name,l=u.dynamic,p=c[f]=co("template",[],e);p.slotTarget=f,p.slotTargetDynamic=l,p.children=e.children.filter(function(e){if(!e.slotScope)return e.parent=p,!0}),p.slotScope=s.value||bu,e.children=[],e.plain=!1}}}function Ao(e){var t=e.name.replace(hu,"");return t||"#"!==e.name[0]&&(t="default"),lu.test(t)?{name:t.slice(1,-1),dynamic:!0}:{name:'"'+t+'"',dynamic:!1}}function Co(e){"slot"===e.tag&&(e.slotName=Xn(e,"name"))}function ko(e){var t;(t=Xn(e,"is"))&&(e.component=t),null!=Wn(e,"inline-template")&&(e.inlineTemplate=!0)}function To(e){var t,n,r,o,i,a,s,c,u=e.attrsList;for(t=0,n=u.length;t<n;t++)if(r=o=u[t].name,i=u[t].value,su.test(r))if(e.hasBindings=!0,a=Oo(r.replace(su,"")),a&&(r=r.replace(vu,"")),du.test(r))r=r.replace(du,""),i=Rn(i),c=lu.test(r),c&&(r=r.slice(1,-1)),a&&(a.prop&&!c&&"innerHtml"===(r=Ei(r))&&(r="innerHTML"),a.camel&&!c&&(r=Ei(r)),a.sync&&(s=Qn(i,"$event"),c?Kn(e,'"update:"+('+r+")",s,null,!1,xc,u[t],!0):(Kn(e,"update:"+Ei(r),s,null,!1,xc,u[t]),Li(r)!==Ei(r)&&Kn(e,"update:"+Li(r),s,null,!1,xc,u[t])))),a&&a.prop||!e.component&&Sc(e.tag,e.attrsMap.type,r)?Un(e,r,i,u[t],c):Hn(e,r,i,u[t],c);else if(au.test(r))r=r.replace(au,""),c=lu.test(r),c&&(r=r.slice(1,-1)),Kn(e,r,i,a,!1,xc,u[t],c);else{r=r.replace(su,"");var f=r.match(pu),l=f&&f[1];c=!1,l&&(r=r.slice(0,-(l.length+1)),lu.test(l)&&(l=l.slice(1,-1),c=!0)),zn(e,r,o,i,l,c,a,u[t])}else Hn(e,r,JSON.stringify(i),u[t]),!e.component&&"muted"===r&&Sc(e.tag,e.attrsMap.type,r)&&Un(e,r,"true",u[t])}function So(e){for(var t=e;t;){if(void 0!==t.for)return!0;t=t.parent}return!1}function Oo(e){var t=e.match(vu);if(t){var n={};return t.forEach(function(e){n[e.slice(1)]=!0}),n}}function Eo(e){for(var t={},n=0,r=e.length;n<r;n++)t[e[n].name]=e[n].value;return t}function jo(e){return"script"===e.tag||"style"===e.tag}function Io(e){return"style"===e.tag||"script"===e.tag&&(!e.attrsMap.type||"text/javascript"===e.attrsMap.type)}function Lo(e){for(var t=[],n=0;n<e.length;n++){var r=e[n];_u.test(r.name)||(r.name=r.name.replace(wu,""),t.push(r))}return t}function No(e,t){if("input"===e.tag){var n=e.attrsMap;if(!n["v-model"])return;var r;if((n[":type"]||n["v-bind:type"])&&(r=Xn(e,"type")),n.type||r||!n["v-bind"]||(r="("+n["v-bind"]+").type"),r){var o=Wn(e,"v-if",!0),i=o?"&&("+o+")":"",a=null!=Wn(e,"v-else",!0),s=Wn(e,"v-else-if",!0),c=Do(e);mo(c),qn(c,"type","checkbox"),po(c,t),c.processed=!0,c.if="("+r+")==='checkbox'"+i,wo(c,{exp:c.if,block:c});var u=Do(e);Wn(u,"v-for",!0),qn(u,"type","radio"),po(u,t),wo(c,{exp:"("+r+")==='radio'"+i,block:u});var f=Do(e);return Wn(f,"v-for",!0),qn(f,":type",r),po(f,t),wo(c,{exp:o,block:f}),a?c.else=!0:s&&(c.elseif=s),c}}}function Do(e){return co(e.tag,e.attrsList.slice(),e.parent)}function Po(e,t){t.value&&Un(e,"textContent","_s("+t.value+")",t)}function Ro(e,t){t.value&&Un(e,"innerHTML","_s("+t.value+")",t)}function Mo(e,t){e&&(jc=ku(t.staticKeys||""),Ic=t.isReservedTag||Di,Fo(e),Uo(e,!1))}function Bo(e){return h("type,tag,attrsList,attrsMap,plain,parent,children,attrs,start,end,rawAttrsMap"+(e?","+e:""))}function Fo(e){if(e.static=Ho(e),1===e.type){if(!Ic(e.tag)&&"slot"!==e.tag&&null==e.attrsMap["inline-template"])return;for(var t=0,n=e.children.length;t<n;t++){var r=e.children[t];Fo(r),r.static||(e.static=!1)}if(e.ifConditions)for(var o=1,i=e.ifConditions.length;o<i;o++){var a=e.ifConditions[o].block;Fo(a),a.static||(e.static=!1)}}}function Uo(e,t){if(1===e.type){if((e.static||e.once)&&(e.staticInFor=t),e.static&&e.children.length&&(1!==e.children.length||3!==e.children[0].type))return void(e.staticRoot=!0);if(e.staticRoot=!1,e.children)for(var n=0,r=e.children.length;n<r;n++)Uo(e.children[n],t||!!e.for);if(e.ifConditions)for(var o=1,i=e.ifConditions.length;o<i;o++)Uo(e.ifConditions[o].block,t)}}function Ho(e){return 2!==e.type&&(3===e.type||!(!e.pre&&(e.hasBindings||e.if||e.for||ki(e.tag)||!Ic(e.tag)||qo(e)||!Object.keys(e).every(jc))))}function qo(e){for(;e.parent;){if(e=e.parent,"template"!==e.tag)return!1;if(e.for)return!0}return!1}function zo(e,t){var n=t?"nativeOn:":"on:",r="",o="";for(var i in e){var a=Vo(e[i]);e[i]&&e[i].dynamic?o+=i+","+a+",":r+='"'+i+'":'+a+","}return r="{"+r.slice(0,-1)+"}",o?n+"_d("+r+",["+o.slice(0,-1)+"])":n+r}function Vo(e){if(!e)return"function(){}";if(Array.isArray(e))return"["+e.map(function(e){return Vo(e)}).join(",")+"]";var t=Ou.test(e.value),n=Tu.test(e.value),r=Ou.test(e.value.replace(Su,""));if(e.modifiers){var o="",i="",a=[];for(var s in e.modifiers)if(Lu[s])i+=Lu[s],Eu[s]&&a.push(s);else if("exact"===s){var c=e.modifiers;i+=Iu(["ctrl","shift","alt","meta"].filter(function(e){return!c[e]}).map(function(e){return"$event."+e+"Key"}).join("||"))}else a.push(s);return a.length&&(o+=Ko(a)),i&&(o+=i),"function($event){"+o+(t?"return "+e.value+"($event)":n?"return ("+e.value+")($event)":r?"return "+e.value:e.value)+"}"}return t||n?e.value:"function($event){"+(r?"return "+e.value:e.value)+"}"}function Ko(e){return"if(!$event.type.indexOf('key')&&"+e.map(Jo).join("&&")+")return null;"}function Jo(e){var t=parseInt(e,10);if(t)return"$event.keyCode!=="+t;var n=Eu[e],r=ju[e];return"_k($event.keyCode,"+JSON.stringify(e)+","+JSON.stringify(n)+",$event.key,"+JSON.stringify(r)+")"}function Xo(e,t){e.wrapListeners=function(e){return"_g("+e+","+t.value+")"}}function Wo(e,t){e.wrapData=function(n){return"_b("+n+",'"+e.tag+"',"+t.value+","+(t.modifiers&&t.modifiers.prop?"true":"false")+(t.modifiers&&t.modifiers.sync?",true":"")+")"}}function Go(e,t){var n=new Du(t);return{render:"with(this){return "+(e?Zo(e,n):'_c("div")')+"}",staticRenderFns:n.staticRenderFns}}function Zo(e,t){if(e.parent&&(e.pre=e.pre||e.parent.pre),e.staticRoot&&!e.staticProcessed)return Yo(e,t);if(e.once&&!e.onceProcessed)return Qo(e,t);if(e.for&&!e.forProcessed)return ni(e,t);if(e.if&&!e.ifProcessed)return ei(e,t);if("template"!==e.tag||e.slotTarget||t.pre){if("slot"===e.tag)return mi(e,t);var n;if(e.component)n=yi(e.component,e,t);else{var r;(!e.plain||e.pre&&t.maybeComponent(e))&&(r=ri(e,t));var o=e.inlineTemplate?null:fi(e,t,!0);n="_c('"+e.tag+"'"+(r?","+r:"")+(o?","+o:"")+")"}for(var i=0;i<t.transforms.length;i++)n=t.transforms[i](e,n);return n}return fi(e,t)||"void 0"}function Yo(e,t){e.staticProcessed=!0;var n=t.pre;return e.pre&&(t.pre=e.pre),t.staticRenderFns.push("with(this){return "+Zo(e,t)+"}"),t.pre=n,"_m("+(t.staticRenderFns.length-1)+(e.staticInFor?",true":"")+")"}function Qo(e,t){if(e.onceProcessed=!0,e.if&&!e.ifProcessed)return ei(e,t);if(e.staticInFor){for(var n="",r=e.parent;r;){if(r.for){n=r.key;break}r=r.parent}return n?"_o("+Zo(e,t)+","+t.onceId+++","+n+")":Zo(e,t)}return Yo(e,t)}function ei(e,t,n,r){return e.ifProcessed=!0,ti(e.ifConditions.slice(),t,n,r)}function ti(e,t,n,r){function o(e){return n?n(e,t):e.once?Qo(e,t):Zo(e,t)}if(!e.length)return r||"_e()";var i=e.shift();return i.exp?"("+i.exp+")?"+o(i.block)+":"+ti(e,t,n,r):""+o(i.block)}function ni(e,t,n,r){var o=e.for,i=e.alias,a=e.iterator1?","+e.iterator1:"",s=e.iterator2?","+e.iterator2:"";return e.forProcessed=!0,(r||"_l")+"(("+o+"),function("+i+a+s+"){return "+(n||Zo)(e,t)+"})"}function ri(e,t){var n="{",r=oi(e,t);r&&(n+=r+","),e.key&&(n+="key:"+e.key+","),e.ref&&(n+="ref:"+e.ref+","),e.refInFor&&(n+="refInFor:true,"),e.pre&&(n+="pre:true,"),e.component&&(n+='tag:"'+e.tag+'",');for(var o=0;o<t.dataGenFns.length;o++)n+=t.dataGenFns[o](e);if(e.attrs&&(n+="attrs:"+gi(e.attrs)+","),e.props&&(n+="domProps:"+gi(e.props)+","),e.events&&(n+=zo(e.events,!1)+","),e.nativeEvents&&(n+=zo(e.nativeEvents,!0)+","),e.slotTarget&&!e.slotScope&&(n+="slot:"+e.slotTarget+","),e.scopedSlots&&(n+=ai(e,e.scopedSlots,t)+","),e.model&&(n+="model:{value:"+e.model.value+",callback:"+e.model.callback+",expression:"+e.model.expression+"},"),e.inlineTemplate){var i=ii(e,t);i&&(n+=i+",")}return n=n.replace(/,$/,"")+"}",e.dynamicAttrs&&(n="_b("+n+',"'+e.tag+'",'+gi(e.dynamicAttrs)+")"),e.wrapData&&(n=e.wrapData(n)),e.wrapListeners&&(n=e.wrapListeners(n)),n}function oi(e,t){var n=e.directives;if(n){var r,o,i,a,s="directives:[",c=!1;for(r=0,o=n.length;r<o;r++){i=n[r],a=!0;var u=t.directives[i.name];u&&(a=!!u(e,i,t.warn)),a&&(c=!0,s+='{name:"'+i.name+'",rawName:"'+i.rawName+'"'+(i.value?",value:("+i.value+"),expression:"+JSON.stringify(i.value):"")+(i.arg?",arg:"+(i.isDynamicArg?i.arg:'"'+i.arg+'"'):"")+(i.modifiers?",modifiers:"+JSON.stringify(i.modifiers):"")+"},")}return c?s.slice(0,-1)+"]":void 0}}function ii(e,t){var n=e.children[0];if(n&&1===n.type){var r=Go(n,t.options);return"inlineTemplate:{render:function(){"+r.render+"},staticRenderFns:["+r.staticRenderFns.map(function(e){return"function(){"+e+"}"}).join(",")+"]}"}}function ai(e,t,n){var r=Object.keys(t).some(function(e){var n=t[e];return n.slotTargetDynamic||n.if||n.for||ci(n)}),o=!!e.if;if(!r)for(var i=e.parent;i;){if(i.slotScope&&i.slotScope!==bu||i.for){r=!0;break}i.if&&(o=!0),i=i.parent}var a=Object.keys(t).map(function(e){return ui(t[e],n)}).join(",");return"scopedSlots:_u(["+a+"]"+(r?",null,true":"")+(!r&&o?",null,false,"+si(a):"")+")"}function si(e){for(var t=5381,n=e.length;n;)t=33*t^e.charCodeAt(--n);return t>>>0}function ci(e){return 1===e.type&&("slot"===e.tag||e.children.some(ci))}function ui(e,t){var n=e.attrsMap["slot-scope"];if(e.if&&!e.ifProcessed&&!n)return ei(e,t,ui,"null");if(e.for&&!e.forProcessed)return ni(e,t,ui);var r=e.slotScope===bu?"":String(e.slotScope),o="function("+r+"){return "+("template"===e.tag?e.if&&n?"("+e.if+")?"+(fi(e,t)||"undefined")+":undefined":fi(e,t)||"undefined":Zo(e,t))+"}",i=r?"":",proxy:true";return"{key:"+(e.slotTarget||'"default"')+",fn:"+o+i+"}"}function fi(e,t,n,r,o){var i=e.children;if(i.length){var a=i[0];if(1===i.length&&a.for&&"template"!==a.tag&&"slot"!==a.tag){var s=n?t.maybeComponent(a)?",1":",0":"";return""+(r||Zo)(a,t)+s}var c=n?li(i,t.maybeComponent):0,u=o||di;return"["+i.map(function(e){return u(e,t)}).join(",")+"]"+(c?","+c:"")}}function li(e,t){for(var n=0,r=0;r<e.length;r++){var o=e[r];if(1===o.type){if(pi(o)||o.ifConditions&&o.ifConditions.some(function(e){return pi(e.block)})){n=2;break}(t(o)||o.ifConditions&&o.ifConditions.some(function(e){return t(e.block)}))&&(n=1)}}return n}function pi(e){return void 0!==e.for||"template"===e.tag||"slot"===e.tag}function di(e,t){return 1===e.type?Zo(e,t):3===e.type&&e.isComment?hi(e):vi(e)}function vi(e){return"_v("+(2===e.type?e.expression:bi(JSON.stringify(e.text)))+")"}function hi(e){return"_e("+JSON.stringify(e.text)+")"}function mi(e,t){var n=e.slotName||'"default"',r=fi(e,t),o="_t("+n+(r?","+r:""),i=e.attrs||e.dynamicAttrs?gi((e.attrs||[]).concat(e.dynamicAttrs||[]).map(function(e){return{name:Ei(e.name),value:e.value,dynamic:e.dynamic}})):null,a=e.attrsMap["v-bind"];return!i&&!a||r||(o+=",null"),i&&(o+=","+i),a&&(o+=(i?"":",null")+","+a),o+")"}function yi(e,t,n){var r=t.inlineTemplate?null:fi(t,n,!0);return"_c("+e+","+ri(t,n)+(r?","+r:"")+")"}function gi(e){for(var t="",n="",r=0;r<e.length;r++){var o=e[r],i=bi(o.value);o.dynamic?n+=o.name+","+i+",":t+='"'+o.name+'":'+i+","}return t="{"+t.slice(0,-1)+"}",n?"_d("+t+",["+n.slice(0,-1)+"])":t}function bi(e){return e.replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029")}function _i(e,t){try{return new Function(e)}catch(n){return t.push({err:n,code:e}),A}}function wi(e){var t=Object.create(null);return function(n,r,o){r=x({},r),r.warn,delete r.warn;var i=r.delimiters?String(r.delimiters)+n:n;if(t[i])return t[i];var a=e(n,r),s={},c=[];return s.render=_i(a.render,c),s.staticRenderFns=a.staticRenderFns.map(function(e){return _i(e,c)}),t[i]=s}}function xi(e){return Lc=Lc||document.createElement("div"),Lc.innerHTML=e?'<a href="\n"/>':'<div a="\n"/>',Lc.innerHTML.indexOf("&#10;")>0}function $i(e){if(e.outerHTML)return e.outerHTML;var t=document.createElement("div");return t.appendChild(e.cloneNode(!0)),t.innerHTML}/*!
2
+ * Vue.js v2.6.7
3
+ * (c) 2014-2019 Evan You
4
+ * Released under the MIT License.
5
+ */
6
+ var Ai=Object.freeze({}),Ci=Object.prototype.toString,ki=h("slot,component",!0),Ti=h("key,ref,slot,slot-scope,is"),Si=Object.prototype.hasOwnProperty,Oi=/-(\w)/g,Ei=g(function(e){return e.replace(Oi,function(e,t){return t?t.toUpperCase():""})}),ji=g(function(e){return e.charAt(0).toUpperCase()+e.slice(1)}),Ii=/\B([A-Z])/g,Li=g(function(e){return e.replace(Ii,"-$1").toLowerCase()}),Ni=Function.prototype.bind?_:b,Di=function(e,t,n){return!1},Pi=function(e){return e},Ri="data-server-rendered",Mi=["component","directive","filter"],Bi=["beforeCreate","created","beforeMount","mounted","beforeUpdate","updated","beforeDestroy","destroyed","activated","deactivated","errorCaptured","serverPrefetch"],Fi={optionMergeStrategies:Object.create(null),silent:!1,productionTip:!1,devtools:!1,performance:!1,errorHandler:null,warnHandler:null,ignoredElements:[],keyCodes:Object.create(null),isReservedTag:Di,isReservedAttr:Di,isUnknownElement:Di,getTagNamespace:A,parsePlatformTagName:Pi,mustUseProp:Di,async:!0,_lifecycleHooks:Bi},Ui="a-zA-Z·À-ÖØ-öø-ͽͿ-῿‌-‍‿-⁀⁰-↏Ⰰ-⿯、-퟿豈-﷏ﷰ-�",Hi=new RegExp("[^"+Ui+".$_\\d]"),qi="__proto__"in{},zi="undefined"!=typeof window,Vi="undefined"!=typeof WXEnvironment&&!!WXEnvironment.platform,Ki=Vi&&WXEnvironment.platform.toLowerCase(),Ji=zi&&window.navigator.userAgent.toLowerCase(),Xi=Ji&&/msie|trident/.test(Ji),Wi=Ji&&Ji.indexOf("msie 9.0")>0,Gi=Ji&&Ji.indexOf("edge/")>0,Zi=(Ji&&Ji.indexOf("android"),Ji&&/iphone|ipad|ipod|ios/.test(Ji)||"ios"===Ki),Yi=(Ji&&/chrome\/\d+/.test(Ji),Ji&&/phantomjs/.test(Ji),Ji&&Ji.match(/firefox\/(\d+)/)),Qi={}.watch,ea=!1;if(zi)try{var ta={};Object.defineProperty(ta,"passive",{get:function(){ea=!0}}),window.addEventListener("test-passive",null,ta)}catch(e){}var na,ra,oa=function(){return void 0===na&&(na=!zi&&!Vi&&void 0!==e&&e.process&&"server"===e.process.env.VUE_ENV),na},ia=zi&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__,aa="undefined"!=typeof Symbol&&j(Symbol)&&"undefined"!=typeof Reflect&&j(Reflect.ownKeys);ra="undefined"!=typeof Set&&j(Set)?Set:function(){function e(){this.set=Object.create(null)}return e.prototype.has=function(e){return!0===this.set[e]},e.prototype.add=function(e){this.set[e]=!0},e.prototype.clear=function(){this.set=Object.create(null)},e}();var sa=A,ca=0,ua=function(){this.id=ca++,this.subs=[]};ua.prototype.addSub=function(e){this.subs.push(e)},ua.prototype.removeSub=function(e){m(this.subs,e)},ua.prototype.depend=function(){ua.target&&ua.target.addDep(this)},ua.prototype.notify=function(){for(var e=this.subs.slice(),t=0,n=e.length;t<n;t++)e[t].update()},ua.target=null;var fa=[],la=function(e,t,n,r,o,i,a,s){this.tag=e,this.data=t,this.children=n,this.text=r,this.elm=o,this.ns=void 0,this.context=i,this.fnContext=void 0,this.fnOptions=void 0,this.fnScopeId=void 0,this.key=t&&t.key,this.componentOptions=a,this.componentInstance=void 0,this.parent=void 0,this.raw=!1,this.isStatic=!1,this.isRootInsert=!0,this.isComment=!1,this.isCloned=!1,this.isOnce=!1,this.asyncFactory=s,this.asyncMeta=void 0,this.isAsyncPlaceholder=!1},pa={child:{configurable:!0}};pa.child.get=function(){return this.componentInstance},Object.defineProperties(la.prototype,pa);var da=function(e){void 0===e&&(e="");var t=new la;return t.text=e,t.isComment=!0,t},va=Array.prototype,ha=Object.create(va);["push","pop","shift","unshift","splice","sort","reverse"].forEach(function(e){var t=va[e];O(ha,e,function(){for(var n=[],r=arguments.length;r--;)n[r]=arguments[r];var o,i=t.apply(this,n),a=this.__ob__;switch(e){case"push":case"unshift":o=n;break;case"splice":o=n.slice(2)}return o&&a.observeArray(o),a.dep.notify(),i})});var ma=Object.getOwnPropertyNames(ha),ya=!0,ga=function(e){this.value=e,this.dep=new ua,this.vmCount=0,O(e,"__ob__",this),Array.isArray(e)?(qi?R(e,ha):M(e,ha,ma),this.observeArray(e)):this.walk(e)};ga.prototype.walk=function(e){for(var t=Object.keys(e),n=0;n<t.length;n++)F(e,t[n])},ga.prototype.observeArray=function(e){for(var t=0,n=e.length;t<n;t++)B(e[t])};var ba=Fi.optionMergeStrategies;ba.data=function(e,t,n){return n?V(e,t,n):t&&"function"!=typeof t?e:V(e,t)},Bi.forEach(function(e){ba[e]=K}),Mi.forEach(function(e){ba[e+"s"]=X}),ba.watch=function(e,t,n,r){if(e===Qi&&(e=void 0),t===Qi&&(t=void 0),!t)return Object.create(e||null);if(!e)return t;var o={};x(o,e);for(var i in t){var a=o[i],s=t[i];a&&!Array.isArray(a)&&(a=[a]),o[i]=a?a.concat(s):Array.isArray(s)?s:[s]}return o},ba.props=ba.methods=ba.inject=ba.computed=function(e,t,n,r){if(!e)return t;var o=Object.create(null);return x(o,e),t&&x(o,t),o},ba.provide=V;var _a,wa=function(e,t){return void 0===t?e:t},xa=!1,$a=[],Aa=!1;if("undefined"!=typeof Promise&&j(Promise)){var Ca=Promise.resolve();_a=function(){Ca.then(ue),Zi&&setTimeout(A)},xa=!0}else if(Xi||"undefined"==typeof MutationObserver||!j(MutationObserver)&&"[object MutationObserverConstructor]"!==MutationObserver.toString())_a=void 0!==n&&j(n)?function(){n(ue)}:function(){setTimeout(ue,0)};else{var ka=1,Ta=new MutationObserver(ue),Sa=document.createTextNode(String(ka));Ta.observe(Sa,{characterData:!0}),_a=function(){ka=(ka+1)%2,Sa.data=String(ka)},xa=!0}var Oa=new ra,Ea=g(function(e){var t="&"===e.charAt(0);e=t?e.slice(1):e;var n="~"===e.charAt(0);e=n?e.slice(1):e;var r="!"===e.charAt(0);return e=r?e.slice(1):e,{name:e,once:n,capture:r,passive:t}});ze(Ve.prototype);var ja,Ia={init:function(e,t){if(e.componentInstance&&!e.componentInstance._isDestroyed&&e.data.keepAlive){var n=e;Ia.prepatch(n,n)}else(e.componentInstance=Ge(e,Ra)).$mount(t?e.elm:void 0,t)},prepatch:function(e,t){var n=t.componentOptions;gt(t.componentInstance=e.componentInstance,n.propsData,n.listeners,t,n.children)},insert:function(e){var t=e.context,n=e.componentInstance;n._isMounted||(n._isMounted=!0,xt(n,"mounted")),e.data.keepAlive&&(t._isMounted?kt(n):_t(n,!0))},destroy:function(e){var t=e.componentInstance;t._isDestroyed||(e.data.keepAlive?wt(t,!0):t.$destroy())}},La=Object.keys(Ia),Na=1,Da=2,Pa=null,Ra=null,Ma=[],Ba=[],Fa={},Ua=!1,Ha=!1,qa=0,za=0,Va=Date.now;zi&&Va()>document.createEvent("Event").timeStamp&&(Va=function(){return performance.now()});var Ka=0,Ja=function(e,t,n,r,o){this.vm=e,o&&(e._watcher=this),e._watchers.push(this),r?(this.deep=!!r.deep,this.user=!!r.user,this.lazy=!!r.lazy,this.sync=!!r.sync,this.before=r.before):this.deep=this.user=this.lazy=this.sync=!1,this.cb=n,this.id=++Ka,this.active=!0,this.dirty=this.lazy,this.deps=[],this.newDeps=[],this.depIds=new ra,this.newDepIds=new ra,this.expression="","function"==typeof t?this.getter=t:(this.getter=E(t),this.getter||(this.getter=A)),this.value=this.lazy?void 0:this.get()};Ja.prototype.get=function(){I(this);var e,t=this.vm;try{e=this.getter.call(t,t)}catch(e){if(!this.user)throw e;ie(e,t,'getter for watcher "'+this.expression+'"')}finally{this.deep&&le(e),L(),this.cleanupDeps()}return e},Ja.prototype.addDep=function(e){var t=e.id;this.newDepIds.has(t)||(this.newDepIds.add(t),this.newDeps.push(e),this.depIds.has(t)||e.addSub(this))},Ja.prototype.cleanupDeps=function(){for(var e=this.deps.length;e--;){var t=this.deps[e];this.newDepIds.has(t.id)||t.removeSub(this)}var n=this.depIds;this.depIds=this.newDepIds,this.newDepIds=n,this.newDepIds.clear(),n=this.deps,this.deps=this.newDeps,this.newDeps=n,this.newDeps.length=0},Ja.prototype.update=function(){this.lazy?this.dirty=!0:this.sync?this.run():St(this)},Ja.prototype.run=function(){if(this.active){var e=this.get();if(e!==this.value||c(e)||this.deep){var t=this.value;if(this.value=e,this.user)try{this.cb.call(this.vm,e,t)}catch(e){ie(e,this.vm,'callback for watcher "'+this.expression+'"')}else this.cb.call(this.vm,e,t)}}},Ja.prototype.evaluate=function(){this.value=this.get(),this.dirty=!1},Ja.prototype.depend=function(){for(var e=this.deps.length;e--;)this.deps[e].depend()},Ja.prototype.teardown=function(){if(this.active){this.vm._isBeingDestroyed||m(this.vm._watchers,this);for(var e=this.deps.length;e--;)this.deps[e].removeSub(this);this.active=!1}};var Xa={enumerable:!0,configurable:!0,get:A,set:A},Wa={lazy:!0},Ga=0;!function(e){e.prototype._init=function(e){var t=this;t._uid=Ga++,t._isVue=!0,e&&e._isComponent?Ut(t,e):t.$options=Y(Ht(t.constructor),e||{},t),t._renderProxy=t,t._self=t,mt(t),ft(t),ot(t),xt(t,"beforeCreate"),$e(t),Et(t),xe(t),xt(t,"created"),t.$options.el&&t.$mount(t.$options.el)}}(zt),function(e){var t={};t.get=function(){return this._data};var n={};n.get=function(){return this._props},Object.defineProperty(e.prototype,"$data",t),Object.defineProperty(e.prototype,"$props",n),e.prototype.$set=U,e.prototype.$delete=H,e.prototype.$watch=function(e,t,n){var r=this;if(u(t))return Ft(r,e,t,n);n=n||{},n.user=!0;var o=new Ja(r,e,t,n);if(n.immediate)try{t.call(r,o.value)}catch(e){ie(e,r,'callback for immediate watcher "'+o.expression+'"')}return function(){o.teardown()}}}(zt),function(e){var t=/^hook:/;e.prototype.$on=function(e,n){var r=this;if(Array.isArray(e))for(var o=0,i=e.length;o<i;o++)r.$on(e[o],n);else(r._events[e]||(r._events[e]=[])).push(n),t.test(e)&&(r._hasHookEvent=!0);return r},e.prototype.$once=function(e,t){function n(){r.$off(e,n),t.apply(r,arguments)}var r=this;return n.fn=t,r.$on(e,n),r},e.prototype.$off=function(e,t){var n=this;if(!arguments.length)return n._events=Object.create(null),n;if(Array.isArray(e)){for(var r=0,o=e.length;r<o;r++)n.$off(e[r],t);return n}var i=n._events[e];if(!i)return n;if(!t)return n._events[e]=null,n;for(var a,s=i.length;s--;)if((a=i[s])===t||a.fn===t){i.splice(s,1);break}return n},e.prototype.$emit=function(e){var t=this,n=t._events[e];if(n){n=n.length>1?w(n):n;for(var r=w(arguments,1),o='event handler for "'+e+'"',i=0,a=n.length;i<a;i++)ae(n[i],t,r,t,o)}return t}}(zt),function(e){e.prototype._update=function(e,t){var n=this,r=n.$el,o=n._vnode,i=ht(n);n._vnode=e,n.$el=o?n.__patch__(o,e):n.__patch__(n.$el,e,t,!1),i(),r&&(r.__vue__=null),n.$el&&(n.$el.__vue__=n),n.$vnode&&n.$parent&&n.$vnode===n.$parent._vnode&&(n.$parent.$el=n.$el)},e.prototype.$forceUpdate=function(){var e=this;e._watcher&&e._watcher.update()},e.prototype.$destroy=function(){var e=this;if(!e._isBeingDestroyed){xt(e,"beforeDestroy"),e._isBeingDestroyed=!0;var t=e.$parent;!t||t._isBeingDestroyed||e.$options.abstract||m(t.$children,e),e._watcher&&e._watcher.teardown();for(var n=e._watchers.length;n--;)e._watchers[n].teardown();e._data.__ob__&&e._data.__ob__.vmCount--,e._isDestroyed=!0,e.__patch__(e._vnode,null),xt(e,"destroyed"),e.$off(),e.$el&&(e.$el.__vue__=null),e.$vnode&&(e.$vnode.parent=null)}}}(zt),function(e){ze(e.prototype),e.prototype.$nextTick=function(e){return fe(e,this)},e.prototype._render=function(){var e=this,t=e.$options,n=t.render,r=t._parentVnode;r&&(e.$scopedSlots=Te(r.data.scopedSlots,e.$slots,e.$scopedSlots)),e.$vnode=r;var o;try{Pa=e,o=n.call(e._renderProxy,e.$createElement)}catch(t){ie(t,e,"render"),o=e._vnode}finally{Pa=null}return Array.isArray(o)&&1===o.length&&(o=o[0]),o instanceof la||(o=da()),o.parent=r,o}}(zt);var Za=[String,RegExp,Array],Ya={name:"keep-alive",abstract:!0,props:{include:Za,exclude:Za,max:[String,Number]},created:function(){this.cache=Object.create(null),this.keys=[]},destroyed:function(){for(var e in this.cache)en(this.cache,e,this.keys)},mounted:function(){var e=this;this.$watch("include",function(t){Qt(e,function(e){return Yt(t,e)})}),this.$watch("exclude",function(t){Qt(e,function(e){return!Yt(t,e)})})},render:function(){var e=this.$slots.default,t=ut(e),n=t&&t.componentOptions;if(n){var r=Zt(n),o=this,i=o.include,a=o.exclude;if(i&&(!r||!Yt(i,r))||a&&r&&Yt(a,r))return t;var s=this,c=s.cache,u=s.keys,f=null==t.key?n.Ctor.cid+(n.tag?"::"+n.tag:""):t.key;c[f]?(t.componentInstance=c[f].componentInstance,m(u,f),u.push(f)):(c[f]=t,u.push(f),this.max&&u.length>parseInt(this.max)&&en(c,u[0],u,this._vnode)),t.data.keepAlive=!0}return t||e&&e[0]}},Qa={KeepAlive:Ya};!function(e){var t={};t.get=function(){return Fi},Object.defineProperty(e,"config",t),e.util={warn:sa,extend:x,mergeOptions:Y,defineReactive:F},e.set=U,e.delete=H,e.nextTick=fe,e.observable=function(e){return B(e),e},e.options=Object.create(null),Mi.forEach(function(t){e.options[t+"s"]=Object.create(null)}),e.options._base=e,x(e.options.components,Qa),Vt(e),Kt(e),Jt(e),Gt(e)}(zt),Object.defineProperty(zt.prototype,"$isServer",{get:oa}),Object.defineProperty(zt.prototype,"$ssrContext",{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Object.defineProperty(zt,"FunctionalRenderContext",{value:Ve}),zt.version="2.6.7";var es,ts,ns,rs,os,is,as,ss,cs,us,fs=h("style,class"),ls=h("input,textarea,option,select,progress"),ps=function(e,t,n){return"value"===n&&ls(e)&&"button"!==t||"selected"===n&&"option"===e||"checked"===n&&"input"===e||"muted"===n&&"video"===e},ds=h("contenteditable,draggable,spellcheck"),vs=h("events,caret,typing,plaintext-only"),hs=function(e,t){return _s(t)||"false"===t?"false":"contenteditable"===e&&vs(t)?t:"true"},ms=h("allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,defaultchecked,defaultmuted,defaultselected,defer,disabled,enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,translate,truespeed,typemustmatch,visible"),ys="http://www.w3.org/1999/xlink",gs=function(e){return":"===e.charAt(5)&&"xlink"===e.slice(0,5)},bs=function(e){return gs(e)?e.slice(6,e.length):""},_s=function(e){return null==e||!1===e},ws={svg:"http://www.w3.org/2000/svg",math:"http://www.w3.org/1998/Math/MathML"},xs=h("html,body,base,head,link,meta,style,title,address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,s,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,output,progress,select,textarea,details,dialog,menu,menuitem,summary,content,element,shadow,template,blockquote,iframe,tfoot"),$s=h("svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,font-face,foreignObject,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view",!0),As=function(e){return"pre"===e},Cs=function(e){return xs(e)||$s(e)},ks=Object.create(null),Ts=h("text,number,password,search,email,tel,url"),Ss=Object.freeze({createElement:pn,createElementNS:dn,createTextNode:vn,createComment:hn,insertBefore:mn,removeChild:yn,appendChild:gn,parentNode:bn,nextSibling:_n,tagName:wn,setTextContent:xn,setStyleScope:$n}),Os={create:function(e,t){An(t)},update:function(e,t){e.data.ref!==t.data.ref&&(An(e,!0),An(t))},destroy:function(e){An(e,!0)}},Es=new la("",{},[]),js=["create","activate","update","remove","destroy"],Is={create:Sn,update:Sn,destroy:function(e){Sn(e,Es)}},Ls=Object.create(null),Ns=[Os,Is],Ds={create:Ln,update:Ln},Ps={create:Pn,update:Pn},Rs=/[\w).+\-_$\]]/,Ms="__r",Bs="__c",Fs=xa&&!(Yi&&Number(Yi[1])<=53),Us={create:hr,update:hr},Hs={create:mr,update:mr},qs=g(function(e){var t={},n=/;(?![^(]*\))/g,r=/:(.+)/;return e.split(n).forEach(function(e){if(e){var n=e.split(r);n.length>1&&(t[n[0].trim()]=n[1].trim())}}),t}),zs=/^--/,Vs=/\s*!important$/,Ks=function(e,t,n){if(zs.test(t))e.style.setProperty(t,n);else if(Vs.test(n))e.style.setProperty(Li(t),n.replace(Vs,""),"important");else{var r=Xs(t);if(Array.isArray(n))for(var o=0,i=n.length;o<i;o++)e.style[r]=n[o];else e.style[r]=n}},Js=["Webkit","Moz","ms"],Xs=g(function(e){if(us=us||document.createElement("div").style,"filter"!==(e=Ei(e))&&e in us)return e;for(var t=e.charAt(0).toUpperCase()+e.slice(1),n=0;n<Js.length;n++){var r=Js[n]+t;if(r in us)return r}}),Ws={create:$r,update:$r},Gs=/\s+/,Zs=g(function(e){return{enterClass:e+"-enter",enterToClass:e+"-enter-to",enterActiveClass:e+"-enter-active",leaveClass:e+"-leave",leaveToClass:e+"-leave-to",leaveActiveClass:e+"-leave-active"}}),Ys=zi&&!Wi,Qs="transition",ec="animation",tc="transition",nc="transitionend",rc="animation",oc="animationend";Ys&&(void 0===window.ontransitionend&&void 0!==window.onwebkittransitionend&&(tc="WebkitTransition",nc="webkitTransitionEnd"),void 0===window.onanimationend&&void 0!==window.onwebkitanimationend&&(rc="WebkitAnimation",oc="webkitAnimationEnd"));var ic=zi?window.requestAnimationFrame?window.requestAnimationFrame.bind(window):setTimeout:function(e){return e()},ac=/\b(transform|all)(,|$)/,sc=zi?{create:Mr,activate:Mr,remove:function(e,t){!0!==e.data.show?Dr(e,t):t()}}:{},cc=[Ds,Ps,Us,Hs,Ws,sc],uc=cc.concat(Ns),fc=function(e){function t(e){return new la(j.tagName(e).toLowerCase(),{},[],void 0,e)}function n(e,t){function n(){0==--n.listeners&&a(e)}return n.listeners=t,n}function a(e){var t=j.parentNode(e);o(t)&&j.removeChild(t,e)}function c(e,t,n,r,a,s,c){if(o(e.elm)&&o(s)&&(e=s[c]=D(e)),e.isRootInsert=!a,!u(e,t,n,r)){var f=e.data,l=e.children,v=e.tag;o(v)?(e.elm=e.ns?j.createElementNS(e.ns,v):j.createElement(v,e),y(e),d(e,l,t),o(f)&&m(e,t),p(n,e.elm,r)):i(e.isComment)?(e.elm=j.createComment(e.text),p(n,e.elm,r)):(e.elm=j.createTextNode(e.text),p(n,e.elm,r))}}function u(e,t,n,r){var a=e.data;if(o(a)){var s=o(e.componentInstance)&&a.keepAlive;if(o(a=a.hook)&&o(a=a.init)&&a(e,!1),o(e.componentInstance))return f(e,t),p(n,e.elm,r),i(s)&&l(e,t,n,r),!0}}function f(e,t){o(e.data.pendingInsert)&&(t.push.apply(t,e.data.pendingInsert),e.data.pendingInsert=null),e.elm=e.componentInstance.$el,v(e)?(m(e,t),y(e)):(An(e),t.push(e))}function l(e,t,n,r){for(var i,a=e;a.componentInstance;)if(a=a.componentInstance._vnode,o(i=a.data)&&o(i=i.transition)){for(i=0;i<O.activate.length;++i)O.activate[i](Es,a);t.push(a);break}p(n,e.elm,r)}function p(e,t,n){o(e)&&(o(n)?j.parentNode(n)===e&&j.insertBefore(e,t,n):j.appendChild(e,t))}function d(e,t,n){if(Array.isArray(t))for(var r=0;r<t.length;++r)c(t[r],n,e.elm,null,!0,t,r);else s(e.text)&&j.appendChild(e.elm,j.createTextNode(String(e.text)))}function v(e){for(;e.componentInstance;)e=e.componentInstance._vnode;return o(e.tag)}function m(e,t){for(var n=0;n<O.create.length;++n)O.create[n](Es,e);T=e.data.hook,o(T)&&(o(T.create)&&T.create(Es,e),o(T.insert)&&t.push(e))}function y(e){var t;if(o(t=e.fnScopeId))j.setStyleScope(e.elm,t);else for(var n=e;n;)o(t=n.context)&&o(t=t.$options._scopeId)&&j.setStyleScope(e.elm,t),n=n.parent;o(t=Ra)&&t!==e.context&&t!==e.fnContext&&o(t=t.$options._scopeId)&&j.setStyleScope(e.elm,t)}function g(e,t,n,r,o,i){for(;r<=o;++r)c(n[r],i,e,t,!1,n,r)}function b(e){var t,n,r=e.data;if(o(r))for(o(t=r.hook)&&o(t=t.destroy)&&t(e),t=0;t<O.destroy.length;++t)O.destroy[t](e);if(o(t=e.children))for(n=0;n<e.children.length;++n)b(e.children[n])}function _(e,t,n,r){for(;n<=r;++n){var i=t[n];o(i)&&(o(i.tag)?(w(i),b(i)):a(i.elm))}}function w(e,t){if(o(t)||o(e.data)){var r,i=O.remove.length+1;for(o(t)?t.listeners+=i:t=n(e.elm,i),o(r=e.componentInstance)&&o(r=r._vnode)&&o(r.data)&&w(r,t),r=0;r<O.remove.length;++r)O.remove[r](e,t);o(r=e.data.hook)&&o(r=r.remove)?r(e,t):t()}else a(e.elm)}function x(e,t,n,i,a){for(var s,u,f,l,p=0,d=0,v=t.length-1,h=t[0],m=t[v],y=n.length-1,b=n[0],w=n[y],x=!a;p<=v&&d<=y;)r(h)?h=t[++p]:r(m)?m=t[--v]:Cn(h,b)?(A(h,b,i,n,d),h=t[++p],b=n[++d]):Cn(m,w)?(A(m,w,i,n,y),m=t[--v],w=n[--y]):Cn(h,w)?(A(h,w,i,n,y),x&&j.insertBefore(e,h.elm,j.nextSibling(m.elm)),h=t[++p],w=n[--y]):Cn(m,b)?(A(m,b,i,n,d),x&&j.insertBefore(e,m.elm,h.elm),m=t[--v],b=n[++d]):(r(s)&&(s=Tn(t,p,v)),u=o(b.key)?s[b.key]:$(b,t,p,v),r(u)?c(b,i,e,h.elm,!1,n,d):(f=t[u],Cn(f,b)?(A(f,b,i,n,d),t[u]=void 0,x&&j.insertBefore(e,f.elm,h.elm)):c(b,i,e,h.elm,!1,n,d)),b=n[++d]);p>v?(l=r(n[y+1])?null:n[y+1].elm,g(e,l,n,d,y,i)):d>y&&_(e,t,p,v)}function $(e,t,n,r){for(var i=n;i<r;i++){var a=t[i];if(o(a)&&Cn(e,a))return i}}function A(e,t,n,a,s,c){if(e!==t){o(t.elm)&&o(a)&&(t=a[s]=D(t));var u=t.elm=e.elm;if(i(e.isAsyncPlaceholder))return void(o(t.asyncFactory.resolved)?k(e.elm,t,n):t.isAsyncPlaceholder=!0);if(i(t.isStatic)&&i(e.isStatic)&&t.key===e.key&&(i(t.isCloned)||i(t.isOnce)))return void(t.componentInstance=e.componentInstance);var f,l=t.data;o(l)&&o(f=l.hook)&&o(f=f.prepatch)&&f(e,t);var p=e.children,d=t.children;if(o(l)&&v(t)){for(f=0;f<O.update.length;++f)O.update[f](e,t);o(f=l.hook)&&o(f=f.update)&&f(e,t)}r(t.text)?o(p)&&o(d)?p!==d&&x(u,p,d,n,c):o(d)?(o(e.text)&&j.setTextContent(u,""),g(u,null,d,0,d.length-1,n)):o(p)?_(u,p,0,p.length-1):o(e.text)&&j.setTextContent(u,""):e.text!==t.text&&j.setTextContent(u,t.text),o(l)&&o(f=l.hook)&&o(f=f.postpatch)&&f(e,t)}}function C(e,t,n){if(i(n)&&o(e.parent))e.parent.data.pendingInsert=t;else for(var r=0;r<t.length;++r)t[r].data.hook.insert(t[r])}function k(e,t,n,r){var a,s=t.tag,c=t.data,u=t.children;if(r=r||c&&c.pre,t.elm=e,i(t.isComment)&&o(t.asyncFactory))return t.isAsyncPlaceholder=!0,!0;if(o(c)&&(o(a=c.hook)&&o(a=a.init)&&a(t,!0),o(a=t.componentInstance)))return f(t,n),!0;if(o(s)){if(o(u))if(e.hasChildNodes())if(o(a=c)&&o(a=a.domProps)&&o(a=a.innerHTML)){if(a!==e.innerHTML)return!1}else{for(var l=!0,p=e.firstChild,v=0;v<u.length;v++){if(!p||!k(p,u[v],n,r)){l=!1;break}p=p.nextSibling}if(!l||p)return!1}else d(t,u,n);if(o(c)){var h=!1;for(var y in c)if(!I(y)){h=!0,m(t,n);break}!h&&c.class&&le(c.class)}}else e.data!==t.text&&(e.data=t.text);return!0}var T,S,O={},E=e.modules,j=e.nodeOps;for(T=0;T<js.length;++T)for(O[js[T]]=[],S=0;S<E.length;++S)o(E[S][js[T]])&&O[js[T]].push(E[S][js[T]]);var I=h("attrs,class,staticClass,staticStyle,key");return function(e,n,a,s){if(r(n))return void(o(e)&&b(e));var u=!1,f=[];if(r(e))u=!0,c(n,f);else{var l=o(e.nodeType);if(!l&&Cn(e,n))A(e,n,f,null,null,s);else{if(l){if(1===e.nodeType&&e.hasAttribute(Ri)&&(e.removeAttribute(Ri),a=!0),i(a)&&k(e,n,f))return C(n,f,!0),e;e=t(e)}var p=e.elm,d=j.parentNode(p);if(c(n,f,p._leaveCb?null:d,j.nextSibling(p)),o(n.parent))for(var h=n.parent,m=v(n);h;){for(var y=0;y<O.destroy.length;++y)O.destroy[y](h);if(h.elm=n.elm,m){for(var g=0;g<O.create.length;++g)O.create[g](Es,h);var w=h.data.hook.insert;if(w.merged)for(var x=1;x<w.fns.length;x++)w.fns[x]()}else An(h);h=h.parent}o(d)?_(d,[e],0,0):o(e.tag)&&b(e)}}return C(n,f,u),n.elm}}({nodeOps:Ss,modules:uc});Wi&&document.addEventListener("selectionchange",function(){var e=document.activeElement;e&&e.vmodel&&Vr(e,"input")});var lc={inserted:function(e,t,n,r){"select"===n.tag?(r.elm&&!r.elm._vOptions?he(n,"postpatch",function(){lc.componentUpdated(e,t,n)}):Br(e,t,n.context),e._vOptions=[].map.call(e.options,Hr)):("textarea"===n.tag||Ts(e.type))&&(e._vModifiers=t.modifiers,t.modifiers.lazy||(e.addEventListener("compositionstart",qr),e.addEventListener("compositionend",zr),e.addEventListener("change",zr),Wi&&(e.vmodel=!0)))},componentUpdated:function(e,t,n){if("select"===n.tag){Br(e,t,n.context);var r=e._vOptions,o=e._vOptions=[].map.call(e.options,Hr);o.some(function(e,t){return!C(e,r[t])})&&(e.multiple?t.value.some(function(e){return Ur(e,o)}):t.value!==t.oldValue&&Ur(t.value,o))&&Vr(e,"change")}}},pc={bind:function(e,t,n){var r=t.value;n=Kr(n);var o=n.data&&n.data.transition,i=e.__vOriginalDisplay="none"===e.style.display?"":e.style.display;r&&o?(n.data.show=!0,Nr(n,function(){e.style.display=i})):e.style.display=r?i:"none"},update:function(e,t,n){var r=t.value;!r!=!t.oldValue&&(n=Kr(n),n.data&&n.data.transition?(n.data.show=!0,r?Nr(n,function(){e.style.display=e.__vOriginalDisplay}):Dr(n,function(){e.style.display="none"})):e.style.display=r?e.__vOriginalDisplay:"none")},unbind:function(e,t,n,r,o){o||(e.style.display=e.__vOriginalDisplay)}},dc={model:lc,show:pc},vc={name:String,appear:Boolean,css:Boolean,mode:String,type:String,enterClass:String,leaveClass:String,enterToClass:String,leaveToClass:String,enterActiveClass:String,leaveActiveClass:String,appearClass:String,appearActiveClass:String,appearToClass:String,duration:[Number,String,Object]},hc=function(e){return e.tag||ct(e)},mc=function(e){return"show"===e.name},yc={name:"transition",props:vc,abstract:!0,render:function(e){var t=this,n=this.$slots.default;if(n&&(n=n.filter(hc),n.length)){var r=this.mode,o=n[0];if(Gr(this.$vnode))return o;var i=Jr(o);if(!i)return o;if(this._leaving)return Wr(e,o);var a="__transition-"+this._uid+"-";i.key=null==i.key?i.isComment?a+"comment":a+i.tag:s(i.key)?0===String(i.key).indexOf(a)?i.key:a+i.key:i.key;var c=(i.data||(i.data={})).transition=Xr(this),u=this._vnode,f=Jr(u);if(i.data.directives&&i.data.directives.some(mc)&&(i.data.show=!0),f&&f.data&&!Zr(i,f)&&!ct(f)&&(!f.componentInstance||!f.componentInstance._vnode.isComment)){var l=f.data.transition=x({},c);if("out-in"===r)return this._leaving=!0,he(l,"afterLeave",function(){t._leaving=!1,t.$forceUpdate()}),Wr(e,o);if("in-out"===r){if(ct(i))return u;var p,d=function(){p()};he(c,"afterEnter",d),he(c,"enterCancelled",d),he(l,"delayLeave",function(e){p=e})}}return o}}},gc=x({tag:String,moveClass:String},vc);delete gc.mode;var bc={props:gc,beforeMount:function(){var e=this,t=this._update;this._update=function(n,r){var o=ht(e);e.__patch__(e._vnode,e.kept,!1,!0),e._vnode=e.kept,o(),t.call(e,n,r)}},render:function(e){for(var t=this.tag||this.$vnode.data.tag||"span",n=Object.create(null),r=this.prevChildren=this.children,o=this.$slots.default||[],i=this.children=[],a=Xr(this),s=0;s<o.length;s++){var c=o[s];c.tag&&null!=c.key&&0!==String(c.key).indexOf("__vlist")&&(i.push(c),n[c.key]=c,(c.data||(c.data={})).transition=a)}if(r){for(var u=[],f=[],l=0;l<r.length;l++){var p=r[l];p.data.transition=a,p.data.pos=p.elm.getBoundingClientRect(),n[p.key]?u.push(p):f.push(p)}this.kept=e(t,null,u),this.removed=f}return e(t,null,i)},updated:function(){var e=this.prevChildren,t=this.moveClass||(this.name||"v")+"-move";e.length&&this.hasMove(e[0].elm,t)&&(e.forEach(Yr),e.forEach(Qr),e.forEach(eo),this._reflow=document.body.offsetHeight,e.forEach(function(e){if(e.data.moved){var n=e.elm,r=n.style;Sr(n,t),r.transform=r.WebkitTransform=r.transitionDuration="",n.addEventListener(nc,n._moveCb=function e(r){r&&r.target!==n||r&&!/transform$/.test(r.propertyName)||(n.removeEventListener(nc,e),n._moveCb=null,Or(n,t))})}}))},methods:{hasMove:function(e,t){if(!Ys)return!1;if(this._hasMove)return this._hasMove;var n=e.cloneNode();e._transitionClasses&&e._transitionClasses.forEach(function(e){Cr(n,e)}),Ar(n,t),n.style.display="none",this.$el.appendChild(n);var r=jr(n);return this.$el.removeChild(n),this._hasMove=r.hasTransform}}},_c={Transition:yc,TransitionGroup:bc};zt.config.mustUseProp=ps,zt.config.isReservedTag=Cs,zt.config.isReservedAttr=fs,zt.config.getTagNamespace=un,zt.config.isUnknownElement=fn,x(zt.options.directives,dc),x(zt.options.components,_c),zt.prototype.__patch__=zi?fc:A,zt.prototype.$mount=function(e,t){return e=e&&zi?ln(e):void 0,yt(this,e,t)},zi&&setTimeout(function(){Fi.devtools&&ia&&ia.emit("init",zt)},0);var wc,xc,$c,Ac,Cc,kc,Tc,Sc,Oc,Ec,jc,Ic,Lc,Nc=/\{\{((?:.|\r?\n)+?)\}\}/g,Dc=/[-.*+?^${}()|[\]\/\\]/g,Pc=g(function(e){var t=e[0].replace(Dc,"\\$&"),n=e[1].replace(Dc,"\\$&");return new RegExp(t+"((?:.|\\n)+?)"+n,"g")}),Rc={staticKeys:["staticClass"],transformNode:no,genData:ro},Mc={staticKeys:["staticStyle"],transformNode:oo,genData:io},Bc={decode:function(e){return wc=wc||document.createElement("div"),wc.innerHTML=e,wc.textContent}},Fc=h("area,base,br,col,embed,frame,hr,img,input,isindex,keygen,link,meta,param,source,track,wbr"),Uc=h("colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr,source"),Hc=h("address,article,aside,base,blockquote,body,caption,col,colgroup,dd,details,dialog,div,dl,dt,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,legend,li,menuitem,meta,optgroup,option,param,rp,rt,source,style,summary,tbody,td,tfoot,th,thead,title,tr,track"),qc=/^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/,zc=/^\s*((?:v-[\w-]+:|@|:|#)\[[^=]+\][^\s"'<>\/=]*)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/,Vc="[a-zA-Z_][\\-\\.0-9_a-zA-Z"+Ui+"]*",Kc="((?:"+Vc+"\\:)?"+Vc+")",Jc=new RegExp("^<"+Kc),Xc=/^\s*(\/?)>/,Wc=new RegExp("^<\\/"+Kc+"[^>]*>"),Gc=/^<!DOCTYPE [^>]+>/i,Zc=/^<!\--/,Yc=/^<!\[/,Qc=h("script,style,textarea",!0),eu={},tu={"&lt;":"<","&gt;":">","&quot;":'"',"&amp;":"&","&#10;":"\n","&#9;":"\t","&#39;":"'"},nu=/&(?:lt|gt|quot|amp|#39);/g,ru=/&(?:lt|gt|quot|amp|#39|#10|#9);/g,ou=h("pre,textarea",!0),iu=function(e,t){return e&&ou(e)&&"\n"===t[0]},au=/^@|^v-on:/,su=/^v-|^@|^:/,cu=/([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/,uu=/,([^,\}\]]*)(?:,([^,\}\]]*))?$/,fu=/^\(|\)$/g,lu=/^\[.*\]$/,pu=/:(.*)$/,du=/^:|^\.|^v-bind:/,vu=/\.[^.]+/g,hu=/^v-slot(:|$)|^#/,mu=/[\r\n]/,yu=/\s+/g,gu=g(Bc.decode),bu="_empty_",_u=/^xmlns:NS\d+/,wu=/^NS\d+:/,xu={preTransformNode:No},$u=[Rc,Mc,xu],Au={model:ar,text:Po,html:Ro},Cu={expectHTML:!0,modules:$u,directives:Au,isPreTag:As,isUnaryTag:Fc,mustUseProp:ps,canBeLeftOpenTag:Uc,isReservedTag:Cs,getTagNamespace:un,staticKeys:function(e){return e.reduce(function(e,t){return e.concat(t.staticKeys||[])},[]).join(",")}($u)},ku=g(Bo),Tu=/^([\w$_]+|\([^)]*?\))\s*=>|^function\s*\(/,Su=/\([^)]*?\);*$/,Ou=/^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/,Eu={esc:27,tab:9,enter:13,space:32,up:38,left:37,right:39,down:40,delete:[8,46]},ju={esc:["Esc","Escape"],tab:"Tab",enter:"Enter",space:[" ","Spacebar"],up:["Up","ArrowUp"],left:["Left","ArrowLeft"],right:["Right","ArrowRight"],down:["Down","ArrowDown"],delete:["Backspace","Delete","Del"]},Iu=function(e){return"if("+e+")return null;"},Lu={stop:"$event.stopPropagation();",prevent:"$event.preventDefault();",self:Iu("$event.target !== $event.currentTarget"),ctrl:Iu("!$event.ctrlKey"),shift:Iu("!$event.shiftKey"),alt:Iu("!$event.altKey"),meta:Iu("!$event.metaKey"),left:Iu("'button' in $event && $event.button !== 0"),middle:Iu("'button' in $event && $event.button !== 1"),right:Iu("'button' in $event && $event.button !== 2")},Nu={on:Xo,bind:Wo,cloak:A},Du=function(e){this.options=e,this.warn=e.warn||Bn,this.transforms=Fn(e.modules,"transformCode"),this.dataGenFns=Fn(e.modules,"genData"),this.directives=x(x({},Nu),e.directives);var t=e.isReservedTag||Di;this.maybeComponent=function(e){return!!e.component||!t(e.tag)},this.onceId=0,this.staticRenderFns=[],this.pre=!1},Pu=(new RegExp("\\b"+"do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,super,throw,while,yield,delete,export,import,return,switch,default,extends,finally,continue,debugger,function,arguments".split(",").join("\\b|\\b")+"\\b"),new RegExp("\\b"+"delete,typeof,void".split(",").join("\\s*\\([^\\)]*\\)|\\b")+"\\s*\\([^\\)]*\\)"),function(e){return function(t){function n(n,r){var o=Object.create(t),i=[],a=[],s=function(e,t,n){(n?a:i).push(e)};if(r){r.modules&&(o.modules=(t.modules||[]).concat(r.modules)),r.directives&&(o.directives=x(Object.create(t.directives||null),r.directives));for(var c in r)"modules"!==c&&"directives"!==c&&(o[c]=r[c])}o.warn=s;var u=e(n.trim(),o);return u.errors=i,u.tips=a,u}return{compile:n,compileToFunctions:wi(n)}}}(function(e,t){var n=uo(e.trim(),t);!1!==t.optimize&&Mo(n,t);var r=Go(n,t);return{ast:n,render:r.render,staticRenderFns:r.staticRenderFns}})),Ru=Pu(Cu),Mu=(Ru.compile,Ru.compileToFunctions),Bu=!!zi&&xi(!1),Fu=!!zi&&xi(!0),Uu=g(function(e){var t=ln(e);return t&&t.innerHTML}),Hu=zt.prototype.$mount;zt.prototype.$mount=function(e,t){if((e=e&&ln(e))===document.body||e===document.documentElement)return this;var n=this.$options;if(!n.render){var r=n.template;if(r)if("string"==typeof r)"#"===r.charAt(0)&&(r=Uu(r));else{if(!r.nodeType)return this;r=r.innerHTML}else e&&(r=$i(e));if(r){var o=Mu(r,{outputSourceRange:!1,shouldDecodeNewlines:Bu,shouldDecodeNewlinesForHref:Fu,delimiters:n.delimiters,comments:n.comments},this),i=o.render,a=o.staticRenderFns;n.render=i,n.staticRenderFns=a}}return Hu.call(this,e,t)},zt.compile=Mu,t.a=zt}).call(t,n(2),n(13).setImmediate)},function(e,t){function n(){throw new Error("setTimeout has not been defined")}function r(){throw new Error("clearTimeout has not been defined")}function o(e){if(f===setTimeout)return setTimeout(e,0);if((f===n||!f)&&setTimeout)return f=setTimeout,setTimeout(e,0);try{return f(e,0)}catch(t){try{return f.call(null,e,0)}catch(t){return f.call(this,e,0)}}}function i(e){if(l===clearTimeout)return clearTimeout(e);if((l===r||!l)&&clearTimeout)return l=clearTimeout,clearTimeout(e);try{return l(e)}catch(t){try{return l.call(null,e)}catch(t){return l.call(this,e)}}}function a(){h&&d&&(h=!1,d.length?v=d.concat(v):m=-1,v.length&&s())}function s(){if(!h){var e=o(a);h=!0;for(var t=v.length;t;){for(d=v,v=[];++m<t;)d&&d[m].run();m=-1,t=v.length}d=null,h=!1,i(e)}}function c(e,t){this.fun=e,this.array=t}function u(){}var f,l,p=e.exports={};!function(){try{f="function"==typeof setTimeout?setTimeout:n}catch(e){f=n}try{l="function"==typeof clearTimeout?clearTimeout:r}catch(e){l=r}}();var d,v=[],h=!1,m=-1;p.nextTick=function(e){var t=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];v.push(new c(e,t)),1!==v.length||h||o(s)},c.prototype.run=function(){this.fun.apply(null,this.array)},p.title="browser",p.browser=!0,p.env={},p.argv=[],p.version="",p.versions={},p.on=u,p.addListener=u,p.once=u,p.off=u,p.removeListener=u,p.removeAllListeners=u,p.emit=u,p.prependListener=u,p.prependOnceListener=u,p.listeners=function(e){return[]},p.binding=function(e){throw new Error("process.binding is not supported")},p.cwd=function(){return"/"},p.chdir=function(e){throw new Error("process.chdir is not supported")},p.umask=function(){return 0}},function(e,t,n){"use strict";e.exports=function(e,t){return function(){for(var n=new Array(arguments.length),r=0;r<n.length;r++)n[r]=arguments[r];return e.apply(t,n)}}},function(e,t,n){"use strict";var r=n(0),o=n(23),i=n(25),a=n(26),s=n(27),c=n(8),u="undefined"!=typeof window&&window.btoa&&window.btoa.bind(window)||n(28);e.exports=function(e){return new Promise(function(t,f){var l=e.data,p=e.headers;r.isFormData(l)&&delete p["Content-Type"];var d=new XMLHttpRequest,v="onreadystatechange",h=!1;if("undefined"==typeof window||!window.XDomainRequest||"withCredentials"in d||s(e.url)||(d=new window.XDomainRequest,v="onload",h=!0,d.onprogress=function(){},d.ontimeout=function(){}),e.auth){var m=e.auth.username||"",y=e.auth.password||"";p.Authorization="Basic "+u(m+":"+y)}if(d.open(e.method.toUpperCase(),i(e.url,e.params,e.paramsSerializer),!0),d.timeout=e.timeout,d[v]=function(){if(d&&(4===d.readyState||h)&&(0!==d.status||d.responseURL&&0===d.responseURL.indexOf("file:"))){var n="getAllResponseHeaders"in d?a(d.getAllResponseHeaders()):null,r=e.responseType&&"text"!==e.responseType?d.response:d.responseText,i={data:r,status:1223===d.status?204:d.status,statusText:1223===d.status?"No Content":d.statusText,headers:n,config:e,request:d};o(t,f,i),d=null}},d.onerror=function(){f(c("Network Error",e,null,d)),d=null},d.ontimeout=function(){f(c("timeout of "+e.timeout+"ms exceeded",e,"ECONNABORTED",d)),d=null},r.isStandardBrowserEnv()){var g=n(29),b=(e.withCredentials||s(e.url))&&e.xsrfCookieName?g.read(e.xsrfCookieName):void 0;b&&(p[e.xsrfHeaderName]=b)}if("setRequestHeader"in d&&r.forEach(p,function(e,t){void 0===l&&"content-type"===t.toLowerCase()?delete p[t]:d.setRequestHeader(t,e)}),e.withCredentials&&(d.withCredentials=!0),e.responseType)try{d.responseType=e.responseType}catch(t){if("json"!==e.responseType)throw t}"function"==typeof e.onDownloadProgress&&d.addEventListener("progress",e.onDownloadProgress),"function"==typeof e.onUploadProgress&&d.upload&&d.upload.addEventListener("progress",e.onUploadProgress),e.cancelToken&&e.cancelToken.promise.then(function(e){d&&(d.abort(),f(e),d=null)}),void 0===l&&(l=null),d.send(l)})}},function(e,t,n){"use strict";var r=n(24);e.exports=function(e,t,n,o,i){var a=new Error(e);return r(a,t,n,o,i)}},function(e,t,n){"use strict";e.exports=function(e){return!(!e||!e.__CANCEL__)}},function(e,t,n){"use strict";function r(e){this.message=e}r.prototype.toString=function(){return"Cancel"+(this.message?": "+this.message:"")},r.prototype.__CANCEL__=!0,e.exports=r},,,function(e,t,n){(function(e){function r(e,t){this._id=e,this._clearFn=t}var o=void 0!==e&&e||"undefined"!=typeof self&&self||window,i=Function.prototype.apply;t.setTimeout=function(){return new r(i.call(setTimeout,o,arguments),clearTimeout)},t.setInterval=function(){return new r(i.call(setInterval,o,arguments),clearInterval)},t.clearTimeout=t.clearInterval=function(e){e&&e.close()},r.prototype.unref=r.prototype.ref=function(){},r.prototype.close=function(){this._clearFn.call(o,this._id)},t.enroll=function(e,t){clearTimeout(e._idleTimeoutId),e._idleTimeout=t},t.unenroll=function(e){clearTimeout(e._idleTimeoutId),e._idleTimeout=-1},t._unrefActive=t.active=function(e){clearTimeout(e._idleTimeoutId);var t=e._idleTimeout;t>=0&&(e._idleTimeoutId=setTimeout(function(){e._onTimeout&&e._onTimeout()},t))},n(14),t.setImmediate="undefined"!=typeof self&&self.setImmediate||void 0!==e&&e.setImmediate||this&&this.setImmediate,t.clearImmediate="undefined"!=typeof self&&self.clearImmediate||void 0!==e&&e.clearImmediate||this&&this.clearImmediate}).call(t,n(2))},function(e,t,n){(function(e,t){!function(e,n){"use strict";function r(e){"function"!=typeof e&&(e=new Function(""+e));for(var t=new Array(arguments.length-1),n=0;n<t.length;n++)t[n]=arguments[n+1];var r={callback:e,args:t};return u[c]=r,s(c),c++}function o(e){delete u[e]}function i(e){var t=e.callback,r=e.args;switch(r.length){case 0:t();break;case 1:t(r[0]);break;case 2:t(r[0],r[1]);break;case 3:t(r[0],r[1],r[2]);break;default:t.apply(n,r)}}function a(e){if(f)setTimeout(a,0,e);else{var t=u[e];if(t){f=!0;try{i(t)}finally{o(e),f=!1}}}}if(!e.setImmediate){var s,c=1,u={},f=!1,l=e.document,p=Object.getPrototypeOf&&Object.getPrototypeOf(e);p=p&&p.setTimeout?p:e,"[object process]"==={}.toString.call(e.process)?function(){s=function(e){t.nextTick(function(){a(e)})}}():function(){if(e.postMessage&&!e.importScripts){var t=!0,n=e.onmessage;return e.onmessage=function(){t=!1},e.postMessage("","*"),e.onmessage=n,t}}()?function(){var t="setImmediate$"+Math.random()+"$",n=function(n){n.source===e&&"string"==typeof n.data&&0===n.data.indexOf(t)&&a(+n.data.slice(t.length))};e.addEventListener?e.addEventListener("message",n,!1):e.attachEvent("onmessage",n),s=function(n){e.postMessage(t+n,"*")}}():e.MessageChannel?function(){var e=new MessageChannel;e.port1.onmessage=function(e){a(e.data)},s=function(t){e.port2.postMessage(t)}}():l&&"onreadystatechange"in l.createElement("script")?function(){var e=l.documentElement;s=function(t){var n=l.createElement("script");n.onreadystatechange=function(){a(t),n.onreadystatechange=null,e.removeChild(n),n=null},e.appendChild(n)}}():function(){s=function(e){setTimeout(a,0,e)}}(),p.setImmediate=r,p.clearImmediate=o}}("undefined"==typeof self?void 0===e?this:e:self)}).call(t,n(2),n(5))},function(e,t,n){"use strict";function r(e){return e&&DataView.prototype.isPrototypeOf(e)}function o(e){if("string"!=typeof e&&(e=String(e)),/[^a-z0-9\-#$%&'*+.^_`|~]/i.test(e))throw new TypeError("Invalid character in header field name");return e.toLowerCase()}function i(e){return"string"!=typeof e&&(e=String(e)),e}function a(e){var t={next:function(){var t=e.shift();return{done:void 0===t,value:t}}};return w.iterable&&(t[Symbol.iterator]=function(){return t}),t}function s(e){this.map={},e instanceof s?e.forEach(function(e,t){this.append(t,e)},this):Array.isArray(e)?e.forEach(function(e){this.append(e[0],e[1])},this):e&&Object.getOwnPropertyNames(e).forEach(function(t){this.append(t,e[t])},this)}function c(e){if(e.bodyUsed)return Promise.reject(new TypeError("Already read"));e.bodyUsed=!0}function u(e){return new Promise(function(t,n){e.onload=function(){t(e.result)},e.onerror=function(){n(e.error)}})}function f(e){var t=new FileReader,n=u(t);return t.readAsArrayBuffer(e),n}function l(e){var t=new FileReader,n=u(t);return t.readAsText(e),n}function p(e){for(var t=new Uint8Array(e),n=new Array(t.length),r=0;r<t.length;r++)n[r]=String.fromCharCode(t[r]);return n.join("")}function d(e){if(e.slice)return e.slice(0);var t=new Uint8Array(e.byteLength);return t.set(new Uint8Array(e)),t.buffer}function v(){return this.bodyUsed=!1,this._initBody=function(e){this._bodyInit=e,e?"string"==typeof e?this._bodyText=e:w.blob&&Blob.prototype.isPrototypeOf(e)?this._bodyBlob=e:w.formData&&FormData.prototype.isPrototypeOf(e)?this._bodyFormData=e:w.searchParams&&URLSearchParams.prototype.isPrototypeOf(e)?this._bodyText=e.toString():w.arrayBuffer&&w.blob&&r(e)?(this._bodyArrayBuffer=d(e.buffer),this._bodyInit=new Blob([this._bodyArrayBuffer])):w.arrayBuffer&&(ArrayBuffer.prototype.isPrototypeOf(e)||$(e))?this._bodyArrayBuffer=d(e):this._bodyText=e=Object.prototype.toString.call(e):this._bodyText="",this.headers.get("content-type")||("string"==typeof e?this.headers.set("content-type","text/plain;charset=UTF-8"):this._bodyBlob&&this._bodyBlob.type?this.headers.set("content-type",this._bodyBlob.type):w.searchParams&&URLSearchParams.prototype.isPrototypeOf(e)&&this.headers.set("content-type","application/x-www-form-urlencoded;charset=UTF-8"))},w.blob&&(this.blob=function(){var e=c(this);if(e)return e;if(this._bodyBlob)return Promise.resolve(this._bodyBlob);if(this._bodyArrayBuffer)return Promise.resolve(new Blob([this._bodyArrayBuffer]));if(this._bodyFormData)throw new Error("could not read FormData body as blob");return Promise.resolve(new Blob([this._bodyText]))},this.arrayBuffer=function(){return this._bodyArrayBuffer?c(this)||Promise.resolve(this._bodyArrayBuffer):this.blob().then(f)}),this.text=function(){var e=c(this);if(e)return e;if(this._bodyBlob)return l(this._bodyBlob);if(this._bodyArrayBuffer)return Promise.resolve(p(this._bodyArrayBuffer));if(this._bodyFormData)throw new Error("could not read FormData body as text");return Promise.resolve(this._bodyText)},w.formData&&(this.formData=function(){return this.text().then(y)}),this.json=function(){return this.text().then(JSON.parse)},this}function h(e){var t=e.toUpperCase();return A.indexOf(t)>-1?t:e}function m(e,t){t=t||{};var n=t.body;if(e instanceof m){if(e.bodyUsed)throw new TypeError("Already read");this.url=e.url,this.credentials=e.credentials,t.headers||(this.headers=new s(e.headers)),this.method=e.method,this.mode=e.mode,this.signal=e.signal,n||null==e._bodyInit||(n=e._bodyInit,e.bodyUsed=!0)}else this.url=String(e);if(this.credentials=t.credentials||this.credentials||"same-origin",!t.headers&&this.headers||(this.headers=new s(t.headers)),this.method=h(t.method||this.method||"GET"),this.mode=t.mode||this.mode||null,this.signal=t.signal||this.signal,this.referrer=null,("GET"===this.method||"HEAD"===this.method)&&n)throw new TypeError("Body not allowed for GET or HEAD requests");this._initBody(n)}function y(e){var t=new FormData;return e.trim().split("&").forEach(function(e){if(e){var n=e.split("="),r=n.shift().replace(/\+/g," "),o=n.join("=").replace(/\+/g," ");t.append(decodeURIComponent(r),decodeURIComponent(o))}}),t}function g(e){var t=new s;return e.replace(/\r?\n[\t ]+/g," ").split(/\r?\n/).forEach(function(e){var n=e.split(":"),r=n.shift().trim();if(r){var o=n.join(":").trim();t.append(r,o)}}),t}function b(e,t){t||(t={}),this.type="default",this.status=void 0===t.status?200:t.status,this.ok=this.status>=200&&this.status<300,this.statusText="statusText"in t?t.statusText:"OK",this.headers=new s(t.headers),this.url=t.url||"",this._initBody(e)}function _(e,t){return new Promise(function(n,r){function o(){a.abort()}var i=new m(e,t);if(i.signal&&i.signal.aborted)return r(new k("Aborted","AbortError"));var a=new XMLHttpRequest;a.onload=function(){var e={status:a.status,statusText:a.statusText,headers:g(a.getAllResponseHeaders()||"")};e.url="responseURL"in a?a.responseURL:e.headers.get("X-Request-URL");var t="response"in a?a.response:a.responseText;n(new b(t,e))},a.onerror=function(){r(new TypeError("Network request failed"))},a.ontimeout=function(){r(new TypeError("Network request failed"))},a.onabort=function(){r(new k("Aborted","AbortError"))},a.open(i.method,i.url,!0),"include"===i.credentials?a.withCredentials=!0:"omit"===i.credentials&&(a.withCredentials=!1),"responseType"in a&&w.blob&&(a.responseType="blob"),i.headers.forEach(function(e,t){a.setRequestHeader(t,e)}),i.signal&&(i.signal.addEventListener("abort",o),a.onreadystatechange=function(){4===a.readyState&&i.signal.removeEventListener("abort",o)}),a.send(void 0===i._bodyInit?null:i._bodyInit)})}var w={searchParams:"URLSearchParams"in self,iterable:"Symbol"in self&&"iterator"in Symbol,blob:"FileReader"in self&&"Blob"in self&&function(){try{return new Blob,!0}catch(e){return!1}}(),formData:"FormData"in self,arrayBuffer:"ArrayBuffer"in self};if(w.arrayBuffer)var x=["[object Int8Array]","[object Uint8Array]","[object Uint8ClampedArray]","[object Int16Array]","[object Uint16Array]","[object Int32Array]","[object Uint32Array]","[object Float32Array]","[object Float64Array]"],$=ArrayBuffer.isView||function(e){return e&&x.indexOf(Object.prototype.toString.call(e))>-1};s.prototype.append=function(e,t){e=o(e),t=i(t);var n=this.map[e];this.map[e]=n?n+", "+t:t},s.prototype.delete=function(e){delete this.map[o(e)]},s.prototype.get=function(e){return e=o(e),this.has(e)?this.map[e]:null},s.prototype.has=function(e){return this.map.hasOwnProperty(o(e))},s.prototype.set=function(e,t){this.map[o(e)]=i(t)},s.prototype.forEach=function(e,t){for(var n in this.map)this.map.hasOwnProperty(n)&&e.call(t,this.map[n],n,this)},s.prototype.keys=function(){var e=[];return this.forEach(function(t,n){e.push(n)}),a(e)},s.prototype.values=function(){var e=[];return this.forEach(function(t){e.push(t)}),a(e)},s.prototype.entries=function(){var e=[];return this.forEach(function(t,n){e.push([n,t])}),a(e)},w.iterable&&(s.prototype[Symbol.iterator]=s.prototype.entries);var A=["DELETE","GET","HEAD","OPTIONS","POST","PUT"];m.prototype.clone=function(){return new m(this,{body:this._bodyInit})},v.call(m.prototype),v.call(b.prototype),b.prototype.clone=function(){return new b(this._bodyInit,{status:this.status,statusText:this.statusText,headers:new s(this.headers),url:this.url})},b.error=function(){var e=new b(null,{status:0,statusText:""});return e.type="error",e};var C=[301,302,303,307,308];b.redirect=function(e,t){if(-1===C.indexOf(t))throw new RangeError("Invalid status code");return new b(null,{status:t,headers:{location:e}})};var k=self.DOMException;try{new k}catch(e){k=function(e,t){this.message=e,this.name=t;var n=Error(e);this.stack=n.stack},k.prototype=Object.create(Error.prototype),k.prototype.constructor=k}_.polyfill=!0,self.fetch||(self.fetch=_,self.Headers=s,self.Request=m,self.Response=b)},,,function(e,t,n){e.exports=n(19)},function(e,t,n){"use strict";function r(e){var t=new a(e),n=i(a.prototype.request,t);return o.extend(n,a.prototype,t),o.extend(n,t),n}var o=n(0),i=n(6),a=n(21),s=n(3),c=r(s);c.Axios=a,c.create=function(e){return r(o.merge(s,e))},c.Cancel=n(10),c.CancelToken=n(35),c.isCancel=n(9),c.all=function(e){return Promise.all(e)},c.spread=n(36),e.exports=c,e.exports.default=c},function(e,t){function n(e){return!!e.constructor&&"function"==typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)}function r(e){return"function"==typeof e.readFloatLE&&"function"==typeof e.slice&&n(e.slice(0,0))}/*!
7
+ * Determine if an object is a Buffer
8
+ *
9
+ * @author Feross Aboukhadijeh <https://feross.org>
10
+ * @license MIT
11
+ */
12
+ e.exports=function(e){return null!=e&&(n(e)||r(e)||!!e._isBuffer)}},function(e,t,n){"use strict";function r(e){this.defaults=e,this.interceptors={request:new a,response:new a}}var o=n(3),i=n(0),a=n(30),s=n(31);r.prototype.request=function(e){"string"==typeof e&&(e=i.merge({url:arguments[0]},arguments[1])),e=i.merge(o,{method:"get"},this.defaults,e),e.method=e.method.toLowerCase();var t=[s,void 0],n=Promise.resolve(e);for(this.interceptors.request.forEach(function(e){t.unshift(e.fulfilled,e.rejected)}),this.interceptors.response.forEach(function(e){t.push(e.fulfilled,e.rejected)});t.length;)n=n.then(t.shift(),t.shift());return n},i.forEach(["delete","get","head","options"],function(e){r.prototype[e]=function(t,n){return this.request(i.merge(n||{},{method:e,url:t}))}}),i.forEach(["post","put","patch"],function(e){r.prototype[e]=function(t,n,r){return this.request(i.merge(r||{},{method:e,url:t,data:n}))}}),e.exports=r},function(e,t,n){"use strict";var r=n(0);e.exports=function(e,t){r.forEach(e,function(n,r){r!==t&&r.toUpperCase()===t.toUpperCase()&&(e[t]=n,delete e[r])})}},function(e,t,n){"use strict";var r=n(8);e.exports=function(e,t,n){var o=n.config.validateStatus;n.status&&o&&!o(n.status)?t(r("Request failed with status code "+n.status,n.config,null,n.request,n)):e(n)}},function(e,t,n){"use strict";e.exports=function(e,t,n,r,o){return e.config=t,n&&(e.code=n),e.request=r,e.response=o,e}},function(e,t,n){"use strict";function r(e){return encodeURIComponent(e).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}var o=n(0);e.exports=function(e,t,n){if(!t)return e;var i;if(n)i=n(t);else if(o.isURLSearchParams(t))i=t.toString();else{var a=[];o.forEach(t,function(e,t){null!==e&&void 0!==e&&(o.isArray(e)?t+="[]":e=[e],o.forEach(e,function(e){o.isDate(e)?e=e.toISOString():o.isObject(e)&&(e=JSON.stringify(e)),a.push(r(t)+"="+r(e))}))}),i=a.join("&")}return i&&(e+=(-1===e.indexOf("?")?"?":"&")+i),e}},function(e,t,n){"use strict";var r=n(0),o=["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"];e.exports=function(e){var t,n,i,a={};return e?(r.forEach(e.split("\n"),function(e){if(i=e.indexOf(":"),t=r.trim(e.substr(0,i)).toLowerCase(),n=r.trim(e.substr(i+1)),t){if(a[t]&&o.indexOf(t)>=0)return;a[t]="set-cookie"===t?(a[t]?a[t]:[]).concat([n]):a[t]?a[t]+", "+n:n}}),a):a}},function(e,t,n){"use strict";var r=n(0);e.exports=r.isStandardBrowserEnv()?function(){function e(e){var t=e;return n&&(o.setAttribute("href",t),t=o.href),o.setAttribute("href",t),{href:o.href,protocol:o.protocol?o.protocol.replace(/:$/,""):"",host:o.host,search:o.search?o.search.replace(/^\?/,""):"",hash:o.hash?o.hash.replace(/^#/,""):"",hostname:o.hostname,port:o.port,pathname:"/"===o.pathname.charAt(0)?o.pathname:"/"+o.pathname}}var t,n=/(msie|trident)/i.test(navigator.userAgent),o=document.createElement("a");return t=e(window.location.href),function(n){var o=r.isString(n)?e(n):n;return o.protocol===t.protocol&&o.host===t.host}}():function(){return function(){return!0}}()},function(e,t,n){"use strict";function r(){this.message="String contains an invalid character"}function o(e){for(var t,n,o=String(e),a="",s=0,c=i;o.charAt(0|s)||(c="=",s%1);a+=c.charAt(63&t>>8-s%1*8)){if((n=o.charCodeAt(s+=.75))>255)throw new r;t=t<<8|n}return a}var i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";r.prototype=new Error,r.prototype.code=5,r.prototype.name="InvalidCharacterError",e.exports=o},function(e,t,n){"use strict";var r=n(0);e.exports=r.isStandardBrowserEnv()?function(){return{write:function(e,t,n,o,i,a){var s=[];s.push(e+"="+encodeURIComponent(t)),r.isNumber(n)&&s.push("expires="+new Date(n).toGMTString()),r.isString(o)&&s.push("path="+o),r.isString(i)&&s.push("domain="+i),!0===a&&s.push("secure"),document.cookie=s.join("; ")},read:function(e){var t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove:function(e){this.write(e,"",Date.now()-864e5)}}}():function(){return{write:function(){},read:function(){return null},remove:function(){}}}()},function(e,t,n){"use strict";function r(){this.handlers=[]}var o=n(0);r.prototype.use=function(e,t){return this.handlers.push({fulfilled:e,rejected:t}),this.handlers.length-1},r.prototype.eject=function(e){this.handlers[e]&&(this.handlers[e]=null)},r.prototype.forEach=function(e){o.forEach(this.handlers,function(t){null!==t&&e(t)})},e.exports=r},function(e,t,n){"use strict";function r(e){e.cancelToken&&e.cancelToken.throwIfRequested()}var o=n(0),i=n(32),a=n(9),s=n(3),c=n(33),u=n(34);e.exports=function(e){return r(e),e.baseURL&&!c(e.url)&&(e.url=u(e.baseURL,e.url)),e.headers=e.headers||{},e.data=i(e.data,e.headers,e.transformRequest),e.headers=o.merge(e.headers.common||{},e.headers[e.method]||{},e.headers||{}),o.forEach(["delete","get","head","post","put","patch","common"],function(t){delete e.headers[t]}),(e.adapter||s.adapter)(e).then(function(t){return r(e),t.data=i(t.data,t.headers,e.transformResponse),t},function(t){return a(t)||(r(e),t&&t.response&&(t.response.data=i(t.response.data,t.response.headers,e.transformResponse))),Promise.reject(t)})}},function(e,t,n){"use strict";var r=n(0);e.exports=function(e,t,n){return r.forEach(n,function(n){e=n(e,t)}),e}},function(e,t,n){"use strict";e.exports=function(e){return/^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(e)}},function(e,t,n){"use strict";e.exports=function(e,t){return t?e.replace(/\/+$/,"")+"/"+t.replace(/^\/+/,""):e}},function(e,t,n){"use strict";function r(e){if("function"!=typeof e)throw new TypeError("executor must be a function.");var t;this.promise=new Promise(function(e){t=e});var n=this;e(function(e){n.reason||(n.reason=new o(e),t(n.reason))})}var o=n(10);r.prototype.throwIfRequested=function(){if(this.reason)throw this.reason},r.source=function(){var e;return{token:new r(function(t){e=t}),cancel:e}},e.exports=r},function(e,t,n){"use strict";e.exports=function(e){return function(t){return e.apply(null,t)}}}]);
readme.txt CHANGED
@@ -3,113 +3,118 @@ Contributors: RebelCode, jeangalea, markzahra, Mekku, xedin.unknown,
3
  Plugin URI: https://www.wprssaggregator.com
4
  Tags: RSS import, RSS aggregator, autoblog, content curation, feed to post
5
  Requires at least: 4.0 or higher
6
- Tested up to: 5.0.3
7
  Requires PHP: 5.3.9 or higher
8
- Stable tag: 4.12
9
  License: GPLv3
10
 
11
  WP RSS Aggregator is the original & most popular WordPress solution for importing RSS feeds, auto-blogging, content curation & aggregation.
12
 
13
  == Description ==
14
 
15
- WP RSS Aggregator is the original and best plugin for easily importing, merging and displaying RSS and Atom feeds on your WordPress site. It's the most comprehensive and elegant RSS feed solution for WordPress.
16
 
17
- == Engage Your Audience with Fresh Content ==
18
-
19
- Content remains an integral part of any website, which is why we provide a reliable solution to share content from any source on your own WordPress site. Whether sharing your own content across sites or importing news, tutorials, Youtube videos & more, from top sources around the world, this is the only solution you need.
20
 
21
  * No limit on the number of sources you can import from.
22
  * No limit on the number of items you can import.
23
  * Automate each import on its own schedule.
24
- * Use our [shortcode](https://kb.wprssaggregator.com/article/54-how-to-use-the-shortcode-to-display-feed-items) to easily display items.
25
-
26
- [youtube https://www.youtube.com/watch?v=OgB3veegtz4]
27
-
28
- == More Free Features ==
29
-
30
- * Feed auto-discovery to add sources without the exact feed URL
31
  * Open YouTube, DailyMotion and Vimeo videos directly
32
- * Only import feed items with [unique titles](https://kb.wprssaggregator.com/article/52-general-settings) to prevent duplicates
33
  * Limit the number of feed items stored to maintain performance
34
- * Link the title and source name to the original source to give credit
35
- * Choose to hide or show the date and source of each feed item
36
- * Choose to display the original author's name with each feed item
37
- * Style the shortcode display with [some basic CSS](https://kb.wprssaggregator.com/article/196-shortcode-styles-classes)
38
- * Create a [custom RSS feed](https://kb.wprssaggregator.com/article/219-how-to-create-custom-rss-feeds) from imported feed items to use elsewhere
39
- * Extendable via [action and filter hooks](https://kb.wprssaggregator.com/collection/72-for-developers)
40
- * Integrated with the Simplepie library that comes with WordPress.
41
- * Multilingual ready
42
 
43
  [Click here to learn more about this free core plugin.](https://www.wprssaggregator.com/extension/core-plugin/?utm_source=wordpress-dot-org&utm_medium=readme&utm_campaign=readme_learn_more&utm_content=learn_more)
44
 
45
- == Take It A Step Further - Import Posts ==
46
 
47
- Increase your WordPress site's credibility and popularity with related posts, job listings, Youtube videos, and more. Build news aggregators, curate articles from around the web, make money from affiliate programs and much more.
48
 
49
- [youtube https://www.youtube.com/watch?v=-2z_bNws2MM]
 
50
 
51
- Our **[Advanced Feeds Bundle](https://www.wprssaggregator.com/extension/advanced-feeds-bundle/?utm_source=wordpress-dot-org&utm_medium=readme&utm_campaign=readme_afb_link&utm_content=afb_link)** contains our 3 most popular premium add-ons which turn simple RSS feeds into full WordPress posts on your site.
52
 
53
- * Import as Drafts or set posts to Publish upon import
54
- * Import into Posts or any Custom Post Type on your site
55
- * Automatically categorise imported posts and assign tags
56
- * Import media within the content and set featured images
57
- * Import the original author's details or assign a new one
58
- * Add you own custom content before or after the imported posts
59
- * Custom field mapping for the more experienced among you
60
- * Extract unwanted elements from the original source
61
- * Import only what you need with keyword, phrase and tag filters
62
- * Connect to our premium full text service to automatically import the full content from sources that only provide excerpts or are missing images and/or videos
63
 
64
- This bundle is a discounted grouping of all 3 add-ons, but each one can also be purchased separately. Get to know the add-ons individually:
 
 
65
 
66
- * **[Feed to Post](https://www.wprssaggregator.com/extension/feed-to-post/?utm_source=wordpress-dot-org&utm_medium=readme&utm_campaign=readme_f2p_link&utm_content=f2p_link)**
67
- * **[Full Text RSS Feeds](https://www.wprssaggregator.com/extension/full-text-rss-feeds/?utm_source=wordpress-dot-org&utm_medium=readme&utm_campaign=readme_ftr_link&utm_content=ftr_link)**
68
- * **[Keyword Filtering](https://www.wprssaggregator.com/extension/keyword-filtering/?utm_source=wordpress-dot-org&utm_medium=readme&utm_campaign=readme_kf_link&utm_content=kf_link)**
69
 
70
- [Click here for a free demo of the above 3 add-ons.](http://demo.wprssaggregator.com/)
71
 
72
- You may even use our content spinner integrations with the above add-ons to spin the content upon import.
73
 
74
- * [WordAi Integration](https://www.wprssaggregator.com/extension/wordai/?utm_source=wordpress-dot-org&utm_medium=readme&utm_campaign=readme_wai_link&utm_content=wai_link)
75
- * [SpinnerChief Integration](https://www.wprssaggregator.com/extension/spinnerchief/?utm_source=wordpress-dot-org&utm_medium=readme&utm_campaign=readme_sc_link&utm_content=sc_link)
 
 
 
 
 
76
 
77
- Have a look at these incredible plugins in action:
78
 
79
- * [WP News Desk](http://wpnewsdesk.com/)
80
- * [Crypto Headlines](http://cryptoheadlines.com/)
81
- * [Travel Blogger Community](http://travelbloggercommunity.com/)
82
 
83
- You can even take things a step further by easily creating a mobile app using the imported content. [Check out this tutorial from MobiLoud](https://www.mobiloud.com/help/knowledge-base/wp-rss-aggregator-mobile-app/) on how we built an app for WP News Desk.
84
 
85
- == ...Or Enhance Your Feed List Display (Using the Shortcode) ==
86
 
87
- Sometimes, the shortcode display of a list of feed items is all you need.
88
 
89
- [youtube https://www.youtube.com/watch?v=Wx2gkEq3MxU]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
 
91
- If this is what you're looking for, we have two add-ons that will enhance your feed item display. For instance, you can include thumbnail images and excerpts alongside the titles for a more modern and colourful look.
92
 
93
- If you're a more organised person, you can categorise the feed sources as you want. The shortcode parameter for categories then lets you display groups of feed sources together. So you can now set up a page dedicate to world news showing only sources which work for that, another for entertainment, another for sport, and so on.
94
 
95
  * **[Excerpts & Thumbnails](https://www.wprssaggregator.com/extension/excerpts-thumbnails/?utm_source=wordpress-dot-org&utm_medium=readme&utm_campaign=readme_et_link&utm_content=et_link)**
96
  * **[Categories](https://www.wprssaggregator.com/extension/categories/?utm_source=wordpress-dot-org&utm_medium=readme&utm_campaign=readme_cat_link&utm_content=cat_link)**
 
 
 
97
 
98
- These two add-ons form part of a discounted bundle called the **[Simple Feeds Bundle](https://www.wprssaggregator.com/extension/simple-feeds-bundle/?utm_source=wordpress-dot-org&utm_medium=readme&utm_campaign=readme_sfb_link&utm_content=sfb_link)** which also includes keyword filtering.
99
 
100
- [Click here for a free demo of these 3 add-ons.](http://simple.wprssaggregator.com/)
 
 
101
 
102
  == We Stand Behind What We Build ==
103
 
104
  Our comprehensive [Knowledge Base](https://kb.wprssaggregator.com/) provides you with everything you need to install, set up and customise the plugin to your needs. You can also browse through a number of FAQs to get started.
105
 
106
- If that doesn't do the trick, we provide support for the free version of WP RSS Aggregator via the plugin repo support forum [here](https://wordpress.org/support/plugin/wp-rss-aggregator), while for premium support (owners of valid premium add-on licenses) and pre-sales questions please contact us via our [premium support channel](https://www.wprssaggregator.com/contact/?utm_source=wordpress-dot-org&utm_medium=readme&utm_campaign=readme_contact_link&utm_content=contact_link).
107
 
108
  == Related Info ==
109
 
110
- WP RSS Aggregator and its premium add-ons are compatible with the new Gutenberg block editor introduced in the revolutionary WordPress 5.0. You can find more information about how the two work together [here](https://kb.wprssaggregator.com/article/444-gutenberg-compatibility-core-plugin).
111
 
112
- We provide a [Feed Creator](http://createfeed.wprssaggregator.com/) service that allows you to generate RSS feeds from any webpage, even if it doesn't have its own RSS feed.
113
 
114
  Our terms & conditions can be found [here](https://www.wprssaggregator.com/terms-conditions/).
115
 
@@ -243,15 +248,15 @@ Our complete Knowledge Base with FAQs included can be found [here](https://kb.wp
243
 
244
  == Screenshots ==
245
 
246
- 1. The default shortcode display of Feed items imported by WP RSS Aggregator
247
 
248
- 2. A customised shortcode display using some simple [CSS](https://kb.wprssaggregator.com/article/196-shortcode-styles-classes)
249
 
250
- 3. Another customised display of the Feed Items using CSS styling, but with the [Excerpts & Thumbnails](http://www.wprssaggregator.com/extensions/excerpts-thumbnails) add-on installed
251
 
252
- 4. Posts imported using Feed to Post
253
 
254
- 5. Youtube videos imported using Feed to Post
255
 
256
  6. Adding/Editing a feed source
257
 
@@ -263,6 +268,15 @@ Our complete Knowledge Base with FAQs included can be found [here](https://kb.wp
263
 
264
  == Changelog ==
265
 
 
 
 
 
 
 
 
 
 
266
  = 4.12 (2019-01-29) =
267
  * The plugin now checks if its running on PHP 5.3.9, and deactivates itself when not.
268
  * Added message informing users that v4.13 will drop support for PHP 5.3.
3
  Plugin URI: https://www.wprssaggregator.com
4
  Tags: RSS import, RSS aggregator, autoblog, content curation, feed to post
5
  Requires at least: 4.0 or higher
6
+ Tested up to: 5.1
7
  Requires PHP: 5.3.9 or higher
8
+ Stable tag: 4.12.1
9
  License: GPLv3
10
 
11
  WP RSS Aggregator is the original & most popular WordPress solution for importing RSS feeds, auto-blogging, content curation & aggregation.
12
 
13
  == Description ==
14
 
15
+ WP RSS Aggregator is the original and best plugin for easily importing, merging and displaying RSS and Atom feeds on your WordPress site. It's the most comprehensive and elegant RSS feed importer for WordPress.
16
 
17
+ == Automatically Import RSS Feeds & Display Them On Your Site ==
 
 
18
 
19
  * No limit on the number of sources you can import from.
20
  * No limit on the number of items you can import.
21
  * Automate each import on its own schedule.
22
+ * Use our [wp-rss-aggregator] [shortcode](https://kb.wprssaggregator.com/article/54-how-to-use-the-shortcode-to-display-feed-items) to easily display items.
23
+ * Feed auto-discovery to add sources without the exact RSS feed URL
 
 
 
 
 
24
  * Open YouTube, DailyMotion and Vimeo videos directly
 
25
  * Limit the number of feed items stored to maintain performance
26
+ * Choose to show, hide and/or link the author, source and publish date.
27
+ * Create a custom RSS feed from imported feed items to use elsewhere
28
+ * Extendable via action and filter hooks
 
 
 
 
 
29
 
30
  [Click here to learn more about this free core plugin.](https://www.wprssaggregator.com/extension/core-plugin/?utm_source=wordpress-dot-org&utm_medium=readme&utm_campaign=readme_learn_more&utm_content=learn_more)
31
 
32
+ == Bloggers & Content Marketers ==
33
 
34
+ Increase your WordPress site's credibility and popularity by importing full or partial Posts into your site with our premium add-ons.
35
 
36
+ * Beginner Bloggers and Copywriters - Find and display fresh, new content to **engage and grow your audience**.
37
+ * Site Owners & Content Marketers - Curate content to **keep your avid readers on your site for longer**.
38
 
39
+ == SEO Benefits from RSS Feeds ==
40
 
41
+ Importing RSS feeds alone won't improve your site's SEO, however, if you curate content (articles, tutorials, videos, listings, etc) and bring in quality traffic, the benefits begin to appear:
 
 
 
 
 
 
 
 
 
42
 
43
+ * Generate lots of new backlinks to your site.
44
+ * Enhance your online presence and gain more trust.
45
+ * And therefore, you can help boost your SEO!
46
 
47
+ *Quick sidetone: Don't steal other people's work; give credit where it's due.*
 
 
48
 
49
+ == Who is this useful for? ==
50
 
51
+ Importing and displaying RSS feeds is helpful for many types of sites:
52
 
53
+ * Curate news, videos and more from the top sources in your niche.
54
+ * Add related posts from other sites to your site.
55
+ * Curate job, real estate or other listings for your market or niche.
56
+ * Show Youtube videos on your site to engage more visitors.
57
+ * Aggregate podcast episodes related to your hobby or profession.
58
+ * Writers, list your articles from across the web on your main site.
59
+ * And much more.
60
 
61
+ For example, [WP News Desk](http://wpnewsdesk.com/) curates WordPress news, tutorials and more from over 100 trusted sources. [Travel Blogger Community](http://travelbloggercommunity.com/) does something similar to share blog posts from well-known travellers. [Crypto Headlines](https://cryptoheadlines.com/youtube-videos/) shares Youtube videos from popular Youtubers. **What will you do with WP RSS Aggregator?**
62
 
63
+ == Premium Add-ons to Import Posts ==
 
 
64
 
65
+ Import RSS feeds as WordPress posts or any other custom post type to display them just the way you want on your site.
66
 
67
+ **[Advanced Feeds Bundle](https://www.wprssaggregator.com/extension/advanced-feeds-bundle/?utm_source=wordpress-dot-org&utm_medium=readme&utm_campaign=readme_afb_link&utm_content=afb_link)** | [Free Demo](http://demo.wprssaggregator.com/)
68
 
69
+ This bundle is made up of 3 great add-ons:
70
 
71
+ * **[Feed to Post](https://www.wprssaggregator.com/extension/feed-to-post/?utm_source=wordpress-dot-org&utm_medium=readme&utm_campaign=readme_f2p_link&utm_content=f2p_link)**
72
+ * **[Full Text RSS Feeds](https://www.wprssaggregator.com/extension/full-text-rss-feeds/?utm_source=wordpress-dot-org&utm_medium=readme&utm_campaign=readme_ftr_link&utm_content=ftr_link)**
73
+ * **[Keyword Filtering](https://www.wprssaggregator.com/extension/keyword-filtering/?utm_source=wordpress-dot-org&utm_medium=readme&utm_campaign=readme_kf_link&utm_content=kf_link)**
74
+
75
+ [youtube https://www.youtube.com/watch?v=-2z_bNws2MM]
76
+
77
+ Here's a quick look at what these add-ons can offer:
78
+
79
+ * Import Posts as Drafts or set them to Publish upon import.
80
+ * Automatically categorise imported posts and/or assign tags.
81
+ * Import all media within the content and pre-set featured images.
82
+ * Import the original author's details or assign an existing user.
83
+ * Automatically add you own custom content before or after imported posts.
84
+ * Custom field mapping for the more experienced among you.
85
+ * Exclude unwanted elements from the original source with extraction rules.
86
+ * Import only the Posts you want with keyword, phrase and tag filters.
87
+ * Connect to our premium full text service to import the full content from sources that are missing text, images and more in the original RSS feeds.
88
+
89
+ == Premium Add-ons to Enhance the Shortcode Display ==
90
 
91
+ **[Simple Feeds Bundle](https://www.wprssaggregator.com/extension/simple-feeds-bundle/?utm_source=wordpress-dot-org&utm_medium=readme&utm_campaign=readme_afb_link&utm_content=afb_link)** | [Free Demo](http://simple.wprssaggregator.com/)
92
 
93
+ This bundle is made up of 3 add-ons:
94
 
95
  * **[Excerpts & Thumbnails](https://www.wprssaggregator.com/extension/excerpts-thumbnails/?utm_source=wordpress-dot-org&utm_medium=readme&utm_campaign=readme_et_link&utm_content=et_link)**
96
  * **[Categories](https://www.wprssaggregator.com/extension/categories/?utm_source=wordpress-dot-org&utm_medium=readme&utm_campaign=readme_cat_link&utm_content=cat_link)**
97
+ * **[Keyword Filtering](https://www.wprssaggregator.com/extension/keyword-filtering/?utm_source=wordpress-dot-org&utm_medium=readme&utm_campaign=readme_kf_link&utm_content=kf_link)**
98
+
99
+ [youtube https://www.youtube.com/watch?v=Wx2gkEq3MxU]
100
 
101
+ == Showcase Of WordPress Sites Running WP RSS Aggregator ==
102
 
103
+ Browse through our entire [**Showcase**](https://www.wprssaggregator.com/showcase/) to see how WP RSS Aggregator is being put to great use on a large variety of websites.
104
+
105
+ You can even take things a step further by using our 3rd-party content spinner integrations or by creating a mobile app using the imported content. [Check out this tutorial from MobiLoud](https://www.mobiloud.com/help/knowledge-base/wp-rss-aggregator-mobile-app/) on how we built an app for the WP News Desk website.
106
 
107
  == We Stand Behind What We Build ==
108
 
109
  Our comprehensive [Knowledge Base](https://kb.wprssaggregator.com/) provides you with everything you need to install, set up and customise the plugin to your needs. You can also browse through a number of FAQs to get started.
110
 
111
+ If that doesn't do the trick, we provide support for the free version of WP RSS Aggregator via the support forum [here](https://wordpress.org/support/plugin/wp-rss-aggregator), while for premium support (owners of valid premium add-on licenses) and pre-sales questions please contact us via our [premium support channel](https://www.wprssaggregator.com/contact/?utm_source=wordpress-dot-org&utm_medium=readme&utm_campaign=readme_contact_link&utm_content=contact_link).
112
 
113
  == Related Info ==
114
 
115
+ WP RSS Aggregator and its premium add-ons are compatible with the new Gutenberg block editor introduced in the revolutionary WordPress 5.0. You can find more information about how the two work together [here](https://kb.wprssaggregator.com/article/444-gutenberg-compatibility-core-plugin). A dedicated Gutenberg block is in development.
116
 
117
+ We provide a [Feed Creator](http://createfeed.wprssaggregator.com/) service that allows you to generate RSS feeds from any webpage, even if it doesn't have its own RSS feed. It provides inline documentation on how to use the service.
118
 
119
  Our terms & conditions can be found [here](https://www.wprssaggregator.com/terms-conditions/).
120
 
248
 
249
  == Screenshots ==
250
 
251
+ 1. The free shortcode display of Feed items imported by WP RSS Aggregator
252
 
253
+ 2. A customised shortcode display using some simple [CSS changes](https://kb.wprssaggregator.com/article/196-shortcode-styles-classes)
254
 
255
+ 3. Another customised display of the Feed Items using CSS styling, but with the [Excerpts & Thumbnails](http://www.wprssaggregator.com/extensions/excerpts-thumbnails) add-on
256
 
257
+ 4. Posts imported using the Feed to Post add-on
258
 
259
+ 5. Youtube videos imported using the Feed to Post add-on
260
 
261
  6. Adding/Editing a feed source
262
 
268
 
269
  == Changelog ==
270
 
271
+ = 4.12.1 (2019-02-27) =
272
+ * Added a modal with an optional poll when the plugin is deactivated.
273
+ * Improved the core plugin's on-boarding process for brand new users.
274
+ * Fixed the "Sorted" error appearing constantly in the debug log.
275
+ * The timeout for the truncating posts hook has been extended.
276
+ * Fixed PHP warnings appearing on WordPress multisite.
277
+ * Fixed PHP notice appearing on Feed Items page.
278
+ * Fixed strict standards notice appearing on settings import.
279
+
280
  = 4.12 (2019-01-29) =
281
  * The plugin now checks if its running on PHP 5.3.9, and deactivates itself when not.
282
  * Added message informing users that v4.13 will drop support for PHP 5.3.
templates/admin-update-page.twig ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="wrap wrap--wpra-update">
2
+ <div class="wpra-update wpra-text-center">
3
+ <div class="wpra-update__logo">
4
+ <img src="https://www.wprssaggregator.com/wp-content/themes/wp_rss_theme/assets/images/wp_rss_logo.png">
5
+ </div>
6
+ <div class="wpra-update-head__copy">
7
+ <div class="wpra-update-head__title">{{ title }}</div>
8
+ <div class="wpra-update-head__link">
9
+ <a href="{{ url.main }}">Skip the update details and get back to the plugin.</a>
10
+ </div>
11
+ </div>
12
+ </div>
13
+
14
+ <hr class="wp-header-end">
15
+
16
+ <div id="wpra-update-app">
17
+ <div class="postbox">
18
+ <div class="inside wpra-update-feature">
19
+ <div class="wpra-update-feature__text">
20
+ <h3>Better self-help solutions right on your site</h3>
21
+ <p>You can now make the best use of our knowledge base and support options from right within your
22
+ WordPress Dashboard! Through our support beacon you will have access to our complete knowledge base
23
+ without ever leaving your site. It even includes a contact form should you need to ask us any
24
+ questions.</p>
25
+ <p>The beacon will be visible on the bottom right-hand corner of only WP RSS Aggregator's pages. It can
26
+ be enabled or disabled at any time through the Help & Support page in our sub-menu on the left.</p>
27
+ <form method="post" class="wpra-inline-form">
28
+ {% if beacon_enabled == false %}
29
+ <button class="button button-primary button-large" type="submit" name="wprss_hs_beacon_enabled"
30
+ value="1">Enable Support Beacon
31
+ </button>
32
+ {% else %}
33
+ <button class="button button-large" type="submit" name="wprss_hs_beacon_enabled" value="0">
34
+ Disable Support Beacon
35
+ </button>
36
+ {% endif %}
37
+ {{ beacon_nonce_field | raw }}
38
+ </form>
39
+ </div>
40
+ <div class="wpra-update-feature__image">
41
+ <img src="{{ path.images }}/wp-rss-aggregator-support-beacon.png" alt="Support Beacon">
42
+ </div>
43
+ </div>
44
+ </div>
45
+
46
+ <div class="postbox">
47
+ <div class="inside">
48
+ <h3>Other fixes and improvements</h3>
49
+ <ul class="wpra-updates">
50
+ <li>Performance improvements across the core plugin.</li>
51
+ <li>Sorted out the "Sorted" error appearing constantly in the debug log.</li>
52
+ <li>Improved the core plugin's on-boarding process for brand new users.</li>
53
+ <li>The timeout for the truncating posts hook has been extended.</li>
54
+ <li>Fixed PHP warnings appearing on WordPress multisite.</li>
55
+ <li>Fixed PHP notice appearing on Feed Items page.</li>
56
+ <li>Fixed strict standards notice appearing on settings import.</li>
57
+ </ul>
58
+ </div>
59
+ </div>
60
+
61
+ <div class="wpra-text-center">
62
+ <a class="button button-large button-icon" href="{{ url.main }}">
63
+ Continue to WP RSS Aggregator
64
+ <span class="dashicons dashicons-arrow-right-alt2"></span>
65
+ </a>
66
+ </div>
67
+
68
+ <div class="wpra-text-center wpra-links">
69
+ <a href="{{ url.website }}" target="_blank">Visit website</a> |
70
+ <a href="{{ url.support }}" target="_blank">Contact support</a> |
71
+ <a href="{{ url.kb }}" target="_blank">Browse knowledge base</a>
72
+ </div>
73
+ </div>
74
+
75
+ <br class="clear">
76
+ </div>
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
- return ComposerAutoloaderInit0545fe6ed375a2225242ff880484f3bb::getLoader();
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInitf863e81b820c8b6030ee7817e9830c58::getLoader();
vendor/composer/ClassLoader.php CHANGED
@@ -279,7 +279,7 @@ class ClassLoader
279
  */
280
  public function setApcuPrefix($apcuPrefix)
281
  {
282
- $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
283
  }
284
 
285
  /**
@@ -377,7 +377,7 @@ class ClassLoader
377
  $subPath = $class;
378
  while (false !== $lastPos = strrpos($subPath, '\\')) {
379
  $subPath = substr($subPath, 0, $lastPos);
380
- $search = $subPath.'\\';
381
  if (isset($this->prefixDirsPsr4[$search])) {
382
  $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
383
  foreach ($this->prefixDirsPsr4[$search] as $dir) {
279
  */
280
  public function setApcuPrefix($apcuPrefix)
281
  {
282
+ $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
283
  }
284
 
285
  /**
377
  $subPath = $class;
378
  while (false !== $lastPos = strrpos($subPath, '\\')) {
379
  $subPath = substr($subPath, 0, $lastPos);
380
+ $search = $subPath . '\\';
381
  if (isset($this->prefixDirsPsr4[$search])) {
382
  $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
383
  foreach ($this->prefixDirsPsr4[$search] as $dir) {
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInit0545fe6ed375a2225242ff880484f3bb
6
  {
7
  private static $loader;
8
 
@@ -19,15 +19,15 @@ class ComposerAutoloaderInit0545fe6ed375a2225242ff880484f3bb
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInit0545fe6ed375a2225242ff880484f3bb', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInit0545fe6ed375a2225242ff880484f3bb', 'loadClassLoader'));
25
 
26
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27
  if ($useStaticLoader) {
28
  require_once __DIR__ . '/autoload_static.php';
29
 
30
- call_user_func(\Composer\Autoload\ComposerStaticInit0545fe6ed375a2225242ff880484f3bb::getInitializer($loader));
31
  } else {
32
  $map = require __DIR__ . '/autoload_namespaces.php';
33
  foreach ($map as $namespace => $path) {
@@ -48,19 +48,19 @@ class ComposerAutoloaderInit0545fe6ed375a2225242ff880484f3bb
48
  $loader->register(true);
49
 
50
  if ($useStaticLoader) {
51
- $includeFiles = Composer\Autoload\ComposerStaticInit0545fe6ed375a2225242ff880484f3bb::$files;
52
  } else {
53
  $includeFiles = require __DIR__ . '/autoload_files.php';
54
  }
55
  foreach ($includeFiles as $fileIdentifier => $file) {
56
- composerRequire0545fe6ed375a2225242ff880484f3bb($fileIdentifier, $file);
57
  }
58
 
59
  return $loader;
60
  }
61
  }
62
 
63
- function composerRequire0545fe6ed375a2225242ff880484f3bb($fileIdentifier, $file)
64
  {
65
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
66
  require $file;
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInitf863e81b820c8b6030ee7817e9830c58
6
  {
7
  private static $loader;
8
 
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInitf863e81b820c8b6030ee7817e9830c58', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInitf863e81b820c8b6030ee7817e9830c58', 'loadClassLoader'));
25
 
26
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27
  if ($useStaticLoader) {
28
  require_once __DIR__ . '/autoload_static.php';
29
 
30
+ call_user_func(\Composer\Autoload\ComposerStaticInitf863e81b820c8b6030ee7817e9830c58::getInitializer($loader));
31
  } else {
32
  $map = require __DIR__ . '/autoload_namespaces.php';
33
  foreach ($map as $namespace => $path) {
48
  $loader->register(true);
49
 
50
  if ($useStaticLoader) {
51
+ $includeFiles = Composer\Autoload\ComposerStaticInitf863e81b820c8b6030ee7817e9830c58::$files;
52
  } else {
53
  $includeFiles = require __DIR__ . '/autoload_files.php';
54
  }
55
  foreach ($includeFiles as $fileIdentifier => $file) {
56
+ composerRequiref863e81b820c8b6030ee7817e9830c58($fileIdentifier, $file);
57
  }
58
 
59
  return $loader;
60
  }
61
  }
62
 
63
+ function composerRequiref863e81b820c8b6030ee7817e9830c58($fileIdentifier, $file)
64
  {
65
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
66
  require $file;
vendor/composer/autoload_static.php CHANGED
@@ -4,7 +4,7 @@
4
 
5
  namespace Composer\Autoload;
6
 
7
- class ComposerStaticInit0545fe6ed375a2225242ff880484f3bb
8
  {
9
  public static $files = array (
10
  '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
@@ -85,9 +85,9 @@ class ComposerStaticInit0545fe6ed375a2225242ff880484f3bb
85
  public static function getInitializer(ClassLoader $loader)
86
  {
87
  return \Closure::bind(function () use ($loader) {
88
- $loader->prefixLengthsPsr4 = ComposerStaticInit0545fe6ed375a2225242ff880484f3bb::$prefixLengthsPsr4;
89
- $loader->prefixDirsPsr4 = ComposerStaticInit0545fe6ed375a2225242ff880484f3bb::$prefixDirsPsr4;
90
- $loader->prefixesPsr0 = ComposerStaticInit0545fe6ed375a2225242ff880484f3bb::$prefixesPsr0;
91
 
92
  }, null, ClassLoader::class);
93
  }
4
 
5
  namespace Composer\Autoload;
6
 
7
+ class ComposerStaticInitf863e81b820c8b6030ee7817e9830c58
8
  {
9
  public static $files = array (
10
  '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
85
  public static function getInitializer(ClassLoader $loader)
86
  {
87
  return \Closure::bind(function () use ($loader) {
88
+ $loader->prefixLengthsPsr4 = ComposerStaticInitf863e81b820c8b6030ee7817e9830c58::$prefixLengthsPsr4;
89
+ $loader->prefixDirsPsr4 = ComposerStaticInitf863e81b820c8b6030ee7817e9830c58::$prefixDirsPsr4;
90
+ $loader->prefixesPsr0 = ComposerStaticInitf863e81b820c8b6030ee7817e9830c58::$prefixesPsr0;
91
 
92
  }, null, ClassLoader::class);
93
  }
vendor/composer/installed.json CHANGED
@@ -484,17 +484,17 @@
484
  },
485
  {
486
  "name": "symfony/polyfill-ctype",
487
- "version": "v1.10.0",
488
- "version_normalized": "1.10.0.0",
489
  "source": {
490
  "type": "git",
491
  "url": "https://github.com/symfony/polyfill-ctype.git",
492
- "reference": "e3d826245268269cd66f8326bd8bc066687b4a19"
493
  },
494
  "dist": {
495
  "type": "zip",
496
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e3d826245268269cd66f8326bd8bc066687b4a19",
497
- "reference": "e3d826245268269cd66f8326bd8bc066687b4a19",
498
  "shasum": ""
499
  },
500
  "require": {
@@ -503,14 +503,14 @@
503
  "suggest": {
504
  "ext-ctype": "For best performance"
505
  },
506
- "time": "2018-08-06T14:22:27+00:00",
507
  "type": "library",
508
  "extra": {
509
  "branch-alias": {
510
- "dev-master": "1.9-dev"
511
  }
512
  },
513
- "installation-source": "dist",
514
  "autoload": {
515
  "psr-4": {
516
  "Symfony\\Polyfill\\Ctype\\": ""
@@ -549,12 +549,12 @@
549
  "source": {
550
  "type": "git",
551
  "url": "https://github.com/twigphp/Twig.git",
552
- "reference": "3afb492c4d36a3607942ce25824bc1d042928bf8"
553
  },
554
  "dist": {
555
  "type": "zip",
556
- "url": "https://api.github.com/repos/twigphp/Twig/zipball/3afb492c4d36a3607942ce25824bc1d042928bf8",
557
- "reference": "3afb492c4d36a3607942ce25824bc1d042928bf8",
558
  "shasum": ""
559
  },
560
  "require": {
@@ -566,11 +566,11 @@
566
  "symfony/debug": "^2.7",
567
  "symfony/phpunit-bridge": "^3.4.19|^4.1.8"
568
  },
569
- "time": "2019-01-14T15:13:59+00:00",
570
  "type": "library",
571
  "extra": {
572
  "branch-alias": {
573
- "dev-master": "1.37-dev"
574
  }
575
  },
576
  "installation-source": "source",
484
  },
485
  {
486
  "name": "symfony/polyfill-ctype",
487
+ "version": "dev-master",
488
+ "version_normalized": "9999999-dev",
489
  "source": {
490
  "type": "git",
491
  "url": "https://github.com/symfony/polyfill-ctype.git",
492
+ "reference": "82ebae02209c21113908c229e9883c419720738a"
493
  },
494
  "dist": {
495
  "type": "zip",
496
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/82ebae02209c21113908c229e9883c419720738a",
497
+ "reference": "82ebae02209c21113908c229e9883c419720738a",
498
  "shasum": ""
499
  },
500
  "require": {
503
  "suggest": {
504
  "ext-ctype": "For best performance"
505
  },
506
+ "time": "2019-02-06T07:57:58+00:00",
507
  "type": "library",
508
  "extra": {
509
  "branch-alias": {
510
+ "dev-master": "1.11-dev"
511
  }
512
  },
513
+ "installation-source": "source",
514
  "autoload": {
515
  "psr-4": {
516
  "Symfony\\Polyfill\\Ctype\\": ""
549
  "source": {
550
  "type": "git",
551
  "url": "https://github.com/twigphp/Twig.git",
552
+ "reference": "ea371bee8102f28e5d715d6410eb0d46fecf96b4"
553
  },
554
  "dist": {
555
  "type": "zip",
556
+ "url": "https://api.github.com/repos/twigphp/Twig/zipball/ea371bee8102f28e5d715d6410eb0d46fecf96b4",
557
+ "reference": "ea371bee8102f28e5d715d6410eb0d46fecf96b4",
558
  "shasum": ""
559
  },
560
  "require": {
566
  "symfony/debug": "^2.7",
567
  "symfony/phpunit-bridge": "^3.4.19|^4.1.8"
568
  },
569
+ "time": "2019-02-27T07:39:35+00:00",
570
  "type": "library",
571
  "extra": {
572
  "branch-alias": {
573
+ "dev-master": "1.38-dev"
574
  }
575
  },
576
  "installation-source": "source",
vendor/symfony/polyfill-ctype/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2018 Fabien Potencier
2
 
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
  of this software and associated documentation files (the "Software"), to deal
1
+ Copyright (c) 2018-2019 Fabien Potencier
2
 
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
  of this software and associated documentation files (the "Software"), to deal
vendor/symfony/polyfill-ctype/composer.json CHANGED
@@ -28,7 +28,7 @@
28
  "minimum-stability": "dev",
29
  "extra": {
30
  "branch-alias": {
31
- "dev-master": "1.9-dev"
32
  }
33
  }
34
  }
28
  "minimum-stability": "dev",
29
  "extra": {
30
  "branch-alias": {
31
+ "dev-master": "1.11-dev"
32
  }
33
  }
34
  }
vendor/twig/twig/.php_cs.dist CHANGED
@@ -5,11 +5,13 @@ return PhpCsFixer\Config::create()
5
  '@Symfony' => true,
6
  '@Symfony:risky' => true,
7
  'array_syntax' => ['syntax' => 'short'],
8
- 'php_unit_fqcn_annotation' => false,
9
  'no_unreachable_default_argument_value' => false,
10
  'braces' => ['allow_single_line_closure' => true],
11
  'heredoc_to_nowdoc' => false,
12
- 'dir_constant' => false,
 
 
13
  ])
14
  ->setRiskyAllowed(true)
15
  ->setFinder(PhpCsFixer\Finder::create()->in(__DIR__))
5
  '@Symfony' => true,
6
  '@Symfony:risky' => true,
7
  'array_syntax' => ['syntax' => 'short'],
8
+ 'php_unit_fqcn_annotation' => true,
9
  'no_unreachable_default_argument_value' => false,
10
  'braces' => ['allow_single_line_closure' => true],
11
  'heredoc_to_nowdoc' => false,
12
+ 'ordered_imports' => true,
13
+ 'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'],
14
+ 'native_function_invocation' => ['include' => ['@compiler_optimized'], 'scope' => 'all'],
15
  ])
16
  ->setRiskyAllowed(true)
17
  ->setFinder(PhpCsFixer\Finder::create()->in(__DIR__))
vendor/twig/twig/.travis.yml CHANGED
@@ -15,7 +15,6 @@ php:
15
  - 7.1
16
  - 7.2
17
  - 7.3
18
- - nightly
19
 
20
  env:
21
  - TWIG_EXT=no
15
  - 7.1
16
  - 7.2
17
  - 7.3
 
18
 
19
  env:
20
  - TWIG_EXT=no
vendor/twig/twig/CHANGELOG CHANGED
@@ -1,6 +1,6 @@
1
- * 1.37.2 (2019-XX-XX)
2
 
3
- * n/a
4
 
5
  * 1.37.1 (2019-01-14)
6
 
1
+ * 1.38.0 (2019-XX-XX)
2
 
3
+ * changed internal code to use the namespaced classes as much as possible
4
 
5
  * 1.37.1 (2019-01-14)
6
 
vendor/twig/twig/composer.json CHANGED
@@ -23,9 +23,6 @@
23
  "role": "Project Founder"
24
  }
25
  ],
26
- "support": {
27
- "forum": "https://groups.google.com/forum/#!forum/twig-users"
28
- },
29
  "require": {
30
  "php": ">=5.4.0",
31
  "symfony/polyfill-ctype": "^1.8"
@@ -45,7 +42,7 @@
45
  },
46
  "extra": {
47
  "branch-alias": {
48
- "dev-master": "1.37-dev"
49
  }
50
  }
51
  }
23
  "role": "Project Founder"
24
  }
25
  ],
 
 
 
26
  "require": {
27
  "php": ">=5.4.0",
28
  "symfony/polyfill-ctype": "^1.8"
42
  },
43
  "extra": {
44
  "branch-alias": {
45
+ "dev-master": "1.38-dev"
46
  }
47
  }
48
  }
vendor/twig/twig/doc/advanced.rst CHANGED
@@ -114,7 +114,7 @@ Globals
114
  A global variable is like any other template variable, except that it's
115
  available in all templates and macros::
116
 
117
- $twig = new Twig_Environment($loader);
118
  $twig->addGlobal('text', new Text());
119
 
120
  You can then use the ``text`` variable anywhere in a template:
@@ -129,29 +129,29 @@ Filters
129
  Creating a filter is as simple as associating a name with a PHP callable::
130
 
131
  // an anonymous function
132
- $filter = new Twig_SimpleFilter('rot13', function ($string) {
133
  return str_rot13($string);
134
  });
135
 
136
  // or a simple PHP function
137
- $filter = new Twig_SimpleFilter('rot13', 'str_rot13');
138
 
139
  // or a class static method
140
- $filter = new Twig_SimpleFilter('rot13', ['SomeClass', 'rot13Filter']);
141
- $filter = new Twig_SimpleFilter('rot13', 'SomeClass::rot13Filter');
142
 
143
  // or a class method
144
- $filter = new Twig_SimpleFilter('rot13', [$this, 'rot13Filter']);
145
  // the one below needs a runtime implementation (see below for more information)
146
- $filter = new Twig_SimpleFilter('rot13', ['SomeClass', 'rot13Filter']);
147
 
148
- The first argument passed to the ``Twig_SimpleFilter`` constructor is the name
149
  of the filter you will use in templates and the second one is the PHP callable
150
  to associate with it.
151
 
152
  Then, add the filter to your Twig environment::
153
 
154
- $twig = new Twig_Environment($loader);
155
  $twig->addFilter($filter);
156
 
157
  And here is how to use it in a template:
@@ -178,10 +178,10 @@ is compiled to something like the following::
178
  <?php echo strtolower('TWIG') ?>
179
  <?php echo twig_date_format_filter($now, 'd/m/Y') ?>
180
 
181
- The ``Twig_SimpleFilter`` class takes an array of options as its last
182
  argument::
183
 
184
- $filter = new Twig_SimpleFilter('rot13', 'str_rot13', $options);
185
 
186
  Environment-aware Filters
187
  ~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -190,7 +190,7 @@ If you want to access the current environment instance in your filter, set the
190
  ``needs_environment`` option to ``true``; Twig will pass the current
191
  environment as the first argument to the filter call::
192
 
193
- $filter = new Twig_SimpleFilter('rot13', function (Twig_Environment $env, $string) {
194
  // get the current charset for instance
195
  $charset = $env->getCharset();
196
 
@@ -205,11 +205,11 @@ If you want to access the current context in your filter, set the
205
  the first argument to the filter call (or the second one if
206
  ``needs_environment`` is also set to ``true``)::
207
 
208
- $filter = new Twig_SimpleFilter('rot13', function ($context, $string) {
209
  // ...
210
  }, ['needs_context' => true]);
211
 
212
- $filter = new Twig_SimpleFilter('rot13', function (Twig_Environment $env, $context, $string) {
213
  // ...
214
  }, ['needs_context' => true, 'needs_environment' => true]);
215
 
@@ -221,14 +221,14 @@ before printing. If your filter acts as an escaper (or explicitly outputs HTML
221
  or JavaScript code), you will want the raw output to be printed. In such a
222
  case, set the ``is_safe`` option::
223
 
224
- $filter = new Twig_SimpleFilter('nl2br', 'nl2br', ['is_safe' => ['html']]);
225
 
226
  Some filters may need to work on input that is already escaped or safe, for
227
  example when adding (safe) HTML tags to originally unsafe output. In such a
228
  case, set the ``pre_escape`` option to escape the input data before it is run
229
  through your filter::
230
 
231
- $filter = new Twig_SimpleFilter('somefilter', 'somefilter', ['pre_escape' => 'html', 'is_safe' => ['html']]);
232
 
233
  Variadic Filters
234
  ~~~~~~~~~~~~~~~~
@@ -240,12 +240,13 @@ When a filter should accept an arbitrary number of arguments, set the
240
  ``is_variadic`` option to ``true``; Twig will pass the extra arguments as the
241
  last argument to the filter call as an array::
242
 
243
- $filter = new Twig_SimpleFilter('thumbnail', function ($file, array $options = []) {
244
  // ...
245
  }, ['is_variadic' => true]);
246
 
247
- Be warned that named arguments passed to a variadic filter cannot be checked
248
- for validity as they will automatically end up in the option array.
 
249
 
250
  Dynamic Filters
251
  ~~~~~~~~~~~~~~~
@@ -253,7 +254,7 @@ Dynamic Filters
253
  A filter name containing the special ``*`` character is a dynamic filter as
254
  the ``*`` can be any string::
255
 
256
- $filter = new Twig_SimpleFilter('*_path', function ($name, $arguments) {
257
  // ...
258
  });
259
 
@@ -264,7 +265,7 @@ The following filters will be matched by the above defined dynamic filter:
264
 
265
  A dynamic filter can define more than one dynamic parts::
266
 
267
- $filter = new Twig_SimpleFilter('*_path_*', function ($name, $suffix, $arguments) {
268
  // ...
269
  });
270
 
@@ -283,7 +284,7 @@ You can mark a filter as being deprecated by setting the ``deprecated`` option
283
  to ``true``. You can also give an alternative filter that replaces the
284
  deprecated one when that makes sense::
285
 
286
- $filter = new Twig_SimpleFilter('obsolete', function () {
287
  // ...
288
  }, ['deprecated' => true, 'alternative' => 'new_one']);
289
 
@@ -294,10 +295,10 @@ Functions
294
  ---------
295
 
296
  Functions are defined in the exact same way as filters, but you need to create
297
- an instance of ``Twig_SimpleFunction``::
298
 
299
- $twig = new Twig_Environment($loader);
300
- $function = new Twig_SimpleFunction('function_name', function () {
301
  // ...
302
  });
303
  $twig->addFunction($function);
@@ -309,10 +310,10 @@ Tests
309
  -----
310
 
311
  Tests are defined in the exact same way as filters and functions, but you need
312
- to create an instance of ``Twig_SimpleTest``::
313
 
314
- $twig = new Twig_Environment($loader);
315
- $test = new Twig_SimpleTest('test_name', function () {
316
  // ...
317
  });
318
  $twig->addTest($test);
@@ -321,8 +322,8 @@ Tests allow you to create custom application specific logic for evaluating
321
  boolean conditions. As a simple example, let's create a Twig test that checks if
322
  objects are 'red'::
323
 
324
- $twig = new Twig_Environment($loader);
325
- $test = new Twig_SimpleTest('red', function ($value) {
326
  if (isset($value->color) && $value->color == 'red') {
327
  return true;
328
  }
@@ -339,16 +340,16 @@ When creating tests you can use the ``node_class`` option to provide custom test
339
  compilation. This is useful if your test can be compiled into PHP primitives.
340
  This is used by many of the tests built into Twig::
341
 
342
- $twig = new Twig_Environment($loader);
343
- $test = new Twig_SimpleTest(
344
  'odd',
345
  null,
346
- ['node_class' => 'Twig_Node_Expression_Test_Odd']);
347
  $twig->addTest($test);
348
 
349
- class Twig_Node_Expression_Test_Odd extends Twig_Node_Expression_Test
350
  {
351
- public function compile(Twig_Compiler $compiler)
352
  {
353
  $compiler
354
  ->raw('(')
@@ -382,9 +383,47 @@ Tags
382
  ----
383
 
384
  One of the most exciting features of a template engine like Twig is the
385
- possibility to define new language constructs. This is also the most complex
386
  feature as you need to understand how Twig's internals work.
387
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
388
  Let's create a simple ``set`` tag that allows the definition of simple
389
  variables from within a template. The tag can be used like follows:
390
 
@@ -415,9 +454,9 @@ Registering a new tag
415
  ~~~~~~~~~~~~~~~~~~~~~
416
 
417
  Adding a tag is as simple as calling the ``addTokenParser`` method on the
418
- ``Twig_Environment`` instance::
419
 
420
- $twig = new Twig_Environment($loader);
421
  $twig->addTokenParser(new Project_Set_TokenParser());
422
 
423
  Defining a Token Parser
@@ -425,17 +464,17 @@ Defining a Token Parser
425
 
426
  Now, let's see the actual code of this class::
427
 
428
- class Project_Set_TokenParser extends Twig_TokenParser
429
  {
430
- public function parse(Twig_Token $token)
431
  {
432
  $parser = $this->parser;
433
  $stream = $parser->getStream();
434
 
435
- $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
436
- $stream->expect(Twig_Token::OPERATOR_TYPE, '=');
437
  $value = $parser->getExpressionParser()->parseExpression();
438
- $stream->expect(Twig_Token::BLOCK_END_TYPE);
439
 
440
  return new Project_Set_Node($name, $value, $token->getLine(), $this->getTag());
441
  }
@@ -449,7 +488,7 @@ Now, let's see the actual code of this class::
449
  The ``getTag()`` method must return the tag we want to parse, here ``set``.
450
 
451
  The ``parse()`` method is invoked whenever the parser encounters a ``set``
452
- tag. It should return a ``Twig_Node`` instance that represents the node (the
453
  ``Project_Set_Node`` calls creating is explained in the next section).
454
 
455
  The parsing process is simplified thanks to a bunch of methods you can call
@@ -482,14 +521,14 @@ Defining a Node
482
 
483
  The ``Project_Set_Node`` class itself is rather simple::
484
 
485
- class Project_Set_Node extends Twig_Node
486
  {
487
- public function __construct($name, Twig_Node_Expression $value, $line, $tag = null)
488
  {
489
  parent::__construct(['value' => $value], ['name' => $name], $line, $tag);
490
  }
491
 
492
- public function compile(Twig_Compiler $compiler)
493
  {
494
  $compiler
495
  ->addDebugInfo($this)
@@ -513,15 +552,15 @@ developer generate beautiful and readable PHP code:
513
  * ``string()``: Writes a quoted string.
514
 
515
  * ``repr()``: Writes a PHP representation of a given value (see
516
- ``Twig_Node_For`` for a usage example).
517
 
518
  * ``addDebugInfo()``: Adds the line of the original template file related to
519
  the current node as a comment.
520
 
521
- * ``indent()``: Indents the generated code (see ``Twig_Node_Block`` for a
522
  usage example).
523
 
524
- * ``outdent()``: Outdents the generated code (see ``Twig_Node_Block`` for a
525
  usage example).
526
 
527
  .. _creating_extensions:
@@ -557,9 +596,9 @@ An extension is a class that implements the following interface::
557
  *
558
  * This is where you can load some file that contains filter functions for instance.
559
  *
560
- * @deprecated since 1.23 (to be removed in 2.0), implement Twig_Extension_InitRuntimeInterface instead
561
  */
562
- function initRuntime(Twig_Environment $environment);
563
 
564
  /**
565
  * Returns the token parser instances to add to the existing list.
@@ -571,28 +610,28 @@ An extension is a class that implements the following interface::
571
  /**
572
  * Returns the node visitor instances to add to the existing list.
573
  *
574
- * @return Twig_NodeVisitorInterface[]
575
  */
576
  function getNodeVisitors();
577
 
578
  /**
579
  * Returns a list of filters to add to the existing list.
580
  *
581
- * @return Twig_SimpleFilter[]
582
  */
583
  function getFilters();
584
 
585
  /**
586
  * Returns a list of tests to add to the existing list.
587
  *
588
- * @return Twig_SimpleTest[]
589
  */
590
  function getTests();
591
 
592
  /**
593
  * Returns a list of functions to add to the existing list.
594
  *
595
- * @return Twig_SimpleFunction[]
596
  */
597
  function getFunctions();
598
 
@@ -608,7 +647,7 @@ An extension is a class that implements the following interface::
608
  *
609
  * @return array An array of global variables
610
  *
611
- * @deprecated since 1.23 (to be removed in 2.0), implement Twig_Extension_GlobalsInterface instead
612
  */
613
  function getGlobals();
614
 
@@ -623,10 +662,10 @@ An extension is a class that implements the following interface::
623
  }
624
 
625
  To keep your extension class clean and lean, inherit from the built-in
626
- ``Twig_Extension`` class instead of implementing the interface as it provides
627
  empty implementations for all methods:
628
 
629
- class Project_Twig_Extension extends Twig_Extension
630
  {
631
  }
632
 
@@ -644,7 +683,7 @@ extensions must be registered explicitly to be available in your templates.
644
  You can register an extension by using the ``addExtension()`` method on your
645
  main ``Environment`` object::
646
 
647
- $twig = new Twig_Environment($loader);
648
  $twig->addExtension(new Project_Twig_Extension());
649
 
650
  .. tip::
@@ -657,7 +696,7 @@ Globals
657
  Global variables can be registered in an extension via the ``getGlobals()``
658
  method::
659
 
660
- class Project_Twig_Extension extends Twig_Extension implements Twig_Extension_GlobalsInterface
661
  {
662
  public function getGlobals()
663
  {
@@ -675,12 +714,12 @@ Functions
675
  Functions can be registered in an extension via the ``getFunctions()``
676
  method::
677
 
678
- class Project_Twig_Extension extends Twig_Extension
679
  {
680
  public function getFunctions()
681
  {
682
  return [
683
- new Twig_SimpleFunction('lipsum', 'generate_lipsum'),
684
  ];
685
  }
686
 
@@ -694,12 +733,12 @@ To add a filter to an extension, you need to override the ``getFilters()``
694
  method. This method must return an array of filters to add to the Twig
695
  environment::
696
 
697
- class Project_Twig_Extension extends Twig_Extension
698
  {
699
  public function getFilters()
700
  {
701
  return [
702
- new Twig_SimpleFilter('rot13', 'str_rot13'),
703
  ];
704
  }
705
 
@@ -713,7 +752,7 @@ Adding a tag in an extension can be done by overriding the
713
  ``getTokenParsers()`` method. This method must return an array of tags to add
714
  to the Twig environment::
715
 
716
- class Project_Twig_Extension extends Twig_Extension
717
  {
718
  public function getTokenParsers()
719
  {
@@ -733,17 +772,17 @@ Operators
733
  The ``getOperators()`` methods lets you add new operators. Here is how to add
734
  ``!``, ``||``, and ``&&`` operators::
735
 
736
- class Project_Twig_Extension extends Twig_Extension
737
  {
738
  public function getOperators()
739
  {
740
  return [
741
  [
742
- '!' => ['precedence' => 50, 'class' => 'Twig_Node_Expression_Unary_Not'],
743
  ],
744
  [
745
- '||' => ['precedence' => 10, 'class' => 'Twig_Node_Expression_Binary_Or', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT],
746
- '&&' => ['precedence' => 15, 'class' => 'Twig_Node_Expression_Binary_And', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT],
747
  ],
748
  ];
749
  }
@@ -756,12 +795,12 @@ Tests
756
 
757
  The ``getTests()`` method lets you add new test functions::
758
 
759
- class Project_Twig_Extension extends Twig_Extension
760
  {
761
  public function getTests()
762
  {
763
  return [
764
- new Twig_SimpleTest('even', 'twig_test_even'),
765
  ];
766
  }
767
 
@@ -785,7 +824,7 @@ any valid PHP callable:
785
 
786
  The simplest way to use methods is to define them on the extension itself::
787
 
788
- class Project_Twig_Extension extends Twig_Extension
789
  {
790
  private $rot13Provider;
791
 
@@ -797,7 +836,7 @@ The simplest way to use methods is to define them on the extension itself::
797
  public function getFunctions()
798
  {
799
  return [
800
- new Twig_SimpleFunction('rot13', [$this, 'rot13']),
801
  ];
802
  }
803
 
@@ -812,11 +851,11 @@ depend on runtime dependencies even if they are not needed (think for instance
812
  as a dependency that connects to a database engine).
813
 
814
  As of Twig 1.26, you can easily decouple the extension definitions from their
815
- runtime implementations by registering a ``Twig_RuntimeLoaderInterface``
816
  instance on the environment that knows how to instantiate such runtime classes
817
  (runtime classes must be autoload-able)::
818
 
819
- class RuntimeLoader implements Twig_RuntimeLoaderInterface
820
  {
821
  public function load($class)
822
  {
@@ -836,7 +875,7 @@ instance on the environment that knows how to instantiate such runtime classes
836
  .. note::
837
 
838
  As of Twig 1.32, Twig comes with a PSR-11 compatible runtime loader
839
- (``Twig_ContainerRuntimeLoader``) that works on PHP 5.3+.
840
 
841
  It is now possible to move the runtime logic to a new
842
  ``Project_Twig_RuntimeExtension`` class and use it directly in the extension::
@@ -856,14 +895,14 @@ It is now possible to move the runtime logic to a new
856
  }
857
  }
858
 
859
- class Project_Twig_Extension extends Twig_Extension
860
  {
861
  public function getFunctions()
862
  {
863
  return [
864
- new Twig_SimpleFunction('rot13', ['Project_Twig_RuntimeExtension', 'rot13']),
865
  // or
866
- new Twig_SimpleFunction('rot13', 'Project_Twig_RuntimeExtension::rot13'),
867
  ];
868
  }
869
  }
@@ -875,12 +914,12 @@ To overload an already defined filter, test, operator, global variable, or
875
  function, re-define it in an extension and register it **as late as
876
  possible** (order matters)::
877
 
878
- class MyCoreExtension extends Twig_Extension
879
  {
880
  public function getFilters()
881
  {
882
  return [
883
- new Twig_SimpleFilter('date', [$this, 'dateFilter']),
884
  ];
885
  }
886
 
@@ -890,16 +929,16 @@ possible** (order matters)::
890
  }
891
  }
892
 
893
- $twig = new Twig_Environment($loader);
894
  $twig->addExtension(new MyCoreExtension());
895
 
896
  Here, we have overloaded the built-in ``date`` filter with a custom one.
897
 
898
- If you do the same on the ``Twig_Environment`` itself, beware that it takes
899
  precedence over any other registered extensions::
900
 
901
- $twig = new Twig_Environment($loader);
902
- $twig->addFilter(new Twig_SimpleFilter('date', function ($timestamp, $format = 'F j, Y H:i') {
903
  // do something different from the built-in date filter
904
  }));
905
  // the date filter will come from the above registration, not
@@ -934,7 +973,7 @@ following file structure in your test directory::
934
 
935
  The ``IntegrationTest.php`` file should look like this::
936
 
937
- class Project_Tests_IntegrationTest extends Twig_Test_IntegrationTestCase
938
  {
939
  public function getExtensions()
940
  {
@@ -957,7 +996,7 @@ Node Tests
957
  ~~~~~~~~~~
958
 
959
  Testing the node visitors can be complex, so extend your test cases from
960
- ``Twig_Test_NodeTestCase``. Examples can be found in the Twig repository
961
  `tests/Twig/Node`_ directory.
962
 
963
  .. _`rot13`: https://secure.php.net/manual/en/function.str-rot13.php
114
  A global variable is like any other template variable, except that it's
115
  available in all templates and macros::
116
 
117
+ $twig = new \Twig\Environment($loader);
118
  $twig->addGlobal('text', new Text());
119
 
120
  You can then use the ``text`` variable anywhere in a template:
129
  Creating a filter is as simple as associating a name with a PHP callable::
130
 
131
  // an anonymous function
132
+ $filter = new \Twig\TwigFilter('rot13', function ($string) {
133
  return str_rot13($string);
134
  });
135
 
136
  // or a simple PHP function
137
+ $filter = new \Twig\TwigFilter('rot13', 'str_rot13');
138
 
139
  // or a class static method
140
+ $filter = new \Twig\TwigFilter('rot13', ['SomeClass', 'rot13Filter']);
141
+ $filter = new \Twig\TwigFilter('rot13', 'SomeClass::rot13Filter');
142
 
143
  // or a class method
144
+ $filter = new \Twig\TwigFilter('rot13', [$this, 'rot13Filter']);
145
  // the one below needs a runtime implementation (see below for more information)
146
+ $filter = new \Twig\TwigFilter('rot13', ['SomeClass', 'rot13Filter']);
147
 
148
+ The first argument passed to the ``\Twig\TwigFilter`` constructor is the name
149
  of the filter you will use in templates and the second one is the PHP callable
150
  to associate with it.
151
 
152
  Then, add the filter to your Twig environment::
153
 
154
+ $twig = new \Twig\Environment($loader);
155
  $twig->addFilter($filter);
156
 
157
  And here is how to use it in a template:
178
  <?php echo strtolower('TWIG') ?>
179
  <?php echo twig_date_format_filter($now, 'd/m/Y') ?>
180
 
181
+ The ``\Twig\TwigFilter`` class takes an array of options as its last
182
  argument::
183
 
184
+ $filter = new \Twig\TwigFilter('rot13', 'str_rot13', $options);
185
 
186
  Environment-aware Filters
187
  ~~~~~~~~~~~~~~~~~~~~~~~~~
190
  ``needs_environment`` option to ``true``; Twig will pass the current
191
  environment as the first argument to the filter call::
192
 
193
+ $filter = new \Twig\TwigFilter('rot13', function (Twig_Environment $env, $string) {
194
  // get the current charset for instance
195
  $charset = $env->getCharset();
196
 
205
  the first argument to the filter call (or the second one if
206
  ``needs_environment`` is also set to ``true``)::
207
 
208
+ $filter = new \Twig\TwigFilter('rot13', function ($context, $string) {
209
  // ...
210
  }, ['needs_context' => true]);
211
 
212
+ $filter = new \Twig\TwigFilter('rot13', function (Twig_Environment $env, $context, $string) {
213
  // ...
214
  }, ['needs_context' => true, 'needs_environment' => true]);
215
 
221
  or JavaScript code), you will want the raw output to be printed. In such a
222
  case, set the ``is_safe`` option::
223
 
224
+ $filter = new \Twig\TwigFilter('nl2br', 'nl2br', ['is_safe' => ['html']]);
225
 
226
  Some filters may need to work on input that is already escaped or safe, for
227
  example when adding (safe) HTML tags to originally unsafe output. In such a
228
  case, set the ``pre_escape`` option to escape the input data before it is run
229
  through your filter::
230
 
231
+ $filter = new \Twig\TwigFilter('somefilter', 'somefilter', ['pre_escape' => 'html', 'is_safe' => ['html']]);
232
 
233
  Variadic Filters
234
  ~~~~~~~~~~~~~~~~
240
  ``is_variadic`` option to ``true``; Twig will pass the extra arguments as the
241
  last argument to the filter call as an array::
242
 
243
+ $filter = new \Twig\TwigFilter('thumbnail', function ($file, array $options = []) {
244
  // ...
245
  }, ['is_variadic' => true]);
246
 
247
+ Be warned that :ref:`named arguments <named-arguments>` passed to a variadic
248
+ filter cannot be checked for validity as they will automatically end up in the
249
+ option array.
250
 
251
  Dynamic Filters
252
  ~~~~~~~~~~~~~~~
254
  A filter name containing the special ``*`` character is a dynamic filter as
255
  the ``*`` can be any string::
256
 
257
+ $filter = new \Twig\TwigFilter('*_path', function ($name, $arguments) {
258
  // ...
259
  });
260
 
265
 
266
  A dynamic filter can define more than one dynamic parts::
267
 
268
+ $filter = new \Twig\TwigFilter('*_path_*', function ($name, $suffix, $arguments) {
269
  // ...
270
  });
271
 
284
  to ``true``. You can also give an alternative filter that replaces the
285
  deprecated one when that makes sense::
286
 
287
+ $filter = new \Twig\TwigFilter('obsolete', function () {
288
  // ...
289
  }, ['deprecated' => true, 'alternative' => 'new_one']);
290
 
295
  ---------
296
 
297
  Functions are defined in the exact same way as filters, but you need to create
298
+ an instance of ``\Twig\TwigFunction``::
299
 
300
+ $twig = new \Twig\Environment($loader);
301
+ $function = new \Twig\TwigFunction('function_name', function () {
302
  // ...
303
  });
304
  $twig->addFunction($function);
310
  -----
311
 
312
  Tests are defined in the exact same way as filters and functions, but you need
313
+ to create an instance of ``\Twig\TwigTest``::
314
 
315
+ $twig = new \Twig\Environment($loader);
316
+ $test = new \Twig\TwigTest('test_name', function () {
317
  // ...
318
  });
319
  $twig->addTest($test);
322
  boolean conditions. As a simple example, let's create a Twig test that checks if
323
  objects are 'red'::
324
 
325
+ $twig = new \Twig\Environment($loader);
326
+ $test = new \Twig\TwigTest('red', function ($value) {
327
  if (isset($value->color) && $value->color == 'red') {
328
  return true;
329
  }
340
  compilation. This is useful if your test can be compiled into PHP primitives.
341
  This is used by many of the tests built into Twig::
342
 
343
+ $twig = new \Twig\Environment($loader);
344
+ $test = new \Twig\TwigTest(
345
  'odd',
346
  null,
347
+ ['node_class' => '\Twig\Node\Expression\Test\OddTest']);
348
  $twig->addTest($test);
349
 
350
+ class Twig_Node_Expression_Test_Odd extends \Twig\Node\Expression\TestExpression
351
  {
352
+ public function compile(\Twig\Compiler $compiler)
353
  {
354
  $compiler
355
  ->raw('(')
383
  ----
384
 
385
  One of the most exciting features of a template engine like Twig is the
386
+ possibility to define new **language constructs**. This is also the most complex
387
  feature as you need to understand how Twig's internals work.
388
 
389
+ Most of the time though, a tag is not needed:
390
+
391
+ * If your tag generates some output, use a **function** instead.
392
+
393
+ * If your tag modifies some content and returns it, use a **filter** instead.
394
+
395
+ For instance, if you want to create a tag that converts a Markdown formatted
396
+ text to HTML, create a ``markdown`` filter instead:
397
+
398
+ .. code-block:: jinja
399
+
400
+ {{ '**markdown** text'|markdown }}
401
+
402
+ If you want use this filter on large amounts of text, wrap it with the
403
+ :doc:`filter <tags/filter>` tag:
404
+
405
+ .. code-block:: jinja
406
+
407
+ {% filter markdown %}
408
+ Title
409
+ =====
410
+
411
+ Much better than creating a tag as you can **compose** filters.
412
+ {% endfilter %}
413
+
414
+ * If your tag does not output anything, but only exists because of a side
415
+ effect, create a **function** that returns nothing and call it via the
416
+ :doc:`filter <tags/do>` tag.
417
+
418
+ For instance, if you want to create a tag that logs text, create a ``log``
419
+ function instead and call it via the :doc:`do <tags/do>` tag:
420
+
421
+ .. code-block:: jinja
422
+
423
+ {% do log('Log some things') %}
424
+
425
+ If you still want to create a tag for a new language construct, great!
426
+
427
  Let's create a simple ``set`` tag that allows the definition of simple
428
  variables from within a template. The tag can be used like follows:
429
 
454
  ~~~~~~~~~~~~~~~~~~~~~
455
 
456
  Adding a tag is as simple as calling the ``addTokenParser`` method on the
457
+ ``\Twig\Environment`` instance::
458
 
459
+ $twig = new \Twig\Environment($loader);
460
  $twig->addTokenParser(new Project_Set_TokenParser());
461
 
462
  Defining a Token Parser
464
 
465
  Now, let's see the actual code of this class::
466
 
467
+ class Project_Set_TokenParser extends \Twig\TokenParser\AbstractTokenParser
468
  {
469
+ public function parse(\Twig\Token $token)
470
  {
471
  $parser = $this->parser;
472
  $stream = $parser->getStream();
473
 
474
+ $name = $stream->expect(\Twig\Token::NAME_TYPE)->getValue();
475
+ $stream->expect(\Twig\Token::OPERATOR_TYPE, '=');
476
  $value = $parser->getExpressionParser()->parseExpression();
477
+ $stream->expect(\Twig\Token::BLOCK_END_TYPE);
478
 
479
  return new Project_Set_Node($name, $value, $token->getLine(), $this->getTag());
480
  }
488
  The ``getTag()`` method must return the tag we want to parse, here ``set``.
489
 
490
  The ``parse()`` method is invoked whenever the parser encounters a ``set``
491
+ tag. It should return a ``\Twig\Node\Node`` instance that represents the node (the
492
  ``Project_Set_Node`` calls creating is explained in the next section).
493
 
494
  The parsing process is simplified thanks to a bunch of methods you can call
521
 
522
  The ``Project_Set_Node`` class itself is rather simple::
523
 
524
+ class Project_Set_Node extends \Twig\Node\Node
525
  {
526
+ public function __construct($name, \Twig\Node\Expression\AbstractExpression $value, $line, $tag = null)
527
  {
528
  parent::__construct(['value' => $value], ['name' => $name], $line, $tag);
529
  }
530
 
531
+ public function compile(\Twig\Compiler $compiler)
532
  {
533
  $compiler
534
  ->addDebugInfo($this)
552
  * ``string()``: Writes a quoted string.
553
 
554
  * ``repr()``: Writes a PHP representation of a given value (see
555
+ ``\Twig\Node\ForNode`` for a usage example).
556
 
557
  * ``addDebugInfo()``: Adds the line of the original template file related to
558
  the current node as a comment.
559
 
560
+ * ``indent()``: Indents the generated code (see ``\Twig\Node\BlockNode`` for a
561
  usage example).
562
 
563
+ * ``outdent()``: Outdents the generated code (see ``\Twig\Node\BlockNode`` for a
564
  usage example).
565
 
566
  .. _creating_extensions:
596
  *
597
  * This is where you can load some file that contains filter functions for instance.
598
  *
599
+ * @deprecated since 1.23 (to be removed in 2.0), implement \Twig\Extension\InitRuntimeInterface instead
600
  */
601
+ function initRuntime(\Twig\Environment $environment);
602
 
603
  /**
604
  * Returns the token parser instances to add to the existing list.
610
  /**
611
  * Returns the node visitor instances to add to the existing list.
612
  *
613
+ * @return \Twig\NodeVisitor\NodeVisitorInterface[]
614
  */
615
  function getNodeVisitors();
616
 
617
  /**
618
  * Returns a list of filters to add to the existing list.
619
  *
620
+ * @return \Twig\TwigFilter[]
621
  */
622
  function getFilters();
623
 
624
  /**
625
  * Returns a list of tests to add to the existing list.
626
  *
627
+ * @return \Twig\TwigTest[]
628
  */
629
  function getTests();
630
 
631
  /**
632
  * Returns a list of functions to add to the existing list.
633
  *
634
+ * @return \Twig\TwigFunction[]
635
  */
636
  function getFunctions();
637
 
647
  *
648
  * @return array An array of global variables
649
  *
650
+ * @deprecated since 1.23 (to be removed in 2.0), implement \Twig\Extension\GlobalsInterface instead
651
  */
652
  function getGlobals();
653
 
662
  }
663
 
664
  To keep your extension class clean and lean, inherit from the built-in
665
+ ``\Twig\Extension\AbstractExtension`` class instead of implementing the interface as it provides
666
  empty implementations for all methods:
667
 
668
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
669
  {
670
  }
671
 
683
  You can register an extension by using the ``addExtension()`` method on your
684
  main ``Environment`` object::
685
 
686
+ $twig = new \Twig\Environment($loader);
687
  $twig->addExtension(new Project_Twig_Extension());
688
 
689
  .. tip::
696
  Global variables can be registered in an extension via the ``getGlobals()``
697
  method::
698
 
699
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension implements \Twig\Extension\GlobalsInterface
700
  {
701
  public function getGlobals()
702
  {
714
  Functions can be registered in an extension via the ``getFunctions()``
715
  method::
716
 
717
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
718
  {
719
  public function getFunctions()
720
  {
721
  return [
722
+ new \Twig\TwigFunction('lipsum', 'generate_lipsum'),
723
  ];
724
  }
725
 
733
  method. This method must return an array of filters to add to the Twig
734
  environment::
735
 
736
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
737
  {
738
  public function getFilters()
739
  {
740
  return [
741
+ new \Twig\TwigFilter('rot13', 'str_rot13'),
742
  ];
743
  }
744
 
752
  ``getTokenParsers()`` method. This method must return an array of tags to add
753
  to the Twig environment::
754
 
755
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
756
  {
757
  public function getTokenParsers()
758
  {
772
  The ``getOperators()`` methods lets you add new operators. Here is how to add
773
  ``!``, ``||``, and ``&&`` operators::
774
 
775
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
776
  {
777
  public function getOperators()
778
  {
779
  return [
780
  [
781
+ '!' => ['precedence' => 50, 'class' => '\Twig\Node\Expression\Unary\NotUnary'],
782
  ],
783
  [
784
+ '||' => ['precedence' => 10, 'class' => '\Twig\Node\Expression\Binary\OrBinary', 'associativity' => \Twig\ExpressionParser::OPERATOR_LEFT],
785
+ '&&' => ['precedence' => 15, 'class' => '\Twig\Node\Expression\Binary\AndBinary', 'associativity' => \Twig\ExpressionParser::OPERATOR_LEFT],
786
  ],
787
  ];
788
  }
795
 
796
  The ``getTests()`` method lets you add new test functions::
797
 
798
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
799
  {
800
  public function getTests()
801
  {
802
  return [
803
+ new \Twig\TwigTest('even', 'twig_test_even'),
804
  ];
805
  }
806
 
824
 
825
  The simplest way to use methods is to define them on the extension itself::
826
 
827
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
828
  {
829
  private $rot13Provider;
830
 
836
  public function getFunctions()
837
  {
838
  return [
839
+ new \Twig\TwigFunction('rot13', [$this, 'rot13']),
840
  ];
841
  }
842
 
851
  as a dependency that connects to a database engine).
852
 
853
  As of Twig 1.26, you can easily decouple the extension definitions from their
854
+ runtime implementations by registering a ``\Twig\RuntimeLoader\RuntimeLoaderInterface``
855
  instance on the environment that knows how to instantiate such runtime classes
856
  (runtime classes must be autoload-able)::
857
 
858
+ class RuntimeLoader implements \Twig\RuntimeLoader\RuntimeLoaderInterface
859
  {
860
  public function load($class)
861
  {
875
  .. note::
876
 
877
  As of Twig 1.32, Twig comes with a PSR-11 compatible runtime loader
878
+ (``\Twig\RuntimeLoader\ContainerRuntimeLoader``) that works on PHP 5.3+.
879
 
880
  It is now possible to move the runtime logic to a new
881
  ``Project_Twig_RuntimeExtension`` class and use it directly in the extension::
895
  }
896
  }
897
 
898
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
899
  {
900
  public function getFunctions()
901
  {
902
  return [
903
+ new \Twig\TwigFunction('rot13', ['Project_Twig_RuntimeExtension', 'rot13']),
904
  // or
905
+ new \Twig\TwigFunction('rot13', 'Project_Twig_RuntimeExtension::rot13'),
906
  ];
907
  }
908
  }
914
  function, re-define it in an extension and register it **as late as
915
  possible** (order matters)::
916
 
917
+ class MyCoreExtension extends \Twig\Extension\AbstractExtension
918
  {
919
  public function getFilters()
920
  {
921
  return [
922
+ new \Twig\TwigFilter('date', [$this, 'dateFilter']),
923
  ];
924
  }
925
 
929
  }
930
  }
931
 
932
+ $twig = new \Twig\Environment($loader);
933
  $twig->addExtension(new MyCoreExtension());
934
 
935
  Here, we have overloaded the built-in ``date`` filter with a custom one.
936
 
937
+ If you do the same on the ``\Twig\Environment`` itself, beware that it takes
938
  precedence over any other registered extensions::
939
 
940
+ $twig = new \Twig\Environment($loader);
941
+ $twig->addFilter(new \Twig\TwigFilter('date', function ($timestamp, $format = 'F j, Y H:i') {
942
  // do something different from the built-in date filter
943
  }));
944
  // the date filter will come from the above registration, not
973
 
974
  The ``IntegrationTest.php`` file should look like this::
975
 
976
+ class Project_Tests_IntegrationTest extends \Twig\Test\IntegrationTestCase
977
  {
978
  public function getExtensions()
979
  {
996
  ~~~~~~~~~~
997
 
998
  Testing the node visitors can be complex, so extend your test cases from
999
+ ``\Twig\Test\NodeTestCase``. Examples can be found in the Twig repository
1000
  `tests/Twig/Node`_ directory.
1001
 
1002
  .. _`rot13`: https://secure.php.net/manual/en/function.str-rot13.php
vendor/twig/twig/doc/advanced_legacy.rst CHANGED
@@ -115,7 +115,7 @@ Globals
115
  A global variable is like any other template variable, except that it's
116
  available in all templates and macros::
117
 
118
- $twig = new Twig_Environment($loader);
119
  $twig->addGlobal('text', new Text());
120
 
121
  You can then use the ``text`` variable anywhere in a template:
@@ -176,9 +176,9 @@ expected output:
176
  {# should displays Gjvt #}
177
 
178
  Adding a filter is as simple as calling the ``addFilter()`` method on the
179
- ``Twig_Environment`` instance::
180
 
181
- $twig = new Twig_Environment($loader);
182
  $twig->addFilter('rot13', new Twig_Filter_Function('str_rot13'));
183
 
184
  The second argument of ``addFilter()`` is an instance of ``Twig_Filter``.
@@ -232,7 +232,7 @@ if you want access to the current environment instance in your filter, set the
232
  Twig will then pass the current environment as the first argument to the
233
  filter call::
234
 
235
- function twig_compute_rot13(Twig_Environment $env, $string)
236
  {
237
  // get the current charset for instance
238
  $charset = $env->getCharset();
@@ -311,15 +311,15 @@ compilation, the generated PHP code is roughly equivalent to:
311
  <?php echo constant('DATE_W3C') ?>
312
 
313
  Adding a function is similar to adding a filter. This can be done by calling the
314
- ``addFunction()`` method on the ``Twig_Environment`` instance::
315
 
316
- $twig = new Twig_Environment($loader);
317
  $twig->addFunction('functionName', new Twig_Function_Function('someFunction'));
318
 
319
  You can also expose extension methods as functions in your templates::
320
 
321
- // $this is an object that implements Twig_ExtensionInterface.
322
- $twig = new Twig_Environment($loader);
323
  $twig->addFunction('otherFunction', new Twig_Function_Method($this, 'someMethod'));
324
 
325
  Functions also support ``needs_environment`` and ``is_safe`` parameters.
@@ -395,9 +395,9 @@ Registering a new tag
395
  ~~~~~~~~~~~~~~~~~~~~~
396
 
397
  Adding a tag is as simple as calling the ``addTokenParser`` method on the
398
- ``Twig_Environment`` instance::
399
 
400
- $twig = new Twig_Environment($loader);
401
  $twig->addTokenParser(new Project_Set_TokenParser());
402
 
403
  Defining a Token Parser
@@ -405,16 +405,16 @@ Defining a Token Parser
405
 
406
  Now, let's see the actual code of this class::
407
 
408
- class Project_Set_TokenParser extends Twig_TokenParser
409
  {
410
- public function parse(Twig_Token $token)
411
  {
412
  $lineno = $token->getLine();
413
- $name = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE)->getValue();
414
- $this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, '=');
415
  $value = $this->parser->getExpressionParser()->parseExpression();
416
 
417
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
418
 
419
  return new Project_Set_Node($name, $value, $lineno, $this->getTag());
420
  }
@@ -428,7 +428,7 @@ Now, let's see the actual code of this class::
428
  The ``getTag()`` method must return the tag we want to parse, here ``set``.
429
 
430
  The ``parse()`` method is invoked whenever the parser encounters a ``set``
431
- tag. It should return a ``Twig_Node`` instance that represents the node (the
432
  ``Project_Set_Node`` calls creating is explained in the next section).
433
 
434
  The parsing process is simplified thanks to a bunch of methods you can call
@@ -461,14 +461,14 @@ Defining a Node
461
 
462
  The ``Project_Set_Node`` class itself is rather simple::
463
 
464
- class Project_Set_Node extends Twig_Node
465
  {
466
- public function __construct($name, Twig_Node_Expression $value, $lineno, $tag = null)
467
  {
468
  parent::__construct(['value' => $value], ['name' => $name], $lineno, $tag);
469
  }
470
 
471
- public function compile(Twig_Compiler $compiler)
472
  {
473
  $compiler
474
  ->addDebugInfo($this)
@@ -492,15 +492,15 @@ developer generate beautiful and readable PHP code:
492
  * ``string()``: Writes a quoted string.
493
 
494
  * ``repr()``: Writes a PHP representation of a given value (see
495
- ``Twig_Node_For`` for a usage example).
496
 
497
  * ``addDebugInfo()``: Adds the line of the original template file related to
498
  the current node as a comment.
499
 
500
- * ``indent()``: Indents the generated code (see ``Twig_Node_Block`` for a
501
  usage example).
502
 
503
- * ``outdent()``: Outdents the generated code (see ``Twig_Node_Block`` for a
504
  usage example).
505
 
506
  .. _creating_extensions:
@@ -540,7 +540,7 @@ An extension is a class that implements the following interface::
540
  *
541
  * This is where you can load some file that contains filter functions for instance.
542
  */
543
- function initRuntime(Twig_Environment $environment);
544
 
545
  /**
546
  * Returns the token parser instances to add to the existing list.
@@ -552,28 +552,28 @@ An extension is a class that implements the following interface::
552
  /**
553
  * Returns the node visitor instances to add to the existing list.
554
  *
555
- * @return Twig_NodeVisitorInterface[]
556
  */
557
  function getNodeVisitors();
558
 
559
  /**
560
  * Returns a list of filters to add to the existing list.
561
  *
562
- * @return Twig_SimpleFilter[]
563
  */
564
  function getFilters();
565
 
566
  /**
567
  * Returns a list of tests to add to the existing list.
568
  *
569
- * @return Twig_SimpleTest[]
570
  */
571
  function getTests();
572
 
573
  /**
574
  * Returns a list of functions to add to the existing list.
575
  *
576
- * @return Twig_SimpleFunction[]
577
  */
578
  function getFunctions();
579
 
@@ -600,16 +600,16 @@ An extension is a class that implements the following interface::
600
  }
601
 
602
  To keep your extension class clean and lean, it can inherit from the built-in
603
- ``Twig_Extension`` class instead of implementing the whole interface. That
604
  way, you just need to implement the ``getName()`` method as the
605
- ``Twig_Extension`` provides empty implementations for all other methods.
606
 
607
  The ``getName()`` method must return a unique identifier for your extension.
608
 
609
  Now, with this information in mind, let's create the most basic extension
610
  possible::
611
 
612
- class Project_Twig_Extension extends Twig_Extension
613
  {
614
  public function getName()
615
  {
@@ -628,7 +628,7 @@ extensions must be registered explicitly to be available in your templates.
628
  You can register an extension by using the ``addExtension()`` method on your
629
  main ``Environment`` object::
630
 
631
- $twig = new Twig_Environment($loader);
632
  $twig->addExtension(new Project_Twig_Extension());
633
 
634
  Of course, you need to first load the extension file by either using
@@ -644,7 +644,7 @@ Globals
644
  Global variables can be registered in an extension via the ``getGlobals()``
645
  method::
646
 
647
- class Project_Twig_Extension extends Twig_Extension
648
  {
649
  public function getGlobals()
650
  {
@@ -662,7 +662,7 @@ Functions
662
  Functions can be registered in an extension via the ``getFunctions()``
663
  method::
664
 
665
- class Project_Twig_Extension extends Twig_Extension
666
  {
667
  public function getFunctions()
668
  {
@@ -681,7 +681,7 @@ To add a filter to an extension, you need to override the ``getFilters()``
681
  method. This method must return an array of filters to add to the Twig
682
  environment::
683
 
684
- class Project_Twig_Extension extends Twig_Extension
685
  {
686
  public function getFilters()
687
  {
@@ -705,7 +705,7 @@ $twig->addFilter('rot13', new Twig_Filter_Function('Project_Twig_Extension::rot1
705
  You can also use ``Twig_Filter_Method`` instead of ``Twig_Filter_Function``
706
  when defining a filter to use a method::
707
 
708
- class Project_Twig_Extension extends Twig_Extension
709
  {
710
  public function getFilters()
711
  {
@@ -737,7 +737,7 @@ If some default core filters do not suit your needs, you can easily override
737
  them by creating your own extension. Just use the same names as the one you
738
  want to override::
739
 
740
- class MyCoreExtension extends Twig_Extension
741
  {
742
  public function getFilters()
743
  {
@@ -762,7 +762,7 @@ Here, we override the ``date`` filter with a custom one. Using this extension
762
  is as simple as registering the ``MyCoreExtension`` extension by calling the
763
  ``addExtension()`` method on the environment instance::
764
 
765
- $twig = new Twig_Environment($loader);
766
  $twig->addExtension(new MyCoreExtension());
767
 
768
  Tags
@@ -772,7 +772,7 @@ Adding a tag in an extension can be done by overriding the
772
  ``getTokenParsers()`` method. This method must return an array of tags to add
773
  to the Twig environment::
774
 
775
- class Project_Twig_Extension extends Twig_Extension
776
  {
777
  public function getTokenParsers()
778
  {
@@ -792,17 +792,17 @@ Operators
792
  The ``getOperators()`` methods allows to add new operators. Here is how to add
793
  ``!``, ``||``, and ``&&`` operators::
794
 
795
- class Project_Twig_Extension extends Twig_Extension
796
  {
797
  public function getOperators()
798
  {
799
  return [
800
  [
801
- '!' => ['precedence' => 50, 'class' => 'Twig_Node_Expression_Unary_Not'],
802
  ),
803
  [
804
- '||' => ['precedence' => 10, 'class' => 'Twig_Node_Expression_Binary_Or', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT],
805
- '&&' => ['precedence' => 15, 'class' => 'Twig_Node_Expression_Binary_And', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT],
806
  ],
807
  ];
808
  }
@@ -815,7 +815,7 @@ Tests
815
 
816
  The ``getTests()`` methods allows to add new test functions::
817
 
818
- class Project_Twig_Extension extends Twig_Extension
819
  {
820
  public function getTests()
821
  {
@@ -853,7 +853,7 @@ following file structure in your test directory::
853
 
854
  The ``IntegrationTest.php`` file should look like this::
855
 
856
- class Project_Tests_IntegrationTest extends Twig_Test_IntegrationTestCase
857
  {
858
  public function getExtensions()
859
  {
@@ -876,7 +876,7 @@ Node Tests
876
  ~~~~~~~~~~
877
 
878
  Testing the node visitors can be complex, so extend your test cases from
879
- ``Twig_Test_NodeTestCase``. Examples can be found in the Twig repository
880
  `tests/Twig/Node`_ directory.
881
 
882
  .. _`spl_autoload_register()`: https://secure.php.net/spl_autoload_register
115
  A global variable is like any other template variable, except that it's
116
  available in all templates and macros::
117
 
118
+ $twig = new \Twig\Environment($loader);
119
  $twig->addGlobal('text', new Text());
120
 
121
  You can then use the ``text`` variable anywhere in a template:
176
  {# should displays Gjvt #}
177
 
178
  Adding a filter is as simple as calling the ``addFilter()`` method on the
179
+ ``\Twig\Environment`` instance::
180
 
181
+ $twig = new \Twig\Environment($loader);
182
  $twig->addFilter('rot13', new Twig_Filter_Function('str_rot13'));
183
 
184
  The second argument of ``addFilter()`` is an instance of ``Twig_Filter``.
232
  Twig will then pass the current environment as the first argument to the
233
  filter call::
234
 
235
+ function twig_compute_rot13(\Twig\Environment $env, $string)
236
  {
237
  // get the current charset for instance
238
  $charset = $env->getCharset();
311
  <?php echo constant('DATE_W3C') ?>
312
 
313
  Adding a function is similar to adding a filter. This can be done by calling the
314
+ ``addFunction()`` method on the ``\Twig\Environment`` instance::
315
 
316
+ $twig = new \Twig\Environment($loader);
317
  $twig->addFunction('functionName', new Twig_Function_Function('someFunction'));
318
 
319
  You can also expose extension methods as functions in your templates::
320
 
321
+ // $this is an object that implements \Twig\Extension\ExtensionInterface.
322
+ $twig = new \Twig\Environment($loader);
323
  $twig->addFunction('otherFunction', new Twig_Function_Method($this, 'someMethod'));
324
 
325
  Functions also support ``needs_environment`` and ``is_safe`` parameters.
395
  ~~~~~~~~~~~~~~~~~~~~~
396
 
397
  Adding a tag is as simple as calling the ``addTokenParser`` method on the
398
+ ``\Twig\Environment`` instance::
399
 
400
+ $twig = new \Twig\Environment($loader);
401
  $twig->addTokenParser(new Project_Set_TokenParser());
402
 
403
  Defining a Token Parser
405
 
406
  Now, let's see the actual code of this class::
407
 
408
+ class Project_Set_TokenParser extends \Twig\TokenParser\AbstractTokenParser
409
  {
410
+ public function parse(\Twig\Token $token)
411
  {
412
  $lineno = $token->getLine();
413
+ $name = $this->parser->getStream()->expect(\Twig\Token::NAME_TYPE)->getValue();
414
+ $this->parser->getStream()->expect(\Twig\Token::OPERATOR_TYPE, '=');
415
  $value = $this->parser->getExpressionParser()->parseExpression();
416
 
417
+ $this->parser->getStream()->expect(\Twig\Token::BLOCK_END_TYPE);
418
 
419
  return new Project_Set_Node($name, $value, $lineno, $this->getTag());
420
  }
428
  The ``getTag()`` method must return the tag we want to parse, here ``set``.
429
 
430
  The ``parse()`` method is invoked whenever the parser encounters a ``set``
431
+ tag. It should return a ``\Twig\Node\Node`` instance that represents the node (the
432
  ``Project_Set_Node`` calls creating is explained in the next section).
433
 
434
  The parsing process is simplified thanks to a bunch of methods you can call
461
 
462
  The ``Project_Set_Node`` class itself is rather simple::
463
 
464
+ class Project_Set_Node extends \Twig\Node\Node
465
  {
466
+ public function __construct($name, \Twig\Node\Expression\AbstractExpression $value, $lineno, $tag = null)
467
  {
468
  parent::__construct(['value' => $value], ['name' => $name], $lineno, $tag);
469
  }
470
 
471
+ public function compile(\Twig\Compiler $compiler)
472
  {
473
  $compiler
474
  ->addDebugInfo($this)
492
  * ``string()``: Writes a quoted string.
493
 
494
  * ``repr()``: Writes a PHP representation of a given value (see
495
+ ``\Twig\Node\ForNode`` for a usage example).
496
 
497
  * ``addDebugInfo()``: Adds the line of the original template file related to
498
  the current node as a comment.
499
 
500
+ * ``indent()``: Indents the generated code (see ``\Twig\Node\BlockNode`` for a
501
  usage example).
502
 
503
+ * ``outdent()``: Outdents the generated code (see ``\Twig\Node\BlockNode`` for a
504
  usage example).
505
 
506
  .. _creating_extensions:
540
  *
541
  * This is where you can load some file that contains filter functions for instance.
542
  */
543
+ function initRuntime(\Twig\Environment $environment);
544
 
545
  /**
546
  * Returns the token parser instances to add to the existing list.
552
  /**
553
  * Returns the node visitor instances to add to the existing list.
554
  *
555
+ * @return \Twig\NodeVisitor\NodeVisitorInterface[]
556
  */
557
  function getNodeVisitors();
558
 
559
  /**
560
  * Returns a list of filters to add to the existing list.
561
  *
562
+ * @return \Twig\TwigFilter[]
563
  */
564
  function getFilters();
565
 
566
  /**
567
  * Returns a list of tests to add to the existing list.
568
  *
569
+ * @return \Twig\TwigTest[]
570
  */
571
  function getTests();
572
 
573
  /**
574
  * Returns a list of functions to add to the existing list.
575
  *
576
+ * @return \Twig\TwigFunction[]
577
  */
578
  function getFunctions();
579
 
600
  }
601
 
602
  To keep your extension class clean and lean, it can inherit from the built-in
603
+ ``\Twig\Extension\AbstractExtension`` class instead of implementing the whole interface. That
604
  way, you just need to implement the ``getName()`` method as the
605
+ ``\Twig\Extension\AbstractExtension`` provides empty implementations for all other methods.
606
 
607
  The ``getName()`` method must return a unique identifier for your extension.
608
 
609
  Now, with this information in mind, let's create the most basic extension
610
  possible::
611
 
612
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
613
  {
614
  public function getName()
615
  {
628
  You can register an extension by using the ``addExtension()`` method on your
629
  main ``Environment`` object::
630
 
631
+ $twig = new \Twig\Environment($loader);
632
  $twig->addExtension(new Project_Twig_Extension());
633
 
634
  Of course, you need to first load the extension file by either using
644
  Global variables can be registered in an extension via the ``getGlobals()``
645
  method::
646
 
647
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
648
  {
649
  public function getGlobals()
650
  {
662
  Functions can be registered in an extension via the ``getFunctions()``
663
  method::
664
 
665
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
666
  {
667
  public function getFunctions()
668
  {
681
  method. This method must return an array of filters to add to the Twig
682
  environment::
683
 
684
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
685
  {
686
  public function getFilters()
687
  {
705
  You can also use ``Twig_Filter_Method`` instead of ``Twig_Filter_Function``
706
  when defining a filter to use a method::
707
 
708
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
709
  {
710
  public function getFilters()
711
  {
737
  them by creating your own extension. Just use the same names as the one you
738
  want to override::
739
 
740
+ class MyCoreExtension extends \Twig\Extension\AbstractExtension
741
  {
742
  public function getFilters()
743
  {
762
  is as simple as registering the ``MyCoreExtension`` extension by calling the
763
  ``addExtension()`` method on the environment instance::
764
 
765
+ $twig = new \Twig\Environment($loader);
766
  $twig->addExtension(new MyCoreExtension());
767
 
768
  Tags
772
  ``getTokenParsers()`` method. This method must return an array of tags to add
773
  to the Twig environment::
774
 
775
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
776
  {
777
  public function getTokenParsers()
778
  {
792
  The ``getOperators()`` methods allows to add new operators. Here is how to add
793
  ``!``, ``||``, and ``&&`` operators::
794
 
795
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
796
  {
797
  public function getOperators()
798
  {
799
  return [
800
  [
801
+ '!' => ['precedence' => 50, 'class' => '\Twig\Node\Expression\Unary\NotUnary'],
802
  ),
803
  [
804
+ '||' => ['precedence' => 10, 'class' => '\Twig\Node\Expression\Binary\OrBinary', 'associativity' => \Twig\ExpressionParser::OPERATOR_LEFT],
805
+ '&&' => ['precedence' => 15, 'class' => '\Twig\Node\Expression\Binary\AndBinary', 'associativity' => \Twig\ExpressionParser::OPERATOR_LEFT],
806
  ],
807
  ];
808
  }
815
 
816
  The ``getTests()`` methods allows to add new test functions::
817
 
818
+ class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
819
  {
820
  public function getTests()
821
  {
853
 
854
  The ``IntegrationTest.php`` file should look like this::
855
 
856
+ class Project_Tests_IntegrationTest extends \Twig\Test\IntegrationTestCase
857
  {
858
  public function getExtensions()
859
  {
876
  ~~~~~~~~~~
877
 
878
  Testing the node visitors can be complex, so extend your test cases from
879
+ ``\Twig\Test\NodeTestCase``. Examples can be found in the Twig repository
880
  `tests/Twig/Node`_ directory.
881
 
882
  .. _`spl_autoload_register()`: https://secure.php.net/spl_autoload_register
vendor/twig/twig/doc/api.rst CHANGED
@@ -9,11 +9,11 @@ Basics
9
  ------
10
 
11
  Twig uses a central object called the **environment** (of class
12
- ``Twig_Environment``). Instances of this class are used to store the
13
  configuration and extensions, and are used to load templates from the file
14
  system or other locations.
15
 
16
- Most applications will create one ``Twig_Environment`` object on application
17
  initialization and use that to load templates. In some cases it's however
18
  useful to have multiple environments side by side, if different configurations
19
  are in use.
@@ -24,8 +24,8 @@ looks roughly like this::
24
  require_once '/path/to/lib/Twig/Autoloader.php';
25
  Twig_Autoloader::register();
26
 
27
- $loader = new Twig_Loader_Filesystem('/path/to/templates');
28
- $twig = new Twig_Environment($loader, [
29
  'cache' => '/path/to/compilation_cache',
30
  ]);
31
 
@@ -47,14 +47,14 @@ Rendering Templates
47
  -------------------
48
 
49
  To load a template from a Twig environment, call the ``load()`` method which
50
- returns a ``Twig_TemplateWrapper`` instance::
51
 
52
  $template = $twig->load('index.html');
53
 
54
  .. note::
55
 
56
  Before Twig 1.28, you should use ``loadTemplate()`` instead which returns a
57
- ``Twig_Template`` instance.
58
 
59
  To render the template with some variables, call the ``render()`` method::
60
 
@@ -81,10 +81,10 @@ If a template defines blocks, they can be rendered individually via the
81
  Environment Options
82
  -------------------
83
 
84
- When creating a new ``Twig_Environment`` instance, you can pass an array of
85
  options as the constructor second argument::
86
 
87
- $twig = new Twig_Environment($loader, ['debug' => true]);
88
 
89
  The following options are available:
90
 
@@ -98,7 +98,7 @@ The following options are available:
98
 
99
  The charset used by the templates.
100
 
101
- * ``base_template_class`` *string* (defaults to ``Twig_Template``)
102
 
103
  The base template class to use for generated
104
  templates.
@@ -158,7 +158,7 @@ Compilation Cache
158
  All template loaders can cache the compiled templates on the filesystem for
159
  future reuse. It speeds up Twig a lot as templates are only compiled once; and
160
  the performance boost is even larger if you use a PHP accelerator such as APC.
161
- See the ``cache`` and ``auto_reload`` options of ``Twig_Environment`` above
162
  for more information.
163
 
164
  Built-in Loaders
@@ -166,7 +166,7 @@ Built-in Loaders
166
 
167
  Here is a list of the built-in loaders Twig provides:
168
 
169
- ``Twig_Loader_Filesystem``
170
  ..........................
171
 
172
  .. versionadded:: 1.10
@@ -175,15 +175,15 @@ Here is a list of the built-in loaders Twig provides:
175
  .. versionadded:: 1.27
176
  Relative paths support was added in Twig 1.27.
177
 
178
- ``Twig_Loader_Filesystem`` loads templates from the file system. This loader
179
  can find templates in folders on the file system and is the preferred way to
180
  load them::
181
 
182
- $loader = new Twig_Loader_Filesystem($templateDir);
183
 
184
  It can also look for templates in an array of directories::
185
 
186
- $loader = new Twig_Loader_Filesystem([$templateDir1, $templateDir2]);
187
 
188
  With such a configuration, Twig will first look for templates in
189
  ``$templateDir1`` and if they do not exist, it will fallback to look for them
@@ -209,28 +209,28 @@ Namespaced templates can be accessed via the special
209
 
210
  $twig->render('@admin/index.html', []);
211
 
212
- ``Twig_Loader_Filesystem`` support absolute and relative paths. Using relative
213
  paths is preferred as it makes the cache keys independent of the project root
214
  directory (for instance, it allows warming the cache from a build server where
215
  the directory might be different from the one used on production servers)::
216
 
217
- $loader = new Twig_Loader_Filesystem('templates', getcwd().'/..');
218
 
219
  .. note::
220
 
221
  When not passing the root path as a second argument, Twig uses ``getcwd()``
222
  for relative paths.
223
 
224
- ``Twig_Loader_Array``
225
  .....................
226
 
227
- ``Twig_Loader_Array`` loads a template from a PHP array. It's passed an array
228
  of strings bound to template names::
229
 
230
- $loader = new Twig_Loader_Array([
231
  'index.html' => 'Hello {{ name }}!',
232
  ]);
233
- $twig = new Twig_Environment($loader);
234
 
235
  echo $twig->render('index.html', ['name' => 'Fabien']);
236
 
@@ -245,30 +245,30 @@ projects where storing all templates in a single PHP file might make sense.
245
  don't want to see your cache grows out of control, you need to take care
246
  of clearing the old cache file by yourself.
247
 
248
- ``Twig_Loader_Chain``
249
  .....................
250
 
251
- ``Twig_Loader_Chain`` delegates the loading of templates to other loaders::
252
 
253
- $loader1 = new Twig_Loader_Array([
254
  'base.html' => '{% block content %}{% endblock %}',
255
  ]);
256
- $loader2 = new Twig_Loader_Array([
257
  'index.html' => '{% extends "base.html" %}{% block content %}Hello {{ name }}{% endblock %}',
258
  'base.html' => 'Will never be loaded',
259
  ]);
260
 
261
- $loader = new Twig_Loader_Chain([$loader1, $loader2]);
262
 
263
- $twig = new Twig_Environment($loader);
264
 
265
  When looking for a template, Twig will try each loader in turn and it will
266
  return as soon as the template is found. When rendering the ``index.html``
267
  template from the above example, Twig will load it with ``$loader2`` but the
268
  ``base.html`` template will be loaded from ``$loader1``.
269
 
270
- ``Twig_Loader_Chain`` accepts any loader that implements
271
- ``Twig_LoaderInterface``.
272
 
273
  .. note::
274
 
@@ -277,7 +277,7 @@ template from the above example, Twig will load it with ``$loader2`` but the
277
  Create your own Loader
278
  ~~~~~~~~~~~~~~~~~~~~~~
279
 
280
- All loaders implement the ``Twig_LoaderInterface``::
281
 
282
  interface Twig_LoaderInterface
283
  {
@@ -288,7 +288,7 @@ All loaders implement the ``Twig_LoaderInterface``::
288
  *
289
  * @return string The template source code
290
  *
291
- * @deprecated since 1.27 (to be removed in 2.0), implement Twig_SourceContextLoaderInterface
292
  */
293
  function getSource($name);
294
 
@@ -316,11 +316,11 @@ is still fresh, given the last modification time, or ``false`` otherwise.
316
  .. note::
317
 
318
  As of Twig 1.27, you should also implement
319
- ``Twig_SourceContextLoaderInterface`` to avoid deprecation notices.
320
 
321
  .. tip::
322
 
323
- As of Twig 1.11.0, you can also implement ``Twig_ExistsLoaderInterface``
324
  to make your loader faster when used with the chain loader.
325
 
326
  Using Extensions
@@ -329,7 +329,7 @@ Using Extensions
329
  Twig extensions are packages that add new features to Twig. Using an
330
  extension is as simple as using the ``addExtension()`` method::
331
 
332
- $twig->addExtension(new Twig_Extension_Sandbox());
333
 
334
  Twig comes bundled with the following extensions:
335
 
@@ -378,7 +378,7 @@ tag, ``autoescape``, and a filter, ``raw``.
378
  When creating the escaper extension, you can switch on or off the global
379
  output escaping strategy::
380
 
381
- $escaper = new Twig_Extension_Escaper('html');
382
  $twig->addExtension($escaper);
383
 
384
  If set to ``html``, all variables in templates are escaped (using the ``html``
@@ -473,7 +473,7 @@ Sandbox Extension
473
  The ``sandbox`` extension can be used to evaluate untrusted code. Access to
474
  unsafe attributes and methods is prohibited. The sandbox security is managed
475
  by a policy instance. By default, Twig comes with one policy class:
476
- ``Twig_Sandbox_SecurityPolicy``. This class allows you to white-list some
477
  tags, filters, properties, and methods::
478
 
479
  $tags = ['if'];
@@ -485,17 +485,17 @@ tags, filters, properties, and methods::
485
  'Article' => ['title', 'body'],
486
  ];
487
  $functions = ['range'];
488
- $policy = new Twig_Sandbox_SecurityPolicy($tags, $filters, $methods, $properties, $functions);
489
 
490
  With the previous configuration, the security policy will only allow usage of
491
  the ``if`` tag, and the ``upper`` filter. Moreover, the templates will only be
492
  able to call the ``getTitle()`` and ``getBody()`` methods on ``Article``
493
  objects, and the ``title`` and ``body`` public properties. Everything else
494
- won't be allowed and will generate a ``Twig_Sandbox_SecurityError`` exception.
495
 
496
  The policy object is the first argument of the sandbox constructor::
497
 
498
- $sandbox = new Twig_Extension_Sandbox($policy);
499
  $twig->addExtension($sandbox);
500
 
501
  By default, the sandbox mode is disabled and should be enabled when including
@@ -510,7 +510,7 @@ untrusted template code by using the ``sandbox`` tag:
510
  You can sandbox all templates by passing ``true`` as the second argument of
511
  the extension constructor::
512
 
513
- $sandbox = new Twig_Extension_Sandbox($policy, true);
514
 
515
  Profiler Extension
516
  ~~~~~~~~~~~~~~~~~~
@@ -521,10 +521,10 @@ Profiler Extension
521
  The ``profiler`` extension enables a profiler for Twig templates; it should
522
  only be used on your development machines as it adds some overhead::
523
 
524
- $profile = new Twig_Profiler_Profile();
525
- $twig->addExtension(new Twig_Extension_Profiler($profile));
526
 
527
- $dumper = new Twig_Profiler_Dumper_Text();
528
  echo $dumper->dump($profile);
529
 
530
  A profile contains information about time and memory consumption for template,
@@ -533,7 +533,7 @@ block, and macro executions.
533
  You can also dump the data in a `Blackfire.io <https://blackfire.io/>`_
534
  compatible format::
535
 
536
- $dumper = new Twig_Profiler_Dumper_Blackfire();
537
  file_put_contents('/path/to/profile.prof', $dumper->dump($profile));
538
 
539
  Upload the profile to visualize it (create a `free account
@@ -548,27 +548,27 @@ Optimizer Extension
548
 
549
  The ``optimizer`` extension optimizes the node tree before compilation::
550
 
551
- $twig->addExtension(new Twig_Extension_Optimizer());
552
 
553
  By default, all optimizations are turned on. You can select the ones you want
554
  to enable by passing them to the constructor::
555
 
556
- $optimizer = new Twig_Extension_Optimizer(Twig_NodeVisitor_Optimizer::OPTIMIZE_FOR);
557
 
558
  $twig->addExtension($optimizer);
559
 
560
  Twig supports the following optimizations:
561
 
562
- * ``Twig_NodeVisitor_Optimizer::OPTIMIZE_ALL``, enables all optimizations
563
  (this is the default value).
564
- * ``Twig_NodeVisitor_Optimizer::OPTIMIZE_NONE``, disables all optimizations.
565
  This reduces the compilation time, but it can increase the execution time
566
  and the consumed memory.
567
- * ``Twig_NodeVisitor_Optimizer::OPTIMIZE_FOR``, optimizes the ``for`` tag by
568
  removing the ``loop`` variable creation whenever possible.
569
- * ``Twig_NodeVisitor_Optimizer::OPTIMIZE_RAW_FILTER``, removes the ``raw``
570
  filter whenever possible.
571
- * ``Twig_NodeVisitor_Optimizer::OPTIMIZE_VAR_ACCESS``, simplifies the creation
572
  and access of variables in the compiled templates whenever possible.
573
 
574
  Exceptions
@@ -576,15 +576,15 @@ Exceptions
576
 
577
  Twig can throw exceptions:
578
 
579
- * ``Twig_Error``: The base exception for all errors.
580
 
581
- * ``Twig_Error_Syntax``: Thrown to tell the user that there is a problem with
582
  the template syntax.
583
 
584
- * ``Twig_Error_Runtime``: Thrown when an error occurs at runtime (when a filter
585
  does not exist for instance).
586
 
587
- * ``Twig_Error_Loader``: Thrown when an error occurs during template loading.
588
 
589
- * ``Twig_Sandbox_SecurityError``: Thrown when an unallowed tag, filter, or
590
  method is called in a sandboxed template.
9
  ------
10
 
11
  Twig uses a central object called the **environment** (of class
12
+ ``\Twig\Environment``). Instances of this class are used to store the
13
  configuration and extensions, and are used to load templates from the file
14
  system or other locations.
15
 
16
+ Most applications will create one ``\Twig\Environment`` object on application
17
  initialization and use that to load templates. In some cases it's however
18
  useful to have multiple environments side by side, if different configurations
19
  are in use.
24
  require_once '/path/to/lib/Twig/Autoloader.php';
25
  Twig_Autoloader::register();
26
 
27
+ $loader = new \Twig\Loader\FilesystemLoader('/path/to/templates');
28
+ $twig = new \Twig\Environment($loader, [
29
  'cache' => '/path/to/compilation_cache',
30
  ]);
31
 
47
  -------------------
48
 
49
  To load a template from a Twig environment, call the ``load()`` method which
50
+ returns a ``\Twig\TemplateWrapper`` instance::
51
 
52
  $template = $twig->load('index.html');
53
 
54
  .. note::
55
 
56
  Before Twig 1.28, you should use ``loadTemplate()`` instead which returns a
57
+ ``\Twig\Template`` instance.
58
 
59
  To render the template with some variables, call the ``render()`` method::
60
 
81
  Environment Options
82
  -------------------
83
 
84
+ When creating a new ``\Twig\Environment`` instance, you can pass an array of
85
  options as the constructor second argument::
86
 
87
+ $twig = new \Twig\Environment($loader, ['debug' => true]);
88
 
89
  The following options are available:
90
 
98
 
99
  The charset used by the templates.
100
 
101
+ * ``base_template_class`` *string* (defaults to ``\Twig\Template``)
102
 
103
  The base template class to use for generated
104
  templates.
158
  All template loaders can cache the compiled templates on the filesystem for
159
  future reuse. It speeds up Twig a lot as templates are only compiled once; and
160
  the performance boost is even larger if you use a PHP accelerator such as APC.
161
+ See the ``cache`` and ``auto_reload`` options of ``\Twig\Environment`` above
162
  for more information.
163
 
164
  Built-in Loaders
166
 
167
  Here is a list of the built-in loaders Twig provides:
168
 
169
+ ``\Twig\Loader\FilesystemLoader``
170
  ..........................
171
 
172
  .. versionadded:: 1.10
175
  .. versionadded:: 1.27
176
  Relative paths support was added in Twig 1.27.
177
 
178
+ ``\Twig\Loader\FilesystemLoader`` loads templates from the file system. This loader
179
  can find templates in folders on the file system and is the preferred way to
180
  load them::
181
 
182
+ $loader = new \Twig\Loader\FilesystemLoader($templateDir);
183
 
184
  It can also look for templates in an array of directories::
185
 
186
+ $loader = new \Twig\Loader\FilesystemLoader([$templateDir1, $templateDir2]);
187
 
188
  With such a configuration, Twig will first look for templates in
189
  ``$templateDir1`` and if they do not exist, it will fallback to look for them
209
 
210
  $twig->render('@admin/index.html', []);
211
 
212
+ ``\Twig\Loader\FilesystemLoader`` support absolute and relative paths. Using relative
213
  paths is preferred as it makes the cache keys independent of the project root
214
  directory (for instance, it allows warming the cache from a build server where
215
  the directory might be different from the one used on production servers)::
216
 
217
+ $loader = new \Twig\Loader\FilesystemLoader('templates', getcwd().'/..');
218
 
219
  .. note::
220
 
221
  When not passing the root path as a second argument, Twig uses ``getcwd()``
222
  for relative paths.
223
 
224
+ ``\Twig\Loader\ArrayLoader``
225
  .....................
226
 
227
+ ``\Twig\Loader\ArrayLoader`` loads a template from a PHP array. It's passed an array
228
  of strings bound to template names::
229
 
230
+ $loader = new \Twig\Loader\ArrayLoader([
231
  'index.html' => 'Hello {{ name }}!',
232
  ]);
233
+ $twig = new \Twig\Environment($loader);
234
 
235
  echo $twig->render('index.html', ['name' => 'Fabien']);
236
 
245
  don't want to see your cache grows out of control, you need to take care
246
  of clearing the old cache file by yourself.
247
 
248
+ ``\Twig\Loader\ChainLoader``
249
  .....................
250
 
251
+ ``\Twig\Loader\ChainLoader`` delegates the loading of templates to other loaders::
252
 
253
+ $loader1 = new \Twig\Loader\ArrayLoader([
254
  'base.html' => '{% block content %}{% endblock %}',
255
  ]);
256
+ $loader2 = new \Twig\Loader\ArrayLoader([
257
  'index.html' => '{% extends "base.html" %}{% block content %}Hello {{ name }}{% endblock %}',
258
  'base.html' => 'Will never be loaded',
259
  ]);
260
 
261
+ $loader = new \Twig\Loader\ChainLoader([$loader1, $loader2]);
262
 
263
+ $twig = new \Twig\Environment($loader);
264
 
265
  When looking for a template, Twig will try each loader in turn and it will
266
  return as soon as the template is found. When rendering the ``index.html``
267
  template from the above example, Twig will load it with ``$loader2`` but the
268
  ``base.html`` template will be loaded from ``$loader1``.
269
 
270
+ ``\Twig\Loader\ChainLoader`` accepts any loader that implements
271
+ ``\Twig\Loader\LoaderInterface``.
272
 
273
  .. note::
274
 
277
  Create your own Loader
278
  ~~~~~~~~~~~~~~~~~~~~~~
279
 
280
+ All loaders implement the ``\Twig\Loader\LoaderInterface``::
281
 
282
  interface Twig_LoaderInterface
283
  {
288
  *
289
  * @return string The template source code
290
  *
291
+ * @deprecated since 1.27 (to be removed in 2.0), implement \Twig\Loader\SourceContextLoaderInterface
292
  */
293
  function getSource($name);
294
 
316
  .. note::
317
 
318
  As of Twig 1.27, you should also implement
319
+ ``\Twig\Loader\SourceContextLoaderInterface`` to avoid deprecation notices.
320
 
321
  .. tip::
322
 
323
+ As of Twig 1.11.0, you can also implement ``\Twig\Loader\ExistsLoaderInterface``
324
  to make your loader faster when used with the chain loader.
325
 
326
  Using Extensions
329
  Twig extensions are packages that add new features to Twig. Using an
330
  extension is as simple as using the ``addExtension()`` method::
331
 
332
+ $twig->addExtension(new \Twig\Extension\SandboxExtension());
333
 
334
  Twig comes bundled with the following extensions:
335
 
378
  When creating the escaper extension, you can switch on or off the global
379
  output escaping strategy::
380
 
381
+ $escaper = new \Twig\Extension\EscaperExtension('html');
382
  $twig->addExtension($escaper);
383
 
384
  If set to ``html``, all variables in templates are escaped (using the ``html``
473
  The ``sandbox`` extension can be used to evaluate untrusted code. Access to
474
  unsafe attributes and methods is prohibited. The sandbox security is managed
475
  by a policy instance. By default, Twig comes with one policy class:
476
+ ``\Twig\Sandbox\SecurityPolicy``. This class allows you to white-list some
477
  tags, filters, properties, and methods::
478
 
479
  $tags = ['if'];
485
  'Article' => ['title', 'body'],
486
  ];
487
  $functions = ['range'];
488
+ $policy = new \Twig\Sandbox\SecurityPolicy($tags, $filters, $methods, $properties, $functions);
489
 
490
  With the previous configuration, the security policy will only allow usage of
491
  the ``if`` tag, and the ``upper`` filter. Moreover, the templates will only be
492
  able to call the ``getTitle()`` and ``getBody()`` methods on ``Article``
493
  objects, and the ``title`` and ``body`` public properties. Everything else
494
+ won't be allowed and will generate a ``\Twig\Sandbox\SecurityError`` exception.
495
 
496
  The policy object is the first argument of the sandbox constructor::
497
 
498
+ $sandbox = new \Twig\Extension\SandboxExtension($policy);
499
  $twig->addExtension($sandbox);
500
 
501
  By default, the sandbox mode is disabled and should be enabled when including
510
  You can sandbox all templates by passing ``true`` as the second argument of
511
  the extension constructor::
512
 
513
+ $sandbox = new \Twig\Extension\SandboxExtension($policy, true);
514
 
515
  Profiler Extension
516
  ~~~~~~~~~~~~~~~~~~
521
  The ``profiler`` extension enables a profiler for Twig templates; it should
522
  only be used on your development machines as it adds some overhead::
523
 
524
+ $profile = new \Twig\Profiler\Profile();
525
+ $twig->addExtension(new \Twig\Extension\ProfilerExtension($profile));
526
 
527
+ $dumper = new \Twig\Profiler\Dumper\TextDumper();
528
  echo $dumper->dump($profile);
529
 
530
  A profile contains information about time and memory consumption for template,
533
  You can also dump the data in a `Blackfire.io <https://blackfire.io/>`_
534
  compatible format::
535
 
536
+ $dumper = new \Twig\Profiler\Dumper\BlackfireDumper();
537
  file_put_contents('/path/to/profile.prof', $dumper->dump($profile));
538
 
539
  Upload the profile to visualize it (create a `free account
548
 
549
  The ``optimizer`` extension optimizes the node tree before compilation::
550
 
551
+ $twig->addExtension(new \Twig\Extension\OptimizerExtension());
552
 
553
  By default, all optimizations are turned on. You can select the ones you want
554
  to enable by passing them to the constructor::
555
 
556
+ $optimizer = new \Twig\Extension\OptimizerExtension(\Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_FOR);
557
 
558
  $twig->addExtension($optimizer);
559
 
560
  Twig supports the following optimizations:
561
 
562
+ * ``\Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_ALL``, enables all optimizations
563
  (this is the default value).
564
+ * ``\Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_NONE``, disables all optimizations.
565
  This reduces the compilation time, but it can increase the execution time
566
  and the consumed memory.
567
+ * ``\Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_FOR``, optimizes the ``for`` tag by
568
  removing the ``loop`` variable creation whenever possible.
569
+ * ``\Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_RAW_FILTER``, removes the ``raw``
570
  filter whenever possible.
571
+ * ``\Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_VAR_ACCESS``, simplifies the creation
572
  and access of variables in the compiled templates whenever possible.
573
 
574
  Exceptions
576
 
577
  Twig can throw exceptions:
578
 
579
+ * ``\Twig\Error\Error``: The base exception for all errors.
580
 
581
+ * ``\Twig\Error\SyntaxError``: Thrown to tell the user that there is a problem with
582
  the template syntax.
583
 
584
+ * ``\Twig\Error\RuntimeError``: Thrown when an error occurs at runtime (when a filter
585
  does not exist for instance).
586
 
587
+ * ``\Twig\Error\LoaderError``: Thrown when an error occurs during template loading.
588
 
589
+ * ``\Twig\Sandbox\SecurityError``: Thrown when an unallowed tag, filter, or
590
  method is called in a sandboxed template.
vendor/twig/twig/doc/deprecated.rst CHANGED
@@ -27,29 +27,29 @@ Token Parsers
27
  * ``Twig_TokenParserBrokerInterface``
28
  * ``Twig_TokenParserBroker``
29
 
30
- * As of Twig 1.27, ``Twig_Parser::getFilename()`` is deprecated. From a token
31
  parser, use ``$this->parser->getStream()->getSourceContext()->getPath()`` instead.
32
 
33
- * As of Twig 1.27, ``Twig_Parser::getEnvironment()`` is deprecated.
34
 
35
  Extensions
36
  ----------
37
 
38
  * As of Twig 1.x, the ability to remove an extension is deprecated and the
39
- ``Twig_Environment::removeExtension()`` method will be removed in 2.0.
40
 
41
- * As of Twig 1.23, the ``Twig_ExtensionInterface::initRuntime()`` method is
42
  deprecated. You have two options to avoid the deprecation notice: if you
43
  implement this method to store the environment for your custom filters,
44
  functions, or tests, use the ``needs_environment`` option instead; if you
45
  have more complex needs, explicitly implement
46
- ``Twig_Extension_InitRuntimeInterface`` (not recommended).
47
 
48
- * As of Twig 1.23, the ``Twig_ExtensionInterface::getGlobals()`` method is
49
- deprecated. Implement ``Twig_Extension_GlobalsInterface`` to avoid
50
  deprecation notices.
51
 
52
- * As of Twig 1.26, the ``Twig_ExtensionInterface::getName()`` method is
53
  deprecated and it is not used internally anymore.
54
 
55
  PEAR
@@ -61,7 +61,7 @@ provided anymore. Use Composer instead.
61
  Filters
62
  -------
63
 
64
- * As of Twig 1.x, use ``Twig_SimpleFilter`` to add a filter. The following
65
  classes and interfaces will be removed in 2.0:
66
 
67
  * ``Twig_FilterInterface``
@@ -71,14 +71,14 @@ Filters
71
  * ``Twig_Filter_Method``
72
  * ``Twig_Filter_Node``
73
 
74
- * As of Twig 2.x, the ``Twig_SimpleFilter`` class is deprecated and will be
75
  removed in Twig 3.x (use ``Twig_Filter`` instead). In Twig 2.x,
76
- ``Twig_SimpleFilter`` is just an alias for ``Twig_Filter``.
77
 
78
  Functions
79
  ---------
80
 
81
- * As of Twig 1.x, use ``Twig_SimpleFunction`` to add a function. The following
82
  classes and interfaces will be removed in 2.0:
83
 
84
  * ``Twig_FunctionInterface``
@@ -88,14 +88,14 @@ Functions
88
  * ``Twig_Function_Method``
89
  * ``Twig_Function_Node``
90
 
91
- * As of Twig 2.x, the ``Twig_SimpleFunction`` class is deprecated and will be
92
  removed in Twig 3.x (use ``Twig_Function`` instead). In Twig 2.x,
93
- ``Twig_SimpleFunction`` is just an alias for ``Twig_Function``.
94
 
95
  Tests
96
  -----
97
 
98
- * As of Twig 1.x, use ``Twig_SimpleTest`` to add a test. The following classes
99
  and interfaces will be removed in 2.0:
100
 
101
  * ``Twig_TestInterface``
@@ -105,9 +105,9 @@ Tests
105
  * ``Twig_Test_Method``
106
  * ``Twig_Test_Node``
107
 
108
- * As of Twig 2.x, the ``Twig_SimpleTest`` class is deprecated and will be
109
  removed in Twig 3.x (use ``Twig_Test`` instead). In Twig 2.x,
110
- ``Twig_SimpleTest`` is just an alias for ``Twig_Test``.
111
 
112
  * The ``sameas`` and ``divisibleby`` tests are deprecated in favor of ``same
113
  as`` and ``divisible by`` respectively.
@@ -124,16 +124,16 @@ Nodes
124
  * As of Twig 1.x, ``Node::toXml()`` is deprecated and will be removed in Twig
125
  2.0.
126
 
127
- * As of Twig 1.26, ``Node::$nodes`` should only contains ``Twig_Node``
128
  instances, storing a ``null`` value is deprecated and won't be possible in
129
  Twig 2.x.
130
 
131
- * As of Twig 1.27, the ``filename`` attribute on ``Twig_Node_Module`` is
132
  deprecated. Use ``getName()`` instead.
133
 
134
- * As of Twig 1.27, the ``Twig_Node::getFilename()/Twig_Node::getLine()``
135
  methods are deprecated, use
136
- ``Twig_Node::getTemplateName()/Twig_Node::getTemplateLine()`` instead.
137
 
138
  Interfaces
139
  ----------
@@ -141,40 +141,40 @@ Interfaces
141
  * As of Twig 2.x, the following interfaces are deprecated and empty (they will
142
  be removed in Twig 3.0):
143
 
144
- * ``Twig_CompilerInterface`` (use ``Twig_Compiler`` instead)
145
- * ``Twig_LexerInterface`` (use ``Twig_Lexer`` instead)
146
- * ``Twig_NodeInterface`` (use ``Twig_Node`` instead)
147
- * ``Twig_ParserInterface`` (use ``Twig_Parser`` instead)
148
- * ``Twig_ExistsLoaderInterface`` (merged with ``Twig_LoaderInterface``)
149
- * ``Twig_SourceContextLoaderInterface`` (merged with ``Twig_LoaderInterface``)
150
- * ``Twig_TemplateInterface`` (use ``Twig_Template`` instead, and use
151
- those constants Twig_Template::ANY_CALL, Twig_Template::ARRAY_CALL,
152
- Twig_Template::METHOD_CALL)
153
 
154
  Compiler
155
  --------
156
 
157
- * As of Twig 1.26, the ``Twig_Compiler::getFilename()`` has been deprecated.
158
  You should not use it anyway as its values is not reliable.
159
 
160
- * As of Twig 1.27, the ``Twig_Compiler::addIndentation()`` has been deprecated.
161
- Use ``Twig_Compiler::write('')`` instead.
162
 
163
  Loaders
164
  -------
165
 
166
  * As of Twig 1.x, ``Twig_Loader_String`` is deprecated and will be removed in
167
- 2.0. You can render a string via ``Twig_Environment::createTemplate()``.
168
 
169
- * As of Twig 1.27, ``Twig_LoaderInterface::getSource()`` is deprecated.
170
- Implement ``Twig_SourceContextLoaderInterface`` instead and use
171
  ``getSourceContext()``.
172
 
173
  Node Visitors
174
  -------------
175
 
176
  * Because of the removal of ``Twig_NodeInterface`` in 2.0, you need to extend
177
- ``Twig_BaseNodeVisitor`` instead of implementing ``Twig_NodeVisitorInterface``
178
  directly to make your node visitors compatible with both Twig 1.x and 2.x.
179
 
180
  Globals
@@ -185,40 +185,40 @@ Globals
185
  changing the value of an already registered global is possible).
186
 
187
  * As of Twig 1.x, using the ``_self`` global variable to get access to the
188
- current ``Twig_Template`` instance is deprecated; most usages only need the
189
  current template name, which will continue to work in Twig 2.0. In Twig 2.0,
190
  ``_self`` returns the current template name instead of the current
191
- ``Twig_Template`` instance. If you are using ``{{ _self.templateName }}``,
192
  just replace it with ``{{ _self }}``.
193
 
194
  Miscellaneous
195
  -------------
196
 
197
- * As of Twig 1.x, ``Twig_Environment::clearTemplateCache()``,
198
- ``Twig_Environment::writeCacheFile()``,
199
- ``Twig_Environment::clearCacheFiles()``,
200
- ``Twig_Environment::getCacheFilename()``,
201
- ``Twig_Environment::getTemplateClassPrefix()``,
202
- ``Twig_Environment::getLexer()``, ``Twig_Environment::getParser()``, and
203
- ``Twig_Environment::getCompiler()`` are deprecated and will be removed in 2.0.
204
 
205
- * As of Twig 1.x, ``Twig_Template::getEnvironment()`` and
206
  ``Twig_TemplateInterface::getEnvironment()`` are deprecated and will be
207
  removed in 2.0.
208
 
209
  * As of Twig 1.21, setting the environment option ``autoescape`` to ``true`` is
210
  deprecated and will be removed in 2.0. Use ``"html"`` instead.
211
 
212
- * As of Twig 1.27, ``Twig_Error::getTemplateFile()`` and
213
- ``Twig_Error::setTemplateFile()`` are deprecated. Use
214
- ``Twig_Error::getTemplateName()`` and ``Twig_Error::setTemplateName()``
215
  instead.
216
 
217
- * As of Twig 1.27, ``Twig_Template::getSource()`` is deprecated. Use
218
- ``Twig_Template::getSourceContext()`` instead.
219
 
220
- * As of Twig 1.27, ``Twig_Parser::addHandler()`` and
221
- ``Twig_Parser::addNodeVisitor()`` are deprecated and will be removed in 2.0.
222
 
223
  * As of Twig 1.29, some classes are marked as being final via the `@final`
224
  annotation. Those classes will be marked as final in 2.0.
27
  * ``Twig_TokenParserBrokerInterface``
28
  * ``Twig_TokenParserBroker``
29
 
30
+ * As of Twig 1.27, ``\Twig\Parser::getFilename()`` is deprecated. From a token
31
  parser, use ``$this->parser->getStream()->getSourceContext()->getPath()`` instead.
32
 
33
+ * As of Twig 1.27, ``\Twig\Parser::getEnvironment()`` is deprecated.
34
 
35
  Extensions
36
  ----------
37
 
38
  * As of Twig 1.x, the ability to remove an extension is deprecated and the
39
+ ``\Twig\Environment::removeExtension()`` method will be removed in 2.0.
40
 
41
+ * As of Twig 1.23, the ``\Twig\Extension\ExtensionInterface::initRuntime()`` method is
42
  deprecated. You have two options to avoid the deprecation notice: if you
43
  implement this method to store the environment for your custom filters,
44
  functions, or tests, use the ``needs_environment`` option instead; if you
45
  have more complex needs, explicitly implement
46
+ ``\Twig\Extension\InitRuntimeInterface`` (not recommended).
47
 
48
+ * As of Twig 1.23, the ``\Twig\Extension\ExtensionInterface::getGlobals()`` method is
49
+ deprecated. Implement ``\Twig\Extension\GlobalsInterface`` to avoid
50
  deprecation notices.
51
 
52
+ * As of Twig 1.26, the ``\Twig\Extension\ExtensionInterface::getName()`` method is
53
  deprecated and it is not used internally anymore.
54
 
55
  PEAR
61
  Filters
62
  -------
63
 
64
+ * As of Twig 1.x, use ``\Twig\TwigFilter`` to add a filter. The following
65
  classes and interfaces will be removed in 2.0:
66
 
67
  * ``Twig_FilterInterface``
71
  * ``Twig_Filter_Method``
72
  * ``Twig_Filter_Node``
73
 
74
+ * As of Twig 2.x, the ``\Twig\TwigFilter`` class is deprecated and will be
75
  removed in Twig 3.x (use ``Twig_Filter`` instead). In Twig 2.x,
76
+ ``\Twig\TwigFilter`` is just an alias for ``Twig_Filter``.
77
 
78
  Functions
79
  ---------
80
 
81
+ * As of Twig 1.x, use ``\Twig\TwigFunction`` to add a function. The following
82
  classes and interfaces will be removed in 2.0:
83
 
84
  * ``Twig_FunctionInterface``
88
  * ``Twig_Function_Method``
89
  * ``Twig_Function_Node``
90
 
91
+ * As of Twig 2.x, the ``\Twig\TwigFunction`` class is deprecated and will be
92
  removed in Twig 3.x (use ``Twig_Function`` instead). In Twig 2.x,
93
+ ``\Twig\TwigFunction`` is just an alias for ``Twig_Function``.
94
 
95
  Tests
96
  -----
97
 
98
+ * As of Twig 1.x, use ``\Twig\TwigTest`` to add a test. The following classes
99
  and interfaces will be removed in 2.0:
100
 
101
  * ``Twig_TestInterface``
105
  * ``Twig_Test_Method``
106
  * ``Twig_Test_Node``
107
 
108
+ * As of Twig 2.x, the ``\Twig\TwigTest`` class is deprecated and will be
109
  removed in Twig 3.x (use ``Twig_Test`` instead). In Twig 2.x,
110
+ ``\Twig\TwigTest`` is just an alias for ``Twig_Test``.
111
 
112
  * The ``sameas`` and ``divisibleby`` tests are deprecated in favor of ``same
113
  as`` and ``divisible by`` respectively.
124
  * As of Twig 1.x, ``Node::toXml()`` is deprecated and will be removed in Twig
125
  2.0.
126
 
127
+ * As of Twig 1.26, ``Node::$nodes`` should only contains ``\Twig\Node\Node``
128
  instances, storing a ``null`` value is deprecated and won't be possible in
129
  Twig 2.x.
130
 
131
+ * As of Twig 1.27, the ``filename`` attribute on ``\Twig\Node\ModuleNode`` is
132
  deprecated. Use ``getName()`` instead.
133
 
134
+ * As of Twig 1.27, the ``\Twig\Node\Node::getFilename()/\Twig\Node\Node::getLine()``
135
  methods are deprecated, use
136
+ ``\Twig\Node\Node::getTemplateName()/\Twig\Node\Node::getTemplateLine()`` instead.
137
 
138
  Interfaces
139
  ----------
141
  * As of Twig 2.x, the following interfaces are deprecated and empty (they will
142
  be removed in Twig 3.0):
143
 
144
+ * ``Twig_CompilerInterface`` (use ``\Twig\Compiler`` instead)
145
+ * ``Twig_LexerInterface`` (use ``\Twig\Lexer`` instead)
146
+ * ``Twig_NodeInterface`` (use ``\Twig\Node\Node`` instead)
147
+ * ``Twig_ParserInterface`` (use ``\Twig\Parser`` instead)
148
+ * ``\Twig\Loader\ExistsLoaderInterface`` (merged with ``\Twig\Loader\LoaderInterface``)
149
+ * ``\Twig\Loader\SourceContextLoaderInterface`` (merged with ``\Twig\Loader\LoaderInterface``)
150
+ * ``Twig_TemplateInterface`` (use ``\Twig\Template`` instead, and use
151
+ those constants \Twig\Template::ANY_CALL, \Twig\Template::ARRAY_CALL,
152
+ \Twig\Template::METHOD_CALL)
153
 
154
  Compiler
155
  --------
156
 
157
+ * As of Twig 1.26, the ``\Twig\Compiler::getFilename()`` has been deprecated.
158
  You should not use it anyway as its values is not reliable.
159
 
160
+ * As of Twig 1.27, the ``\Twig\Compiler::addIndentation()`` has been deprecated.
161
+ Use ``\Twig\Compiler::write('')`` instead.
162
 
163
  Loaders
164
  -------
165
 
166
  * As of Twig 1.x, ``Twig_Loader_String`` is deprecated and will be removed in
167
+ 2.0. You can render a string via ``\Twig\Environment::createTemplate()``.
168
 
169
+ * As of Twig 1.27, ``\Twig\Loader\LoaderInterface::getSource()`` is deprecated.
170
+ Implement ``\Twig\Loader\SourceContextLoaderInterface`` instead and use
171
  ``getSourceContext()``.
172
 
173
  Node Visitors
174
  -------------
175
 
176
  * Because of the removal of ``Twig_NodeInterface`` in 2.0, you need to extend
177
+ ``\Twig\NodeVisitor\AbstractNodeVisitor`` instead of implementing ``\Twig\NodeVisitor\NodeVisitorInterface``
178
  directly to make your node visitors compatible with both Twig 1.x and 2.x.
179
 
180
  Globals
185
  changing the value of an already registered global is possible).
186
 
187
  * As of Twig 1.x, using the ``_self`` global variable to get access to the
188
+ current ``\Twig\Template`` instance is deprecated; most usages only need the
189
  current template name, which will continue to work in Twig 2.0. In Twig 2.0,
190
  ``_self`` returns the current template name instead of the current
191
+ ``\Twig\Template`` instance. If you are using ``{{ _self.templateName }}``,
192
  just replace it with ``{{ _self }}``.
193
 
194
  Miscellaneous
195
  -------------
196
 
197
+ * As of Twig 1.x, ``\Twig\Environment::clearTemplateCache()``,
198
+ ``\Twig\Environment::writeCacheFile()``,
199
+ ``\Twig\Environment::clearCacheFiles()``,
200
+ ``\Twig\Environment::getCacheFilename()``,
201
+ ``\Twig\Environment::getTemplateClassPrefix()``,
202
+ ``\Twig\Environment::getLexer()``, ``\Twig\Environment::getParser()``, and
203
+ ``\Twig\Environment::getCompiler()`` are deprecated and will be removed in 2.0.
204
 
205
+ * As of Twig 1.x, ``\Twig\Template::getEnvironment()`` and
206
  ``Twig_TemplateInterface::getEnvironment()`` are deprecated and will be
207
  removed in 2.0.
208
 
209
  * As of Twig 1.21, setting the environment option ``autoescape`` to ``true`` is
210
  deprecated and will be removed in 2.0. Use ``"html"`` instead.
211
 
212
+ * As of Twig 1.27, ``\Twig\Error\Error::getTemplateFile()`` and
213
+ ``\Twig\Error\Error::setTemplateFile()`` are deprecated. Use
214
+ ``\Twig\Error\Error::getTemplateName()`` and ``\Twig\Error\Error::setTemplateName()``
215
  instead.
216
 
217
+ * As of Twig 1.27, ``\Twig\Template::getSource()`` is deprecated. Use
218
+ ``\Twig\Template::getSourceContext()`` instead.
219
 
220
+ * As of Twig 1.27, ``\Twig\Parser::addHandler()`` and
221
+ ``\Twig\Parser::addNodeVisitor()`` are deprecated and will be removed in 2.0.
222
 
223
  * As of Twig 1.29, some classes are marked as being final via the `@final`
224
  annotation. Those classes will be marked as final in 2.0.
vendor/twig/twig/doc/filters/date.rst CHANGED
@@ -53,8 +53,8 @@ dates and the second one is the default format for date intervals:
53
 
54
  .. code-block:: php
55
 
56
- $twig = new Twig_Environment($loader);
57
- $twig->getExtension('Twig_Extension_Core')->setDateFormat('d/m/Y', '%d days');
58
 
59
  // before Twig 1.26
60
  $twig->getExtension('core')->setDateFormat('d/m/Y', '%d days');
@@ -81,8 +81,8 @@ The default timezone can also be set globally by calling ``setTimezone()``:
81
 
82
  .. code-block:: php
83
 
84
- $twig = new Twig_Environment($loader);
85
- $twig->getExtension('Twig_Extension_Core')->setTimezone('Europe/Paris');
86
 
87
  // before Twig 1.26
88
  $twig->getExtension('core')->setTimezone('Europe/Paris');
53
 
54
  .. code-block:: php
55
 
56
+ $twig = new \Twig\Environment($loader);
57
+ $twig->getExtension('\Twig\Extension\CoreExtension')->setDateFormat('d/m/Y', '%d days');
58
 
59
  // before Twig 1.26
60
  $twig->getExtension('core')->setDateFormat('d/m/Y', '%d days');
81
 
82
  .. code-block:: php
83
 
84
+ $twig = new \Twig\Environment($loader);
85
+ $twig->getExtension('\Twig\Extension\CoreExtension')->setTimezone('Europe/Paris');
86
 
87
  // before Twig 1.26
88
  $twig->getExtension('core')->setTimezone('Europe/Paris');
vendor/twig/twig/doc/filters/escape.rst CHANGED
@@ -96,8 +96,8 @@ used in the ``escape`` call) and the second one must be a valid PHP callable:
96
 
97
  .. code-block:: php
98
 
99
- $twig = new Twig_Environment($loader);
100
- $twig->getExtension('Twig_Extension_Core')->setEscaper('csv', 'csv_escaper');
101
 
102
  // before Twig 1.26
103
  $twig->getExtension('core')->setEscaper('csv', 'csv_escaper');
96
 
97
  .. code-block:: php
98
 
99
+ $twig = new \Twig\Environment($loader);
100
+ $twig->getExtension('\Twig\Extension\CoreExtension')->setEscaper('csv', 'csv_escaper');
101
 
102
  // before Twig 1.26
103
  $twig->getExtension('core')->setEscaper('csv', 'csv_escaper');
vendor/twig/twig/doc/filters/join.rst CHANGED
@@ -1,8 +1,8 @@
1
  ``join``
2
  ========
3
 
4
- .. versionadded:: 1.36.1
5
- The ``and`` argument was added in Twig 1.36.1.
6
 
7
  The ``join`` filter returns a string which is the concatenation of the items
8
  of a sequence:
1
  ``join``
2
  ========
3
 
4
+ .. versionadded:: 1.37 and 2.6.1
5
+ The ``and`` argument was added in Twig 1.37 and 2.6.1.
6
 
7
  The ``join`` filter returns a string which is the concatenation of the items
8
  of a sequence:
vendor/twig/twig/doc/filters/number_format.rst CHANGED
@@ -37,8 +37,8 @@ These defaults can be easily changed through the core extension:
37
 
38
  .. code-block:: php
39
 
40
- $twig = new Twig_Environment($loader);
41
- $twig->getExtension('Twig_Extension_Core')->setNumberFormat(3, '.', ',');
42
 
43
  // before Twig 1.26
44
  $twig->getExtension('core')->setNumberFormat(3, '.', ',');
37
 
38
  .. code-block:: php
39
 
40
+ $twig = new \Twig\Environment($loader);
41
+ $twig->getExtension('\Twig\Extension\CoreExtension')->setNumberFormat(3, '.', ',');
42
 
43
  // before Twig 1.26
44
  $twig->getExtension('core')->setNumberFormat(3, '.', ',');
vendor/twig/twig/doc/functions/date.rst CHANGED
@@ -40,8 +40,8 @@ If no argument is passed, the function returns the current date:
40
 
41
  .. code-block:: php
42
 
43
- $twig = new Twig_Environment($loader);
44
- $twig->getExtension('Twig_Extension_Core')->setTimezone('Europe/Paris');
45
 
46
  // before Twig 1.26
47
  $twig->getExtension('core')->setTimezone('Europe/Paris');
40
 
41
  .. code-block:: php
42
 
43
+ $twig = new \Twig\Environment($loader);
44
+ $twig->getExtension('\Twig\Extension\CoreExtension')->setTimezone('Europe/Paris');
45
 
46
  // before Twig 1.26
47
  $twig->getExtension('core')->setTimezone('Europe/Paris');
vendor/twig/twig/doc/functions/dump.rst CHANGED
@@ -15,14 +15,14 @@ introspecting its variables:
15
  .. note::
16
 
17
  The ``dump`` function is not available by default. You must add the
18
- ``Twig_Extension_Debug`` extension explicitly when creating your Twig
19
  environment::
20
 
21
- $twig = new Twig_Environment($loader, [
22
  'debug' => true,
23
  // ...
24
  ]);
25
- $twig->addExtension(new Twig_Extension_Debug());
26
 
27
  Even when enabled, the ``dump`` function won't display anything if the
28
  ``debug`` option on the environment is not enabled (to avoid leaking debug
15
  .. note::
16
 
17
  The ``dump`` function is not available by default. You must add the
18
+ ``\Twig\Extension\DebugExtension`` extension explicitly when creating your Twig
19
  environment::
20
 
21
+ $twig = new \Twig\Environment($loader, [
22
  'debug' => true,
23
  // ...
24
  ]);
25
+ $twig->addExtension(new \Twig\Extension\DebugExtension());
26
 
27
  Even when enabled, the ``dump`` function won't display anything if the
28
  ``debug`` option on the environment is not enabled (to avoid leaking debug
vendor/twig/twig/doc/functions/include.rst CHANGED
@@ -37,8 +37,8 @@ You can disable access to the context by setting ``with_context`` to
37
  {# no variables will be accessible #}
38
  {{ include('template.html', with_context = false) }}
39
 
40
- And if the expression evaluates to a ``Twig_Template`` or a
41
- ``Twig_TemplateWrapper`` instance, Twig will use it directly::
42
 
43
  // {{ include(template) }}
44
 
37
  {# no variables will be accessible #}
38
  {{ include('template.html', with_context = false) }}
39
 
40
+ And if the expression evaluates to a ``\Twig\Template`` or a
41
+ ``\Twig\TemplateWrapper`` instance, Twig will use it directly::
42
 
43
  // {{ include(template) }}
44
 
vendor/twig/twig/doc/functions/template_from_string.rst CHANGED
@@ -14,11 +14,11 @@ The ``template_from_string`` function loads a template from a string:
14
  .. note::
15
 
16
  The ``template_from_string`` function is not available by default. You
17
- must add the ``Twig_Extension_StringLoader`` extension explicitly when
18
  creating your Twig environment::
19
 
20
- $twig = new Twig_Environment(...);
21
- $twig->addExtension(new Twig_Extension_StringLoader());
22
 
23
  .. note::
24
 
14
  .. note::
15
 
16
  The ``template_from_string`` function is not available by default. You
17
+ must add the ``\Twig\Extension\StringLoaderExtension`` extension explicitly when
18
  creating your Twig environment::
19
 
20
+ $twig = new \Twig\Environment(...);
21
+ $twig->addExtension(new \Twig\Extension\StringLoaderExtension());
22
 
23
  .. note::
24
 
vendor/twig/twig/doc/installation.rst CHANGED
@@ -109,7 +109,7 @@ Finally, enable the extension in your ``php.ini`` configuration file:
109
  And from now on, Twig will automatically compile your templates to take
110
  advantage of the C extension. Note that this extension does not replace the
111
  PHP code but only provides an optimized version of the
112
- ``Twig_Template::getAttribute()`` method.
113
 
114
  .. _`download page`: https://github.com/twigphp/Twig/tags
115
  .. _`Composer`: https://getcomposer.org/download/
109
  And from now on, Twig will automatically compile your templates to take
110
  advantage of the C extension. Note that this extension does not replace the
111
  PHP code but only provides an optimized version of the
112
+ ``\Twig\Template::getAttribute()`` method.
113
 
114
  .. _`download page`: https://github.com/twigphp/Twig/tags
115
  .. _`Composer`: https://getcomposer.org/download/
vendor/twig/twig/doc/internals.rst CHANGED
@@ -27,27 +27,27 @@ The Lexer
27
  ---------
28
 
29
  The lexer tokenizes a template source code into a token stream (each token is
30
- an instance of ``Twig_Token``, and the stream is an instance of
31
- ``Twig_TokenStream``). The default lexer recognizes 13 different token types:
32
-
33
- * ``Twig_Token::BLOCK_START_TYPE``, ``Twig_Token::BLOCK_END_TYPE``: Delimiters for blocks (``{% %}``)
34
- * ``Twig_Token::VAR_START_TYPE``, ``Twig_Token::VAR_END_TYPE``: Delimiters for variables (``{{ }}``)
35
- * ``Twig_Token::TEXT_TYPE``: A text outside an expression;
36
- * ``Twig_Token::NAME_TYPE``: A name in an expression;
37
- * ``Twig_Token::NUMBER_TYPE``: A number in an expression;
38
- * ``Twig_Token::STRING_TYPE``: A string in an expression;
39
- * ``Twig_Token::OPERATOR_TYPE``: An operator;
40
- * ``Twig_Token::PUNCTUATION_TYPE``: A punctuation sign;
41
- * ``Twig_Token::INTERPOLATION_START_TYPE``, ``Twig_Token::INTERPOLATION_END_TYPE`` (as of Twig 1.5): Delimiters for string interpolation;
42
- * ``Twig_Token::EOF_TYPE``: Ends of template.
43
 
44
  You can manually convert a source code into a token stream by calling the
45
  ``tokenize()`` method of an environment::
46
 
47
- $stream = $twig->tokenize(new Twig_Source($source, $identifier));
48
 
49
  .. versionadded:: 1.27
50
- ``Twig_Source`` was introduced in version 1.27, pass the source and the
51
  identifier directly on previous versions.
52
 
53
  As the stream has a ``__toString()`` method, you can have a textual
@@ -67,7 +67,7 @@ Here is the output for the ``Hello {{ name }}`` template:
67
 
68
  .. note::
69
 
70
- The default lexer (``Twig_Lexer``) can be changed by calling
71
  the ``setLexer()`` method::
72
 
73
  $twig->setLexer($lexer);
@@ -76,7 +76,7 @@ The Parser
76
  ----------
77
 
78
  The parser converts the token stream into an AST (Abstract Syntax Tree), or a
79
- node tree (an instance of ``Twig_Node_Module``). The core extension defines
80
  the basic nodes like: ``for``, ``if``, ... and the expression nodes.
81
 
82
  You can manually convert a token stream into a node tree by calling the
@@ -92,16 +92,16 @@ Here is the output for the ``Hello {{ name }}`` template:
92
 
93
  .. code-block:: text
94
 
95
- Twig_Node_Module(
96
- Twig_Node_Text(Hello )
97
- Twig_Node_Print(
98
- Twig_Node_Expression_Name(name)
99
  )
100
  )
101
 
102
  .. note::
103
 
104
- The default parser (``Twig_TokenParser``) can be changed by calling the
105
  ``setParser()`` method::
106
 
107
  $twig->setParser($parser);
@@ -122,7 +122,7 @@ The generated template for a ``Hello {{ name }}`` template reads as follows
122
  using)::
123
 
124
  /* Hello {{ name }} */
125
- class __TwigTemplate_1121b6f109fe93ebe8c6e22e3712bceb extends Twig_Template
126
  {
127
  protected function doDisplay(array $context, array $blocks = [])
128
  {
@@ -136,7 +136,7 @@ using)::
136
 
137
  .. note::
138
 
139
- The default compiler (``Twig_Compiler``) can be changed by calling the
140
  ``setCompiler()`` method::
141
 
142
  $twig->setCompiler($compiler);
27
  ---------
28
 
29
  The lexer tokenizes a template source code into a token stream (each token is
30
+ an instance of ``\Twig\Token``, and the stream is an instance of
31
+ ``\Twig\TokenStream``). The default lexer recognizes 13 different token types:
32
+
33
+ * ``\Twig\Token::BLOCK_START_TYPE``, ``\Twig\Token::BLOCK_END_TYPE``: Delimiters for blocks (``{% %}``)
34
+ * ``\Twig\Token::VAR_START_TYPE``, ``\Twig\Token::VAR_END_TYPE``: Delimiters for variables (``{{ }}``)
35
+ * ``\Twig\Token::TEXT_TYPE``: A text outside an expression;
36
+ * ``\Twig\Token::NAME_TYPE``: A name in an expression;
37
+ * ``\Twig\Token::NUMBER_TYPE``: A number in an expression;
38
+ * ``\Twig\Token::STRING_TYPE``: A string in an expression;
39
+ * ``\Twig\Token::OPERATOR_TYPE``: An operator;
40
+ * ``\Twig\Token::PUNCTUATION_TYPE``: A punctuation sign;
41
+ * ``\Twig\Token::INTERPOLATION_START_TYPE``, ``\Twig\Token::INTERPOLATION_END_TYPE`` (as of Twig 1.5): Delimiters for string interpolation;
42
+ * ``\Twig\Token::EOF_TYPE``: Ends of template.
43
 
44
  You can manually convert a source code into a token stream by calling the
45
  ``tokenize()`` method of an environment::
46
 
47
+ $stream = $twig->tokenize(new \Twig\Source($source, $identifier));
48
 
49
  .. versionadded:: 1.27
50
+ ``\Twig\Source`` was introduced in version 1.27, pass the source and the
51
  identifier directly on previous versions.
52
 
53
  As the stream has a ``__toString()`` method, you can have a textual
67
 
68
  .. note::
69
 
70
+ The default lexer (``\Twig\Lexer``) can be changed by calling
71
  the ``setLexer()`` method::
72
 
73
  $twig->setLexer($lexer);
76
  ----------
77
 
78
  The parser converts the token stream into an AST (Abstract Syntax Tree), or a
79
+ node tree (an instance of ``\Twig\Node\ModuleNode``). The core extension defines
80
  the basic nodes like: ``for``, ``if``, ... and the expression nodes.
81
 
82
  You can manually convert a token stream into a node tree by calling the
92
 
93
  .. code-block:: text
94
 
95
+ \Twig\Node\ModuleNode(
96
+ \Twig\Node\TextNode(Hello )
97
+ \Twig\Node\PrintNode(
98
+ \Twig\Node\Expression\NameExpression(name)
99
  )
100
  )
101
 
102
  .. note::
103
 
104
+ The default parser (``\Twig\TokenParser\AbstractTokenParser``) can be changed by calling the
105
  ``setParser()`` method::
106
 
107
  $twig->setParser($parser);
122
  using)::
123
 
124
  /* Hello {{ name }} */
125
+ class __TwigTemplate_1121b6f109fe93ebe8c6e22e3712bceb extends \Twig\Template
126
  {
127
  protected function doDisplay(array $context, array $blocks = [])
128
  {
136
 
137
  .. note::
138
 
139
+ The default compiler (``\Twig\Compiler``) can be changed by calling the
140
  ``setCompiler()`` method::
141
 
142
  $twig->setCompiler($compiler);
vendor/twig/twig/doc/intro.rst CHANGED
@@ -55,15 +55,15 @@ This section gives you a brief introduction to the PHP API for Twig.
55
 
56
  require_once '/path/to/vendor/autoload.php';
57
 
58
- $loader = new Twig_Loader_Array([
59
  'index' => 'Hello {{ name }}!',
60
  ]);
61
- $twig = new Twig_Environment($loader);
62
 
63
  echo $twig->render('index', ['name' => 'Fabien']);
64
 
65
- Twig uses a loader (``Twig_Loader_Array``) to locate templates, and an
66
- environment (``Twig_Environment``) to store the configuration.
67
 
68
  The ``render()`` method loads the template passed as a first argument and
69
  renders it with the variables passed as a second argument.
@@ -71,8 +71,8 @@ renders it with the variables passed as a second argument.
71
  As templates are generally stored on the filesystem, Twig also comes with a
72
  filesystem loader::
73
 
74
- $loader = new Twig_Loader_Filesystem('/path/to/templates');
75
- $twig = new Twig_Environment($loader, [
76
  'cache' => '/path/to/compilation_cache',
77
  ]);
78
 
55
 
56
  require_once '/path/to/vendor/autoload.php';
57
 
58
+ $loader = new \Twig\Loader\ArrayLoader([
59
  'index' => 'Hello {{ name }}!',
60
  ]);
61
+ $twig = new \Twig\Environment($loader);
62
 
63
  echo $twig->render('index', ['name' => 'Fabien']);
64
 
65
+ Twig uses a loader (``\Twig\Loader\ArrayLoader``) to locate templates, and an
66
+ environment (``\Twig\Environment``) to store the configuration.
67
 
68
  The ``render()`` method loads the template passed as a first argument and
69
  renders it with the variables passed as a second argument.
71
  As templates are generally stored on the filesystem, Twig also comes with a
72
  filesystem loader::
73
 
74
+ $loader = new \Twig\Loader\FilesystemLoader('/path/to/templates');
75
+ $twig = new \Twig\Environment($loader, [
76
  'cache' => '/path/to/compilation_cache',
77
  ]);
78
 
vendor/twig/twig/doc/recipes.rst CHANGED
@@ -20,7 +20,7 @@ run a script along the lines of the following::
20
 
21
  $twig = create_your_twig_env();
22
 
23
- $deprecations = new Twig_Util_DeprecationCollector($twig);
24
 
25
  print_r($deprecations->collectDir(__DIR__.'/templates'));
26
 
@@ -32,7 +32,7 @@ catches deprecation notices, and return them.
32
  If your templates are not stored on the filesystem, use the ``collect()``
33
  method instead. ``collect()`` takes a ``Traversable`` which must return
34
  template names as keys and template contents as values (as done by
35
- ``Twig_Util_TemplateDirIterator``).
36
 
37
  However, this code won't find all deprecations (like using deprecated some Twig
38
  classes). To catch all notices, register a custom error handler like the one
@@ -161,9 +161,9 @@ syntax. But for specific projects, it can make sense to change the defaults.
161
 
162
  To change the block delimiters, you need to create your own lexer object::
163
 
164
- $twig = new Twig_Environment();
165
 
166
- $lexer = new Twig_Lexer($twig, [
167
  'tag_comment' => ['{#', '#}'],
168
  'tag_block' => ['{%', '%}'],
169
  'tag_variable' => ['{{', '}}'],
@@ -175,21 +175,21 @@ Here are some configuration example that simulates some other template engines
175
  syntax::
176
 
177
  // Ruby erb syntax
178
- $lexer = new Twig_Lexer($twig, [
179
  'tag_comment' => ['<%#', '%>'],
180
  'tag_block' => ['<%', '%>'],
181
  'tag_variable' => ['<%=', '%>'],
182
  ]);
183
 
184
  // SGML Comment Syntax
185
- $lexer = new Twig_Lexer($twig, [
186
  'tag_comment' => ['<!--#', '-->'],
187
  'tag_block' => ['<!--', '-->'],
188
  'tag_variable' => ['${', '}'],
189
  ]);
190
 
191
  // Smarty like
192
- $lexer = new Twig_Lexer($twig, [
193
  'tag_comment' => ['{*', '*}'],
194
  'tag_block' => ['{', '}'],
195
  'tag_variable' => ['{$', '}'],
@@ -270,7 +270,7 @@ Defining undefined Functions and Filters on the Fly
270
  ---------------------------------------------------
271
 
272
  When a function (or a filter) is not defined, Twig defaults to throw a
273
- ``Twig_Error_Syntax`` exception. However, it can also call a `callback`_ (any
274
  valid PHP callable) which should return a function (or a filter).
275
 
276
  For filters, register callbacks with ``registerUndefinedFilterCallback()``.
@@ -280,7 +280,7 @@ For functions, use ``registerUndefinedFunctionCallback()``::
280
  // don't try this at home as it's not secure at all!
281
  $twig->registerUndefinedFunctionCallback(function ($name) {
282
  if (function_exists($name)) {
283
- return new Twig_SimpleFunction($name, $name);
284
  }
285
 
286
  return false;
@@ -306,10 +306,10 @@ saving it. If the template code is stored in a `$template` variable, here is
306
  how you can do it::
307
 
308
  try {
309
- $twig->parse($twig->tokenize(new Twig_Source($template)));
310
 
311
  // the $template is valid
312
- } catch (Twig_Error_Syntax $e) {
313
  // $template contains one or more syntax errors
314
  }
315
 
@@ -318,16 +318,16 @@ If you iterate over a set of files, you can pass the filename to the
318
 
319
  foreach ($files as $file) {
320
  try {
321
- $twig->parse($twig->tokenize(new Twig_Source($template, $file->getFilename(), $file)));
322
 
323
  // the $template is valid
324
- } catch (Twig_Error_Syntax $e) {
325
  // $template contains one or more syntax errors
326
  }
327
  }
328
 
329
  .. versionadded:: 1.27
330
- ``Twig_Source`` was introduced in version 1.27, pass the source and the
331
  identifier directly on previous versions.
332
 
333
  .. note::
@@ -345,16 +345,16 @@ cache won't update the cache.
345
 
346
  To get around this, force Twig to invalidate the bytecode cache::
347
 
348
- $twig = new Twig_Environment($loader, [
349
- 'cache' => new Twig_Cache_Filesystem('/some/cache/path', Twig_Cache_Filesystem::FORCE_BYTECODE_INVALIDATION),
350
  // ...
351
  ]);
352
 
353
  .. note::
354
 
355
- Before Twig 1.22, you should extend ``Twig_Environment`` instead::
356
 
357
- class OpCacheAwareTwigEnvironment extends Twig_Environment
358
  {
359
  protected function writeCacheFile($file, $content)
360
  {
@@ -372,7 +372,7 @@ To get around this, force Twig to invalidate the bytecode cache::
372
  Reusing a stateful Node Visitor
373
  -------------------------------
374
 
375
- When attaching a visitor to a ``Twig_Environment`` instance, Twig uses it to
376
  visit *all* templates it compiles. If you need to keep some state information
377
  around, you probably want to reset it when visiting a new template.
378
 
@@ -380,9 +380,9 @@ This can be easily achieved with the following code::
380
 
381
  protected $someTemplateState = [];
382
 
383
- public function enterNode(Twig_NodeInterface $node, Twig_Environment $env)
384
  {
385
- if ($node instanceof Twig_Node_Module) {
386
  // reset the state as we are entering a new template
387
  $this->someTemplateState = [];
388
  }
@@ -417,7 +417,7 @@ We have created a simple ``templates`` table that hosts two templates:
417
 
418
  Now, let's define a loader able to use this database::
419
 
420
- class DatabaseTwigLoader implements Twig_LoaderInterface, Twig_ExistsLoaderInterface, Twig_SourceContextLoaderInterface
421
  {
422
  protected $dbh;
423
 
@@ -429,23 +429,23 @@ Now, let's define a loader able to use this database::
429
  public function getSource($name)
430
  {
431
  if (false === $source = $this->getValue('source', $name)) {
432
- throw new Twig_Error_Loader(sprintf('Template "%s" does not exist.', $name));
433
  }
434
 
435
  return $source;
436
  }
437
 
438
- // Twig_SourceContextLoaderInterface as of Twig 1.27
439
  public function getSourceContext($name)
440
  {
441
  if (false === $source = $this->getValue('source', $name)) {
442
- throw new Twig_Error_Loader(sprintf('Template "%s" does not exist.', $name));
443
  }
444
 
445
- return new Twig_Source($source, $name);
446
  }
447
 
448
- // Twig_ExistsLoaderInterface as of Twig 1.11
449
  public function exists($name)
450
  {
451
  return $name === $this->getValue('name', $name);
@@ -477,7 +477,7 @@ Now, let's define a loader able to use this database::
477
  Finally, here is an example on how you can use it::
478
 
479
  $loader = new DatabaseTwigLoader($dbh);
480
- $twig = new Twig_Environment($loader);
481
 
482
  echo $twig->render('index.twig', ['name' => 'Fabien']);
483
 
@@ -487,7 +487,7 @@ Using different Template Sources
487
  This recipe is the continuation of the previous one. Even if you store the
488
  contributed templates in a database, you might want to keep the original/base
489
  templates on the filesystem. When templates can be loaded from different
490
- sources, you need to use the ``Twig_Loader_Chain`` loader.
491
 
492
  As you can see in the previous recipe, we reference the template in the exact
493
  same way as we would have done it with a regular filesystem loader. This is
@@ -496,12 +496,12 @@ filesystem, or any other loader for that matter: the template name should be a
496
  logical name, and not the path from the filesystem::
497
 
498
  $loader1 = new DatabaseTwigLoader($dbh);
499
- $loader2 = new Twig_Loader_Array([
500
  'base.twig' => '{% block content %}{% endblock %}',
501
  ]);
502
- $loader = new Twig_Loader_Chain([$loader1, $loader2]);
503
 
504
- $twig = new Twig_Environment($loader);
505
 
506
  echo $twig->render('index.twig', ['name' => 'Fabien']);
507
 
@@ -513,14 +513,14 @@ Loading a Template from a String
513
 
514
  From a template, you can easily load a template stored in a string via the
515
  ``template_from_string`` function (available as of Twig 1.11 via the
516
- ``Twig_Extension_StringLoader`` extension):
517
 
518
  .. code-block:: jinja
519
 
520
  {{ include(template_from_string("Hello {{ name }}")) }}
521
 
522
  From PHP, it's also possible to load a template stored in a string via
523
- ``Twig_Environment::createTemplate()`` (available as of Twig 1.18)::
524
 
525
  $template = $twig->createTemplate('hello {{ name }}');
526
  echo $template->render(['name' => 'Fabien']);
@@ -561,7 +561,7 @@ include in your templates:
561
 
562
  .. code-block:: php
563
 
564
- $env->setLexer(new Twig_Lexer($env, [
565
  'tag_variable' => ['{[', ']}'],
566
  ]));
567
 
20
 
21
  $twig = create_your_twig_env();
22
 
23
+ $deprecations = new \Twig\Util\DeprecationCollector($twig);
24
 
25
  print_r($deprecations->collectDir(__DIR__.'/templates'));
26
 
32
  If your templates are not stored on the filesystem, use the ``collect()``
33
  method instead. ``collect()`` takes a ``Traversable`` which must return
34
  template names as keys and template contents as values (as done by
35
+ ``\Twig\Util\TemplateDirIterator``).
36
 
37
  However, this code won't find all deprecations (like using deprecated some Twig
38
  classes). To catch all notices, register a custom error handler like the one
161
 
162
  To change the block delimiters, you need to create your own lexer object::
163
 
164
+ $twig = new \Twig\Environment();
165
 
166
+ $lexer = new \Twig\Lexer($twig, [
167
  'tag_comment' => ['{#', '#}'],
168
  'tag_block' => ['{%', '%}'],
169
  'tag_variable' => ['{{', '}}'],
175
  syntax::
176
 
177
  // Ruby erb syntax
178
+ $lexer = new \Twig\Lexer($twig, [
179
  'tag_comment' => ['<%#', '%>'],
180
  'tag_block' => ['<%', '%>'],
181
  'tag_variable' => ['<%=', '%>'],
182
  ]);
183
 
184
  // SGML Comment Syntax
185
+ $lexer = new \Twig\Lexer($twig, [
186
  'tag_comment' => ['<!--#', '-->'],
187
  'tag_block' => ['<!--', '-->'],
188
  'tag_variable' => ['${', '}'],
189
  ]);
190
 
191
  // Smarty like
192
+ $lexer = new \Twig\Lexer($twig, [
193
  'tag_comment' => ['{*', '*}'],
194
  'tag_block' => ['{', '}'],
195
  'tag_variable' => ['{$', '}'],
270
  ---------------------------------------------------
271
 
272
  When a function (or a filter) is not defined, Twig defaults to throw a
273
+ ``\Twig\Error\SyntaxError`` exception. However, it can also call a `callback`_ (any
274
  valid PHP callable) which should return a function (or a filter).
275
 
276
  For filters, register callbacks with ``registerUndefinedFilterCallback()``.
280
  // don't try this at home as it's not secure at all!
281
  $twig->registerUndefinedFunctionCallback(function ($name) {
282
  if (function_exists($name)) {
283
+ return new \Twig\TwigFunction($name, $name);
284
  }
285
 
286
  return false;
306
  how you can do it::
307
 
308
  try {
309
+ $twig->parse($twig->tokenize(new \Twig\Source($template)));
310
 
311
  // the $template is valid
312
+ } catch (\Twig\Error\SyntaxError $e) {
313
  // $template contains one or more syntax errors
314
  }
315
 
318
 
319
  foreach ($files as $file) {
320
  try {
321
+ $twig->parse($twig->tokenize(new \Twig\Source($template, $file->getFilename(), $file)));
322
 
323
  // the $template is valid
324
+ } catch (\Twig\Error\SyntaxError $e) {
325
  // $template contains one or more syntax errors
326
  }
327
  }
328
 
329
  .. versionadded:: 1.27
330
+ ``\Twig\Source`` was introduced in version 1.27, pass the source and the
331
  identifier directly on previous versions.
332
 
333
  .. note::
345
 
346
  To get around this, force Twig to invalidate the bytecode cache::
347
 
348
+ $twig = new \Twig\Environment($loader, [
349
+ 'cache' => new \Twig\Cache\FilesystemCache('/some/cache/path', \Twig\Cache\FilesystemCache::FORCE_BYTECODE_INVALIDATION),
350
  // ...
351
  ]);
352
 
353
  .. note::
354
 
355
+ Before Twig 1.22, you should extend ``\Twig\Environment`` instead::
356
 
357
+ class OpCacheAwareTwigEnvironment extends \Twig\Environment
358
  {
359
  protected function writeCacheFile($file, $content)
360
  {
372
  Reusing a stateful Node Visitor
373
  -------------------------------
374
 
375
+ When attaching a visitor to a ``\Twig\Environment`` instance, Twig uses it to
376
  visit *all* templates it compiles. If you need to keep some state information
377
  around, you probably want to reset it when visiting a new template.
378
 
380
 
381
  protected $someTemplateState = [];
382
 
383
+ public function enterNode(Twig_NodeInterface $node, \Twig\Environment $env)
384
  {
385
+ if ($node instanceof \Twig\Node\ModuleNode) {
386
  // reset the state as we are entering a new template
387
  $this->someTemplateState = [];
388
  }
417
 
418
  Now, let's define a loader able to use this database::
419
 
420
+ class DatabaseTwigLoader implements \Twig\Loader\LoaderInterface, \Twig\Loader\ExistsLoaderInterface, \Twig\Loader\SourceContextLoaderInterface
421
  {
422
  protected $dbh;
423
 
429
  public function getSource($name)
430
  {
431
  if (false === $source = $this->getValue('source', $name)) {
432
+ throw new \Twig\Error\LoaderError(sprintf('Template "%s" does not exist.', $name));
433
  }
434
 
435
  return $source;
436
  }
437
 
438
+ // \Twig\Loader\SourceContextLoaderInterface as of Twig 1.27
439
  public function getSourceContext($name)
440
  {
441
  if (false === $source = $this->getValue('source', $name)) {
442
+ throw new \Twig\Error\LoaderError(sprintf('Template "%s" does not exist.', $name));
443
  }
444
 
445
+ return new \Twig\Source($source, $name);
446
  }
447
 
448
+ // \Twig\Loader\ExistsLoaderInterface as of Twig 1.11
449
  public function exists($name)
450
  {
451
  return $name === $this->getValue('name', $name);
477
  Finally, here is an example on how you can use it::
478
 
479
  $loader = new DatabaseTwigLoader($dbh);
480
+ $twig = new \Twig\Environment($loader);
481
 
482
  echo $twig->render('index.twig', ['name' => 'Fabien']);
483
 
487
  This recipe is the continuation of the previous one. Even if you store the
488
  contributed templates in a database, you might want to keep the original/base
489
  templates on the filesystem. When templates can be loaded from different
490
+ sources, you need to use the ``\Twig\Loader\ChainLoader`` loader.
491
 
492
  As you can see in the previous recipe, we reference the template in the exact
493
  same way as we would have done it with a regular filesystem loader. This is
496
  logical name, and not the path from the filesystem::
497
 
498
  $loader1 = new DatabaseTwigLoader($dbh);
499
+ $loader2 = new \Twig\Loader\ArrayLoader([
500
  'base.twig' => '{% block content %}{% endblock %}',
501
  ]);
502
+ $loader = new \Twig\Loader\ChainLoader([$loader1, $loader2]);
503
 
504
+ $twig = new \Twig\Environment($loader);
505
 
506
  echo $twig->render('index.twig', ['name' => 'Fabien']);
507
 
513
 
514
  From a template, you can easily load a template stored in a string via the
515
  ``template_from_string`` function (available as of Twig 1.11 via the
516
+ ``\Twig\Extension\StringLoaderExtension`` extension):
517
 
518
  .. code-block:: jinja
519
 
520
  {{ include(template_from_string("Hello {{ name }}")) }}
521
 
522
  From PHP, it's also possible to load a template stored in a string via
523
+ ``\Twig\Environment::createTemplate()`` (available as of Twig 1.18)::
524
 
525
  $template = $twig->createTemplate('hello {{ name }}');
526
  echo $template->render(['name' => 'Fabien']);
561
 
562
  .. code-block:: php
563
 
564
+ $env->setLexer(new \Twig\Lexer($env, [
565
  'tag_variable' => ['{[', ']}'],
566
  ]));
567
 
vendor/twig/twig/doc/tags/extends.rst CHANGED
@@ -153,7 +153,7 @@ Twig supports dynamic inheritance by using a variable as the base template:
153
 
154
  {% extends some_var %}
155
 
156
- If the variable evaluates to a ``Twig_Template`` or a ``Twig_TemplateWrapper``
157
  instance, Twig will use it as the parent template::
158
 
159
  // {% extends layout %}
153
 
154
  {% extends some_var %}
155
 
156
+ If the variable evaluates to a ``\Twig\Template`` or a ``\Twig\TemplateWrapper``
157
  instance, Twig will use it as the parent template::
158
 
159
  // {% extends layout %}
vendor/twig/twig/doc/tags/filter.rst CHANGED
@@ -10,11 +10,11 @@ data. Just wrap the code in the special ``filter`` section:
10
  This text becomes uppercase
11
  {% endfilter %}
12
 
13
- You can also chain filters:
14
 
15
  .. code-block:: jinja
16
 
17
- {% filter lower|escape %}
18
  <strong>SOME TEXT</strong>
19
  {% endfilter %}
20
 
10
  This text becomes uppercase
11
  {% endfilter %}
12
 
13
+ You can also chain filters and pass arguments to them:
14
 
15
  .. code-block:: jinja
16
 
17
+ {% filter lower|escape('html') %}
18
  <strong>SOME TEXT</strong>
19
  {% endfilter %}
20
 
vendor/twig/twig/doc/tags/include.rst CHANGED
@@ -2,7 +2,7 @@
2
  ===========
3
 
4
  The ``include`` statement includes a template and returns the rendered content
5
- of that file into the current namespace:
6
 
7
  .. code-block:: jinja
8
 
@@ -10,6 +10,30 @@ of that file into the current namespace:
10
  Body
11
  {% include 'footer.html' %}
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  Included templates have access to the variables of the active context.
14
 
15
  If you are using the filesystem loader, the templates are looked for in the
@@ -50,8 +74,8 @@ The template name can be any valid Twig expression:
50
  {% include some_var %}
51
  {% include ajax ? 'ajax.html' : 'not_ajax.html' %}
52
 
53
- And if the expression evaluates to a ``Twig_Template`` or a
54
- ``Twig_TemplateWrapper`` instance, Twig will use it directly::
55
 
56
  // {% include template %}
57
 
2
  ===========
3
 
4
  The ``include`` statement includes a template and returns the rendered content
5
+ of that file:
6
 
7
  .. code-block:: jinja
8
 
10
  Body
11
  {% include 'footer.html' %}
12
 
13
+ .. note::
14
+
15
+ As of Twig 1.12, it is recommended to use the
16
+ :doc:`include<../functions/include>` function instead as it provides the
17
+ same features with a bit more flexibility:
18
+
19
+ * The ``include`` function is semantically more "correct" (including a
20
+ template outputs its rendered contents in the current scope; a tag should
21
+ not display anything);
22
+
23
+ * The rendered template can be more easily stored in a variable when using
24
+ the ``include`` function:
25
+
26
+ .. code-block:: jinja
27
+
28
+ {% set content %}{% include 'template.html' %}{% endset %}
29
+
30
+ {# vs #}
31
+
32
+ {% set content = include('template.html') %}
33
+
34
+ * The ``include`` function does not impose any specific order for
35
+ arguments thanks to :ref:`named arguments <named-arguments>`.
36
+
37
  Included templates have access to the variables of the active context.
38
 
39
  If you are using the filesystem loader, the templates are looked for in the
74
  {% include some_var %}
75
  {% include ajax ? 'ajax.html' : 'not_ajax.html' %}
76
 
77
+ And if the expression evaluates to a ``\Twig\Template`` or a
78
+ ``\Twig\TemplateWrapper`` instance, Twig will use it directly::
79
 
80
  // {% include template %}
81
 
vendor/twig/twig/doc/tags/set.rst CHANGED
@@ -18,7 +18,7 @@ any other ones:
18
  {# displays bar #}
19
  {{ foo }}
20
 
21
- The assigned value can be any valid :ref:`Twig expressions
22
  <twig-expressions>`:
23
 
24
  .. code-block:: jinja
18
  {# displays bar #}
19
  {{ foo }}
20
 
21
+ The assigned value can be any valid :ref:`Twig expression
22
  <twig-expressions>`:
23
 
24
  .. code-block:: jinja
vendor/twig/twig/doc/templates.rst CHANGED
@@ -196,6 +196,8 @@ progression of integers:
196
  Go to the :doc:`functions<functions/index>` page to learn more about the
197
  built-in functions.
198
 
 
 
199
  Named Arguments
200
  ---------------
201
 
@@ -314,7 +316,7 @@ will be available in the included template too:
314
  The included template ``render_box.html`` is able to access the ``box`` variable.
315
 
316
  The name of the template depends on the template loader. For instance, the
317
- ``Twig_Loader_Filesystem`` allows you to access other templates by giving the
318
  filename. You can access templates in subdirectories with a slash:
319
 
320
  .. code-block:: jinja
196
  Go to the :doc:`functions<functions/index>` page to learn more about the
197
  built-in functions.
198
 
199
+ .. _named-arguments:
200
+
201
  Named Arguments
202
  ---------------
203
 
316
  The included template ``render_box.html`` is able to access the ``box`` variable.
317
 
318
  The name of the template depends on the template loader. For instance, the
319
+ ``\Twig\Loader\FilesystemLoader`` allows you to access other templates by giving the
320
  filename. You can access templates in subdirectories with a slash:
321
 
322
  .. code-block:: jinja
vendor/twig/twig/ext/twig/php_twig.h CHANGED
@@ -15,7 +15,7 @@
15
  #ifndef PHP_TWIG_H
16
  #define PHP_TWIG_H
17
 
18
- #define PHP_TWIG_VERSION "1.37.2-DEV"
19
 
20
  #include "php.h"
21
 
15
  #ifndef PHP_TWIG_H
16
  #define PHP_TWIG_H
17
 
18
+ #define PHP_TWIG_VERSION "1.38.0-DEV"
19
 
20
  #include "php.h"
21
 
vendor/twig/twig/ext/twig/twig.c CHANGED
@@ -733,7 +733,7 @@ PHP_FUNCTION(twig_template_get_attributes)
733
 
734
  /*
735
  // array
736
- if (Twig_Template::METHOD_CALL !== $type) {
737
  $arrayItem = is_bool($item) || is_float($item) ? (int) $item : $item;
738
 
739
  if ((is_array($object) && array_key_exists($arrayItem, $object))
@@ -771,7 +771,7 @@ PHP_FUNCTION(twig_template_get_attributes)
771
  return;
772
  }
773
  /*
774
- if (Twig_Template::ARRAY_CALL === $type) {
775
  if ($isDefinedTest) {
776
  return false;
777
  }
@@ -799,7 +799,7 @@ PHP_FUNCTION(twig_template_get_attributes)
799
  } else {
800
  $message = sprintf('Key "%s" for array with keys "%s" does not exist', $arrayItem, implode(', ', array_keys($object)));
801
  }
802
- } elseif (Twig_Template::ARRAY_CALL === $type) {
803
  if (null === $object) {
804
  $message = sprintf('Impossible to access a key ("%s") on a null variable', $item);
805
  } else {
@@ -810,7 +810,7 @@ PHP_FUNCTION(twig_template_get_attributes)
810
  } else {
811
  $message = sprintf('Impossible to access an attribute ("%s") on a %s variable ("%s")', $item, gettype($object), $object);
812
  }
813
- throw new Twig_Error_Runtime($message, -1, $this->getTemplateName());
814
  }
815
  }
816
  */
@@ -876,7 +876,7 @@ PHP_FUNCTION(twig_template_get_attributes)
876
  $message = sprintf('Impossible to invoke a method ("%s") on a %s variable ("%s")', $item, gettype($object), $object);
877
  }
878
 
879
- throw new Twig_Error_Runtime($message, -1, $this->getTemplateName());
880
  }
881
  */
882
  if (ignoreStrictCheck || !TWIG_CALL_BOOLEAN(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "isStrictVariables" TSRMLS_CC)) {
@@ -916,14 +916,14 @@ PHP_FUNCTION(twig_template_get_attributes)
916
 
917
  /*
918
  // object property
919
- if (Twig_Template::METHOD_CALL !== $type && !$object instanceof Twig_Template) {
920
  if (isset($object->$item) || array_key_exists((string) $item, $object)) {
921
  if ($isDefinedTest) {
922
  return true;
923
  }
924
 
925
- if ($this->env->hasExtension('Twig_Extension_Sandbox')) {
926
- $this->env->getExtension('Twig_Extension_Sandbox')->checkPropertyAllowed($object, $item);
927
  }
928
 
929
  return $object->$item;
@@ -958,7 +958,7 @@ PHP_FUNCTION(twig_template_get_attributes)
958
  // object method
959
  if (!isset(self::$cache[$class]['methods'])) {
960
  if ($object instanceof self) {
961
- $ref = new ReflectionClass($class);
962
  $methods = [];
963
 
964
  foreach ($ref->getMethods(ReflectionMethod::IS_PUBLIC) as $refMethod) {
@@ -1029,7 +1029,7 @@ PHP_FUNCTION(twig_template_get_attributes)
1029
  return null;
1030
  }
1031
 
1032
- throw new Twig_Error_Runtime(sprintf('Method "%s" for object "%s" does not exist.', $item, get_class($object)), -1, $this->getTemplateName());
1033
  }
1034
 
1035
  if ($isDefinedTest) {
@@ -1061,8 +1061,8 @@ PHP_FUNCTION(twig_template_get_attributes)
1061
  RETURN_TRUE;
1062
  }
1063
  /*
1064
- if ($this->env->hasExtension('Twig_Extension_Sandbox')) {
1065
- $this->env->getExtension('Twig_Extension_Sandbox')->checkMethodAllowed($object, $method);
1066
  }
1067
  */
1068
  MAKE_STD_ZVAL(zmethod);
@@ -1082,7 +1082,7 @@ PHP_FUNCTION(twig_template_get_attributes)
1082
  // to call is not supported. If ignoreStrictCheck is true, we should return null.
1083
  try {
1084
  $ret = call_user_func_array([$object, $method], $arguments);
1085
- } catch (BadMethodCallException $e) {
1086
  if ($call && ($ignoreStrictCheck || !$this->env->isStrictVariables())) {
1087
  return null;
1088
  }
@@ -1117,7 +1117,7 @@ PHP_FUNCTION(twig_template_get_attributes)
1117
  }
1118
  @trigger_error($message, E_USER_DEPRECATED);
1119
 
1120
- return $ret === '' ? '' : new Twig_Markup($ret, $this->env->getCharset());
1121
  }
1122
 
1123
  return $ret;
733
 
734
  /*
735
  // array
736
+ if (\Twig\Template::METHOD_CALL !== $type) {
737
  $arrayItem = is_bool($item) || is_float($item) ? (int) $item : $item;
738
 
739
  if ((is_array($object) && array_key_exists($arrayItem, $object))
771
  return;
772
  }
773
  /*
774
+ if (\Twig\Template::ARRAY_CALL === $type) {
775
  if ($isDefinedTest) {
776
  return false;
777
  }
799
  } else {
800
  $message = sprintf('Key "%s" for array with keys "%s" does not exist', $arrayItem, implode(', ', array_keys($object)));
801
  }
802
+ } elseif (\Twig\Template::ARRAY_CALL === $type) {
803
  if (null === $object) {
804
  $message = sprintf('Impossible to access a key ("%s") on a null variable', $item);
805
  } else {
810
  } else {
811
  $message = sprintf('Impossible to access an attribute ("%s") on a %s variable ("%s")', $item, gettype($object), $object);
812
  }
813
+ throw new \Twig\Error\RuntimeError($message, -1, $this->getTemplateName());
814
  }
815
  }
816
  */
876
  $message = sprintf('Impossible to invoke a method ("%s") on a %s variable ("%s")', $item, gettype($object), $object);
877
  }
878
 
879
+ throw new \Twig\Error\RuntimeError($message, -1, $this->getTemplateName());
880
  }
881
  */
882
  if (ignoreStrictCheck || !TWIG_CALL_BOOLEAN(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "isStrictVariables" TSRMLS_CC)) {
916
 
917
  /*
918
  // object property
919
+ if (\Twig\Template::METHOD_CALL !== $type && !$object instanceof \Twig\Template) {
920
  if (isset($object->$item) || array_key_exists((string) $item, $object)) {
921
  if ($isDefinedTest) {
922
  return true;
923
  }
924
 
925
+ if ($this->env->hasExtension('\Twig\Extension\SandboxExtension')) {
926
+ $this->env->getExtension('\Twig\Extension\SandboxExtension')->checkPropertyAllowed($object, $item);
927
  }
928
 
929
  return $object->$item;
958
  // object method
959
  if (!isset(self::$cache[$class]['methods'])) {
960
  if ($object instanceof self) {
961
+ $ref = new \ReflectionClass($class);
962
  $methods = [];
963
 
964
  foreach ($ref->getMethods(ReflectionMethod::IS_PUBLIC) as $refMethod) {
1029
  return null;
1030
  }
1031
 
1032
+ throw new \Twig\Error\RuntimeError(sprintf('Method "%s" for object "%s" does not exist.', $item, get_class($object)), -1, $this->getTemplateName());
1033
  }
1034
 
1035
  if ($isDefinedTest) {
1061
  RETURN_TRUE;
1062
  }
1063
  /*
1064
+ if ($this->env->hasExtension('\Twig\Extension\SandboxExtension')) {
1065
+ $this->env->getExtension('\Twig\Extension\SandboxExtension')->checkMethodAllowed($object, $method);
1066
  }
1067
  */
1068
  MAKE_STD_ZVAL(zmethod);
1082
  // to call is not supported. If ignoreStrictCheck is true, we should return null.
1083
  try {
1084
  $ret = call_user_func_array([$object, $method], $arguments);
1085
+ } catch (\BadMethodCallException $e) {
1086
  if ($call && ($ignoreStrictCheck || !$this->env->isStrictVariables())) {
1087
  return null;
1088
  }
1117
  }
1118
  @trigger_error($message, E_USER_DEPRECATED);
1119
 
1120
+ return $ret === '' ? '' : new \Twig\Markup($ret, $this->env->getCharset());
1121
  }
1122
 
1123
  return $ret;
vendor/twig/twig/lib/Twig/Autoloader.php CHANGED
@@ -43,7 +43,7 @@ class Twig_Autoloader
43
  return;
44
  }
45
 
46
- if (is_file($file = dirname(__FILE__).'/../'.str_replace(['_', "\0"], ['/', ''], $class).'.php')) {
47
  require $file;
48
  }
49
  }
43
  return;
44
  }
45
 
46
+ if (is_file($file = __DIR__.'/../'.str_replace(['_', "\0"], ['/', ''], $class).'.php')) {
47
  require $file;
48
  }
49
  }
vendor/twig/twig/lib/Twig/BaseNodeVisitor.php CHANGED
@@ -9,26 +9,30 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
12
  /**
13
  * Twig_BaseNodeVisitor can be used to make node visitors compatible with Twig 1.x and 2.x.
14
  *
15
  * @author Fabien Potencier <fabien@symfony.com>
16
  */
17
- abstract class Twig_BaseNodeVisitor implements Twig_NodeVisitorInterface
18
  {
19
- final public function enterNode(Twig_NodeInterface $node, Twig_Environment $env)
20
  {
21
- if (!$node instanceof Twig_Node) {
22
- throw new LogicException('Twig_BaseNodeVisitor only supports Twig_Node instances.');
23
  }
24
 
25
  return $this->doEnterNode($node, $env);
26
  }
27
 
28
- final public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env)
29
  {
30
- if (!$node instanceof Twig_Node) {
31
- throw new LogicException('Twig_BaseNodeVisitor only supports Twig_Node instances.');
32
  }
33
 
34
  return $this->doLeaveNode($node, $env);
@@ -37,16 +41,16 @@ abstract class Twig_BaseNodeVisitor implements Twig_NodeVisitorInterface
37
  /**
38
  * Called before child nodes are visited.
39
  *
40
- * @return Twig_Node The modified node
41
  */
42
- abstract protected function doEnterNode(Twig_Node $node, Twig_Environment $env);
43
 
44
  /**
45
  * Called after child nodes are visited.
46
  *
47
- * @return Twig_Node|false The modified node or false if the node must be removed
48
  */
49
- abstract protected function doLeaveNode(Twig_Node $node, Twig_Environment $env);
50
  }
51
 
52
  class_alias('Twig_BaseNodeVisitor', 'Twig\NodeVisitor\AbstractNodeVisitor', false);
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Environment;
13
+ use Twig\Node\Node;
14
+ use Twig\NodeVisitor\NodeVisitorInterface;
15
+
16
  /**
17
  * Twig_BaseNodeVisitor can be used to make node visitors compatible with Twig 1.x and 2.x.
18
  *
19
  * @author Fabien Potencier <fabien@symfony.com>
20
  */
21
+ abstract class Twig_BaseNodeVisitor implements NodeVisitorInterface
22
  {
23
+ final public function enterNode(Twig_NodeInterface $node, Environment $env)
24
  {
25
+ if (!$node instanceof Node) {
26
+ throw new \LogicException(sprintf('%s only supports Twig_Node instances.', __CLASS__));
27
  }
28
 
29
  return $this->doEnterNode($node, $env);
30
  }
31
 
32
+ final public function leaveNode(Twig_NodeInterface $node, Environment $env)
33
  {
34
+ if (!$node instanceof Node) {
35
+ throw new \LogicException(sprintf('%s only supports Twig_Node instances.', __CLASS__));
36
  }
37
 
38
  return $this->doLeaveNode($node, $env);
41
  /**
42
  * Called before child nodes are visited.
43
  *
44
+ * @return Node The modified node
45
  */
46
+ abstract protected function doEnterNode(Node $node, Environment $env);
47
 
48
  /**
49
  * Called after child nodes are visited.
50
  *
51
+ * @return Node|false The modified node or false if the node must be removed
52
  */
53
+ abstract protected function doLeaveNode(Node $node, Environment $env);
54
  }
55
 
56
  class_alias('Twig_BaseNodeVisitor', 'Twig\NodeVisitor\AbstractNodeVisitor', false);
vendor/twig/twig/lib/Twig/Cache/Filesystem.php CHANGED
@@ -9,12 +9,14 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
12
  /**
13
  * Implements a cache on the filesystem.
14
  *
15
  * @author Andrew Tch <andrew@noop.lv>
16
  */
17
- class Twig_Cache_Filesystem implements Twig_CacheInterface
18
  {
19
  const FORCE_BYTECODE_INVALIDATION = 1;
20
 
@@ -22,8 +24,8 @@ class Twig_Cache_Filesystem implements Twig_CacheInterface
22
  private $options;
23
 
24
  /**
25
- * @param $directory string The root cache directory
26
- * @param $options int A set of options
27
  */
28
  public function __construct($directory, $options = 0)
29
  {
@@ -47,16 +49,16 @@ class Twig_Cache_Filesystem implements Twig_CacheInterface
47
 
48
  public function write($key, $content)
49
  {
50
- $dir = dirname($key);
51
  if (!is_dir($dir)) {
52
  if (false === @mkdir($dir, 0777, true)) {
53
  clearstatcache(true, $dir);
54
  if (!is_dir($dir)) {
55
- throw new RuntimeException(sprintf('Unable to create the cache directory (%s).', $dir));
56
  }
57
  }
58
  } elseif (!is_writable($dir)) {
59
- throw new RuntimeException(sprintf('Unable to write in the cache directory (%s).', $dir));
60
  }
61
 
62
  $tmpFile = tempnam($dir, basename($key));
@@ -65,9 +67,9 @@ class Twig_Cache_Filesystem implements Twig_CacheInterface
65
 
66
  if (self::FORCE_BYTECODE_INVALIDATION == ($this->options & self::FORCE_BYTECODE_INVALIDATION)) {
67
  // Compile cached file into bytecode cache
68
- if (function_exists('opcache_invalidate')) {
69
  opcache_invalidate($key, true);
70
- } elseif (function_exists('apc_compile_file')) {
71
  apc_compile_file($key);
72
  }
73
  }
@@ -75,7 +77,7 @@ class Twig_Cache_Filesystem implements Twig_CacheInterface
75
  return;
76
  }
77
 
78
- throw new RuntimeException(sprintf('Failed to write cache file "%s".', $key));
79
  }
80
 
81
  public function getTimestamp($key)
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Cache\CacheInterface;
13
+
14
  /**
15
  * Implements a cache on the filesystem.
16
  *
17
  * @author Andrew Tch <andrew@noop.lv>
18
  */
19
+ class Twig_Cache_Filesystem implements CacheInterface
20
  {
21
  const FORCE_BYTECODE_INVALIDATION = 1;
22
 
24
  private $options;
25
 
26
  /**
27
+ * @param string $directory The root cache directory
28
+ * @param int $options A set of options
29
  */
30
  public function __construct($directory, $options = 0)
31
  {
49
 
50
  public function write($key, $content)
51
  {
52
+ $dir = \dirname($key);
53
  if (!is_dir($dir)) {
54
  if (false === @mkdir($dir, 0777, true)) {
55
  clearstatcache(true, $dir);
56
  if (!is_dir($dir)) {
57
+ throw new \RuntimeException(sprintf('Unable to create the cache directory (%s).', $dir));
58
  }
59
  }
60
  } elseif (!is_writable($dir)) {
61
+ throw new \RuntimeException(sprintf('Unable to write in the cache directory (%s).', $dir));
62
  }
63
 
64
  $tmpFile = tempnam($dir, basename($key));
67
 
68
  if (self::FORCE_BYTECODE_INVALIDATION == ($this->options & self::FORCE_BYTECODE_INVALIDATION)) {
69
  // Compile cached file into bytecode cache
70
+ if (\function_exists('opcache_invalidate')) {
71
  opcache_invalidate($key, true);
72
+ } elseif (\function_exists('apc_compile_file')) {
73
  apc_compile_file($key);
74
  }
75
  }
77
  return;
78
  }
79
 
80
+ throw new \RuntimeException(sprintf('Failed to write cache file "%s".', $key));
81
  }
82
 
83
  public function getTimestamp($key)
vendor/twig/twig/lib/Twig/Cache/Null.php CHANGED
@@ -9,6 +9,8 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
12
  /**
13
  * Implements a no-cache strategy.
14
  *
@@ -16,7 +18,7 @@
16
  *
17
  * @author Fabien Potencier <fabien@symfony.com>
18
  */
19
- class Twig_Cache_Null implements Twig_CacheInterface
20
  {
21
  public function generateKey($name, $className)
22
  {
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Cache\CacheInterface;
13
+
14
  /**
15
  * Implements a no-cache strategy.
16
  *
18
  *
19
  * @author Fabien Potencier <fabien@symfony.com>
20
  */
21
+ class Twig_Cache_Null implements CacheInterface
22
  {
23
  public function generateKey($name, $className)
24
  {
vendor/twig/twig/lib/Twig/Compiler.php CHANGED
@@ -10,6 +10,9 @@
10
  * file that was distributed with this source code.
11
  */
12
 
 
 
 
13
  /**
14
  * Compiles a node to PHP code.
15
  *
@@ -27,7 +30,7 @@ class Twig_Compiler implements Twig_CompilerInterface
27
  protected $filename;
28
  private $varNameSalt = 0;
29
 
30
- public function __construct(Twig_Environment $env)
31
  {
32
  $this->env = $env;
33
  }
@@ -45,7 +48,7 @@ class Twig_Compiler implements Twig_CompilerInterface
45
  /**
46
  * Returns the environment instance related to this compiler.
47
  *
48
- * @return Twig_Environment
49
  */
50
  public function getEnvironment()
51
  {
@@ -65,8 +68,7 @@ class Twig_Compiler implements Twig_CompilerInterface
65
  /**
66
  * Compiles a node.
67
  *
68
- * @param Twig_NodeInterface $node The node to compile
69
- * @param int $indentation The current indentation
70
  *
71
  * @return $this
72
  */
@@ -81,7 +83,7 @@ class Twig_Compiler implements Twig_CompilerInterface
81
  $this->indentation = $indentation;
82
  $this->varNameSalt = 0;
83
 
84
- if ($node instanceof Twig_Node_Module) {
85
  // to be removed in 2.0
86
  $this->filename = $node->getTemplateName();
87
  }
@@ -123,7 +125,7 @@ class Twig_Compiler implements Twig_CompilerInterface
123
  */
124
  public function write()
125
  {
126
- $strings = func_get_args();
127
  foreach ($strings as $string) {
128
  $this->source .= str_repeat(' ', $this->indentation * 4).$string;
129
  }
@@ -170,7 +172,7 @@ class Twig_Compiler implements Twig_CompilerInterface
170
  */
171
  public function repr($value)
172
  {
173
- if (is_int($value) || is_float($value)) {
174
  if (false !== $locale = setlocale(LC_NUMERIC, '0')) {
175
  setlocale(LC_NUMERIC, 'C');
176
  }
@@ -182,9 +184,9 @@ class Twig_Compiler implements Twig_CompilerInterface
182
  }
183
  } elseif (null === $value) {
184
  $this->raw('null');
185
- } elseif (is_bool($value)) {
186
  $this->raw($value ? 'true' : 'false');
187
- } elseif (is_array($value)) {
188
  $this->raw('[');
189
  $first = true;
190
  foreach ($value as $key => $v) {
@@ -225,7 +227,7 @@ class Twig_Compiler implements Twig_CompilerInterface
225
  } else {
226
  $this->sourceLine += substr_count($this->source, "\n", $this->sourceOffset);
227
  }
228
- $this->sourceOffset = strlen($this->source);
229
  $this->debugInfo[$this->sourceLine] = $node->getTemplateLine();
230
 
231
  $this->lastLine = $node->getTemplateLine();
@@ -262,13 +264,13 @@ class Twig_Compiler implements Twig_CompilerInterface
262
  *
263
  * @return $this
264
  *
265
- * @throws LogicException When trying to outdent too much so the indentation would become negative
266
  */
267
  public function outdent($step = 1)
268
  {
269
  // can't outdent by more steps than the current indentation level
270
  if ($this->indentation < $step) {
271
- throw new LogicException('Unable to call outdent() as the indentation would become negative.');
272
  }
273
 
274
  $this->indentation -= $step;
10
  * file that was distributed with this source code.
11
  */
12
 
13
+ use Twig\Environment;
14
+ use Twig\Node\ModuleNode;
15
+
16
  /**
17
  * Compiles a node to PHP code.
18
  *
30
  protected $filename;
31
  private $varNameSalt = 0;
32
 
33
+ public function __construct(Environment $env)
34
  {
35
  $this->env = $env;
36
  }
48
  /**
49
  * Returns the environment instance related to this compiler.
50
  *
51
+ * @return Environment
52
  */
53
  public function getEnvironment()
54
  {
68
  /**
69
  * Compiles a node.
70
  *
71
+ * @param int $indentation The current indentation
 
72
  *
73
  * @return $this
74
  */
83
  $this->indentation = $indentation;
84
  $this->varNameSalt = 0;
85
 
86
+ if ($node instanceof ModuleNode) {
87
  // to be removed in 2.0
88
  $this->filename = $node->getTemplateName();
89
  }
125
  */
126
  public function write()
127
  {
128
+ $strings = \func_get_args();
129
  foreach ($strings as $string) {
130
  $this->source .= str_repeat(' ', $this->indentation * 4).$string;
131
  }
172
  */
173
  public function repr($value)
174
  {
175
+ if (\is_int($value) || \is_float($value)) {
176
  if (false !== $locale = setlocale(LC_NUMERIC, '0')) {
177
  setlocale(LC_NUMERIC, 'C');
178
  }
184
  }
185
  } elseif (null === $value) {
186
  $this->raw('null');
187
+ } elseif (\is_bool($value)) {
188
  $this->raw($value ? 'true' : 'false');
189
+ } elseif (\is_array($value)) {
190
  $this->raw('[');
191
  $first = true;
192
  foreach ($value as $key => $v) {
227
  } else {
228
  $this->sourceLine += substr_count($this->source, "\n", $this->sourceOffset);
229
  }
230
+ $this->sourceOffset = \strlen($this->source);
231
  $this->debugInfo[$this->sourceLine] = $node->getTemplateLine();
232
 
233
  $this->lastLine = $node->getTemplateLine();
264
  *
265
  * @return $this
266
  *
267
+ * @throws \LogicException When trying to outdent too much so the indentation would become negative
268
  */
269
  public function outdent($step = 1)
270
  {
271
  // can't outdent by more steps than the current indentation level
272
  if ($this->indentation < $step) {
273
+ throw new \LogicException('Unable to call outdent() as the indentation would become negative.');
274
  }
275
 
276
  $this->indentation -= $step;
vendor/twig/twig/lib/Twig/ContainerRuntimeLoader.php CHANGED
@@ -10,6 +10,7 @@
10
  */
11
 
12
  use Psr\Container\ContainerInterface;
 
13
 
14
  /**
15
  * Lazily loads Twig runtime implementations from a PSR-11 container.
@@ -19,7 +20,7 @@ use Psr\Container\ContainerInterface;
19
  * @author Fabien Potencier <fabien@symfony.com>
20
  * @author Robin Chalas <robin.chalas@gmail.com>
21
  */
22
- class Twig_ContainerRuntimeLoader implements Twig_RuntimeLoaderInterface
23
  {
24
  private $container;
25
 
10
  */
11
 
12
  use Psr\Container\ContainerInterface;
13
+ use Twig\RuntimeLoader\RuntimeLoaderInterface;
14
 
15
  /**
16
  * Lazily loads Twig runtime implementations from a PSR-11 container.
20
  * @author Fabien Potencier <fabien@symfony.com>
21
  * @author Robin Chalas <robin.chalas@gmail.com>
22
  */
23
+ class Twig_ContainerRuntimeLoader implements RuntimeLoaderInterface
24
  {
25
  private $container;
26
 
vendor/twig/twig/lib/Twig/Environment.php CHANGED
@@ -9,6 +9,39 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  /**
13
  * Stores the Twig configuration.
14
  *
@@ -16,11 +49,11 @@
16
  */
17
  class Twig_Environment
18
  {
19
- const VERSION = '1.37.2-DEV';
20
- const VERSION_ID = 13702;
21
  const MAJOR_VERSION = 1;
22
- const MINOR_VERSION = 37;
23
- const RELEASE_VERSION = 2;
24
  const EXTRA_VERSION = 'DEV';
25
 
26
  protected $charset;
@@ -94,22 +127,19 @@ class Twig_Environment
94
  * * optimizations: A flag that indicates which optimizations to apply
95
  * (default to -1 which means that all optimizations are enabled;
96
  * set it to 0 to disable).
97
- *
98
- * @param Twig_LoaderInterface $loader
99
- * @param array $options An array of options
100
  */
101
- public function __construct(Twig_LoaderInterface $loader = null, $options = [])
102
  {
103
  if (null !== $loader) {
104
  $this->setLoader($loader);
105
  } else {
106
- @trigger_error('Not passing a Twig_LoaderInterface as the first constructor argument of Twig_Environment is deprecated since version 1.21.', E_USER_DEPRECATED);
107
  }
108
 
109
  $options = array_merge([
110
  'debug' => false,
111
  'charset' => 'UTF-8',
112
- 'base_template_class' => 'Twig_Template',
113
  'strict_variables' => false,
114
  'autoescape' => 'html',
115
  'cache' => false,
@@ -124,23 +154,23 @@ class Twig_Environment
124
  $this->strictVariables = (bool) $options['strict_variables'];
125
  $this->setCache($options['cache']);
126
 
127
- $this->addExtension(new Twig_Extension_Core());
128
- $this->addExtension(new Twig_Extension_Escaper($options['autoescape']));
129
- $this->addExtension(new Twig_Extension_Optimizer($options['optimizations']));
130
- $this->staging = new Twig_Extension_Staging();
131
 
132
  // For BC
133
- if (is_string($this->originalCache)) {
134
- $r = new ReflectionMethod($this, 'writeCacheFile');
135
  if (__CLASS__ !== $r->getDeclaringClass()->getName()) {
136
- @trigger_error('The Twig_Environment::writeCacheFile method is deprecated since version 1.22 and will be removed in Twig 2.0.', E_USER_DEPRECATED);
137
 
138
  $this->bcWriteCacheFile = true;
139
  }
140
 
141
- $r = new ReflectionMethod($this, 'getCacheFilename');
142
  if (__CLASS__ !== $r->getDeclaringClass()->getName()) {
143
- @trigger_error('The Twig_Environment::getCacheFilename method is deprecated since version 1.22 and will be removed in Twig 2.0.', E_USER_DEPRECATED);
144
 
145
  $this->bcGetCacheFilename = true;
146
  }
@@ -255,9 +285,9 @@ class Twig_Environment
255
  *
256
  * @param bool $original Whether to return the original cache option or the real cache instance
257
  *
258
- * @return Twig_CacheInterface|string|false A Twig_CacheInterface implementation,
259
- * an absolute path to the compiled templates,
260
- * or false to disable cache
261
  */
262
  public function getCache($original = true)
263
  {
@@ -267,26 +297,26 @@ class Twig_Environment
267
  /**
268
  * Sets the current cache implementation.
269
  *
270
- * @param Twig_CacheInterface|string|false $cache A Twig_CacheInterface implementation,
271
- * an absolute path to the compiled templates,
272
- * or false to disable cache
273
  */
274
  public function setCache($cache)
275
  {
276
- if (is_string($cache)) {
277
  $this->originalCache = $cache;
278
- $this->cache = new Twig_Cache_Filesystem($cache);
279
  } elseif (false === $cache) {
280
  $this->originalCache = $cache;
281
- $this->cache = new Twig_Cache_Null();
282
  } elseif (null === $cache) {
283
  @trigger_error('Using "null" as the cache strategy is deprecated since version 1.23 and will be removed in Twig 2.0.', E_USER_DEPRECATED);
284
  $this->originalCache = false;
285
- $this->cache = new Twig_Cache_Null();
286
- } elseif ($cache instanceof Twig_CacheInterface) {
287
  $this->originalCache = $this->cache = $cache;
288
  } else {
289
- throw new LogicException(sprintf('Cache can only be a string, false, or a Twig_CacheInterface implementation.'));
290
  }
291
  }
292
 
@@ -354,9 +384,9 @@ class Twig_Environment
354
  *
355
  * @return string The rendered template
356
  *
357
- * @throws Twig_Error_Loader When the template cannot be found
358
- * @throws Twig_Error_Syntax When an error occurred during compilation
359
- * @throws Twig_Error_Runtime When an error occurred during rendering
360
  */
361
  public function render($name, array $context = [])
362
  {
@@ -369,9 +399,9 @@ class Twig_Environment
369
  * @param string $name The template name
370
  * @param array $context An array of parameters to pass to the template
371
  *
372
- * @throws Twig_Error_Loader When the template cannot be found
373
- * @throws Twig_Error_Syntax When an error occurred during compilation
374
- * @throws Twig_Error_Runtime When an error occurred during rendering
375
  */
376
  public function display($name, array $context = [])
377
  {
@@ -381,25 +411,25 @@ class Twig_Environment
381
  /**
382
  * Loads a template.
383
  *
384
- * @param string|Twig_TemplateWrapper|Twig_Template $name The template name
385
  *
386
- * @throws Twig_Error_Loader When the template cannot be found
387
- * @throws Twig_Error_Runtime When a previously generated cache is corrupted
388
- * @throws Twig_Error_Syntax When an error occurred during compilation
389
  *
390
- * @return Twig_TemplateWrapper
391
  */
392
  public function load($name)
393
  {
394
- if ($name instanceof Twig_TemplateWrapper) {
395
  return $name;
396
  }
397
 
398
- if ($name instanceof Twig_Template) {
399
- return new Twig_TemplateWrapper($this, $name);
400
  }
401
 
402
- return new Twig_TemplateWrapper($this, $this->loadTemplate($name));
403
  }
404
 
405
  /**
@@ -413,9 +443,9 @@ class Twig_Environment
413
  *
414
  * @return Twig_TemplateInterface A template instance representing the given template name
415
  *
416
- * @throws Twig_Error_Loader When the template cannot be found
417
- * @throws Twig_Error_Runtime When a previously generated cache is corrupted
418
- * @throws Twig_Error_Syntax When an error occurred during compilation
419
  *
420
  * @internal
421
  */
@@ -443,8 +473,8 @@ class Twig_Environment
443
 
444
  if (!class_exists($cls, false)) {
445
  $loader = $this->getLoader();
446
- if (!$loader instanceof Twig_SourceContextLoaderInterface) {
447
- $source = new Twig_Source($loader->getSource($name), $name);
448
  } else {
449
  $source = $loader->getSourceContext($name);
450
  }
@@ -469,7 +499,7 @@ class Twig_Environment
469
  }
470
 
471
  if (!class_exists($cls, false)) {
472
- throw new Twig_Error_Runtime(sprintf('Failed to load Twig template "%s", index "%s": cache is corrupted.', $name, $index), -1, $source);
473
  }
474
  }
475
 
@@ -478,7 +508,7 @@ class Twig_Environment
478
  }
479
 
480
  if (isset($this->loading[$cls])) {
481
- throw new Twig_Error_Runtime(sprintf('Circular reference detected for Twig template "%s", path: %s.', $name, implode(' -> ', array_merge($this->loading, [$name]))));
482
  }
483
 
484
  $this->loading[$cls] = $name;
@@ -502,28 +532,28 @@ class Twig_Environment
502
  *
503
  * @param string $template The template name
504
  *
505
- * @return Twig_Template A template instance representing the given template name
506
  *
507
- * @throws Twig_Error_Loader When the template cannot be found
508
- * @throws Twig_Error_Syntax When an error occurred during compilation
509
  */
510
  public function createTemplate($template)
511
  {
512
  $name = sprintf('__string_template__%s', hash('sha256', $template, false));
513
 
514
- $loader = new Twig_Loader_Chain([
515
- new Twig_Loader_Array([$name => $template]),
516
  $current = $this->getLoader(),
517
  ]);
518
 
519
  $this->setLoader($loader);
520
  try {
521
  $template = $this->loadTemplate($name);
522
- } catch (Exception $e) {
523
  $this->setLoader($current);
524
 
525
  throw $e;
526
- } catch (Throwable $e) {
527
  $this->setLoader($current);
528
 
529
  throw $e;
@@ -549,7 +579,7 @@ class Twig_Environment
549
  {
550
  if (0 === $this->lastModifiedExtension) {
551
  foreach ($this->extensions as $extension) {
552
- $r = new ReflectionObject($extension);
553
  if (file_exists($r->getFileName()) && ($extensionTime = filemtime($r->getFileName())) > $this->lastModifiedExtension) {
554
  $this->lastModifiedExtension = $extensionTime;
555
  }
@@ -565,39 +595,38 @@ class Twig_Environment
565
  * Similar to loadTemplate() but it also accepts instances of Twig_Template and
566
  * Twig_TemplateWrapper, and an array of templates where each is tried to be loaded.
567
  *
568
- * @param string|Twig_Template|Twig_TemplateWrapper|array $names A template or an array of templates to try consecutively
569
  *
570
- * @return Twig_Template|Twig_TemplateWrapper
571
  *
572
- * @throws Twig_Error_Loader When none of the templates can be found
573
- * @throws Twig_Error_Syntax When an error occurred during compilation
574
  */
575
  public function resolveTemplate($names)
576
  {
577
- if (!is_array($names)) {
578
  $names = [$names];
579
  }
580
 
581
  foreach ($names as $name) {
582
- if ($name instanceof Twig_Template) {
583
  return $name;
584
  }
585
 
586
- if ($name instanceof Twig_TemplateWrapper) {
587
  return $name;
588
  }
589
 
590
  try {
591
  return $this->loadTemplate($name);
592
- } catch (Twig_Error_Loader $e) {
 
 
 
593
  }
594
  }
595
 
596
- if (1 === count($names)) {
597
- throw $e;
598
- }
599
-
600
- throw new Twig_Error_Loader(sprintf('Unable to find one of the following templates: "%s".', implode('", "', $names)));
601
  }
602
 
603
  /**
@@ -621,8 +650,8 @@ class Twig_Environment
621
  {
622
  @trigger_error(sprintf('The %s method is deprecated since version 1.22 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED);
623
 
624
- if (is_string($this->originalCache)) {
625
- foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->originalCache), RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
626
  if ($file->isFile()) {
627
  @unlink($file->getPathname());
628
  }
@@ -642,7 +671,7 @@ class Twig_Environment
642
  @trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), E_USER_DEPRECATED);
643
 
644
  if (null === $this->lexer) {
645
- $this->lexer = new Twig_Lexer($this);
646
  }
647
 
648
  return $this->lexer;
@@ -656,22 +685,22 @@ class Twig_Environment
656
  /**
657
  * Tokenizes a source code.
658
  *
659
- * @param string|Twig_Source $source The template source code
660
- * @param string $name The template name (deprecated)
661
  *
662
- * @return Twig_TokenStream
663
  *
664
- * @throws Twig_Error_Syntax When the code is syntactically wrong
665
  */
666
  public function tokenize($source, $name = null)
667
  {
668
- if (!$source instanceof Twig_Source) {
669
- @trigger_error(sprintf('Passing a string as the $source argument of %s() is deprecated since version 1.27. Pass a Twig_Source instance instead.', __METHOD__), E_USER_DEPRECATED);
670
- $source = new Twig_Source($source, $name);
671
  }
672
 
673
  if (null === $this->lexer) {
674
- $this->lexer = new Twig_Lexer($this);
675
  }
676
 
677
  return $this->lexer->tokenize($source);
@@ -689,7 +718,7 @@ class Twig_Environment
689
  @trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), E_USER_DEPRECATED);
690
 
691
  if (null === $this->parser) {
692
- $this->parser = new Twig_Parser($this);
693
  }
694
 
695
  return $this->parser;
@@ -703,14 +732,14 @@ class Twig_Environment
703
  /**
704
  * Converts a token stream to a node tree.
705
  *
706
- * @return Twig_Node_Module
707
  *
708
- * @throws Twig_Error_Syntax When the token stream is syntactically or semantically wrong
709
  */
710
- public function parse(Twig_TokenStream $stream)
711
  {
712
  if (null === $this->parser) {
713
- $this->parser = new Twig_Parser($this);
714
  }
715
 
716
  return $this->parser->parse($stream);
@@ -728,7 +757,7 @@ class Twig_Environment
728
  @trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), E_USER_DEPRECATED);
729
 
730
  if (null === $this->compiler) {
731
- $this->compiler = new Twig_Compiler($this);
732
  }
733
 
734
  return $this->compiler;
@@ -747,7 +776,7 @@ class Twig_Environment
747
  public function compile(Twig_NodeInterface $node)
748
  {
749
  if (null === $this->compiler) {
750
- $this->compiler = new Twig_Compiler($this);
751
  }
752
 
753
  return $this->compiler->compile($node)->getSource();
@@ -756,34 +785,34 @@ class Twig_Environment
756
  /**
757
  * Compiles a template source code.
758
  *
759
- * @param string|Twig_Source $source The template source code
760
- * @param string $name The template name (deprecated)
761
  *
762
  * @return string The compiled PHP source code
763
  *
764
- * @throws Twig_Error_Syntax When there was an error during tokenizing, parsing or compiling
765
  */
766
  public function compileSource($source, $name = null)
767
  {
768
- if (!$source instanceof Twig_Source) {
769
- @trigger_error(sprintf('Passing a string as the $source argument of %s() is deprecated since version 1.27. Pass a Twig_Source instance instead.', __METHOD__), E_USER_DEPRECATED);
770
- $source = new Twig_Source($source, $name);
771
  }
772
 
773
  try {
774
  return $this->compile($this->parse($this->tokenize($source)));
775
- } catch (Twig_Error $e) {
776
  $e->setSourceContext($source);
777
  throw $e;
778
- } catch (Exception $e) {
779
- throw new Twig_Error_Syntax(sprintf('An exception has been thrown during the compilation of a template ("%s").', $e->getMessage()), -1, $source, $e);
780
  }
781
  }
782
 
783
- public function setLoader(Twig_LoaderInterface $loader)
784
  {
785
- if (!$loader instanceof Twig_SourceContextLoaderInterface && 0 !== strpos(get_class($loader), 'Mock_')) {
786
- @trigger_error(sprintf('Twig loader "%s" should implement Twig_SourceContextLoaderInterface since version 1.27.', get_class($loader)), E_USER_DEPRECATED);
787
  }
788
 
789
  $this->loader = $loader;
@@ -792,12 +821,12 @@ class Twig_Environment
792
  /**
793
  * Gets the Loader instance.
794
  *
795
- * @return Twig_LoaderInterface
796
  */
797
  public function getLoader()
798
  {
799
  if (null === $this->loader) {
800
- throw new LogicException('You must set a loader first.');
801
  }
802
 
803
  return $this->loader;
@@ -833,11 +862,11 @@ class Twig_Environment
833
  $this->runtimeInitialized = true;
834
 
835
  foreach ($this->getExtensions() as $name => $extension) {
836
- if (!$extension instanceof Twig_Extension_InitRuntimeInterface) {
837
- $m = new ReflectionMethod($extension, 'initRuntime');
838
 
839
  if ('Twig_Extension' !== $m->getDeclaringClass()->getName()) {
840
- @trigger_error(sprintf('Defining the initRuntime() method in the "%s" extension is deprecated since version 1.23. Use the `needs_environment` option to get the Twig_Environment instance in filters, functions, or tests; or explicitly implement Twig_Extension_InitRuntimeInterface if needed (not recommended).', $name), E_USER_DEPRECATED);
841
  }
842
  }
843
 
@@ -857,12 +886,12 @@ class Twig_Environment
857
  $class = ltrim($class, '\\');
858
  if (!isset($this->extensionsByClass[$class]) && class_exists($class, false)) {
859
  // For BC/FC with namespaced aliases
860
- $class = new ReflectionClass($class);
861
  $class = $class->name;
862
  }
863
 
864
  if (isset($this->extensions[$class])) {
865
- if ($class !== get_class($this->extensions[$class])) {
866
  @trigger_error(sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), E_USER_DEPRECATED);
867
  }
868
 
@@ -875,7 +904,7 @@ class Twig_Environment
875
  /**
876
  * Adds a runtime loader.
877
  */
878
- public function addRuntimeLoader(Twig_RuntimeLoaderInterface $loader)
879
  {
880
  $this->runtimeLoaders[] = $loader;
881
  }
@@ -885,19 +914,19 @@ class Twig_Environment
885
  *
886
  * @param string $class The extension class name
887
  *
888
- * @return Twig_ExtensionInterface
889
  */
890
  public function getExtension($class)
891
  {
892
  $class = ltrim($class, '\\');
893
  if (!isset($this->extensionsByClass[$class]) && class_exists($class, false)) {
894
  // For BC/FC with namespaced aliases
895
- $class = new ReflectionClass($class);
896
  $class = $class->name;
897
  }
898
 
899
  if (isset($this->extensions[$class])) {
900
- if ($class !== get_class($this->extensions[$class])) {
901
  @trigger_error(sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), E_USER_DEPRECATED);
902
  }
903
 
@@ -905,7 +934,7 @@ class Twig_Environment
905
  }
906
 
907
  if (!isset($this->extensionsByClass[$class])) {
908
- throw new Twig_Error_Runtime(sprintf('The "%s" extension is not enabled.', $class));
909
  }
910
 
911
  return $this->extensionsByClass[$class];
@@ -918,7 +947,7 @@ class Twig_Environment
918
  *
919
  * @return object The runtime implementation
920
  *
921
- * @throws Twig_Error_Runtime When the template cannot be found
922
  */
923
  public function getRuntime($class)
924
  {
@@ -932,16 +961,16 @@ class Twig_Environment
932
  }
933
  }
934
 
935
- throw new Twig_Error_Runtime(sprintf('Unable to load the "%s" runtime.', $class));
936
  }
937
 
938
- public function addExtension(Twig_ExtensionInterface $extension)
939
  {
940
  if ($this->extensionInitialized) {
941
- throw new LogicException(sprintf('Unable to register extension "%s" as extensions have already been initialized.', $extension->getName()));
942
  }
943
 
944
- $class = get_class($extension);
945
  if ($class !== $extension->getName()) {
946
  if (isset($this->extensions[$extension->getName()])) {
947
  unset($this->extensions[$extension->getName()], $this->extensionsByClass[$class]);
@@ -969,18 +998,18 @@ class Twig_Environment
969
  @trigger_error(sprintf('The %s method is deprecated since version 1.12 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED);
970
 
971
  if ($this->extensionInitialized) {
972
- throw new LogicException(sprintf('Unable to remove extension "%s" as extensions have already been initialized.', $name));
973
  }
974
 
975
  $class = ltrim($name, '\\');
976
  if (!isset($this->extensionsByClass[$class]) && class_exists($class, false)) {
977
  // For BC/FC with namespaced aliases
978
- $class = new ReflectionClass($class);
979
  $class = $class->name;
980
  }
981
 
982
  if (isset($this->extensions[$class])) {
983
- if ($class !== get_class($this->extensions[$class])) {
984
  @trigger_error(sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), E_USER_DEPRECATED);
985
  }
986
 
@@ -1006,17 +1035,17 @@ class Twig_Environment
1006
  /**
1007
  * Returns all registered extensions.
1008
  *
1009
- * @return Twig_ExtensionInterface[] An array of extensions (keys are for internal usage only and should not be relied on)
1010
  */
1011
  public function getExtensions()
1012
  {
1013
  return $this->extensions;
1014
  }
1015
 
1016
- public function addTokenParser(Twig_TokenParserInterface $parser)
1017
  {
1018
  if ($this->extensionInitialized) {
1019
- throw new LogicException('Unable to add a token parser as extensions have already been initialized.');
1020
  }
1021
 
1022
  $this->staging->addTokenParser($parser);
@@ -1043,7 +1072,7 @@ class Twig_Environment
1043
  *
1044
  * Be warned that this method cannot return tags defined by Twig_TokenParserBrokerInterface classes.
1045
  *
1046
- * @return Twig_TokenParserInterface[]
1047
  *
1048
  * @internal
1049
  */
@@ -1051,7 +1080,7 @@ class Twig_Environment
1051
  {
1052
  $tags = [];
1053
  foreach ($this->getTokenParsers()->getParsers() as $parser) {
1054
- if ($parser instanceof Twig_TokenParserInterface) {
1055
  $tags[$parser->getTag()] = $parser;
1056
  }
1057
  }
@@ -1059,10 +1088,10 @@ class Twig_Environment
1059
  return $tags;
1060
  }
1061
 
1062
- public function addNodeVisitor(Twig_NodeVisitorInterface $visitor)
1063
  {
1064
  if ($this->extensionInitialized) {
1065
- throw new LogicException('Unable to add a node visitor as extensions have already been initialized.');
1066
  }
1067
 
1068
  $this->staging->addNodeVisitor($visitor);
@@ -1071,7 +1100,7 @@ class Twig_Environment
1071
  /**
1072
  * Gets the registered Node Visitors.
1073
  *
1074
- * @return Twig_NodeVisitorInterface[]
1075
  *
1076
  * @internal
1077
  */
@@ -1087,16 +1116,16 @@ class Twig_Environment
1087
  /**
1088
  * Registers a Filter.
1089
  *
1090
- * @param string|Twig_SimpleFilter $name The filter name or a Twig_SimpleFilter instance
1091
- * @param Twig_FilterInterface|Twig_SimpleFilter $filter
1092
  */
1093
  public function addFilter($name, $filter = null)
1094
  {
1095
- if (!$name instanceof Twig_SimpleFilter && !($filter instanceof Twig_SimpleFilter || $filter instanceof Twig_FilterInterface)) {
1096
- throw new LogicException('A filter must be an instance of Twig_FilterInterface or Twig_SimpleFilter.');
1097
  }
1098
 
1099
- if ($name instanceof Twig_SimpleFilter) {
1100
  $filter = $name;
1101
  $name = $filter->getName();
1102
  } else {
@@ -1104,7 +1133,7 @@ class Twig_Environment
1104
  }
1105
 
1106
  if ($this->extensionInitialized) {
1107
- throw new LogicException(sprintf('Unable to add filter "%s" as extensions have already been initialized.', $name));
1108
  }
1109
 
1110
  $this->staging->addFilter($name, $filter);
@@ -1146,7 +1175,7 @@ class Twig_Environment
1146
  }
1147
 
1148
  foreach ($this->filterCallbacks as $callback) {
1149
- if (false !== $filter = call_user_func($callback, $name)) {
1150
  return $filter;
1151
  }
1152
  }
@@ -1182,16 +1211,16 @@ class Twig_Environment
1182
  /**
1183
  * Registers a Test.
1184
  *
1185
- * @param string|Twig_SimpleTest $name The test name or a Twig_SimpleTest instance
1186
- * @param Twig_TestInterface|Twig_SimpleTest $test A Twig_TestInterface instance or a Twig_SimpleTest instance
1187
  */
1188
  public function addTest($name, $test = null)
1189
  {
1190
- if (!$name instanceof Twig_SimpleTest && !($test instanceof Twig_SimpleTest || $test instanceof Twig_TestInterface)) {
1191
- throw new LogicException('A test must be an instance of Twig_TestInterface or Twig_SimpleTest.');
1192
  }
1193
 
1194
- if ($name instanceof Twig_SimpleTest) {
1195
  $test = $name;
1196
  $name = $test->getName();
1197
  } else {
@@ -1199,7 +1228,7 @@ class Twig_Environment
1199
  }
1200
 
1201
  if ($this->extensionInitialized) {
1202
- throw new LogicException(sprintf('Unable to add test "%s" as extensions have already been initialized.', $name));
1203
  }
1204
 
1205
  $this->staging->addTest($name, $test);
@@ -1259,16 +1288,16 @@ class Twig_Environment
1259
  /**
1260
  * Registers a Function.
1261
  *
1262
- * @param string|Twig_SimpleFunction $name The function name or a Twig_SimpleFunction instance
1263
- * @param Twig_FunctionInterface|Twig_SimpleFunction $function
1264
  */
1265
  public function addFunction($name, $function = null)
1266
  {
1267
- if (!$name instanceof Twig_SimpleFunction && !($function instanceof Twig_SimpleFunction || $function instanceof Twig_FunctionInterface)) {
1268
- throw new LogicException('A function must be an instance of Twig_FunctionInterface or Twig_SimpleFunction.');
1269
  }
1270
 
1271
- if ($name instanceof Twig_SimpleFunction) {
1272
  $function = $name;
1273
  $name = $function->getName();
1274
  } else {
@@ -1276,7 +1305,7 @@ class Twig_Environment
1276
  }
1277
 
1278
  if ($this->extensionInitialized) {
1279
- throw new LogicException(sprintf('Unable to add function "%s" as extensions have already been initialized.', $name));
1280
  }
1281
 
1282
  $this->staging->addFunction($name, $function);
@@ -1318,7 +1347,7 @@ class Twig_Environment
1318
  }
1319
 
1320
  foreach ($this->functionCallbacks as $callback) {
1321
- if (false !== $function = call_user_func($callback, $name)) {
1322
  return $function;
1323
  }
1324
  }
@@ -1367,10 +1396,10 @@ class Twig_Environment
1367
  $this->globals = $this->initGlobals();
1368
  }
1369
 
1370
- if (!array_key_exists($name, $this->globals)) {
1371
  // The deprecation notice must be turned into the following exception in Twig 2.0
1372
  @trigger_error(sprintf('Registering global variable "%s" at runtime or when the extensions have already been initialized is deprecated since version 1.21.', $name), E_USER_DEPRECATED);
1373
- //throw new LogicException(sprintf('Unable to add global "%s" as the runtime or the extensions have already been initialized.', $name));
1374
  }
1375
  }
1376
 
@@ -1414,7 +1443,7 @@ class Twig_Environment
1414
  // we don't use array_merge as the context being generally
1415
  // bigger than globals, this code is faster.
1416
  foreach ($this->getGlobals() as $key => $value) {
1417
- if (!array_key_exists($key, $context)) {
1418
  $context[$key] = $value;
1419
  }
1420
  }
@@ -1461,7 +1490,7 @@ class Twig_Environment
1461
  {
1462
  @trigger_error(sprintf('The %s method is deprecated since version 1.23 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED);
1463
 
1464
- return Twig_Error_Syntax::computeAlternatives($name, $items);
1465
  }
1466
 
1467
  /**
@@ -1471,17 +1500,17 @@ class Twig_Environment
1471
  {
1472
  $globals = [];
1473
  foreach ($this->extensions as $name => $extension) {
1474
- if (!$extension instanceof Twig_Extension_GlobalsInterface) {
1475
- $m = new ReflectionMethod($extension, 'getGlobals');
1476
 
1477
  if ('Twig_Extension' !== $m->getDeclaringClass()->getName()) {
1478
- @trigger_error(sprintf('Defining the getGlobals() method in the "%s" extension without explicitly implementing Twig_Extension_GlobalsInterface is deprecated since version 1.23.', $name), E_USER_DEPRECATED);
1479
  }
1480
  }
1481
 
1482
  $extGlob = $extension->getGlobals();
1483
- if (!is_array($extGlob)) {
1484
- throw new UnexpectedValueException(sprintf('"%s::getGlobals()" must return an array of globals.', get_class($extension)));
1485
  }
1486
 
1487
  $globals[] = $extGlob;
@@ -1489,7 +1518,7 @@ class Twig_Environment
1489
 
1490
  $globals[] = $this->staging->getGlobals();
1491
 
1492
- return call_user_func_array('array_merge', $globals);
1493
  }
1494
 
1495
  /**
@@ -1520,14 +1549,14 @@ class Twig_Environment
1520
  /**
1521
  * @internal
1522
  */
1523
- protected function initExtension(Twig_ExtensionInterface $extension)
1524
  {
1525
  // filters
1526
  foreach ($extension->getFilters() as $name => $filter) {
1527
- if ($filter instanceof Twig_SimpleFilter) {
1528
  $name = $filter->getName();
1529
  } else {
1530
- @trigger_error(sprintf('Using an instance of "%s" for filter "%s" is deprecated since version 1.21. Use Twig_SimpleFilter instead.', get_class($filter), $name), E_USER_DEPRECATED);
1531
  }
1532
 
1533
  $this->filters[$name] = $filter;
@@ -1535,10 +1564,10 @@ class Twig_Environment
1535
 
1536
  // functions
1537
  foreach ($extension->getFunctions() as $name => $function) {
1538
- if ($function instanceof Twig_SimpleFunction) {
1539
  $name = $function->getName();
1540
  } else {
1541
- @trigger_error(sprintf('Using an instance of "%s" for function "%s" is deprecated since version 1.21. Use Twig_SimpleFunction instead.', get_class($function), $name), E_USER_DEPRECATED);
1542
  }
1543
 
1544
  $this->functions[$name] = $function;
@@ -1546,10 +1575,10 @@ class Twig_Environment
1546
 
1547
  // tests
1548
  foreach ($extension->getTests() as $name => $test) {
1549
- if ($test instanceof Twig_SimpleTest) {
1550
  $name = $test->getName();
1551
  } else {
1552
- @trigger_error(sprintf('Using an instance of "%s" for test "%s" is deprecated since version 1.21. Use Twig_SimpleTest instead.', get_class($test), $name), E_USER_DEPRECATED);
1553
  }
1554
 
1555
  $this->tests[$name] = $test;
@@ -1557,14 +1586,14 @@ class Twig_Environment
1557
 
1558
  // token parsers
1559
  foreach ($extension->getTokenParsers() as $parser) {
1560
- if ($parser instanceof Twig_TokenParserInterface) {
1561
  $this->parsers->addTokenParser($parser);
1562
  } elseif ($parser instanceof Twig_TokenParserBrokerInterface) {
1563
  @trigger_error('Registering a Twig_TokenParserBrokerInterface instance is deprecated since version 1.21.', E_USER_DEPRECATED);
1564
 
1565
  $this->parsers->addTokenParserBroker($parser);
1566
  } else {
1567
- throw new LogicException('getTokenParsers() must return an array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances.');
1568
  }
1569
  }
1570
 
@@ -1575,12 +1604,12 @@ class Twig_Environment
1575
 
1576
  // operators
1577
  if ($operators = $extension->getOperators()) {
1578
- if (!is_array($operators)) {
1579
- throw new InvalidArgumentException(sprintf('"%s::getOperators()" must return an array with operators, got "%s".', get_class($extension), is_object($operators) ? get_class($operators) : gettype($operators).(is_resource($operators) ? '' : '#'.$operators)));
1580
  }
1581
 
1582
- if (2 !== count($operators)) {
1583
- throw new InvalidArgumentException(sprintf('"%s::getOperators()" must return an array of 2 elements, got %d.', get_class($extension), count($operators)));
1584
  }
1585
 
1586
  $this->unaryOperators = array_merge($this->unaryOperators, $operators[0]);
@@ -1601,7 +1630,7 @@ class Twig_Environment
1601
  $hashParts = array_merge(
1602
  array_keys($this->extensions),
1603
  [
1604
- (int) function_exists('twig_template_get_attributes'),
1605
  PHP_MAJOR_VERSION,
1606
  PHP_MINOR_VERSION,
1607
  self::VERSION,
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Cache\CacheInterface;
13
+ use Twig\Cache\FilesystemCache;
14
+ use Twig\Cache\NullCache;
15
+ use Twig\Compiler;
16
+ use Twig\Error\Error;
17
+ use Twig\Error\LoaderError;
18
+ use Twig\Error\RuntimeError;
19
+ use Twig\Error\SyntaxError;
20
+ use Twig\Extension\CoreExtension;
21
+ use Twig\Extension\EscaperExtension;
22
+ use Twig\Extension\ExtensionInterface;
23
+ use Twig\Extension\GlobalsInterface;
24
+ use Twig\Extension\InitRuntimeInterface;
25
+ use Twig\Extension\OptimizerExtension;
26
+ use Twig\Extension\StagingExtension;
27
+ use Twig\Lexer;
28
+ use Twig\Loader\ArrayLoader;
29
+ use Twig\Loader\ChainLoader;
30
+ use Twig\Loader\LoaderInterface;
31
+ use Twig\Loader\SourceContextLoaderInterface;
32
+ use Twig\Node\ModuleNode;
33
+ use Twig\NodeVisitor\NodeVisitorInterface;
34
+ use Twig\Parser;
35
+ use Twig\RuntimeLoader\RuntimeLoaderInterface;
36
+ use Twig\Source;
37
+ use Twig\Template;
38
+ use Twig\TemplateWrapper;
39
+ use Twig\TokenParser\TokenParserInterface;
40
+ use Twig\TokenStream;
41
+ use Twig\TwigFilter;
42
+ use Twig\TwigFunction;
43
+ use Twig\TwigTest;
44
+
45
  /**
46
  * Stores the Twig configuration.
47
  *
49
  */
50
  class Twig_Environment
51
  {
52
+ const VERSION = '1.38.0-DEV';
53
+ const VERSION_ID = 13800;
54
  const MAJOR_VERSION = 1;
55
+ const MINOR_VERSION = 38;
56
+ const RELEASE_VERSION = 0;
57
  const EXTRA_VERSION = 'DEV';
58
 
59
  protected $charset;
127
  * * optimizations: A flag that indicates which optimizations to apply
128
  * (default to -1 which means that all optimizations are enabled;
129
  * set it to 0 to disable).
 
 
 
130
  */
131
+ public function __construct(LoaderInterface $loader = null, $options = [])
132
  {
133
  if (null !== $loader) {
134
  $this->setLoader($loader);
135
  } else {
136
+ @trigger_error('Not passing a "Twig\Lodaer\LoaderInterface" as the first constructor argument of "Twig\Environment" is deprecated since version 1.21.', E_USER_DEPRECATED);
137
  }
138
 
139
  $options = array_merge([
140
  'debug' => false,
141
  'charset' => 'UTF-8',
142
+ 'base_template_class' => '\Twig\Template',
143
  'strict_variables' => false,
144
  'autoescape' => 'html',
145
  'cache' => false,
154
  $this->strictVariables = (bool) $options['strict_variables'];
155
  $this->setCache($options['cache']);
156
 
157
+ $this->addExtension(new CoreExtension());
158
+ $this->addExtension(new EscaperExtension($options['autoescape']));
159
+ $this->addExtension(new OptimizerExtension($options['optimizations']));
160
+ $this->staging = new StagingExtension();
161
 
162
  // For BC
163
+ if (\is_string($this->originalCache)) {
164
+ $r = new \ReflectionMethod($this, 'writeCacheFile');
165
  if (__CLASS__ !== $r->getDeclaringClass()->getName()) {
166
+ @trigger_error('The Twig\Environment::writeCacheFile method is deprecated since version 1.22 and will be removed in Twig 2.0.', E_USER_DEPRECATED);
167
 
168
  $this->bcWriteCacheFile = true;
169
  }
170
 
171
+ $r = new \ReflectionMethod($this, 'getCacheFilename');
172
  if (__CLASS__ !== $r->getDeclaringClass()->getName()) {
173
+ @trigger_error('The Twig\Environment::getCacheFilename method is deprecated since version 1.22 and will be removed in Twig 2.0.', E_USER_DEPRECATED);
174
 
175
  $this->bcGetCacheFilename = true;
176
  }
285
  *
286
  * @param bool $original Whether to return the original cache option or the real cache instance
287
  *
288
+ * @return CacheInterface|string|false A Twig_CacheInterface implementation,
289
+ * an absolute path to the compiled templates,
290
+ * or false to disable cache
291
  */
292
  public function getCache($original = true)
293
  {
297
  /**
298
  * Sets the current cache implementation.
299
  *
300
+ * @param CacheInterface|string|false $cache A Twig_CacheInterface implementation,
301
+ * an absolute path to the compiled templates,
302
+ * or false to disable cache
303
  */
304
  public function setCache($cache)
305
  {
306
+ if (\is_string($cache)) {
307
  $this->originalCache = $cache;
308
+ $this->cache = new FilesystemCache($cache);
309
  } elseif (false === $cache) {
310
  $this->originalCache = $cache;
311
+ $this->cache = new NullCache();
312
  } elseif (null === $cache) {
313
  @trigger_error('Using "null" as the cache strategy is deprecated since version 1.23 and will be removed in Twig 2.0.', E_USER_DEPRECATED);
314
  $this->originalCache = false;
315
+ $this->cache = new NullCache();
316
+ } elseif ($cache instanceof CacheInterface) {
317
  $this->originalCache = $this->cache = $cache;
318
  } else {
319
+ throw new \LogicException(sprintf('Cache can only be a string, false, or a Twig_CacheInterface implementation.'));
320
  }
321
  }
322
 
384
  *
385
  * @return string The rendered template
386
  *
387
+ * @throws LoaderError When the template cannot be found
388
+ * @throws SyntaxError When an error occurred during compilation
389
+ * @throws RuntimeError When an error occurred during rendering
390
  */
391
  public function render($name, array $context = [])
392
  {
399
  * @param string $name The template name
400
  * @param array $context An array of parameters to pass to the template
401
  *
402
+ * @throws LoaderError When the template cannot be found
403
+ * @throws SyntaxError When an error occurred during compilation
404
+ * @throws RuntimeError When an error occurred during rendering
405
  */
406
  public function display($name, array $context = [])
407
  {
411
  /**
412
  * Loads a template.
413
  *
414
+ * @param string|TemplateWrapper|\Twig\Template $name The template name
415
  *
416
+ * @throws LoaderError When the template cannot be found
417
+ * @throws RuntimeError When a previously generated cache is corrupted
418
+ * @throws SyntaxError When an error occurred during compilation
419
  *
420
+ * @return TemplateWrapper
421
  */
422
  public function load($name)
423
  {
424
+ if ($name instanceof TemplateWrapper) {
425
  return $name;
426
  }
427
 
428
+ if ($name instanceof Template) {
429
+ return new TemplateWrapper($this, $name);
430
  }
431
 
432
+ return new TemplateWrapper($this, $this->loadTemplate($name));
433
  }
434
 
435
  /**
443
  *
444
  * @return Twig_TemplateInterface A template instance representing the given template name
445
  *
446
+ * @throws LoaderError When the template cannot be found
447
+ * @throws RuntimeError When a previously generated cache is corrupted
448
+ * @throws SyntaxError When an error occurred during compilation
449
  *
450
  * @internal
451
  */
473
 
474
  if (!class_exists($cls, false)) {
475
  $loader = $this->getLoader();
476
+ if (!$loader instanceof SourceContextLoaderInterface) {
477
+ $source = new Source($loader->getSource($name), $name);
478
  } else {
479
  $source = $loader->getSourceContext($name);
480
  }
499
  }
500
 
501
  if (!class_exists($cls, false)) {
502
+ throw new RuntimeError(sprintf('Failed to load Twig template "%s", index "%s": cache is corrupted.', $name, $index), -1, $source);
503
  }
504
  }
505
 
508
  }
509
 
510
  if (isset($this->loading[$cls])) {
511
+ throw new RuntimeError(sprintf('Circular reference detected for Twig template "%s", path: %s.', $name, implode(' -> ', array_merge($this->loading, [$name]))));
512
  }
513
 
514
  $this->loading[$cls] = $name;
532
  *
533
  * @param string $template The template name
534
  *
535
+ * @return Template A template instance representing the given template name
536
  *
537
+ * @throws LoaderError When the template cannot be found
538
+ * @throws SyntaxError When an error occurred during compilation
539
  */
540
  public function createTemplate($template)
541
  {
542
  $name = sprintf('__string_template__%s', hash('sha256', $template, false));
543
 
544
+ $loader = new ChainLoader([
545
+ new ArrayLoader([$name => $template]),
546
  $current = $this->getLoader(),
547
  ]);
548
 
549
  $this->setLoader($loader);
550
  try {
551
  $template = $this->loadTemplate($name);
552
+ } catch (\Exception $e) {
553
  $this->setLoader($current);
554
 
555
  throw $e;
556
+ } catch (\Throwable $e) {
557
  $this->setLoader($current);
558
 
559
  throw $e;
579
  {
580
  if (0 === $this->lastModifiedExtension) {
581
  foreach ($this->extensions as $extension) {
582
+ $r = new \ReflectionObject($extension);
583
  if (file_exists($r->getFileName()) && ($extensionTime = filemtime($r->getFileName())) > $this->lastModifiedExtension) {
584
  $this->lastModifiedExtension = $extensionTime;
585
  }
595
  * Similar to loadTemplate() but it also accepts instances of Twig_Template and
596
  * Twig_TemplateWrapper, and an array of templates where each is tried to be loaded.
597
  *
598
+ * @param string|Template|\Twig\TemplateWrapper|array $names A template or an array of templates to try consecutively
599
  *
600
+ * @return Template|Twig_TemplateWrapper
601
  *
602
+ * @throws LoaderError When none of the templates can be found
603
+ * @throws SyntaxError When an error occurred during compilation
604
  */
605
  public function resolveTemplate($names)
606
  {
607
+ if (!\is_array($names)) {
608
  $names = [$names];
609
  }
610
 
611
  foreach ($names as $name) {
612
+ if ($name instanceof Template) {
613
  return $name;
614
  }
615
 
616
+ if ($name instanceof TemplateWrapper) {
617
  return $name;
618
  }
619
 
620
  try {
621
  return $this->loadTemplate($name);
622
+ } catch (LoaderError $e) {
623
+ if (1 === \count($names)) {
624
+ throw $e;
625
+ }
626
  }
627
  }
628
 
629
+ throw new LoaderError(sprintf('Unable to find one of the following templates: "%s".', implode('", "', $names)));
 
 
 
 
630
  }
631
 
632
  /**
650
  {
651
  @trigger_error(sprintf('The %s method is deprecated since version 1.22 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED);
652
 
653
+ if (\is_string($this->originalCache)) {
654
+ foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->originalCache), \RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
655
  if ($file->isFile()) {
656
  @unlink($file->getPathname());
657
  }
671
  @trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), E_USER_DEPRECATED);
672
 
673
  if (null === $this->lexer) {
674
+ $this->lexer = new Lexer($this);
675
  }
676
 
677
  return $this->lexer;
685
  /**
686
  * Tokenizes a source code.
687
  *
688
+ * @param string|Source $source The template source code
689
+ * @param string $name The template name (deprecated)
690
  *
691
+ * @return TokenStream
692
  *
693
+ * @throws SyntaxError When the code is syntactically wrong
694
  */
695
  public function tokenize($source, $name = null)
696
  {
697
+ if (!$source instanceof Source) {
698
+ @trigger_error(sprintf('Passing a string as the $source argument of %s() is deprecated since version 1.27. Pass a Twig\Source instance instead.', __METHOD__), E_USER_DEPRECATED);
699
+ $source = new Source($source, $name);
700
  }
701
 
702
  if (null === $this->lexer) {
703
+ $this->lexer = new Lexer($this);
704
  }
705
 
706
  return $this->lexer->tokenize($source);
718
  @trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), E_USER_DEPRECATED);
719
 
720
  if (null === $this->parser) {
721
+ $this->parser = new Parser($this);
722
  }
723
 
724
  return $this->parser;
732
  /**
733
  * Converts a token stream to a node tree.
734
  *
735
+ * @return ModuleNode
736
  *
737
+ * @throws SyntaxError When the token stream is syntactically or semantically wrong
738
  */
739
+ public function parse(TokenStream $stream)
740
  {
741
  if (null === $this->parser) {
742
+ $this->parser = new Parser($this);
743
  }
744
 
745
  return $this->parser->parse($stream);
757
  @trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), E_USER_DEPRECATED);
758
 
759
  if (null === $this->compiler) {
760
+ $this->compiler = new Compiler($this);
761
  }
762
 
763
  return $this->compiler;
776
  public function compile(Twig_NodeInterface $node)
777
  {
778
  if (null === $this->compiler) {
779
+ $this->compiler = new Compiler($this);
780
  }
781
 
782
  return $this->compiler->compile($node)->getSource();
785
  /**
786
  * Compiles a template source code.
787
  *
788
+ * @param string|Source $source The template source code
789
+ * @param string $name The template name (deprecated)
790
  *
791
  * @return string The compiled PHP source code
792
  *
793
+ * @throws SyntaxError When there was an error during tokenizing, parsing or compiling
794
  */
795
  public function compileSource($source, $name = null)
796
  {
797
+ if (!$source instanceof Source) {
798
+ @trigger_error(sprintf('Passing a string as the $source argument of %s() is deprecated since version 1.27. Pass a Twig\Source instance instead.', __METHOD__), E_USER_DEPRECATED);
799
+ $source = new Source($source, $name);
800
  }
801
 
802
  try {
803
  return $this->compile($this->parse($this->tokenize($source)));
804
+ } catch (Error $e) {
805
  $e->setSourceContext($source);
806
  throw $e;
807
+ } catch (\Exception $e) {
808
+ throw new SyntaxError(sprintf('An exception has been thrown during the compilation of a template ("%s").', $e->getMessage()), -1, $source, $e);
809
  }
810
  }
811
 
812
+ public function setLoader(LoaderInterface $loader)
813
  {
814
+ if (!$loader instanceof SourceContextLoaderInterface && 0 !== strpos(\get_class($loader), 'Mock_')) {
815
+ @trigger_error(sprintf('Twig loader "%s" should implement Twig_SourceContextLoaderInterface since version 1.27.', \get_class($loader)), E_USER_DEPRECATED);
816
  }
817
 
818
  $this->loader = $loader;
821
  /**
822
  * Gets the Loader instance.
823
  *
824
+ * @return LoaderInterface
825
  */
826
  public function getLoader()
827
  {
828
  if (null === $this->loader) {
829
+ throw new \LogicException('You must set a loader first.');
830
  }
831
 
832
  return $this->loader;
862
  $this->runtimeInitialized = true;
863
 
864
  foreach ($this->getExtensions() as $name => $extension) {
865
+ if (!$extension instanceof InitRuntimeInterface) {
866
+ $m = new \ReflectionMethod($extension, 'initRuntime');
867
 
868
  if ('Twig_Extension' !== $m->getDeclaringClass()->getName()) {
869
+ @trigger_error(sprintf('Defining the initRuntime() method in the "%s" extension is deprecated since version 1.23. Use the `needs_environment` option to get the Twig_Environment instance in filters, functions, or tests; or explicitly implement Twig\Extension\InitRuntimeInterface if needed (not recommended).', $name), E_USER_DEPRECATED);
870
  }
871
  }
872
 
886
  $class = ltrim($class, '\\');
887
  if (!isset($this->extensionsByClass[$class]) && class_exists($class, false)) {
888
  // For BC/FC with namespaced aliases
889
+ $class = new \ReflectionClass($class);
890
  $class = $class->name;
891
  }
892
 
893
  if (isset($this->extensions[$class])) {
894
+ if ($class !== \get_class($this->extensions[$class])) {
895
  @trigger_error(sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), E_USER_DEPRECATED);
896
  }
897
 
904
  /**
905
  * Adds a runtime loader.
906
  */
907
+ public function addRuntimeLoader(RuntimeLoaderInterface $loader)
908
  {
909
  $this->runtimeLoaders[] = $loader;
910
  }
914
  *
915
  * @param string $class The extension class name
916
  *
917
+ * @return ExtensionInterface
918
  */
919
  public function getExtension($class)
920
  {
921
  $class = ltrim($class, '\\');
922
  if (!isset($this->extensionsByClass[$class]) && class_exists($class, false)) {
923
  // For BC/FC with namespaced aliases
924
+ $class = new \ReflectionClass($class);
925
  $class = $class->name;
926
  }
927
 
928
  if (isset($this->extensions[$class])) {
929
+ if ($class !== \get_class($this->extensions[$class])) {
930
  @trigger_error(sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), E_USER_DEPRECATED);
931
  }
932
 
934
  }
935
 
936
  if (!isset($this->extensionsByClass[$class])) {
937
+ throw new RuntimeError(sprintf('The "%s" extension is not enabled.', $class));
938
  }
939
 
940
  return $this->extensionsByClass[$class];
947
  *
948
  * @return object The runtime implementation
949
  *
950
+ * @throws RuntimeError When the template cannot be found
951
  */
952
  public function getRuntime($class)
953
  {
961
  }
962
  }
963
 
964
+ throw new RuntimeError(sprintf('Unable to load the "%s" runtime.', $class));
965
  }
966
 
967
+ public function addExtension(ExtensionInterface $extension)
968
  {
969
  if ($this->extensionInitialized) {
970
+ throw new \LogicException(sprintf('Unable to register extension "%s" as extensions have already been initialized.', $extension->getName()));
971
  }
972
 
973
+ $class = \get_class($extension);
974
  if ($class !== $extension->getName()) {
975
  if (isset($this->extensions[$extension->getName()])) {
976
  unset($this->extensions[$extension->getName()], $this->extensionsByClass[$class]);
998
  @trigger_error(sprintf('The %s method is deprecated since version 1.12 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED);
999
 
1000
  if ($this->extensionInitialized) {
1001
+ throw new \LogicException(sprintf('Unable to remove extension "%s" as extensions have already been initialized.', $name));
1002
  }
1003
 
1004
  $class = ltrim($name, '\\');
1005
  if (!isset($this->extensionsByClass[$class]) && class_exists($class, false)) {
1006
  // For BC/FC with namespaced aliases
1007
+ $class = new \ReflectionClass($class);
1008
  $class = $class->name;
1009
  }
1010
 
1011
  if (isset($this->extensions[$class])) {
1012
+ if ($class !== \get_class($this->extensions[$class])) {
1013
  @trigger_error(sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), E_USER_DEPRECATED);
1014
  }
1015
 
1035
  /**
1036
  * Returns all registered extensions.
1037
  *
1038
+ * @return ExtensionInterface[] An array of extensions (keys are for internal usage only and should not be relied on)
1039
  */
1040
  public function getExtensions()
1041
  {
1042
  return $this->extensions;
1043
  }
1044
 
1045
+ public function addTokenParser(TokenParserInterface $parser)
1046
  {
1047
  if ($this->extensionInitialized) {
1048
+ throw new \LogicException('Unable to add a token parser as extensions have already been initialized.');
1049
  }
1050
 
1051
  $this->staging->addTokenParser($parser);
1072
  *
1073
  * Be warned that this method cannot return tags defined by Twig_TokenParserBrokerInterface classes.
1074
  *
1075
+ * @return TokenParserInterface[]
1076
  *
1077
  * @internal
1078
  */
1080
  {
1081
  $tags = [];
1082
  foreach ($this->getTokenParsers()->getParsers() as $parser) {
1083
+ if ($parser instanceof TokenParserInterface) {
1084
  $tags[$parser->getTag()] = $parser;
1085
  }
1086
  }
1088
  return $tags;
1089
  }
1090
 
1091
+ public function addNodeVisitor(NodeVisitorInterface $visitor)
1092
  {
1093
  if ($this->extensionInitialized) {
1094
+ throw new \LogicException('Unable to add a node visitor as extensions have already been initialized.');
1095
  }
1096
 
1097
  $this->staging->addNodeVisitor($visitor);
1100
  /**
1101
  * Gets the registered Node Visitors.
1102
  *
1103
+ * @return NodeVisitorInterface[]
1104
  *
1105
  * @internal
1106
  */
1116
  /**
1117
  * Registers a Filter.
1118
  *
1119
+ * @param string|TwigFilter $name The filter name or a Twig_SimpleFilter instance
1120
+ * @param Twig_FilterInterface|TwigFilter $filter
1121
  */
1122
  public function addFilter($name, $filter = null)
1123
  {
1124
+ if (!$name instanceof TwigFilter && !($filter instanceof TwigFilter || $filter instanceof Twig_FilterInterface)) {
1125
+ throw new \LogicException('A filter must be an instance of Twig_FilterInterface or Twig_SimpleFilter.');
1126
  }
1127
 
1128
+ if ($name instanceof TwigFilter) {
1129
  $filter = $name;
1130
  $name = $filter->getName();
1131
  } else {
1133
  }
1134
 
1135
  if ($this->extensionInitialized) {
1136
+ throw new \LogicException(sprintf('Unable to add filter "%s" as extensions have already been initialized.', $name));
1137
  }
1138
 
1139
  $this->staging->addFilter($name, $filter);
1175
  }
1176
 
1177
  foreach ($this->filterCallbacks as $callback) {
1178
+ if (false !== $filter = \call_user_func($callback, $name)) {
1179
  return $filter;
1180
  }
1181
  }
1211
  /**
1212
  * Registers a Test.
1213
  *
1214
+ * @param string|TwigTest $name The test name or a Twig_SimpleTest instance
1215
+ * @param Twig_TestInterface|TwigTest $test A Twig_TestInterface instance or a Twig_SimpleTest instance
1216
  */
1217
  public function addTest($name, $test = null)
1218
  {
1219
+ if (!$name instanceof TwigTest && !($test instanceof TwigTest || $test instanceof Twig_TestInterface)) {
1220
+ throw new \LogicException('A test must be an instance of Twig_TestInterface or Twig_SimpleTest.');
1221
  }
1222
 
1223
+ if ($name instanceof TwigTest) {
1224
  $test = $name;
1225
  $name = $test->getName();
1226
  } else {
1228
  }
1229
 
1230
  if ($this->extensionInitialized) {
1231
+ throw new \LogicException(sprintf('Unable to add test "%s" as extensions have already been initialized.', $name));
1232
  }
1233
 
1234
  $this->staging->addTest($name, $test);
1288
  /**
1289
  * Registers a Function.
1290
  *
1291
+ * @param string|TwigFunction $name The function name or a Twig_SimpleFunction instance
1292
+ * @param Twig_FunctionInterface|TwigFunction $function
1293
  */
1294
  public function addFunction($name, $function = null)
1295
  {
1296
+ if (!$name instanceof TwigFunction && !($function instanceof TwigFunction || $function instanceof Twig_FunctionInterface)) {
1297
+ throw new \LogicException('A function must be an instance of Twig_FunctionInterface or Twig_SimpleFunction.');
1298
  }
1299
 
1300
+ if ($name instanceof TwigFunction) {
1301
  $function = $name;
1302
  $name = $function->getName();
1303
  } else {
1305
  }
1306
 
1307
  if ($this->extensionInitialized) {
1308
+ throw new \LogicException(sprintf('Unable to add function "%s" as extensions have already been initialized.', $name));
1309
  }
1310
 
1311
  $this->staging->addFunction($name, $function);
1347
  }
1348
 
1349
  foreach ($this->functionCallbacks as $callback) {
1350
+ if (false !== $function = \call_user_func($callback, $name)) {
1351
  return $function;
1352
  }
1353
  }
1396
  $this->globals = $this->initGlobals();
1397
  }
1398
 
1399
+ if (!\array_key_exists($name, $this->globals)) {
1400
  // The deprecation notice must be turned into the following exception in Twig 2.0
1401
  @trigger_error(sprintf('Registering global variable "%s" at runtime or when the extensions have already been initialized is deprecated since version 1.21.', $name), E_USER_DEPRECATED);
1402
+ //throw new \LogicException(sprintf('Unable to add global "%s" as the runtime or the extensions have already been initialized.', $name));
1403
  }
1404
  }
1405
 
1443
  // we don't use array_merge as the context being generally
1444
  // bigger than globals, this code is faster.
1445
  foreach ($this->getGlobals() as $key => $value) {
1446
+ if (!\array_key_exists($key, $context)) {
1447
  $context[$key] = $value;
1448
  }
1449
  }
1490
  {
1491
  @trigger_error(sprintf('The %s method is deprecated since version 1.23 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED);
1492
 
1493
+ return SyntaxError::computeAlternatives($name, $items);
1494
  }
1495
 
1496
  /**
1500
  {
1501
  $globals = [];
1502
  foreach ($this->extensions as $name => $extension) {
1503
+ if (!$extension instanceof GlobalsInterface) {
1504
+ $m = new \ReflectionMethod($extension, 'getGlobals');
1505
 
1506
  if ('Twig_Extension' !== $m->getDeclaringClass()->getName()) {
1507
+ @trigger_error(sprintf('Defining the getGlobals() method in the "%s" extension without explicitly implementing Twig\Extension\GlobalsInterface is deprecated since version 1.23.', $name), E_USER_DEPRECATED);
1508
  }
1509
  }
1510
 
1511
  $extGlob = $extension->getGlobals();
1512
+ if (!\is_array($extGlob)) {
1513
+ throw new \UnexpectedValueException(sprintf('"%s::getGlobals()" must return an array of globals.', \get_class($extension)));
1514
  }
1515
 
1516
  $globals[] = $extGlob;
1518
 
1519
  $globals[] = $this->staging->getGlobals();
1520
 
1521
+ return \call_user_func_array('array_merge', $globals);
1522
  }
1523
 
1524
  /**
1549
  /**
1550
  * @internal
1551
  */
1552
+ protected function initExtension(ExtensionInterface $extension)
1553
  {
1554
  // filters
1555
  foreach ($extension->getFilters() as $name => $filter) {
1556
+ if ($filter instanceof TwigFilter) {
1557
  $name = $filter->getName();
1558
  } else {
1559
+ @trigger_error(sprintf('Using an instance of "%s" for filter "%s" is deprecated since version 1.21. Use Twig_SimpleFilter instead.', \get_class($filter), $name), E_USER_DEPRECATED);
1560
  }
1561
 
1562
  $this->filters[$name] = $filter;
1564
 
1565
  // functions
1566
  foreach ($extension->getFunctions() as $name => $function) {
1567
+ if ($function instanceof TwigFunction) {
1568
  $name = $function->getName();
1569
  } else {
1570
+ @trigger_error(sprintf('Using an instance of "%s" for function "%s" is deprecated since version 1.21. Use Twig_SimpleFunction instead.', \get_class($function), $name), E_USER_DEPRECATED);
1571
  }
1572
 
1573
  $this->functions[$name] = $function;
1575
 
1576
  // tests
1577
  foreach ($extension->getTests() as $name => $test) {
1578
+ if ($test instanceof TwigTest) {
1579
  $name = $test->getName();
1580
  } else {
1581
+ @trigger_error(sprintf('Using an instance of "%s" for test "%s" is deprecated since version 1.21. Use Twig_SimpleTest instead.', \get_class($test), $name), E_USER_DEPRECATED);
1582
  }
1583
 
1584
  $this->tests[$name] = $test;
1586
 
1587
  // token parsers
1588
  foreach ($extension->getTokenParsers() as $parser) {
1589
+ if ($parser instanceof TokenParserInterface) {
1590
  $this->parsers->addTokenParser($parser);
1591
  } elseif ($parser instanceof Twig_TokenParserBrokerInterface) {
1592
  @trigger_error('Registering a Twig_TokenParserBrokerInterface instance is deprecated since version 1.21.', E_USER_DEPRECATED);
1593
 
1594
  $this->parsers->addTokenParserBroker($parser);
1595
  } else {
1596
+ throw new \LogicException('getTokenParsers() must return an array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances.');
1597
  }
1598
  }
1599
 
1604
 
1605
  // operators
1606
  if ($operators = $extension->getOperators()) {
1607
+ if (!\is_array($operators)) {
1608
+ throw new \InvalidArgumentException(sprintf('"%s::getOperators()" must return an array with operators, got "%s".', \get_class($extension), \is_object($operators) ? \get_class($operators) : \gettype($operators).(\is_resource($operators) ? '' : '#'.$operators)));
1609
  }
1610
 
1611
+ if (2 !== \count($operators)) {
1612
+ throw new \InvalidArgumentException(sprintf('"%s::getOperators()" must return an array of 2 elements, got %d.', \get_class($extension), \count($operators)));
1613
  }
1614
 
1615
  $this->unaryOperators = array_merge($this->unaryOperators, $operators[0]);
1630
  $hashParts = array_merge(
1631
  array_keys($this->extensions),
1632
  [
1633
+ (int) \function_exists('twig_template_get_attributes'),
1634
  PHP_MAJOR_VERSION,
1635
  PHP_MINOR_VERSION,
1636
  self::VERSION,
vendor/twig/twig/lib/Twig/Error.php CHANGED
@@ -9,6 +9,9 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
12
  /**
13
  * Twig base exception.
14
  *
@@ -31,7 +34,7 @@
31
  *
32
  * @author Fabien Potencier <fabien@symfony.com>
33
  */
34
- class Twig_Error extends Exception
35
  {
36
  protected $lineno;
37
  // to be renamed to name in 2.0
@@ -53,16 +56,16 @@ class Twig_Error extends Exception
53
  *
54
  * By default, automatic guessing is enabled.
55
  *
56
- * @param string $message The error message
57
- * @param int $lineno The template line where the error occurred
58
- * @param Twig_Source|string|null $source The source context where the error occurred
59
- * @param Exception $previous The previous exception
60
  */
61
- public function __construct($message, $lineno = -1, $source = null, Exception $previous = null)
62
  {
63
  if (null === $source) {
64
  $name = null;
65
- } elseif (!$source instanceof Twig_Source) {
66
  // for compat with the Twig C ext., passing the template name as string is accepted
67
  $name = $source;
68
  } else {
@@ -180,17 +183,17 @@ class Twig_Error extends Exception
180
  /**
181
  * Gets the source context of the Twig template where the error occurred.
182
  *
183
- * @return Twig_Source|null
184
  */
185
  public function getSourceContext()
186
  {
187
- return $this->filename ? new Twig_Source($this->sourceCode, $this->filename, $this->sourcePath) : null;
188
  }
189
 
190
  /**
191
  * Sets the source context of the Twig template where the error occurred.
192
  */
193
- public function setSourceContext(Twig_Source $source = null)
194
  {
195
  if (null === $source) {
196
  $this->sourceCode = $this->filename = $this->sourcePath = null;
@@ -242,7 +245,7 @@ class Twig_Error extends Exception
242
  }
243
 
244
  if ($this->filename) {
245
- if (is_string($this->filename) || (is_object($this->filename) && method_exists($this->filename, '__toString'))) {
246
  $name = sprintf('"%s"', $this->filename);
247
  } else {
248
  $name = json_encode($this->filename);
@@ -273,12 +276,12 @@ class Twig_Error extends Exception
273
 
274
  $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS | DEBUG_BACKTRACE_PROVIDE_OBJECT);
275
  foreach ($backtrace as $trace) {
276
- if (isset($trace['object']) && $trace['object'] instanceof Twig_Template && 'Twig_Template' !== get_class($trace['object'])) {
277
- $currentClass = get_class($trace['object']);
278
  $isEmbedContainer = 0 === strpos($templateClass, $currentClass);
279
  if (null === $this->filename || ($this->filename == $trace['object']->getTemplateName() && !$isEmbedContainer)) {
280
  $template = $trace['object'];
281
- $templateClass = get_class($trace['object']);
282
  }
283
  }
284
  }
@@ -299,7 +302,7 @@ class Twig_Error extends Exception
299
  return;
300
  }
301
 
302
- $r = new ReflectionObject($template);
303
  $file = $r->getFileName();
304
 
305
  $exceptions = [$e = $this];
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Source;
13
+ use Twig\Template;
14
+
15
  /**
16
  * Twig base exception.
17
  *
34
  *
35
  * @author Fabien Potencier <fabien@symfony.com>
36
  */
37
+ class Twig_Error extends \Exception
38
  {
39
  protected $lineno;
40
  // to be renamed to name in 2.0
56
  *
57
  * By default, automatic guessing is enabled.
58
  *
59
+ * @param string $message The error message
60
+ * @param int $lineno The template line where the error occurred
61
+ * @param Source|string|null $source The source context where the error occurred
62
+ * @param \Exception $previous The previous exception
63
  */
64
+ public function __construct($message, $lineno = -1, $source = null, \Exception $previous = null)
65
  {
66
  if (null === $source) {
67
  $name = null;
68
+ } elseif (!$source instanceof Source) {
69
  // for compat with the Twig C ext., passing the template name as string is accepted
70
  $name = $source;
71
  } else {
183
  /**
184
  * Gets the source context of the Twig template where the error occurred.
185
  *
186
+ * @return Source|null
187
  */
188
  public function getSourceContext()
189
  {
190
+ return $this->filename ? new Source($this->sourceCode, $this->filename, $this->sourcePath) : null;
191
  }
192
 
193
  /**
194
  * Sets the source context of the Twig template where the error occurred.
195
  */
196
+ public function setSourceContext(Source $source = null)
197
  {
198
  if (null === $source) {
199
  $this->sourceCode = $this->filename = $this->sourcePath = null;
245
  }
246
 
247
  if ($this->filename) {
248
+ if (\is_string($this->filename) || (\is_object($this->filename) && method_exists($this->filename, '__toString'))) {
249
  $name = sprintf('"%s"', $this->filename);
250
  } else {
251
  $name = json_encode($this->filename);
276
 
277
  $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS | DEBUG_BACKTRACE_PROVIDE_OBJECT);
278
  foreach ($backtrace as $trace) {
279
+ if (isset($trace['object']) && $trace['object'] instanceof Template && 'Twig_Template' !== \get_class($trace['object'])) {
280
+ $currentClass = \get_class($trace['object']);
281
  $isEmbedContainer = 0 === strpos($templateClass, $currentClass);
282
  if (null === $this->filename || ($this->filename == $trace['object']->getTemplateName() && !$isEmbedContainer)) {
283
  $template = $trace['object'];
284
+ $templateClass = \get_class($trace['object']);
285
  }
286
  }
287
  }
302
  return;
303
  }
304
 
305
+ $r = new \ReflectionObject($template);
306
  $file = $r->getFileName();
307
 
308
  $exceptions = [$e = $this];
vendor/twig/twig/lib/Twig/Error/Loader.php CHANGED
@@ -9,6 +9,8 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
12
  /**
13
  * Exception thrown when an error occurs during template loading.
14
  *
@@ -16,17 +18,17 @@
16
  * if a template cannot be loaded, there is nothing to guess.
17
  * However, when a template is loaded from another one, then, we need
18
  * to find the current context and this is automatically done by
19
- * Twig_Template::displayWithErrorHandling().
20
  *
21
- * This strategy makes Twig_Environment::resolveTemplate() much faster.
22
  *
23
  * @author Fabien Potencier <fabien@symfony.com>
24
  */
25
- class Twig_Error_Loader extends Twig_Error
26
  {
27
- public function __construct($message, $lineno = -1, $source = null, Exception $previous = null)
28
  {
29
- Exception::__construct('', 0, $previous);
30
 
31
  $this->appendMessage($message);
32
  $this->setTemplateLine(false);
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Error\Error;
13
+
14
  /**
15
  * Exception thrown when an error occurs during template loading.
16
  *
18
  * if a template cannot be loaded, there is nothing to guess.
19
  * However, when a template is loaded from another one, then, we need
20
  * to find the current context and this is automatically done by
21
+ * Twig\Template::displayWithErrorHandling().
22
  *
23
+ * This strategy makes Twig\Environment::resolveTemplate() much faster.
24
  *
25
  * @author Fabien Potencier <fabien@symfony.com>
26
  */
27
+ class Twig_Error_Loader extends Error
28
  {
29
+ public function __construct($message, $lineno = -1, $source = null, \Exception $previous = null)
30
  {
31
+ \Exception::__construct('', 0, $previous);
32
 
33
  $this->appendMessage($message);
34
  $this->setTemplateLine(false);
vendor/twig/twig/lib/Twig/Error/Runtime.php CHANGED
@@ -10,12 +10,14 @@
10
  * file that was distributed with this source code.
11
  */
12
 
 
 
13
  /**
14
  * Exception thrown when an error occurs at runtime.
15
  *
16
  * @author Fabien Potencier <fabien@symfony.com>
17
  */
18
- class Twig_Error_Runtime extends Twig_Error
19
  {
20
  }
21
 
10
  * file that was distributed with this source code.
11
  */
12
 
13
+ use Twig\Error\Error;
14
+
15
  /**
16
  * Exception thrown when an error occurs at runtime.
17
  *
18
  * @author Fabien Potencier <fabien@symfony.com>
19
  */
20
+ class Twig_Error_Runtime extends Error
21
  {
22
  }
23
 
vendor/twig/twig/lib/Twig/Error/Syntax.php CHANGED
@@ -10,12 +10,14 @@
10
  * file that was distributed with this source code.
11
  */
12
 
 
 
13
  /**
14
- * Exception thrown when a syntax error occurs during lexing or parsing of a template.
15
  *
16
  * @author Fabien Potencier <fabien@symfony.com>
17
  */
18
- class Twig_Error_Syntax extends Twig_Error
19
  {
20
  /**
21
  * Tweaks the error message to include suggestions.
@@ -42,7 +44,7 @@ class Twig_Error_Syntax extends Twig_Error
42
  $alternatives = [];
43
  foreach ($items as $item) {
44
  $lev = levenshtein($name, $item);
45
- if ($lev <= strlen($name) / 3 || false !== strpos($item, $name)) {
46
  $alternatives[$item] = $lev;
47
  }
48
  }
10
  * file that was distributed with this source code.
11
  */
12
 
13
+ use Twig\Error\Error;
14
+
15
  /**
16
+ * \Exception thrown when a syntax error occurs during lexing or parsing of a template.
17
  *
18
  * @author Fabien Potencier <fabien@symfony.com>
19
  */
20
+ class Twig_Error_Syntax extends Error
21
  {
22
  /**
23
  * Tweaks the error message to include suggestions.
44
  $alternatives = [];
45
  foreach ($items as $item) {
46
  $lev = levenshtein($name, $item);
47
+ if ($lev <= \strlen($name) / 3 || false !== strpos($item, $name)) {
48
  $alternatives[$item] = $lev;
49
  }
50
  }
vendor/twig/twig/lib/Twig/ExpressionParser.php CHANGED
@@ -10,6 +10,30 @@
10
  * file that was distributed with this source code.
11
  */
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  /**
14
  * Parses expressions.
15
  *
@@ -33,11 +57,11 @@ class Twig_ExpressionParser
33
 
34
  private $env;
35
 
36
- public function __construct(Twig_Parser $parser, $env = null)
37
  {
38
  $this->parser = $parser;
39
 
40
- if ($env instanceof Twig_Environment) {
41
  $this->env = $env;
42
  $this->unaryOperators = $env->getUnaryOperators();
43
  $this->binaryOperators = $env->getBinaryOperators();
@@ -63,7 +87,7 @@ class Twig_ExpressionParser
63
  } elseif ('is' === $token->getValue()) {
64
  $expr = $this->parseTestExpression($expr);
65
  } elseif (isset($op['callable'])) {
66
- $expr = call_user_func($op['callable'], $this->parser, $expr);
67
  } else {
68
  $expr1 = $this->parseExpression(self::OPERATOR_LEFT === $op['associativity'] ? $op['precedence'] + 1 : $op['precedence']);
69
  $class = $op['class'];
@@ -91,10 +115,10 @@ class Twig_ExpressionParser
91
  $class = $operator['class'];
92
 
93
  return $this->parsePostfixExpression(new $class($expr, $token->getLine()));
94
- } elseif ($token->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
95
  $this->parser->getStream()->next();
96
  $expr = $this->parseExpression();
97
- $this->parser->getStream()->expect(Twig_Token::PUNCTUATION_TYPE, ')', 'An opened parenthesis is not properly closed');
98
 
99
  return $this->parsePostfixExpression($expr);
100
  }
@@ -104,92 +128,92 @@ class Twig_ExpressionParser
104
 
105
  protected function parseConditionalExpression($expr)
106
  {
107
- while ($this->parser->getStream()->nextIf(Twig_Token::PUNCTUATION_TYPE, '?')) {
108
- if (!$this->parser->getStream()->nextIf(Twig_Token::PUNCTUATION_TYPE, ':')) {
109
  $expr2 = $this->parseExpression();
110
- if ($this->parser->getStream()->nextIf(Twig_Token::PUNCTUATION_TYPE, ':')) {
111
  $expr3 = $this->parseExpression();
112
  } else {
113
- $expr3 = new Twig_Node_Expression_Constant('', $this->parser->getCurrentToken()->getLine());
114
  }
115
  } else {
116
  $expr2 = $expr;
117
  $expr3 = $this->parseExpression();
118
  }
119
 
120
- $expr = new Twig_Node_Expression_Conditional($expr, $expr2, $expr3, $this->parser->getCurrentToken()->getLine());
121
  }
122
 
123
  return $expr;
124
  }
125
 
126
- protected function isUnary(Twig_Token $token)
127
  {
128
- return $token->test(Twig_Token::OPERATOR_TYPE) && isset($this->unaryOperators[$token->getValue()]);
129
  }
130
 
131
- protected function isBinary(Twig_Token $token)
132
  {
133
- return $token->test(Twig_Token::OPERATOR_TYPE) && isset($this->binaryOperators[$token->getValue()]);
134
  }
135
 
136
  public function parsePrimaryExpression()
137
  {
138
  $token = $this->parser->getCurrentToken();
139
  switch ($token->getType()) {
140
- case Twig_Token::NAME_TYPE:
141
  $this->parser->getStream()->next();
142
  switch ($token->getValue()) {
143
  case 'true':
144
  case 'TRUE':
145
- $node = new Twig_Node_Expression_Constant(true, $token->getLine());
146
  break;
147
 
148
  case 'false':
149
  case 'FALSE':
150
- $node = new Twig_Node_Expression_Constant(false, $token->getLine());
151
  break;
152
 
153
  case 'none':
154
  case 'NONE':
155
  case 'null':
156
  case 'NULL':
157
- $node = new Twig_Node_Expression_Constant(null, $token->getLine());
158
  break;
159
 
160
  default:
161
  if ('(' === $this->parser->getCurrentToken()->getValue()) {
162
  $node = $this->getFunctionNode($token->getValue(), $token->getLine());
163
  } else {
164
- $node = new Twig_Node_Expression_Name($token->getValue(), $token->getLine());
165
  }
166
  }
167
  break;
168
 
169
- case Twig_Token::NUMBER_TYPE:
170
  $this->parser->getStream()->next();
171
- $node = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine());
172
  break;
173
 
174
- case Twig_Token::STRING_TYPE:
175
- case Twig_Token::INTERPOLATION_START_TYPE:
176
  $node = $this->parseStringExpression();
177
  break;
178
 
179
- case Twig_Token::OPERATOR_TYPE:
180
- if (preg_match(Twig_Lexer::REGEX_NAME, $token->getValue(), $matches) && $matches[0] == $token->getValue()) {
181
  // in this context, string operators are variable names
182
  $this->parser->getStream()->next();
183
- $node = new Twig_Node_Expression_Name($token->getValue(), $token->getLine());
184
  break;
185
  } elseif (isset($this->unaryOperators[$token->getValue()])) {
186
  $class = $this->unaryOperators[$token->getValue()]['class'];
187
 
188
- $ref = new ReflectionClass($class);
189
  $negClass = 'Twig_Node_Expression_Unary_Neg';
190
  $posClass = 'Twig_Node_Expression_Unary_Pos';
191
- if (!(in_array($ref->getName(), [$negClass, $posClass]) || $ref->isSubclassOf($negClass) || $ref->isSubclassOf($posClass))) {
192
- throw new Twig_Error_Syntax(sprintf('Unexpected unary operator "%s".', $token->getValue()), $token->getLine(), $this->parser->getStream()->getSourceContext());
193
  }
194
 
195
  $this->parser->getStream()->next();
@@ -201,14 +225,14 @@ class Twig_ExpressionParser
201
 
202
  // no break
203
  default:
204
- if ($token->test(Twig_Token::PUNCTUATION_TYPE, '[')) {
205
  $node = $this->parseArrayExpression();
206
- } elseif ($token->test(Twig_Token::PUNCTUATION_TYPE, '{')) {
207
  $node = $this->parseHashExpression();
208
- } elseif ($token->test(Twig_Token::OPERATOR_TYPE, '=') && ('==' === $this->parser->getStream()->look(-1)->getValue() || '!=' === $this->parser->getStream()->look(-1)->getValue())) {
209
- throw new Twig_Error_Syntax(sprintf('Unexpected operator of value "%s". Did you try to use "===" or "!==" for strict comparison? Use "is same as(value)" instead.', $token->getValue()), $token->getLine(), $this->parser->getStream()->getSourceContext());
210
  } else {
211
- throw new Twig_Error_Syntax(sprintf('Unexpected token "%s" of value "%s".', Twig_Token::typeToEnglish($token->getType()), $token->getValue()), $token->getLine(), $this->parser->getStream()->getSourceContext());
212
  }
213
  }
214
 
@@ -223,12 +247,12 @@ class Twig_ExpressionParser
223
  // a string cannot be followed by another string in a single expression
224
  $nextCanBeString = true;
225
  while (true) {
226
- if ($nextCanBeString && $token = $stream->nextIf(Twig_Token::STRING_TYPE)) {
227
- $nodes[] = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine());
228
  $nextCanBeString = false;
229
- } elseif ($stream->nextIf(Twig_Token::INTERPOLATION_START_TYPE)) {
230
  $nodes[] = $this->parseExpression();
231
- $stream->expect(Twig_Token::INTERPOLATION_END_TYPE);
232
  $nextCanBeString = true;
233
  } else {
234
  break;
@@ -237,7 +261,7 @@ class Twig_ExpressionParser
237
 
238
  $expr = array_shift($nodes);
239
  foreach ($nodes as $node) {
240
- $expr = new Twig_Node_Expression_Binary_Concat($expr, $node, $node->getTemplateLine());
241
  }
242
 
243
  return $expr;
@@ -246,16 +270,16 @@ class Twig_ExpressionParser
246
  public function parseArrayExpression()
247
  {
248
  $stream = $this->parser->getStream();
249
- $stream->expect(Twig_Token::PUNCTUATION_TYPE, '[', 'An array element was expected');
250
 
251
- $node = new Twig_Node_Expression_Array([], $stream->getCurrent()->getLine());
252
  $first = true;
253
- while (!$stream->test(Twig_Token::PUNCTUATION_TYPE, ']')) {
254
  if (!$first) {
255
- $stream->expect(Twig_Token::PUNCTUATION_TYPE, ',', 'An array element must be followed by a comma');
256
 
257
  // trailing ,?
258
- if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ']')) {
259
  break;
260
  }
261
  }
@@ -263,7 +287,7 @@ class Twig_ExpressionParser
263
 
264
  $node->addElement($this->parseExpression());
265
  }
266
- $stream->expect(Twig_Token::PUNCTUATION_TYPE, ']', 'An opened array is not properly closed');
267
 
268
  return $node;
269
  }
@@ -271,16 +295,16 @@ class Twig_ExpressionParser
271
  public function parseHashExpression()
272
  {
273
  $stream = $this->parser->getStream();
274
- $stream->expect(Twig_Token::PUNCTUATION_TYPE, '{', 'A hash element was expected');
275
 
276
- $node = new Twig_Node_Expression_Array([], $stream->getCurrent()->getLine());
277
  $first = true;
278
- while (!$stream->test(Twig_Token::PUNCTUATION_TYPE, '}')) {
279
  if (!$first) {
280
- $stream->expect(Twig_Token::PUNCTUATION_TYPE, ',', 'A hash value must be followed by a comma');
281
 
282
  // trailing ,?
283
- if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '}')) {
284
  break;
285
  }
286
  }
@@ -292,22 +316,22 @@ class Twig_ExpressionParser
292
  // * a string -- 'a'
293
  // * a name, which is equivalent to a string -- a
294
  // * an expression, which must be enclosed in parentheses -- (1 + 2)
295
- if (($token = $stream->nextIf(Twig_Token::STRING_TYPE)) || ($token = $stream->nextIf(Twig_Token::NAME_TYPE)) || $token = $stream->nextIf(Twig_Token::NUMBER_TYPE)) {
296
- $key = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine());
297
- } elseif ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
298
  $key = $this->parseExpression();
299
  } else {
300
  $current = $stream->getCurrent();
301
 
302
- throw new Twig_Error_Syntax(sprintf('A hash key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "%s" of value "%s".', Twig_Token::typeToEnglish($current->getType()), $current->getValue()), $current->getLine(), $stream->getSourceContext());
303
  }
304
 
305
- $stream->expect(Twig_Token::PUNCTUATION_TYPE, ':', 'A hash key must be followed by a colon (:)');
306
  $value = $this->parseExpression();
307
 
308
  $node->addElement($value, $key);
309
  }
310
- $stream->expect(Twig_Token::PUNCTUATION_TYPE, '}', 'An opened hash is not properly closed');
311
 
312
  return $node;
313
  }
@@ -316,7 +340,7 @@ class Twig_ExpressionParser
316
  {
317
  while (true) {
318
  $token = $this->parser->getCurrentToken();
319
- if (Twig_Token::PUNCTUATION_TYPE == $token->getType()) {
320
  if ('.' == $token->getValue() || '[' == $token->getValue()) {
321
  $node = $this->parseSubscriptExpression($node);
322
  } elseif ('|' == $token->getValue()) {
@@ -337,37 +361,37 @@ class Twig_ExpressionParser
337
  switch ($name) {
338
  case 'parent':
339
  $this->parseArguments();
340
- if (!count($this->parser->getBlockStack())) {
341
- throw new Twig_Error_Syntax('Calling "parent" outside a block is forbidden.', $line, $this->parser->getStream()->getSourceContext());
342
  }
343
 
344
  if (!$this->parser->getParent() && !$this->parser->hasTraits()) {
345
- throw new Twig_Error_Syntax('Calling "parent" on a template that does not extend nor "use" another template is forbidden.', $line, $this->parser->getStream()->getSourceContext());
346
  }
347
 
348
- return new Twig_Node_Expression_Parent($this->parser->peekBlockStack(), $line);
349
  case 'block':
350
  $args = $this->parseArguments();
351
- if (count($args) < 1) {
352
- throw new Twig_Error_Syntax('The "block" function takes one argument (the block name).', $line, $this->parser->getStream()->getSourceContext());
353
  }
354
 
355
- return new Twig_Node_Expression_BlockReference($args->getNode(0), count($args) > 1 ? $args->getNode(1) : null, $line);
356
  case 'attribute':
357
  $args = $this->parseArguments();
358
- if (count($args) < 2) {
359
- throw new Twig_Error_Syntax('The "attribute" function takes at least two arguments (the variable and the attributes).', $line, $this->parser->getStream()->getSourceContext());
360
  }
361
 
362
- return new Twig_Node_Expression_GetAttr($args->getNode(0), $args->getNode(1), count($args) > 2 ? $args->getNode(2) : null, Twig_Template::ANY_CALL, $line);
363
  default:
364
  if (null !== $alias = $this->parser->getImportedSymbol('function', $name)) {
365
- $arguments = new Twig_Node_Expression_Array([], $line);
366
  foreach ($this->parseArguments() as $n) {
367
  $arguments->addElement($n);
368
  }
369
 
370
- $node = new Twig_Node_Expression_MethodCall($alias['node'], $alias['name'], $arguments, $line);
371
  $node->setAttribute('safe', true);
372
 
373
  return $node;
@@ -385,81 +409,81 @@ class Twig_ExpressionParser
385
  $stream = $this->parser->getStream();
386
  $token = $stream->next();
387
  $lineno = $token->getLine();
388
- $arguments = new Twig_Node_Expression_Array([], $lineno);
389
- $type = Twig_Template::ANY_CALL;
390
  if ('.' == $token->getValue()) {
391
  $token = $stream->next();
392
  if (
393
- Twig_Token::NAME_TYPE == $token->getType()
394
  ||
395
- Twig_Token::NUMBER_TYPE == $token->getType()
396
  ||
397
- (Twig_Token::OPERATOR_TYPE == $token->getType() && preg_match(Twig_Lexer::REGEX_NAME, $token->getValue()))
398
  ) {
399
- $arg = new Twig_Node_Expression_Constant($token->getValue(), $lineno);
400
 
401
- if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
402
- $type = Twig_Template::METHOD_CALL;
403
  foreach ($this->parseArguments() as $n) {
404
  $arguments->addElement($n);
405
  }
406
  }
407
  } else {
408
- throw new Twig_Error_Syntax('Expected name or number.', $lineno, $stream->getSourceContext());
409
  }
410
 
411
- if ($node instanceof Twig_Node_Expression_Name && null !== $this->parser->getImportedSymbol('template', $node->getAttribute('name'))) {
412
- if (!$arg instanceof Twig_Node_Expression_Constant) {
413
- throw new Twig_Error_Syntax(sprintf('Dynamic macro names are not supported (called on "%s").', $node->getAttribute('name')), $token->getLine(), $stream->getSourceContext());
414
  }
415
 
416
  $name = $arg->getAttribute('value');
417
 
418
  if ($this->parser->isReservedMacroName($name)) {
419
- throw new Twig_Error_Syntax(sprintf('"%s" cannot be called as macro as it is a reserved keyword.', $name), $token->getLine(), $stream->getSourceContext());
420
  }
421
 
422
- $node = new Twig_Node_Expression_MethodCall($node, 'get'.$name, $arguments, $lineno);
423
  $node->setAttribute('safe', true);
424
 
425
  return $node;
426
  }
427
  } else {
428
- $type = Twig_Template::ARRAY_CALL;
429
 
430
  // slice?
431
  $slice = false;
432
- if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ':')) {
433
  $slice = true;
434
- $arg = new Twig_Node_Expression_Constant(0, $token->getLine());
435
  } else {
436
  $arg = $this->parseExpression();
437
  }
438
 
439
- if ($stream->nextIf(Twig_Token::PUNCTUATION_TYPE, ':')) {
440
  $slice = true;
441
  }
442
 
443
  if ($slice) {
444
- if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ']')) {
445
- $length = new Twig_Node_Expression_Constant(null, $token->getLine());
446
  } else {
447
  $length = $this->parseExpression();
448
  }
449
 
450
  $class = $this->getFilterNodeClass('slice', $token->getLine());
451
- $arguments = new Twig_Node([$arg, $length]);
452
- $filter = new $class($node, new Twig_Node_Expression_Constant('slice', $token->getLine()), $arguments, $token->getLine());
453
 
454
- $stream->expect(Twig_Token::PUNCTUATION_TYPE, ']');
455
 
456
  return $filter;
457
  }
458
 
459
- $stream->expect(Twig_Token::PUNCTUATION_TYPE, ']');
460
  }
461
 
462
- return new Twig_Node_Expression_GetAttr($node, $arg, $arguments, $type, $lineno);
463
  }
464
 
465
  public function parseFilterExpression($node)
@@ -472,11 +496,11 @@ class Twig_ExpressionParser
472
  public function parseFilterExpressionRaw($node, $tag = null)
473
  {
474
  while (true) {
475
- $token = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE);
476
 
477
- $name = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine());
478
- if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
479
- $arguments = new Twig_Node();
480
  } else {
481
  $arguments = $this->parseArguments(true);
482
  }
@@ -485,7 +509,7 @@ class Twig_ExpressionParser
485
 
486
  $node = new $class($node, $name, $arguments, $token->getLine(), $tag);
487
 
488
- if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, '|')) {
489
  break;
490
  }
491
 
@@ -501,32 +525,32 @@ class Twig_ExpressionParser
501
  * @param bool $namedArguments Whether to allow named arguments or not
502
  * @param bool $definition Whether we are parsing arguments for a function definition
503
  *
504
- * @return Twig_Node
505
  *
506
- * @throws Twig_Error_Syntax
507
  */
508
  public function parseArguments($namedArguments = false, $definition = false)
509
  {
510
  $args = [];
511
  $stream = $this->parser->getStream();
512
 
513
- $stream->expect(Twig_Token::PUNCTUATION_TYPE, '(', 'A list of arguments must begin with an opening parenthesis');
514
- while (!$stream->test(Twig_Token::PUNCTUATION_TYPE, ')')) {
515
  if (!empty($args)) {
516
- $stream->expect(Twig_Token::PUNCTUATION_TYPE, ',', 'Arguments must be separated by a comma');
517
  }
518
 
519
  if ($definition) {
520
- $token = $stream->expect(Twig_Token::NAME_TYPE, null, 'An argument must be a name');
521
- $value = new Twig_Node_Expression_Name($token->getValue(), $this->parser->getCurrentToken()->getLine());
522
  } else {
523
  $value = $this->parseExpression();
524
  }
525
 
526
  $name = null;
527
- if ($namedArguments && $token = $stream->nextIf(Twig_Token::OPERATOR_TYPE, '=')) {
528
- if (!$value instanceof Twig_Node_Expression_Name) {
529
- throw new Twig_Error_Syntax(sprintf('A parameter name must be a string, "%s" given.', get_class($value)), $token->getLine(), $stream->getSourceContext());
530
  }
531
  $name = $value->getAttribute('name');
532
 
@@ -534,7 +558,7 @@ class Twig_ExpressionParser
534
  $value = $this->parsePrimaryExpression();
535
 
536
  if (!$this->checkConstantExpression($value)) {
537
- throw new Twig_Error_Syntax(sprintf('A default value for an argument must be a constant (a boolean, a string, a number, or an array).'), $token->getLine(), $stream->getSourceContext());
538
  }
539
  } else {
540
  $value = $this->parseExpression();
@@ -544,7 +568,7 @@ class Twig_ExpressionParser
544
  if ($definition) {
545
  if (null === $name) {
546
  $name = $value->getAttribute('name');
547
- $value = new Twig_Node_Expression_Constant(null, $this->parser->getCurrentToken()->getLine());
548
  }
549
  $args[$name] = $value;
550
  } else {
@@ -555,9 +579,9 @@ class Twig_ExpressionParser
555
  }
556
  }
557
  }
558
- $stream->expect(Twig_Token::PUNCTUATION_TYPE, ')', 'A list of arguments must be closed by a parenthesis');
559
 
560
- return new Twig_Node($args);
561
  }
562
 
563
  public function parseAssignmentExpression()
@@ -565,19 +589,19 @@ class Twig_ExpressionParser
565
  $stream = $this->parser->getStream();
566
  $targets = [];
567
  while (true) {
568
- $token = $stream->expect(Twig_Token::NAME_TYPE, null, 'Only variables can be assigned to');
569
  $value = $token->getValue();
570
- if (in_array(strtolower($value), ['true', 'false', 'none', 'null'])) {
571
- throw new Twig_Error_Syntax(sprintf('You cannot assign a value to "%s".', $value), $token->getLine(), $stream->getSourceContext());
572
  }
573
- $targets[] = new Twig_Node_Expression_AssignName($value, $token->getLine());
574
 
575
- if (!$stream->nextIf(Twig_Token::PUNCTUATION_TYPE, ',')) {
576
  break;
577
  }
578
  }
579
 
580
- return new Twig_Node($targets);
581
  }
582
 
583
  public function parseMultitargetExpression()
@@ -585,17 +609,17 @@ class Twig_ExpressionParser
585
  $targets = [];
586
  while (true) {
587
  $targets[] = $this->parseExpression();
588
- if (!$this->parser->getStream()->nextIf(Twig_Token::PUNCTUATION_TYPE, ',')) {
589
  break;
590
  }
591
  }
592
 
593
- return new Twig_Node($targets);
594
  }
595
 
596
  private function parseNotTestExpression(Twig_NodeInterface $node)
597
  {
598
- return new Twig_Node_Expression_Unary_Not($this->parseTestExpression($node), $this->parser->getCurrentToken()->getLine());
599
  }
600
 
601
  private function parseTestExpression(Twig_NodeInterface $node)
@@ -605,7 +629,7 @@ class Twig_ExpressionParser
605
 
606
  $class = $this->getTestNodeClass($test);
607
  $arguments = null;
608
- if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
609
  $arguments = $this->parser->getExpressionParser()->parseArguments(true);
610
  }
611
 
@@ -615,13 +639,13 @@ class Twig_ExpressionParser
615
  private function getTest($line)
616
  {
617
  $stream = $this->parser->getStream();
618
- $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
619
 
620
  if ($test = $this->env->getTest($name)) {
621
  return [$name, $test];
622
  }
623
 
624
- if ($stream->test(Twig_Token::NAME_TYPE)) {
625
  // try 2-words tests
626
  $name = $name.' '.$this->parser->getCurrentToken()->getValue();
627
 
@@ -632,7 +656,7 @@ class Twig_ExpressionParser
632
  }
633
  }
634
 
635
- $e = new Twig_Error_Syntax(sprintf('Unknown "%s" test.', $name), $line, $stream->getSourceContext());
636
  $e->addSuggestions($name, array_keys($this->env->getTests()));
637
 
638
  throw $e;
@@ -640,10 +664,10 @@ class Twig_ExpressionParser
640
 
641
  private function getTestNodeClass($test)
642
  {
643
- if ($test instanceof Twig_SimpleTest && $test->isDeprecated()) {
644
  $stream = $this->parser->getStream();
645
  $message = sprintf('Twig Test "%s" is deprecated', $test->getName());
646
- if (!is_bool($test->getDeprecatedVersion())) {
647
  $message .= sprintf(' since version %s', $test->getDeprecatedVersion());
648
  }
649
  if ($test->getAlternative()) {
@@ -655,7 +679,7 @@ class Twig_ExpressionParser
655
  @trigger_error($message, E_USER_DEPRECATED);
656
  }
657
 
658
- if ($test instanceof Twig_SimpleTest) {
659
  return $test->getNodeClass();
660
  }
661
 
@@ -665,15 +689,15 @@ class Twig_ExpressionParser
665
  protected function getFunctionNodeClass($name, $line)
666
  {
667
  if (false === $function = $this->env->getFunction($name)) {
668
- $e = new Twig_Error_Syntax(sprintf('Unknown "%s" function.', $name), $line, $this->parser->getStream()->getSourceContext());
669
  $e->addSuggestions($name, array_keys($this->env->getFunctions()));
670
 
671
  throw $e;
672
  }
673
 
674
- if ($function instanceof Twig_SimpleFunction && $function->isDeprecated()) {
675
  $message = sprintf('Twig Function "%s" is deprecated', $function->getName());
676
- if (!is_bool($function->getDeprecatedVersion())) {
677
  $message .= sprintf(' since version %s', $function->getDeprecatedVersion());
678
  }
679
  if ($function->getAlternative()) {
@@ -685,7 +709,7 @@ class Twig_ExpressionParser
685
  @trigger_error($message, E_USER_DEPRECATED);
686
  }
687
 
688
- if ($function instanceof Twig_SimpleFunction) {
689
  return $function->getNodeClass();
690
  }
691
 
@@ -695,15 +719,15 @@ class Twig_ExpressionParser
695
  protected function getFilterNodeClass($name, $line)
696
  {
697
  if (false === $filter = $this->env->getFilter($name)) {
698
- $e = new Twig_Error_Syntax(sprintf('Unknown "%s" filter.', $name), $line, $this->parser->getStream()->getSourceContext());
699
  $e->addSuggestions($name, array_keys($this->env->getFilters()));
700
 
701
  throw $e;
702
  }
703
 
704
- if ($filter instanceof Twig_SimpleFilter && $filter->isDeprecated()) {
705
  $message = sprintf('Twig Filter "%s" is deprecated', $filter->getName());
706
- if (!is_bool($filter->getDeprecatedVersion())) {
707
  $message .= sprintf(' since version %s', $filter->getDeprecatedVersion());
708
  }
709
  if ($filter->getAlternative()) {
@@ -715,7 +739,7 @@ class Twig_ExpressionParser
715
  @trigger_error($message, E_USER_DEPRECATED);
716
  }
717
 
718
- if ($filter instanceof Twig_SimpleFilter) {
719
  return $filter->getNodeClass();
720
  }
721
 
@@ -725,8 +749,8 @@ class Twig_ExpressionParser
725
  // checks that the node only contains "constant" elements
726
  protected function checkConstantExpression(Twig_NodeInterface $node)
727
  {
728
- if (!($node instanceof Twig_Node_Expression_Constant || $node instanceof Twig_Node_Expression_Array
729
- || $node instanceof Twig_Node_Expression_Unary_Neg || $node instanceof Twig_Node_Expression_Unary_Pos
730
  )) {
731
  return false;
732
  }
10
  * file that was distributed with this source code.
11
  */
12
 
13
+ use Twig\Environment;
14
+ use Twig\Error\SyntaxError;
15
+ use Twig\Lexer;
16
+ use Twig\Node\Expression\ArrayExpression;
17
+ use Twig\Node\Expression\AssignNameExpression;
18
+ use Twig\Node\Expression\Binary\ConcatBinary;
19
+ use Twig\Node\Expression\BlockReferenceExpression;
20
+ use Twig\Node\Expression\ConditionalExpression;
21
+ use Twig\Node\Expression\ConstantExpression;
22
+ use Twig\Node\Expression\GetAttrExpression;
23
+ use Twig\Node\Expression\MethodCallExpression;
24
+ use Twig\Node\Expression\NameExpression;
25
+ use Twig\Node\Expression\ParentExpression;
26
+ use Twig\Node\Expression\Unary\NegUnary;
27
+ use Twig\Node\Expression\Unary\NotUnary;
28
+ use Twig\Node\Expression\Unary\PosUnary;
29
+ use Twig\Node\Node;
30
+ use Twig\Parser;
31
+ use Twig\Template;
32
+ use Twig\Token;
33
+ use Twig\TwigFilter;
34
+ use Twig\TwigFunction;
35
+ use Twig\TwigTest;
36
+
37
  /**
38
  * Parses expressions.
39
  *
57
 
58
  private $env;
59
 
60
+ public function __construct(Parser $parser, $env = null)
61
  {
62
  $this->parser = $parser;
63
 
64
+ if ($env instanceof Environment) {
65
  $this->env = $env;
66
  $this->unaryOperators = $env->getUnaryOperators();
67
  $this->binaryOperators = $env->getBinaryOperators();
87
  } elseif ('is' === $token->getValue()) {
88
  $expr = $this->parseTestExpression($expr);
89
  } elseif (isset($op['callable'])) {
90
+ $expr = \call_user_func($op['callable'], $this->parser, $expr);
91
  } else {
92
  $expr1 = $this->parseExpression(self::OPERATOR_LEFT === $op['associativity'] ? $op['precedence'] + 1 : $op['precedence']);
93
  $class = $op['class'];
115
  $class = $operator['class'];
116
 
117
  return $this->parsePostfixExpression(new $class($expr, $token->getLine()));
118
+ } elseif ($token->test(Token::PUNCTUATION_TYPE, '(')) {
119
  $this->parser->getStream()->next();
120
  $expr = $this->parseExpression();
121
+ $this->parser->getStream()->expect(Token::PUNCTUATION_TYPE, ')', 'An opened parenthesis is not properly closed');
122
 
123
  return $this->parsePostfixExpression($expr);
124
  }
128
 
129
  protected function parseConditionalExpression($expr)
130
  {
131
+ while ($this->parser->getStream()->nextIf(Token::PUNCTUATION_TYPE, '?')) {
132
+ if (!$this->parser->getStream()->nextIf(Token::PUNCTUATION_TYPE, ':')) {
133
  $expr2 = $this->parseExpression();
134
+ if ($this->parser->getStream()->nextIf(Token::PUNCTUATION_TYPE, ':')) {
135
  $expr3 = $this->parseExpression();
136
  } else {
137
+ $expr3 = new ConstantExpression('', $this->parser->getCurrentToken()->getLine());
138
  }
139
  } else {
140
  $expr2 = $expr;
141
  $expr3 = $this->parseExpression();
142
  }
143
 
144
+ $expr = new ConditionalExpression($expr, $expr2, $expr3, $this->parser->getCurrentToken()->getLine());
145
  }
146
 
147
  return $expr;
148
  }
149
 
150
+ protected function isUnary(Token $token)
151
  {
152
+ return $token->test(Token::OPERATOR_TYPE) && isset($this->unaryOperators[$token->getValue()]);
153
  }
154
 
155
+ protected function isBinary(Token $token)
156
  {
157
+ return $token->test(Token::OPERATOR_TYPE) && isset($this->binaryOperators[$token->getValue()]);
158
  }
159
 
160
  public function parsePrimaryExpression()
161
  {
162
  $token = $this->parser->getCurrentToken();
163
  switch ($token->getType()) {
164
+ case Token::NAME_TYPE:
165
  $this->parser->getStream()->next();
166
  switch ($token->getValue()) {
167
  case 'true':
168
  case 'TRUE':
169
+ $node = new ConstantExpression(true, $token->getLine());
170
  break;
171
 
172
  case 'false':
173
  case 'FALSE':
174
+ $node = new ConstantExpression(false, $token->getLine());
175
  break;
176
 
177
  case 'none':
178
  case 'NONE':
179
  case 'null':
180
  case 'NULL':
181
+ $node = new ConstantExpression(null, $token->getLine());
182
  break;
183
 
184
  default:
185
  if ('(' === $this->parser->getCurrentToken()->getValue()) {
186
  $node = $this->getFunctionNode($token->getValue(), $token->getLine());
187
  } else {
188
+ $node = new NameExpression($token->getValue(), $token->getLine());
189
  }
190
  }
191
  break;
192
 
193
+ case Token::NUMBER_TYPE:
194
  $this->parser->getStream()->next();
195
+ $node = new ConstantExpression($token->getValue(), $token->getLine());
196
  break;
197
 
198
+ case Token::STRING_TYPE:
199
+ case Token::INTERPOLATION_START_TYPE:
200
  $node = $this->parseStringExpression();
201
  break;
202
 
203
+ case Token::OPERATOR_TYPE:
204
+ if (preg_match(Lexer::REGEX_NAME, $token->getValue(), $matches) && $matches[0] == $token->getValue()) {
205
  // in this context, string operators are variable names
206
  $this->parser->getStream()->next();
207
+ $node = new NameExpression($token->getValue(), $token->getLine());
208
  break;
209
  } elseif (isset($this->unaryOperators[$token->getValue()])) {
210
  $class = $this->unaryOperators[$token->getValue()]['class'];
211
 
212
+ $ref = new \ReflectionClass($class);
213
  $negClass = 'Twig_Node_Expression_Unary_Neg';
214
  $posClass = 'Twig_Node_Expression_Unary_Pos';
215
+ if (!(\in_array($ref->getName(), [$negClass, $posClass]) || $ref->isSubclassOf($negClass) || $ref->isSubclassOf($posClass))) {
216
+ throw new SyntaxError(sprintf('Unexpected unary operator "%s".', $token->getValue()), $token->getLine(), $this->parser->getStream()->getSourceContext());
217
  }
218
 
219
  $this->parser->getStream()->next();
225
 
226
  // no break
227
  default:
228
+ if ($token->test(Token::PUNCTUATION_TYPE, '[')) {
229
  $node = $this->parseArrayExpression();
230
+ } elseif ($token->test(Token::PUNCTUATION_TYPE, '{')) {
231
  $node = $this->parseHashExpression();
232
+ } elseif ($token->test(Token::OPERATOR_TYPE, '=') && ('==' === $this->parser->getStream()->look(-1)->getValue() || '!=' === $this->parser->getStream()->look(-1)->getValue())) {
233
+ throw new SyntaxError(sprintf('Unexpected operator of value "%s". Did you try to use "===" or "!==" for strict comparison? Use "is same as(value)" instead.', $token->getValue()), $token->getLine(), $this->parser->getStream()->getSourceContext());
234
  } else {
235
+ throw new SyntaxError(sprintf('Unexpected token "%s" of value "%s".', Token::typeToEnglish($token->getType()), $token->getValue()), $token->getLine(), $this->parser->getStream()->getSourceContext());
236
  }
237
  }
238
 
247
  // a string cannot be followed by another string in a single expression
248
  $nextCanBeString = true;
249
  while (true) {
250
+ if ($nextCanBeString && $token = $stream->nextIf(Token::STRING_TYPE)) {
251
+ $nodes[] = new ConstantExpression($token->getValue(), $token->getLine());
252
  $nextCanBeString = false;
253
+ } elseif ($stream->nextIf(Token::INTERPOLATION_START_TYPE)) {
254
  $nodes[] = $this->parseExpression();
255
+ $stream->expect(Token::INTERPOLATION_END_TYPE);
256
  $nextCanBeString = true;
257
  } else {
258
  break;
261
 
262
  $expr = array_shift($nodes);
263
  foreach ($nodes as $node) {
264
+ $expr = new ConcatBinary($expr, $node, $node->getTemplateLine());
265
  }
266
 
267
  return $expr;
270
  public function parseArrayExpression()
271
  {
272
  $stream = $this->parser->getStream();
273
+ $stream->expect(Token::PUNCTUATION_TYPE, '[', 'An array element was expected');
274
 
275
+ $node = new ArrayExpression([], $stream->getCurrent()->getLine());
276
  $first = true;
277
+ while (!$stream->test(Token::PUNCTUATION_TYPE, ']')) {
278
  if (!$first) {
279
+ $stream->expect(Token::PUNCTUATION_TYPE, ',', 'An array element must be followed by a comma');
280
 
281
  // trailing ,?
282
+ if ($stream->test(Token::PUNCTUATION_TYPE, ']')) {
283
  break;
284
  }
285
  }
287
 
288
  $node->addElement($this->parseExpression());
289
  }
290
+ $stream->expect(Token::PUNCTUATION_TYPE, ']', 'An opened array is not properly closed');
291
 
292
  return $node;
293
  }
295
  public function parseHashExpression()
296
  {
297
  $stream = $this->parser->getStream();
298
+ $stream->expect(Token::PUNCTUATION_TYPE, '{', 'A hash element was expected');
299
 
300
+ $node = new ArrayExpression([], $stream->getCurrent()->getLine());
301
  $first = true;
302
+ while (!$stream->test(Token::PUNCTUATION_TYPE, '}')) {
303
  if (!$first) {
304
+ $stream->expect(Token::PUNCTUATION_TYPE, ',', 'A hash value must be followed by a comma');
305
 
306
  // trailing ,?
307
+ if ($stream->test(Token::PUNCTUATION_TYPE, '}')) {
308
  break;
309
  }
310
  }
316
  // * a string -- 'a'
317
  // * a name, which is equivalent to a string -- a
318
  // * an expression, which must be enclosed in parentheses -- (1 + 2)
319
+ if (($token = $stream->nextIf(Token::STRING_TYPE)) || ($token = $stream->nextIf(Token::NAME_TYPE)) || $token = $stream->nextIf(Token::NUMBER_TYPE)) {
320
+ $key = new ConstantExpression($token->getValue(), $token->getLine());
321
+ } elseif ($stream->test(Token::PUNCTUATION_TYPE, '(')) {
322
  $key = $this->parseExpression();
323
  } else {
324
  $current = $stream->getCurrent();
325
 
326
+ throw new SyntaxError(sprintf('A hash key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "%s" of value "%s".', Token::typeToEnglish($current->getType()), $current->getValue()), $current->getLine(), $stream->getSourceContext());
327
  }
328
 
329
+ $stream->expect(Token::PUNCTUATION_TYPE, ':', 'A hash key must be followed by a colon (:)');
330
  $value = $this->parseExpression();
331
 
332
  $node->addElement($value, $key);
333
  }
334
+ $stream->expect(Token::PUNCTUATION_TYPE, '}', 'An opened hash is not properly closed');
335
 
336
  return $node;
337
  }
340
  {
341
  while (true) {
342
  $token = $this->parser->getCurrentToken();
343
+ if (Token::PUNCTUATION_TYPE == $token->getType()) {
344
  if ('.' == $token->getValue() || '[' == $token->getValue()) {
345
  $node = $this->parseSubscriptExpression($node);
346
  } elseif ('|' == $token->getValue()) {
361
  switch ($name) {
362
  case 'parent':
363
  $this->parseArguments();
364
+ if (!\count($this->parser->getBlockStack())) {
365
+ throw new SyntaxError('Calling "parent" outside a block is forbidden.', $line, $this->parser->getStream()->getSourceContext());
366
  }
367
 
368
  if (!$this->parser->getParent() && !$this->parser->hasTraits()) {
369
+ throw new SyntaxError('Calling "parent" on a template that does not extend nor "use" another template is forbidden.', $line, $this->parser->getStream()->getSourceContext());
370
  }
371
 
372
+ return new ParentExpression($this->parser->peekBlockStack(), $line);
373
  case 'block':
374
  $args = $this->parseArguments();
375
+ if (\count($args) < 1) {
376
+ throw new SyntaxError('The "block" function takes one argument (the block name).', $line, $this->parser->getStream()->getSourceContext());
377
  }
378
 
379
+ return new BlockReferenceExpression($args->getNode(0), \count($args) > 1 ? $args->getNode(1) : null, $line);
380
  case 'attribute':
381
  $args = $this->parseArguments();
382
+ if (\count($args) < 2) {
383
+ throw new SyntaxError('The "attribute" function takes at least two arguments (the variable and the attributes).', $line, $this->parser->getStream()->getSourceContext());
384
  }
385
 
386
+ return new GetAttrExpression($args->getNode(0), $args->getNode(1), \count($args) > 2 ? $args->getNode(2) : null, Template::ANY_CALL, $line);
387
  default:
388
  if (null !== $alias = $this->parser->getImportedSymbol('function', $name)) {
389
+ $arguments = new ArrayExpression([], $line);
390
  foreach ($this->parseArguments() as $n) {
391
  $arguments->addElement($n);
392
  }
393
 
394
+ $node = new MethodCallExpression($alias['node'], $alias['name'], $arguments, $line);
395
  $node->setAttribute('safe', true);
396
 
397
  return $node;
409
  $stream = $this->parser->getStream();
410
  $token = $stream->next();
411
  $lineno = $token->getLine();
412
+ $arguments = new ArrayExpression([], $lineno);
413
+ $type = Template::ANY_CALL;
414
  if ('.' == $token->getValue()) {
415
  $token = $stream->next();
416
  if (
417
+ Token::NAME_TYPE == $token->getType()
418
  ||
419
+ Token::NUMBER_TYPE == $token->getType()
420
  ||
421
+ (Token::OPERATOR_TYPE == $token->getType() && preg_match(Lexer::REGEX_NAME, $token->getValue()))
422
  ) {
423
+ $arg = new ConstantExpression($token->getValue(), $lineno);
424
 
425
+ if ($stream->test(Token::PUNCTUATION_TYPE, '(')) {
426
+ $type = Template::METHOD_CALL;
427
  foreach ($this->parseArguments() as $n) {
428
  $arguments->addElement($n);
429
  }
430
  }
431
  } else {
432
+ throw new SyntaxError('Expected name or number.', $lineno, $stream->getSourceContext());
433
  }
434
 
435
+ if ($node instanceof NameExpression && null !== $this->parser->getImportedSymbol('template', $node->getAttribute('name'))) {
436
+ if (!$arg instanceof ConstantExpression) {
437
+ throw new SyntaxError(sprintf('Dynamic macro names are not supported (called on "%s").', $node->getAttribute('name')), $token->getLine(), $stream->getSourceContext());
438
  }
439
 
440
  $name = $arg->getAttribute('value');
441
 
442
  if ($this->parser->isReservedMacroName($name)) {
443
+ throw new SyntaxError(sprintf('"%s" cannot be called as macro as it is a reserved keyword.', $name), $token->getLine(), $stream->getSourceContext());
444
  }
445
 
446
+ $node = new MethodCallExpression($node, 'get'.$name, $arguments, $lineno);
447
  $node->setAttribute('safe', true);
448
 
449
  return $node;
450
  }
451
  } else {
452
+ $type = Template::ARRAY_CALL;
453
 
454
  // slice?
455
  $slice = false;
456
+ if ($stream->test(Token::PUNCTUATION_TYPE, ':')) {
457
  $slice = true;
458
+ $arg = new ConstantExpression(0, $token->getLine());
459
  } else {
460
  $arg = $this->parseExpression();
461
  }
462
 
463
+ if ($stream->nextIf(Token::PUNCTUATION_TYPE, ':')) {
464
  $slice = true;
465
  }
466
 
467
  if ($slice) {
468
+ if ($stream->test(Token::PUNCTUATION_TYPE, ']')) {
469
+ $length = new ConstantExpression(null, $token->getLine());
470
  } else {
471
  $length = $this->parseExpression();
472
  }
473
 
474
  $class = $this->getFilterNodeClass('slice', $token->getLine());
475
+ $arguments = new Node([$arg, $length]);
476
+ $filter = new $class($node, new ConstantExpression('slice', $token->getLine()), $arguments, $token->getLine());
477
 
478
+ $stream->expect(Token::PUNCTUATION_TYPE, ']');
479
 
480
  return $filter;
481
  }
482
 
483
+ $stream->expect(Token::PUNCTUATION_TYPE, ']');
484
  }
485
 
486
+ return new GetAttrExpression($node, $arg, $arguments, $type, $lineno);
487
  }
488
 
489
  public function parseFilterExpression($node)
496
  public function parseFilterExpressionRaw($node, $tag = null)
497
  {
498
  while (true) {
499
+ $token = $this->parser->getStream()->expect(Token::NAME_TYPE);
500
 
501
+ $name = new ConstantExpression($token->getValue(), $token->getLine());
502
+ if (!$this->parser->getStream()->test(Token::PUNCTUATION_TYPE, '(')) {
503
+ $arguments = new Node();
504
  } else {
505
  $arguments = $this->parseArguments(true);
506
  }
509
 
510
  $node = new $class($node, $name, $arguments, $token->getLine(), $tag);
511
 
512
+ if (!$this->parser->getStream()->test(Token::PUNCTUATION_TYPE, '|')) {
513
  break;
514
  }
515
 
525
  * @param bool $namedArguments Whether to allow named arguments or not
526
  * @param bool $definition Whether we are parsing arguments for a function definition
527
  *
528
+ * @return Node
529
  *
530
+ * @throws SyntaxError
531
  */
532
  public function parseArguments($namedArguments = false, $definition = false)
533
  {
534
  $args = [];
535
  $stream = $this->parser->getStream();
536
 
537
+ $stream->expect(Token::PUNCTUATION_TYPE, '(', 'A list of arguments must begin with an opening parenthesis');
538
+ while (!$stream->test(Token::PUNCTUATION_TYPE, ')')) {
539
  if (!empty($args)) {
540
+ $stream->expect(Token::PUNCTUATION_TYPE, ',', 'Arguments must be separated by a comma');
541
  }
542
 
543
  if ($definition) {
544
+ $token = $stream->expect(Token::NAME_TYPE, null, 'An argument must be a name');
545
+ $value = new NameExpression($token->getValue(), $this->parser->getCurrentToken()->getLine());
546
  } else {
547
  $value = $this->parseExpression();
548
  }
549
 
550
  $name = null;
551
+ if ($namedArguments && $token = $stream->nextIf(Token::OPERATOR_TYPE, '=')) {
552
+ if (!$value instanceof NameExpression) {
553
+ throw new SyntaxError(sprintf('A parameter name must be a string, "%s" given.', \get_class($value)), $token->getLine(), $stream->getSourceContext());
554
  }
555
  $name = $value->getAttribute('name');
556
 
558
  $value = $this->parsePrimaryExpression();
559
 
560
  if (!$this->checkConstantExpression($value)) {
561
+ throw new SyntaxError(sprintf('A default value for an argument must be a constant (a boolean, a string, a number, or an array).'), $token->getLine(), $stream->getSourceContext());
562
  }
563
  } else {
564
  $value = $this->parseExpression();
568
  if ($definition) {
569
  if (null === $name) {
570
  $name = $value->getAttribute('name');
571
+ $value = new ConstantExpression(null, $this->parser->getCurrentToken()->getLine());
572
  }
573
  $args[$name] = $value;
574
  } else {
579
  }
580
  }
581
  }
582
+ $stream->expect(Token::PUNCTUATION_TYPE, ')', 'A list of arguments must be closed by a parenthesis');
583
 
584
+ return new Node($args);
585
  }
586
 
587
  public function parseAssignmentExpression()
589
  $stream = $this->parser->getStream();
590
  $targets = [];
591
  while (true) {
592
+ $token = $stream->expect(Token::NAME_TYPE, null, 'Only variables can be assigned to');
593
  $value = $token->getValue();
594
+ if (\in_array(strtolower($value), ['true', 'false', 'none', 'null'])) {
595
+ throw new SyntaxError(sprintf('You cannot assign a value to "%s".', $value), $token->getLine(), $stream->getSourceContext());
596
  }
597
+ $targets[] = new AssignNameExpression($value, $token->getLine());
598
 
599
+ if (!$stream->nextIf(Token::PUNCTUATION_TYPE, ',')) {
600
  break;
601
  }
602
  }
603
 
604
+ return new Node($targets);
605
  }
606
 
607
  public function parseMultitargetExpression()
609
  $targets = [];
610
  while (true) {
611
  $targets[] = $this->parseExpression();
612
+ if (!$this->parser->getStream()->nextIf(Token::PUNCTUATION_TYPE, ',')) {
613
  break;
614
  }
615
  }
616
 
617
+ return new Node($targets);
618
  }
619
 
620
  private function parseNotTestExpression(Twig_NodeInterface $node)
621
  {
622
+ return new NotUnary($this->parseTestExpression($node), $this->parser->getCurrentToken()->getLine());
623
  }
624
 
625
  private function parseTestExpression(Twig_NodeInterface $node)
629
 
630
  $class = $this->getTestNodeClass($test);
631
  $arguments = null;
632
+ if ($stream->test(Token::PUNCTUATION_TYPE, '(')) {
633
  $arguments = $this->parser->getExpressionParser()->parseArguments(true);
634
  }
635
 
639
  private function getTest($line)
640
  {
641
  $stream = $this->parser->getStream();
642
+ $name = $stream->expect(Token::NAME_TYPE)->getValue();
643
 
644
  if ($test = $this->env->getTest($name)) {
645
  return [$name, $test];
646
  }
647
 
648
+ if ($stream->test(Token::NAME_TYPE)) {
649
  // try 2-words tests
650
  $name = $name.' '.$this->parser->getCurrentToken()->getValue();
651
 
656
  }
657
  }
658
 
659
+ $e = new SyntaxError(sprintf('Unknown "%s" test.', $name), $line, $stream->getSourceContext());
660
  $e->addSuggestions($name, array_keys($this->env->getTests()));
661
 
662
  throw $e;
664
 
665
  private function getTestNodeClass($test)
666
  {
667
+ if ($test instanceof TwigTest && $test->isDeprecated()) {
668
  $stream = $this->parser->getStream();
669
  $message = sprintf('Twig Test "%s" is deprecated', $test->getName());
670
+ if (!\is_bool($test->getDeprecatedVersion())) {
671
  $message .= sprintf(' since version %s', $test->getDeprecatedVersion());
672
  }
673
  if ($test->getAlternative()) {
679
  @trigger_error($message, E_USER_DEPRECATED);
680
  }
681
 
682
+ if ($test instanceof TwigTest) {
683
  return $test->getNodeClass();
684
  }
685
 
689
  protected function getFunctionNodeClass($name, $line)
690
  {
691
  if (false === $function = $this->env->getFunction($name)) {
692
+ $e = new SyntaxError(sprintf('Unknown "%s" function.', $name), $line, $this->parser->getStream()->getSourceContext());
693
  $e->addSuggestions($name, array_keys($this->env->getFunctions()));
694
 
695
  throw $e;
696
  }
697
 
698
+ if ($function instanceof TwigFunction && $function->isDeprecated()) {
699
  $message = sprintf('Twig Function "%s" is deprecated', $function->getName());
700
+ if (!\is_bool($function->getDeprecatedVersion())) {
701
  $message .= sprintf(' since version %s', $function->getDeprecatedVersion());
702
  }
703
  if ($function->getAlternative()) {
709
  @trigger_error($message, E_USER_DEPRECATED);
710
  }
711
 
712
+ if ($function instanceof TwigFunction) {
713
  return $function->getNodeClass();
714
  }
715
 
719
  protected function getFilterNodeClass($name, $line)
720
  {
721
  if (false === $filter = $this->env->getFilter($name)) {
722
+ $e = new SyntaxError(sprintf('Unknown "%s" filter.', $name), $line, $this->parser->getStream()->getSourceContext());
723
  $e->addSuggestions($name, array_keys($this->env->getFilters()));
724
 
725
  throw $e;
726
  }
727
 
728
+ if ($filter instanceof TwigFilter && $filter->isDeprecated()) {
729
  $message = sprintf('Twig Filter "%s" is deprecated', $filter->getName());
730
+ if (!\is_bool($filter->getDeprecatedVersion())) {
731
  $message .= sprintf(' since version %s', $filter->getDeprecatedVersion());
732
  }
733
  if ($filter->getAlternative()) {
739
  @trigger_error($message, E_USER_DEPRECATED);
740
  }
741
 
742
+ if ($filter instanceof TwigFilter) {
743
  return $filter->getNodeClass();
744
  }
745
 
749
  // checks that the node only contains "constant" elements
750
  protected function checkConstantExpression(Twig_NodeInterface $node)
751
  {
752
+ if (!($node instanceof ConstantExpression || $node instanceof ArrayExpression
753
+ || $node instanceof NegUnary || $node instanceof PosUnary
754
  )) {
755
  return false;
756
  }
vendor/twig/twig/lib/Twig/Extension.php CHANGED
@@ -9,12 +9,15 @@
9
  * file that was distributed with this source code.
10
  */
11
 
12
- abstract class Twig_Extension implements Twig_ExtensionInterface
 
 
 
13
  {
14
  /**
15
  * @deprecated since 1.23 (to be removed in 2.0), implement Twig_Extension_InitRuntimeInterface instead
16
  */
17
- public function initRuntime(Twig_Environment $environment)
18
  {
19
  }
20
 
@@ -61,7 +64,7 @@ abstract class Twig_Extension implements Twig_ExtensionInterface
61
  */
62
  public function getName()
63
  {
64
- return get_class($this);
65
  }
66
  }
67
 
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Environment;
13
+ use Twig\Extension\ExtensionInterface;
14
+
15
+ abstract class Twig_Extension implements ExtensionInterface
16
  {
17
  /**
18
  * @deprecated since 1.23 (to be removed in 2.0), implement Twig_Extension_InitRuntimeInterface instead
19
  */
20
+ public function initRuntime(Environment $environment)
21
  {
22
  }
23
 
64
  */
65
  public function getName()
66
  {
67
+ return \get_class($this);
68
  }
69
  }
70
 
vendor/twig/twig/lib/Twig/Extension/Core.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
 
3
- if (!defined('ENT_SUBSTITUTE')) {
4
- define('ENT_SUBSTITUTE', 8);
5
  }
6
 
7
  /*
@@ -13,10 +13,39 @@ if (!defined('ENT_SUBSTITUTE')) {
13
  * file that was distributed with this source code.
14
  */
15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  /**
17
  * @final
18
  */
19
- class Twig_Extension_Core extends Twig_Extension
20
  {
21
  protected $dateFormats = ['F j, Y H:i', '%d days'];
22
  protected $numberFormat = [0, '.', ','];
@@ -74,22 +103,22 @@ class Twig_Extension_Core extends Twig_Extension
74
  /**
75
  * Sets the default timezone to be used by the date filter.
76
  *
77
- * @param DateTimeZone|string $timezone The default timezone string or a DateTimeZone object
78
  */
79
  public function setTimezone($timezone)
80
  {
81
- $this->timezone = $timezone instanceof DateTimeZone ? $timezone : new DateTimeZone($timezone);
82
  }
83
 
84
  /**
85
  * Gets the default timezone to be used by the date filter.
86
  *
87
- * @return DateTimeZone The default timezone currently in use
88
  */
89
  public function getTimezone()
90
  {
91
  if (null === $this->timezone) {
92
- $this->timezone = new DateTimeZone(date_default_timezone_get());
93
  }
94
 
95
  return $this->timezone;
@@ -120,23 +149,23 @@ class Twig_Extension_Core extends Twig_Extension
120
  public function getTokenParsers()
121
  {
122
  return [
123
- new Twig_TokenParser_For(),
124
- new Twig_TokenParser_If(),
125
- new Twig_TokenParser_Extends(),
126
- new Twig_TokenParser_Include(),
127
- new Twig_TokenParser_Block(),
128
- new Twig_TokenParser_Use(),
129
- new Twig_TokenParser_Filter(),
130
- new Twig_TokenParser_Macro(),
131
- new Twig_TokenParser_Import(),
132
- new Twig_TokenParser_From(),
133
- new Twig_TokenParser_Set(),
134
- new Twig_TokenParser_Spaceless(),
135
- new Twig_TokenParser_Flush(),
136
- new Twig_TokenParser_Do(),
137
- new Twig_TokenParser_Embed(),
138
- new Twig_TokenParser_With(),
139
- new Twig_TokenParser_Deprecated(),
140
  ];
141
  }
142
 
@@ -144,54 +173,54 @@ class Twig_Extension_Core extends Twig_Extension
144
  {
145
  $filters = [
146
  // formatting filters
147
- new Twig_SimpleFilter('date', 'twig_date_format_filter', ['needs_environment' => true]),
148
- new Twig_SimpleFilter('date_modify', 'twig_date_modify_filter', ['needs_environment' => true]),
149
- new Twig_SimpleFilter('format', 'sprintf'),
150
- new Twig_SimpleFilter('replace', 'twig_replace_filter'),
151
- new Twig_SimpleFilter('number_format', 'twig_number_format_filter', ['needs_environment' => true]),
152
- new Twig_SimpleFilter('abs', 'abs'),
153
- new Twig_SimpleFilter('round', 'twig_round'),
154
 
155
  // encoding
156
- new Twig_SimpleFilter('url_encode', 'twig_urlencode_filter'),
157
- new Twig_SimpleFilter('json_encode', 'twig_jsonencode_filter'),
158
- new Twig_SimpleFilter('convert_encoding', 'twig_convert_encoding'),
159
 
160
  // string filters
161
- new Twig_SimpleFilter('title', 'twig_title_string_filter', ['needs_environment' => true]),
162
- new Twig_SimpleFilter('capitalize', 'twig_capitalize_string_filter', ['needs_environment' => true]),
163
- new Twig_SimpleFilter('upper', 'strtoupper'),
164
- new Twig_SimpleFilter('lower', 'strtolower'),
165
- new Twig_SimpleFilter('striptags', 'strip_tags'),
166
- new Twig_SimpleFilter('trim', 'twig_trim_filter'),
167
- new Twig_SimpleFilter('nl2br', 'nl2br', ['pre_escape' => 'html', 'is_safe' => ['html']]),
168
 
169
  // array helpers
170
- new Twig_SimpleFilter('join', 'twig_join_filter'),
171
- new Twig_SimpleFilter('split', 'twig_split_filter', ['needs_environment' => true]),
172
- new Twig_SimpleFilter('sort', 'twig_sort_filter'),
173
- new Twig_SimpleFilter('merge', 'twig_array_merge'),
174
- new Twig_SimpleFilter('batch', 'twig_array_batch'),
175
 
176
  // string/array filters
177
- new Twig_SimpleFilter('reverse', 'twig_reverse_filter', ['needs_environment' => true]),
178
- new Twig_SimpleFilter('length', 'twig_length_filter', ['needs_environment' => true]),
179
- new Twig_SimpleFilter('slice', 'twig_slice', ['needs_environment' => true]),
180
- new Twig_SimpleFilter('first', 'twig_first', ['needs_environment' => true]),
181
- new Twig_SimpleFilter('last', 'twig_last', ['needs_environment' => true]),
182
 
183
  // iteration and runtime
184
- new Twig_SimpleFilter('default', '_twig_default_filter', ['node_class' => 'Twig_Node_Expression_Filter_Default']),
185
- new Twig_SimpleFilter('keys', 'twig_get_array_keys_filter'),
186
 
187
  // escaping
188
- new Twig_SimpleFilter('escape', 'twig_escape_filter', ['needs_environment' => true, 'is_safe_callback' => 'twig_escape_filter_is_safe']),
189
- new Twig_SimpleFilter('e', 'twig_escape_filter', ['needs_environment' => true, 'is_safe_callback' => 'twig_escape_filter_is_safe']),
190
  ];
191
 
192
- if (function_exists('mb_get_info')) {
193
- $filters[] = new Twig_SimpleFilter('upper', 'twig_upper_filter', ['needs_environment' => true]);
194
- $filters[] = new Twig_SimpleFilter('lower', 'twig_lower_filter', ['needs_environment' => true]);
195
  }
196
 
197
  return $filters;
@@ -200,33 +229,33 @@ class Twig_Extension_Core extends Twig_Extension
200
  public function getFunctions()
201
  {
202
  return [
203
- new Twig_SimpleFunction('max', 'max'),
204
- new Twig_SimpleFunction('min', 'min'),
205
- new Twig_SimpleFunction('range', 'range'),
206
- new Twig_SimpleFunction('constant', 'twig_constant'),
207
- new Twig_SimpleFunction('cycle', 'twig_cycle'),
208
- new Twig_SimpleFunction('random', 'twig_random', ['needs_environment' => true]),
209
- new Twig_SimpleFunction('date', 'twig_date_converter', ['needs_environment' => true]),
210
- new Twig_SimpleFunction('include', 'twig_include', ['needs_environment' => true, 'needs_context' => true, 'is_safe' => ['all']]),
211
- new Twig_SimpleFunction('source', 'twig_source', ['needs_environment' => true, 'is_safe' => ['all']]),
212
  ];
213
  }
214
 
215
  public function getTests()
216
  {
217
  return [
218
- new Twig_SimpleTest('even', null, ['node_class' => 'Twig_Node_Expression_Test_Even']),
219
- new Twig_SimpleTest('odd', null, ['node_class' => 'Twig_Node_Expression_Test_Odd']),
220
- new Twig_SimpleTest('defined', null, ['node_class' => 'Twig_Node_Expression_Test_Defined']),
221
- new Twig_SimpleTest('sameas', null, ['node_class' => 'Twig_Node_Expression_Test_Sameas', 'deprecated' => '1.21', 'alternative' => 'same as']),
222
- new Twig_SimpleTest('same as', null, ['node_class' => 'Twig_Node_Expression_Test_Sameas']),
223
- new Twig_SimpleTest('none', null, ['node_class' => 'Twig_Node_Expression_Test_Null']),
224
- new Twig_SimpleTest('null', null, ['node_class' => 'Twig_Node_Expression_Test_Null']),
225
- new Twig_SimpleTest('divisibleby', null, ['node_class' => 'Twig_Node_Expression_Test_Divisibleby', 'deprecated' => '1.21', 'alternative' => 'divisible by']),
226
- new Twig_SimpleTest('divisible by', null, ['node_class' => 'Twig_Node_Expression_Test_Divisibleby']),
227
- new Twig_SimpleTest('constant', null, ['node_class' => 'Twig_Node_Expression_Test_Constant']),
228
- new Twig_SimpleTest('empty', 'twig_test_empty'),
229
- new Twig_SimpleTest('iterable', 'twig_test_iterable'),
230
  ];
231
  }
232
 
@@ -234,39 +263,39 @@ class Twig_Extension_Core extends Twig_Extension
234
  {
235
  return [
236
  [
237
- 'not' => ['precedence' => 50, 'class' => 'Twig_Node_Expression_Unary_Not'],
238
- '-' => ['precedence' => 500, 'class' => 'Twig_Node_Expression_Unary_Neg'],
239
- '+' => ['precedence' => 500, 'class' => 'Twig_Node_Expression_Unary_Pos'],
240
  ],
241
  [
242
- 'or' => ['precedence' => 10, 'class' => 'Twig_Node_Expression_Binary_Or', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT],
243
- 'and' => ['precedence' => 15, 'class' => 'Twig_Node_Expression_Binary_And', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT],
244
- 'b-or' => ['precedence' => 16, 'class' => 'Twig_Node_Expression_Binary_BitwiseOr', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT],
245
- 'b-xor' => ['precedence' => 17, 'class' => 'Twig_Node_Expression_Binary_BitwiseXor', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT],
246
- 'b-and' => ['precedence' => 18, 'class' => 'Twig_Node_Expression_Binary_BitwiseAnd', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT],
247
- '==' => ['precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Equal', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT],
248
- '!=' => ['precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT],
249
- '<' => ['precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Less', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT],
250
- '>' => ['precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Greater', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT],
251
- '>=' => ['precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_GreaterEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT],
252
- '<=' => ['precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_LessEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT],
253
- 'not in' => ['precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotIn', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT],
254
- 'in' => ['precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_In', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT],
255
- 'matches' => ['precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Matches', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT],
256
- 'starts with' => ['precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_StartsWith', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT],
257
- 'ends with' => ['precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_EndsWith', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT],
258
- '..' => ['precedence' => 25, 'class' => 'Twig_Node_Expression_Binary_Range', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT],
259
- '+' => ['precedence' => 30, 'class' => 'Twig_Node_Expression_Binary_Add', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT],
260
- '-' => ['precedence' => 30, 'class' => 'Twig_Node_Expression_Binary_Sub', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT],
261
- '~' => ['precedence' => 40, 'class' => 'Twig_Node_Expression_Binary_Concat', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT],
262
- '*' => ['precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mul', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT],
263
- '/' => ['precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Div', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT],
264
- '//' => ['precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_FloorDiv', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT],
265
- '%' => ['precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mod', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT],
266
- 'is' => ['precedence' => 100, 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT],
267
- 'is not' => ['precedence' => 100, 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT],
268
- '**' => ['precedence' => 200, 'class' => 'Twig_Node_Expression_Binary_Power', 'associativity' => Twig_ExpressionParser::OPERATOR_RIGHT],
269
- '??' => ['precedence' => 300, 'class' => 'Twig_Node_Expression_NullCoalesce', 'associativity' => Twig_ExpressionParser::OPERATOR_RIGHT],
270
  ],
271
  ];
272
  }
@@ -287,23 +316,22 @@ class Twig_Extension_Core extends Twig_Extension
287
  */
288
  function twig_cycle($values, $position)
289
  {
290
- if (!is_array($values) && !$values instanceof ArrayAccess) {
291
  return $values;
292
  }
293
 
294
- return $values[$position % count($values)];
295
  }
296
 
297
  /**
298
  * Returns a random value depending on the supplied parameter type:
299
- * - a random item from a Traversable or array
300
  * - a random character from a string
301
  * - a random integer between 0 and the integer parameter.
302
  *
303
- * @param Twig_Environment $env
304
- * @param Traversable|array|int|float|string $values The values to pick a random item from
305
  *
306
- * @throws Twig_Error_Runtime when $values is an empty array (does not apply to an empty string which is returned as is)
307
  *
308
  * @return mixed A random value from the given sequence
309
  */
@@ -313,13 +341,13 @@ function twig_random(Twig_Environment $env, $values = null)
313
  return mt_rand();
314
  }
315
 
316
- if (is_int($values) || is_float($values)) {
317
  return $values < 0 ? mt_rand($values, 0) : mt_rand(0, $values);
318
  }
319
 
320
- if ($values instanceof Traversable) {
321
  $values = iterator_to_array($values);
322
- } elseif (is_string($values)) {
323
  if ('' === $values) {
324
  return '';
325
  }
@@ -338,16 +366,16 @@ function twig_random(Twig_Environment $env, $values = null)
338
  }
339
  }
340
  } else {
341
- return $values[mt_rand(0, strlen($values) - 1)];
342
  }
343
  }
344
 
345
- if (!is_array($values)) {
346
  return $values;
347
  }
348
 
349
- if (0 === count($values)) {
350
- throw new Twig_Error_Runtime('The random function cannot pick from an empty array.');
351
  }
352
 
353
  return $values[array_rand($values, 1)];
@@ -356,25 +384,22 @@ function twig_random(Twig_Environment $env, $values = null)
356
  /**
357
  * Converts a date to the given format.
358
  *
359
- * <pre>
360
  * {{ post.published_at|date("m/d/Y") }}
361
- * </pre>
362
  *
363
- * @param Twig_Environment $env
364
- * @param DateTime|DateTimeInterface|DateInterval|string $date A date
365
- * @param string|null $format The target format, null to use the default
366
- * @param DateTimeZone|string|false|null $timezone The target timezone, null to use the default, false to leave unchanged
367
  *
368
  * @return string The formatted date
369
  */
370
  function twig_date_format_filter(Twig_Environment $env, $date, $format = null, $timezone = null)
371
  {
372
  if (null === $format) {
373
- $formats = $env->getExtension('Twig_Extension_Core')->getDateFormat();
374
- $format = $date instanceof DateInterval ? $formats[1] : $formats[0];
375
  }
376
 
377
- if ($date instanceof DateInterval) {
378
  return $date->format($format);
379
  }
380
 
@@ -384,59 +409,53 @@ function twig_date_format_filter(Twig_Environment $env, $date, $format = null, $
384
  /**
385
  * Returns a new date object modified.
386
  *
387
- * <pre>
388
  * {{ post.published_at|date_modify("-1day")|date("m/d/Y") }}
389
- * </pre>
390
  *
391
- * @param Twig_Environment $env
392
- * @param DateTime|string $date A date
393
  * @param string $modifier A modifier string
394
  *
395
- * @return DateTime A new date object
396
  */
397
  function twig_date_modify_filter(Twig_Environment $env, $date, $modifier)
398
  {
399
  $date = twig_date_converter($env, $date, false);
400
  $resultDate = $date->modify($modifier);
401
 
402
- // This is a hack to ensure PHP 5.2 support and support for DateTimeImmutable
403
- // DateTime::modify does not return the modified DateTime object < 5.3.0
404
- // and DateTimeImmutable does not modify $date.
405
  return null === $resultDate ? $date : $resultDate;
406
  }
407
 
408
  /**
409
- * Converts an input to a DateTime instance.
410
  *
411
- * <pre>
412
  * {% if date(user.created_at) < date('+2days') %}
413
  * {# do something #}
414
  * {% endif %}
415
- * </pre>
416
  *
417
- * @param Twig_Environment $env
418
- * @param DateTime|DateTimeInterface|string|null $date A date
419
- * @param DateTimeZone|string|false|null $timezone The target timezone, null to use the default, false to leave unchanged
420
  *
421
- * @return DateTime A DateTime instance
422
  */
423
  function twig_date_converter(Twig_Environment $env, $date = null, $timezone = null)
424
  {
425
  // determine the timezone
426
  if (false !== $timezone) {
427
  if (null === $timezone) {
428
- $timezone = $env->getExtension('Twig_Extension_Core')->getTimezone();
429
- } elseif (!$timezone instanceof DateTimeZone) {
430
- $timezone = new DateTimeZone($timezone);
431
  }
432
  }
433
 
434
  // immutable dates
435
- if ($date instanceof DateTimeImmutable) {
436
  return false !== $timezone ? $date->setTimezone($timezone) : $date;
437
  }
438
 
439
- if ($date instanceof DateTime || $date instanceof DateTimeInterface) {
440
  $date = clone $date;
441
  if (false !== $timezone) {
442
  $date->setTimezone($timezone);
@@ -446,14 +465,14 @@ function twig_date_converter(Twig_Environment $env, $date = null, $timezone = nu
446
  }
447
 
448
  if (null === $date || 'now' === $date) {
449
- return new DateTime($date, false !== $timezone ? $timezone : $env->getExtension('Twig_Extension_Core')->getTimezone());
450
  }
451
 
452
  $asString = (string) $date;
453
  if (ctype_digit($asString) || (!empty($asString) && '-' === $asString[0] && ctype_digit(substr($asString, 1)))) {
454
- $date = new DateTime('@'.$date);
455
  } else {
456
- $date = new DateTime($date, $env->getExtension('Twig_Extension_Core')->getTimezone());
457
  }
458
 
459
  if (false !== $timezone) {
@@ -466,22 +485,22 @@ function twig_date_converter(Twig_Environment $env, $date = null, $timezone = nu
466
  /**
467
  * Replaces strings within a string.
468
  *
469
- * @param string $str String to replace in
470
- * @param array|Traversable $from Replace values
471
- * @param string|null $to Replace to, deprecated (@see https://secure.php.net/manual/en/function.strtr.php)
472
  *
473
  * @return string
474
  */
475
  function twig_replace_filter($str, $from, $to = null)
476
  {
477
- if ($from instanceof Traversable) {
478
  $from = iterator_to_array($from);
479
- } elseif (is_string($from) && is_string($to)) {
480
  @trigger_error('Using "replace" with character by character replacement is deprecated since version 1.22 and will be removed in Twig 2.0', E_USER_DEPRECATED);
481
 
482
  return strtr($str, $from, $to);
483
- } elseif (!is_array($from)) {
484
- throw new Twig_Error_Runtime(sprintf('The "replace" filter expects an array or "Traversable" as replace values, got "%s".', is_object($from) ? get_class($from) : gettype($from)));
485
  }
486
 
487
  return strtr($str, $from);
@@ -503,7 +522,7 @@ function twig_round($value, $precision = 0, $method = 'common')
503
  }
504
 
505
  if ('ceil' != $method && 'floor' != $method) {
506
- throw new Twig_Error_Runtime('The round filter only supports the "common", "ceil", and "floor" methods.');
507
  }
508
 
509
  return $method($value * pow(10, $precision)) / pow(10, $precision);
@@ -516,17 +535,16 @@ function twig_round($value, $precision = 0, $method = 'common')
516
  * be used. Supplying any of the parameters will override the defaults set in the
517
  * environment object.
518
  *
519
- * @param Twig_Environment $env
520
- * @param mixed $number A float/int/string of the number to format
521
- * @param int $decimal the number of decimal points to display
522
- * @param string $decimalPoint the character(s) to use for the decimal point
523
- * @param string $thousandSep the character(s) to use for the thousands separator
524
  *
525
  * @return string The formatted number
526
  */
527
  function twig_number_format_filter(Twig_Environment $env, $number, $decimal = null, $decimalPoint = null, $thousandSep = null)
528
  {
529
- $defaults = $env->getExtension('Twig_Extension_Core')->getNumberFormat();
530
  if (null === $decimal) {
531
  $decimal = $defaults[0];
532
  }
@@ -551,8 +569,8 @@ function twig_number_format_filter(Twig_Environment $env, $number, $decimal = nu
551
  */
552
  function twig_urlencode_filter($url)
553
  {
554
- if (is_array($url)) {
555
- if (defined('PHP_QUERY_RFC3986')) {
556
  return http_build_query($url, '', '&', PHP_QUERY_RFC3986);
557
  }
558
 
@@ -572,9 +590,9 @@ function twig_urlencode_filter($url)
572
  */
573
  function twig_jsonencode_filter($value, $options = 0)
574
  {
575
- if ($value instanceof Twig_Markup) {
576
  $value = (string) $value;
577
- } elseif (is_array($value)) {
578
  array_walk_recursive($value, '_twig_markup2string');
579
  }
580
 
@@ -583,7 +601,7 @@ function twig_jsonencode_filter($value, $options = 0)
583
 
584
  function _twig_markup2string(&$value)
585
  {
586
- if ($value instanceof Twig_Markup) {
587
  $value = (string) $value;
588
  }
589
  }
@@ -591,31 +609,29 @@ function _twig_markup2string(&$value)
591
  /**
592
  * Merges an array with another one.
593
  *
594
- * <pre>
595
  * {% set items = { 'apple': 'fruit', 'orange': 'fruit' } %}
596
  *
597
  * {% set items = items|merge({ 'peugeot': 'car' }) %}
598
  *
599
  * {# items now contains { 'apple': 'fruit', 'orange': 'fruit', 'peugeot': 'car' } #}
600
- * </pre>
601
  *
602
- * @param array|Traversable $arr1 An array
603
- * @param array|Traversable $arr2 An array
604
  *
605
  * @return array The merged array
606
  */
607
  function twig_array_merge($arr1, $arr2)
608
  {
609
- if ($arr1 instanceof Traversable) {
610
  $arr1 = iterator_to_array($arr1);
611
- } elseif (!is_array($arr1)) {
612
- throw new Twig_Error_Runtime(sprintf('The merge filter only works with arrays or "Traversable", got "%s" as first argument.', gettype($arr1)));
613
  }
614
 
615
- if ($arr2 instanceof Traversable) {
616
  $arr2 = iterator_to_array($arr2);
617
- } elseif (!is_array($arr2)) {
618
- throw new Twig_Error_Runtime(sprintf('The merge filter only works with arrays or "Traversable", got "%s" as second argument.', gettype($arr2)));
619
  }
620
 
621
  return array_merge($arr1, $arr2);
@@ -624,25 +640,24 @@ function twig_array_merge($arr1, $arr2)
624
  /**
625
  * Slices a variable.
626
  *
627
- * @param Twig_Environment $env
628
- * @param mixed $item A variable
629
- * @param int $start Start of the slice
630
- * @param int $length Size of the slice
631
- * @param bool $preserveKeys Whether to preserve key or not (when the input is an array)
632
  *
633
  * @return mixed The sliced variable
634
  */
635
  function twig_slice(Twig_Environment $env, $item, $start, $length = null, $preserveKeys = false)
636
  {
637
- if ($item instanceof Traversable) {
638
- while ($item instanceof IteratorAggregate) {
639
  $item = $item->getIterator();
640
  }
641
 
642
- if ($start >= 0 && $length >= 0 && $item instanceof Iterator) {
643
  try {
644
- return iterator_to_array(new LimitIterator($item, $start, null === $length ? -1 : $length), $preserveKeys);
645
- } catch (OutOfBoundsException $exception) {
646
  return [];
647
  }
648
  }
@@ -650,13 +665,13 @@ function twig_slice(Twig_Environment $env, $item, $start, $length = null, $prese
650
  $item = iterator_to_array($item, $preserveKeys);
651
  }
652
 
653
- if (is_array($item)) {
654
- return array_slice($item, $start, $length, $preserveKeys);
655
  }
656
 
657
  $item = (string) $item;
658
 
659
- if (function_exists('mb_get_info') && null !== $charset = $env->getCharset()) {
660
  return (string) mb_substr($item, $start, null === $length ? mb_strlen($item, $charset) - $start : $length, $charset);
661
  }
662
 
@@ -666,8 +681,7 @@ function twig_slice(Twig_Environment $env, $item, $start, $length = null, $prese
666
  /**
667
  * Returns the first element of the item.
668
  *
669
- * @param Twig_Environment $env
670
- * @param mixed $item A variable
671
  *
672
  * @return mixed The first element of the item
673
  */
@@ -675,14 +689,13 @@ function twig_first(Twig_Environment $env, $item)
675
  {
676
  $elements = twig_slice($env, $item, 0, 1, false);
677
 
678
- return is_string($elements) ? $elements : current($elements);
679
  }
680
 
681
  /**
682
  * Returns the last element of the item.
683
  *
684
- * @param Twig_Environment $env
685
- * @param mixed $item A variable
686
  *
687
  * @return mixed The last element of the item
688
  */
@@ -690,7 +703,7 @@ function twig_last(Twig_Environment $env, $item)
690
  {
691
  $elements = twig_slice($env, $item, -1, 1, false);
692
 
693
- return is_string($elements) ? $elements : current($elements);
694
  }
695
 
696
  /**
@@ -698,7 +711,6 @@ function twig_last(Twig_Environment $env, $item)
698
  *
699
  * The separators between elements are empty strings per default, you can define them with the optional parameters.
700
  *
701
- * <pre>
702
  * {{ [1, 2, 3]|join(', ', ' and ') }}
703
  * {# returns 1, 2 and 3 #}
704
  *
@@ -707,7 +719,6 @@ function twig_last(Twig_Environment $env, $item)
707
  *
708
  * {{ [1, 2, 3]|join }}
709
  * {# returns 123 #}
710
- * </pre>
711
  *
712
  * @param array $value An array
713
  * @param string $glue The separator
@@ -717,13 +728,13 @@ function twig_last(Twig_Environment $env, $item)
717
  */
718
  function twig_join_filter($value, $glue = '', $and = null)
719
  {
720
- if ($value instanceof Traversable) {
721
  $value = iterator_to_array($value, false);
722
  } else {
723
  $value = (array) $value;
724
  }
725
 
726
- if (0 === count($value)) {
727
  return '';
728
  }
729
 
@@ -732,17 +743,16 @@ function twig_join_filter($value, $glue = '', $and = null)
732
  }
733
 
734
  $v = array_values($value);
735
- if (1 === count($v)) {
736
  return $v[0];
737
  }
738
 
739
- return implode($glue, array_slice($value, 0, -1)).$and.$v[count($v) - 1];
740
  }
741
 
742
  /**
743
  * Splits the string into an array.
744
  *
745
- * <pre>
746
  * {{ "one,two,three"|split(',') }}
747
  * {# returns [one, two, three] #}
748
  *
@@ -754,12 +764,10 @@ function twig_join_filter($value, $glue = '', $and = null)
754
  *
755
  * {{ "aabbcc"|split('', 2) }}
756
  * {# returns [aa, bb, cc] #}
757
- * </pre>
758
  *
759
- * @param Twig_Environment $env
760
- * @param string $value A string
761
- * @param string $delimiter The delimiter
762
- * @param int $limit The limit
763
  *
764
  * @return array The split string as an array
765
  */
@@ -769,7 +777,7 @@ function twig_split_filter(Twig_Environment $env, $value, $delimiter, $limit = n
769
  return null === $limit ? explode($delimiter, $value) : explode($delimiter, $value, $limit);
770
  }
771
 
772
- if (!function_exists('mb_get_info') || null === $charset = $env->getCharset()) {
773
  return str_split($value, null === $limit ? 1 : $limit);
774
  }
775
 
@@ -810,11 +818,9 @@ function _twig_default_filter($value, $default = '')
810
  *
811
  * It is useful when you want to iterate over the keys of an array:
812
  *
813
- * <pre>
814
  * {% for key in array|keys %}
815
  * {# ... #}
816
  * {% endfor %}
817
- * </pre>
818
  *
819
  * @param array $array An array
820
  *
@@ -822,12 +828,12 @@ function _twig_default_filter($value, $default = '')
822
  */
823
  function twig_get_array_keys_filter($array)
824
  {
825
- if ($array instanceof Traversable) {
826
- while ($array instanceof IteratorAggregate) {
827
  $array = $array->getIterator();
828
  }
829
 
830
- if ($array instanceof Iterator) {
831
  $keys = [];
832
  $array->rewind();
833
  while ($array->valid()) {
@@ -846,7 +852,7 @@ function twig_get_array_keys_filter($array)
846
  return $keys;
847
  }
848
 
849
- if (!is_array($array)) {
850
  return [];
851
  }
852
 
@@ -856,19 +862,18 @@ function twig_get_array_keys_filter($array)
856
  /**
857
  * Reverses a variable.
858
  *
859
- * @param Twig_Environment $env
860
- * @param array|Traversable|string $item An array, a Traversable instance, or a string
861
- * @param bool $preserveKeys Whether to preserve key or not
862
  *
863
  * @return mixed The reversed input
864
  */
865
  function twig_reverse_filter(Twig_Environment $env, $item, $preserveKeys = false)
866
  {
867
- if ($item instanceof Traversable) {
868
  return array_reverse(iterator_to_array($item), $preserveKeys);
869
  }
870
 
871
- if (is_array($item)) {
872
  return array_reverse($item, $preserveKeys);
873
  }
874
 
@@ -896,16 +901,16 @@ function twig_reverse_filter(Twig_Environment $env, $item, $preserveKeys = false
896
  /**
897
  * Sorts an array.
898
  *
899
- * @param array|Traversable $array
900
  *
901
  * @return array
902
  */
903
  function twig_sort_filter($array)
904
  {
905
- if ($array instanceof Traversable) {
906
  $array = iterator_to_array($array);
907
- } elseif (!is_array($array)) {
908
- throw new Twig_Error_Runtime(sprintf('The sort filter only works with arrays or "Traversable", got "%s".', gettype($array)));
909
  }
910
 
911
  asort($array);
@@ -918,12 +923,12 @@ function twig_sort_filter($array)
918
  */
919
  function twig_in_filter($value, $compare)
920
  {
921
- if (is_array($compare)) {
922
- return in_array($value, $compare, is_object($value) || is_resource($value));
923
- } elseif (is_string($compare) && (is_string($value) || is_int($value) || is_float($value))) {
924
  return '' === $value || false !== strpos($compare, (string) $value);
925
- } elseif ($compare instanceof Traversable) {
926
- if (is_object($value) || is_resource($value)) {
927
  foreach ($compare as $item) {
928
  if ($item === $value) {
929
  return true;
@@ -948,7 +953,7 @@ function twig_in_filter($value, $compare)
948
  *
949
  * @return string
950
  *
951
- * @throws Twig_Error_Runtime When an invalid trimming side is used (not a string or not 'left', 'right', or 'both')
952
  */
953
  function twig_trim_filter($string, $characterMask = null, $side = 'both')
954
  {
@@ -964,31 +969,30 @@ function twig_trim_filter($string, $characterMask = null, $side = 'both')
964
  case 'right':
965
  return rtrim($string, $characterMask);
966
  default:
967
- throw new Twig_Error_Runtime('Trimming side must be "left", "right" or "both".');
968
  }
969
  }
970
 
971
  /**
972
  * Escapes a string.
973
  *
974
- * @param Twig_Environment $env
975
- * @param mixed $string The value to be escaped
976
- * @param string $strategy The escaping strategy
977
- * @param string $charset The charset
978
- * @param bool $autoescape Whether the function is called by the auto-escaping feature (true) or by the developer (false)
979
  *
980
  * @return string
981
  */
982
  function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html', $charset = null, $autoescape = false)
983
  {
984
- if ($autoescape && $string instanceof Twig_Markup) {
985
  return $string;
986
  }
987
 
988
- if (!is_string($string)) {
989
- if (is_object($string) && method_exists($string, '__toString')) {
990
  $string = (string) $string;
991
- } elseif (in_array($strategy, ['html', 'js', 'css', 'html_attr', 'url'])) {
992
  return $string;
993
  }
994
  }
@@ -1049,7 +1053,7 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html',
1049
  }
1050
 
1051
  if (!preg_match('//u', $string)) {
1052
- throw new Twig_Error_Runtime('The string to escape is not a valid UTF-8 string.');
1053
  }
1054
 
1055
  $string = preg_replace_callback('#[^a-zA-Z0-9,\._]#Su', '_twig_escape_js_callback', $string);
@@ -1066,7 +1070,7 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html',
1066
  }
1067
 
1068
  if (!preg_match('//u', $string)) {
1069
- throw new Twig_Error_Runtime('The string to escape is not a valid UTF-8 string.');
1070
  }
1071
 
1072
  $string = preg_replace_callback('#[^a-zA-Z0-9]#Su', '_twig_escape_css_callback', $string);
@@ -1083,7 +1087,7 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html',
1083
  }
1084
 
1085
  if (!preg_match('//u', $string)) {
1086
- throw new Twig_Error_Runtime('The string to escape is not a valid UTF-8 string.');
1087
  }
1088
 
1089
  $string = preg_replace_callback('#[^a-zA-Z0-9,\.\-_]#Su', '_twig_escape_html_attr_callback', $string);
@@ -1101,16 +1105,16 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html',
1101
  static $escapers;
1102
 
1103
  if (null === $escapers) {
1104
- $escapers = $env->getExtension('Twig_Extension_Core')->getEscapers();
1105
  }
1106
 
1107
  if (isset($escapers[$strategy])) {
1108
- return call_user_func($escapers[$strategy], $env, $string, $charset);
1109
  }
1110
 
1111
  $validStrategies = implode(', ', array_merge(['html', 'js', 'url', 'css', 'html_attr'], array_keys($escapers)));
1112
 
1113
- throw new Twig_Error_Runtime(sprintf('Invalid escaping strategy "%s" (valid ones: %s).', $strategy, $validStrategies));
1114
  }
1115
  }
1116
 
@@ -1120,7 +1124,7 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html',
1120
  function twig_escape_filter_is_safe(Twig_Node $filterArgs)
1121
  {
1122
  foreach ($filterArgs as $arg) {
1123
- if ($arg instanceof Twig_Node_Expression_Constant) {
1124
  return [$arg->getAttribute('value')];
1125
  }
1126
 
@@ -1130,12 +1134,12 @@ function twig_escape_filter_is_safe(Twig_Node $filterArgs)
1130
  return ['html'];
1131
  }
1132
 
1133
- if (function_exists('mb_convert_encoding')) {
1134
  function twig_convert_encoding($string, $to, $from)
1135
  {
1136
  return mb_convert_encoding($string, $to, $from);
1137
  }
1138
- } elseif (function_exists('iconv')) {
1139
  function twig_convert_encoding($string, $to, $from)
1140
  {
1141
  return iconv($from, $to, $string);
@@ -1143,11 +1147,11 @@ if (function_exists('mb_convert_encoding')) {
1143
  } else {
1144
  function twig_convert_encoding($string, $to, $from)
1145
  {
1146
- throw new Twig_Error_Runtime('No suitable convert encoding function (use UTF-8 as your encoding or install the iconv or mbstring extension).');
1147
  }
1148
  }
1149
 
1150
- if (function_exists('mb_ord')) {
1151
  function twig_ord($string)
1152
  {
1153
  return mb_ord($string, 'UTF-8');
@@ -1197,7 +1201,7 @@ function _twig_escape_js_callback($matches)
1197
  $char = twig_convert_encoding($char, 'UTF-16BE', 'UTF-8');
1198
  $char = strtoupper(bin2hex($char));
1199
 
1200
- if (4 >= strlen($char)) {
1201
  return sprintf('\u%04s', $char);
1202
  }
1203
 
@@ -1208,7 +1212,7 @@ function _twig_escape_css_callback($matches)
1208
  {
1209
  $char = $matches[0];
1210
 
1211
- return sprintf('\\%X ', 1 === strlen($char) ? ord($char) : twig_ord($char));
1212
  }
1213
 
1214
  /**
@@ -1220,7 +1224,7 @@ function _twig_escape_css_callback($matches)
1220
  function _twig_escape_html_attr_callback($matches)
1221
  {
1222
  $chr = $matches[0];
1223
- $ord = ord($chr);
1224
 
1225
  /*
1226
  * The following replaces characters undefined in HTML with the
@@ -1234,7 +1238,7 @@ function _twig_escape_html_attr_callback($matches)
1234
  * Check if the current character to escape has a name entity we should
1235
  * replace it with while grabbing the hex value of the character.
1236
  */
1237
- if (1 == strlen($chr)) {
1238
  /*
1239
  * While HTML supports far more named entities, the lowest common denominator
1240
  * has become HTML5's XML Serialisation which is restricted to the those named
@@ -1263,16 +1267,15 @@ function _twig_escape_html_attr_callback($matches)
1263
  }
1264
 
1265
  // add multibyte extensions if possible
1266
- if (function_exists('mb_get_info')) {
1267
  /**
1268
  * Returns the length of a variable.
1269
  *
1270
- * @param Twig_Environment $env
1271
- * @param mixed $thing A variable
1272
  *
1273
  * @return int The length of the value
1274
  */
1275
- function twig_length_filter(Twig_Environment $env, $thing)
1276
  {
1277
  if (null === $thing) {
1278
  return 0;
@@ -1283,15 +1286,15 @@ if (function_exists('mb_get_info')) {
1283
  }
1284
 
1285
  if ($thing instanceof \SimpleXMLElement) {
1286
- return count($thing);
1287
  }
1288
 
1289
- if (is_object($thing) && method_exists($thing, '__toString') && !$thing instanceof \Countable) {
1290
  return mb_strlen((string) $thing, $env->getCharset());
1291
  }
1292
 
1293
- if ($thing instanceof \Countable || is_array($thing)) {
1294
- return count($thing);
1295
  }
1296
 
1297
  if ($thing instanceof \IteratorAggregate) {
@@ -1304,12 +1307,11 @@ if (function_exists('mb_get_info')) {
1304
  /**
1305
  * Converts a string to uppercase.
1306
  *
1307
- * @param Twig_Environment $env
1308
- * @param string $string A string
1309
  *
1310
  * @return string The uppercased string
1311
  */
1312
- function twig_upper_filter(Twig_Environment $env, $string)
1313
  {
1314
  if (null !== $charset = $env->getCharset()) {
1315
  return mb_strtoupper($string, $charset);
@@ -1321,12 +1323,11 @@ if (function_exists('mb_get_info')) {
1321
  /**
1322
  * Converts a string to lowercase.
1323
  *
1324
- * @param Twig_Environment $env
1325
- * @param string $string A string
1326
  *
1327
  * @return string The lowercased string
1328
  */
1329
- function twig_lower_filter(Twig_Environment $env, $string)
1330
  {
1331
  if (null !== $charset = $env->getCharset()) {
1332
  return mb_strtolower($string, $charset);
@@ -1338,12 +1339,11 @@ if (function_exists('mb_get_info')) {
1338
  /**
1339
  * Returns a titlecased string.
1340
  *
1341
- * @param Twig_Environment $env
1342
- * @param string $string A string
1343
  *
1344
  * @return string The titlecased string
1345
  */
1346
- function twig_title_string_filter(Twig_Environment $env, $string)
1347
  {
1348
  if (null !== $charset = $env->getCharset()) {
1349
  return mb_convert_case($string, MB_CASE_TITLE, $charset);
@@ -1355,12 +1355,11 @@ if (function_exists('mb_get_info')) {
1355
  /**
1356
  * Returns a capitalized string.
1357
  *
1358
- * @param Twig_Environment $env
1359
- * @param string $string A string
1360
  *
1361
  * @return string The capitalized string
1362
  */
1363
- function twig_capitalize_string_filter(Twig_Environment $env, $string)
1364
  {
1365
  if (null !== $charset = $env->getCharset()) {
1366
  return mb_strtoupper(mb_substr($string, 0, 1, $charset), $charset).mb_strtolower(mb_substr($string, 1, mb_strlen($string, $charset), $charset), $charset);
@@ -1374,31 +1373,30 @@ else {
1374
  /**
1375
  * Returns the length of a variable.
1376
  *
1377
- * @param Twig_Environment $env
1378
- * @param mixed $thing A variable
1379
  *
1380
  * @return int The length of the value
1381
  */
1382
- function twig_length_filter(Twig_Environment $env, $thing)
1383
  {
1384
  if (null === $thing) {
1385
  return 0;
1386
  }
1387
 
1388
  if (is_scalar($thing)) {
1389
- return strlen($thing);
1390
  }
1391
 
1392
  if ($thing instanceof \SimpleXMLElement) {
1393
- return count($thing);
1394
  }
1395
 
1396
- if (is_object($thing) && method_exists($thing, '__toString') && !$thing instanceof \Countable) {
1397
- return strlen((string) $thing);
1398
  }
1399
 
1400
- if ($thing instanceof \Countable || is_array($thing)) {
1401
- return count($thing);
1402
  }
1403
 
1404
  if ($thing instanceof \IteratorAggregate) {
@@ -1411,12 +1409,11 @@ else {
1411
  /**
1412
  * Returns a titlecased string.
1413
  *
1414
- * @param Twig_Environment $env
1415
- * @param string $string A string
1416
  *
1417
  * @return string The titlecased string
1418
  */
1419
- function twig_title_string_filter(Twig_Environment $env, $string)
1420
  {
1421
  return ucwords(strtolower($string));
1422
  }
@@ -1424,12 +1421,11 @@ else {
1424
  /**
1425
  * Returns a capitalized string.
1426
  *
1427
- * @param Twig_Environment $env
1428
- * @param string $string A string
1429
  *
1430
  * @return string The capitalized string
1431
  */
1432
- function twig_capitalize_string_filter(Twig_Environment $env, $string)
1433
  {
1434
  return ucfirst(strtolower($string));
1435
  }
@@ -1440,7 +1436,7 @@ else {
1440
  */
1441
  function twig_ensure_traversable($seq)
1442
  {
1443
- if ($seq instanceof Traversable || is_array($seq)) {
1444
  return $seq;
1445
  }
1446
 
@@ -1450,12 +1446,10 @@ function twig_ensure_traversable($seq)
1450
  /**
1451
  * Checks if a variable is empty.
1452
  *
1453
- * <pre>
1454
- * {# evaluates to true if the foo variable is null, false, or the empty string #}
1455
- * {% if foo is empty %}
1456
- * {# ... #}
1457
- * {% endif %}
1458
- * </pre>
1459
  *
1460
  * @param mixed $value A variable
1461
  *
@@ -1463,11 +1457,11 @@ function twig_ensure_traversable($seq)
1463
  */
1464
  function twig_test_empty($value)
1465
  {
1466
- if ($value instanceof Countable) {
1467
- return 0 == count($value);
1468
  }
1469
 
1470
- if (is_object($value) && method_exists($value, '__toString')) {
1471
  return '' === (string) $value;
1472
  }
1473
 
@@ -1477,12 +1471,10 @@ function twig_test_empty($value)
1477
  /**
1478
  * Checks if a variable is traversable.
1479
  *
1480
- * <pre>
1481
- * {# evaluates to true if the foo variable is an array or a traversable object #}
1482
- * {% if foo is iterable %}
1483
- * {# ... #}
1484
- * {% endif %}
1485
- * </pre>
1486
  *
1487
  * @param mixed $value A variable
1488
  *
@@ -1490,19 +1482,18 @@ function twig_test_empty($value)
1490
  */
1491
  function twig_test_iterable($value)
1492
  {
1493
- return $value instanceof Traversable || is_array($value);
1494
  }
1495
 
1496
  /**
1497
  * Renders a template.
1498
  *
1499
- * @param Twig_Environment $env
1500
- * @param array $context
1501
- * @param string|array $template The template to render or an array of templates to try consecutively
1502
- * @param array $variables The variables to pass to the template
1503
- * @param bool $withContext
1504
- * @param bool $ignoreMissing Whether to ignore missing templates or not
1505
- * @param bool $sandboxed Whether to sandbox the template or not
1506
  *
1507
  * @return string The rendered template
1508
  */
@@ -1514,8 +1505,8 @@ function twig_include(Twig_Environment $env, $context, $template, $variables = [
1514
  $variables = array_merge($context, $variables);
1515
  }
1516
 
1517
- if ($isSandboxed = $sandboxed && $env->hasExtension('Twig_Extension_Sandbox')) {
1518
- $sandbox = $env->getExtension('Twig_Extension_Sandbox');
1519
  if (!$alreadySandboxed = $sandbox->isSandboxed()) {
1520
  $sandbox->enableSandbox();
1521
  }
@@ -1524,7 +1515,7 @@ function twig_include(Twig_Environment $env, $context, $template, $variables = [
1524
  $result = '';
1525
  try {
1526
  $result = $env->resolveTemplate($template)->render($variables);
1527
- } catch (Twig_Error_Loader $e) {
1528
  if (!$ignoreMissing) {
1529
  if ($isSandboxed && !$alreadySandboxed) {
1530
  $sandbox->disableSandbox();
@@ -1532,13 +1523,13 @@ function twig_include(Twig_Environment $env, $context, $template, $variables = [
1532
 
1533
  throw $e;
1534
  }
1535
- } catch (Throwable $e) {
1536
  if ($isSandboxed && !$alreadySandboxed) {
1537
  $sandbox->disableSandbox();
1538
  }
1539
 
1540
  throw $e;
1541
- } catch (Exception $e) {
1542
  if ($isSandboxed && !$alreadySandboxed) {
1543
  $sandbox->disableSandbox();
1544
  }
@@ -1556,9 +1547,8 @@ function twig_include(Twig_Environment $env, $context, $template, $variables = [
1556
  /**
1557
  * Returns a template content without rendering it.
1558
  *
1559
- * @param Twig_Environment $env
1560
- * @param string $name The template name
1561
- * @param bool $ignoreMissing Whether to ignore missing templates or not
1562
  *
1563
  * @return string The template source
1564
  */
@@ -1566,12 +1556,12 @@ function twig_source(Twig_Environment $env, $name, $ignoreMissing = false)
1566
  {
1567
  $loader = $env->getLoader();
1568
  try {
1569
- if (!$loader instanceof Twig_SourceContextLoaderInterface) {
1570
  return $loader->getSource($name);
1571
  } else {
1572
  return $loader->getSourceContext($name)->getCode();
1573
  }
1574
- } catch (Twig_Error_Loader $e) {
1575
  if (!$ignoreMissing) {
1576
  throw $e;
1577
  }
@@ -1589,10 +1579,10 @@ function twig_source(Twig_Environment $env, $name, $ignoreMissing = false)
1589
  function twig_constant($constant, $object = null)
1590
  {
1591
  if (null !== $object) {
1592
- $constant = get_class($object).'::'.$constant;
1593
  }
1594
 
1595
- return constant($constant);
1596
  }
1597
 
1598
  /**
@@ -1606,10 +1596,10 @@ function twig_constant($constant, $object = null)
1606
  function twig_constant_is_defined($constant, $object = null)
1607
  {
1608
  if (null !== $object) {
1609
- $constant = get_class($object).'::'.$constant;
1610
  }
1611
 
1612
- return defined($constant);
1613
  }
1614
 
1615
  /**
@@ -1623,7 +1613,7 @@ function twig_constant_is_defined($constant, $object = null)
1623
  */
1624
  function twig_array_batch($items, $size, $fill = null)
1625
  {
1626
- if ($items instanceof Traversable) {
1627
  $items = iterator_to_array($items, false);
1628
  }
1629
 
@@ -1632,8 +1622,8 @@ function twig_array_batch($items, $size, $fill = null)
1632
  $result = array_chunk($items, $size, true);
1633
 
1634
  if (null !== $fill && !empty($result)) {
1635
- $last = count($result) - 1;
1636
- if ($fillCount = $size - count($result[$last])) {
1637
  $result[$last] = array_merge(
1638
  $result[$last],
1639
  array_fill(0, $fillCount, $fill)
1
  <?php
2
 
3
+ if (!\defined('ENT_SUBSTITUTE')) {
4
+ \define('ENT_SUBSTITUTE', 8);
5
  }
6
 
7
  /*
13
  * file that was distributed with this source code.
14
  */
15
 
16
+ use Twig\Environment;
17
+ use Twig\Error\LoaderError;
18
+ use Twig\Error\RuntimeError;
19
+ use Twig\ExpressionParser;
20
+ use Twig\Extension\AbstractExtension;
21
+ use Twig\Loader\SourceContextLoaderInterface;
22
+ use Twig\Markup;
23
+ use Twig\Node\Expression\ConstantExpression;
24
+ use Twig\TokenParser\BlockTokenParser;
25
+ use Twig\TokenParser\DeprecatedTokenParser;
26
+ use Twig\TokenParser\DoTokenParser;
27
+ use Twig\TokenParser\EmbedTokenParser;
28
+ use Twig\TokenParser\ExtendsTokenParser;
29
+ use Twig\TokenParser\FilterTokenParser;
30
+ use Twig\TokenParser\FlushTokenParser;
31
+ use Twig\TokenParser\ForTokenParser;
32
+ use Twig\TokenParser\FromTokenParser;
33
+ use Twig\TokenParser\IfTokenParser;
34
+ use Twig\TokenParser\ImportTokenParser;
35
+ use Twig\TokenParser\IncludeTokenParser;
36
+ use Twig\TokenParser\MacroTokenParser;
37
+ use Twig\TokenParser\SetTokenParser;
38
+ use Twig\TokenParser\SpacelessTokenParser;
39
+ use Twig\TokenParser\UseTokenParser;
40
+ use Twig\TokenParser\WithTokenParser;
41
+ use Twig\TwigFilter;
42
+ use Twig\TwigFunction;
43
+ use Twig\TwigTest;
44
+
45
  /**
46
  * @final
47
  */
48
+ class Twig_Extension_Core extends AbstractExtension
49
  {
50
  protected $dateFormats = ['F j, Y H:i', '%d days'];
51
  protected $numberFormat = [0, '.', ','];
103
  /**
104
  * Sets the default timezone to be used by the date filter.
105
  *
106
+ * @param \DateTimeZone|string $timezone The default timezone string or a \DateTimeZone object
107
  */
108
  public function setTimezone($timezone)
109
  {
110
+ $this->timezone = $timezone instanceof \DateTimeZone ? $timezone : new \DateTimeZone($timezone);
111
  }
112
 
113
  /**
114
  * Gets the default timezone to be used by the date filter.
115
  *
116
+ * @return \DateTimeZone The default timezone currently in use
117
  */
118
  public function getTimezone()
119
  {
120
  if (null === $this->timezone) {
121
+ $this->timezone = new \DateTimeZone(date_default_timezone_get());
122
  }
123
 
124
  return $this->timezone;
149
  public function getTokenParsers()
150
  {
151
  return [
152
+ new ForTokenParser(),
153
+ new IfTokenParser(),
154
+ new ExtendsTokenParser(),
155
+ new IncludeTokenParser(),
156
+ new BlockTokenParser(),
157
+ new UseTokenParser(),
158
+ new FilterTokenParser(),
159
+ new MacroTokenParser(),
160
+ new ImportTokenParser(),
161
+ new FromTokenParser(),
162
+ new SetTokenParser(),
163
+ new SpacelessTokenParser(),
164
+ new FlushTokenParser(),
165
+ new DoTokenParser(),
166
+ new EmbedTokenParser(),
167
+ new WithTokenParser(),
168
+ new DeprecatedTokenParser(),
169
  ];
170
  }
171
 
173
  {
174
  $filters = [
175
  // formatting filters
176
+ new TwigFilter('date', 'twig_date_format_filter', ['needs_environment' => true]),
177
+ new TwigFilter('date_modify', 'twig_date_modify_filter', ['needs_environment' => true]),
178
+ new TwigFilter('format', 'sprintf'),
179
+ new TwigFilter('replace', 'twig_replace_filter'),
180
+ new TwigFilter('number_format', 'twig_number_format_filter', ['needs_environment' => true]),
181
+ new TwigFilter('abs', 'abs'),
182
+ new TwigFilter('round', 'twig_round'),
183
 
184
  // encoding
185
+ new TwigFilter('url_encode', 'twig_urlencode_filter'),
186
+ new TwigFilter('json_encode', 'twig_jsonencode_filter'),
187
+ new TwigFilter('convert_encoding', 'twig_convert_encoding'),
188
 
189
  // string filters
190
+ new TwigFilter('title', 'twig_title_string_filter', ['needs_environment' => true]),
191
+ new TwigFilter('capitalize', 'twig_capitalize_string_filter', ['needs_environment' => true]),
192
+ new TwigFilter('upper', 'strtoupper'),
193
+ new TwigFilter('lower', 'strtolower'),
194
+ new TwigFilter('striptags', 'strip_tags'),
195
+ new TwigFilter('trim', 'twig_trim_filter'),
196
+ new TwigFilter('nl2br', 'nl2br', ['pre_escape' => 'html', 'is_safe' => ['html']]),
197
 
198
  // array helpers
199
+ new TwigFilter('join', 'twig_join_filter'),
200
+ new TwigFilter('split', 'twig_split_filter', ['needs_environment' => true]),
201
+ new TwigFilter('sort', 'twig_sort_filter'),
202
+ new TwigFilter('merge', 'twig_array_merge'),
203
+ new TwigFilter('batch', 'twig_array_batch'),
204
 
205
  // string/array filters
206
+ new TwigFilter('reverse', 'twig_reverse_filter', ['needs_environment' => true]),
207
+ new TwigFilter('length', 'twig_length_filter', ['needs_environment' => true]),
208
+ new TwigFilter('slice', 'twig_slice', ['needs_environment' => true]),
209
+ new TwigFilter('first', 'twig_first', ['needs_environment' => true]),
210
+ new TwigFilter('last', 'twig_last', ['needs_environment' => true]),
211
 
212
  // iteration and runtime
213
+ new TwigFilter('default', '_twig_default_filter', ['node_class' => '\Twig\Node\Expression\Filter\DefaultFilter']),
214
+ new TwigFilter('keys', 'twig_get_array_keys_filter'),
215
 
216
  // escaping
217
+ new TwigFilter('escape', 'twig_escape_filter', ['needs_environment' => true, 'is_safe_callback' => 'twig_escape_filter_is_safe']),
218
+ new TwigFilter('e', 'twig_escape_filter', ['needs_environment' => true, 'is_safe_callback' => 'twig_escape_filter_is_safe']),
219
  ];
220
 
221
+ if (\function_exists('mb_get_info')) {
222
+ $filters[] = new TwigFilter('upper', 'twig_upper_filter', ['needs_environment' => true]);
223
+ $filters[] = new TwigFilter('lower', 'twig_lower_filter', ['needs_environment' => true]);
224
  }
225
 
226
  return $filters;
229
  public function getFunctions()
230
  {
231
  return [
232
+ new TwigFunction('max', 'max'),
233
+ new TwigFunction('min', 'min'),
234
+ new TwigFunction('range', 'range'),
235
+ new TwigFunction('constant', 'twig_constant'),
236
+ new TwigFunction('cycle', 'twig_cycle'),
237
+ new TwigFunction('random', 'twig_random', ['needs_environment' => true]),
238
+ new TwigFunction('date', 'twig_date_converter', ['needs_environment' => true]),
239
+ new TwigFunction('include', 'twig_include', ['needs_environment' => true, 'needs_context' => true, 'is_safe' => ['all']]),
240
+ new TwigFunction('source', 'twig_source', ['needs_environment' => true, 'is_safe' => ['all']]),
241
  ];
242
  }
243
 
244
  public function getTests()
245
  {
246
  return [
247
+ new TwigTest('even', null, ['node_class' => '\Twig\Node\Expression\Test\EvenTest']),
248
+ new TwigTest('odd', null, ['node_class' => '\Twig\Node\Expression\Test\OddTest']),
249
+ new TwigTest('defined', null, ['node_class' => '\Twig\Node\Expression\Test\DefinedTest']),
250
+ new TwigTest('sameas', null, ['node_class' => '\Twig\Node\Expression\Test\SameasTest', 'deprecated' => '1.21', 'alternative' => 'same as']),
251
+ new TwigTest('same as', null, ['node_class' => '\Twig\Node\Expression\Test\SameasTest']),
252
+ new TwigTest('none', null, ['node_class' => '\Twig\Node\Expression\Test\NullTest']),
253
+ new TwigTest('null', null, ['node_class' => '\Twig\Node\Expression\Test\NullTest']),
254
+ new TwigTest('divisibleby', null, ['node_class' => '\Twig\Node\Expression\Test\DivisiblebyTest', 'deprecated' => '1.21', 'alternative' => 'divisible by']),
255
+ new TwigTest('divisible by', null, ['node_class' => '\Twig\Node\Expression\Test\DivisiblebyTest']),
256
+ new TwigTest('constant', null, ['node_class' => '\Twig\Node\Expression\Test\ConstantTest']),
257
+ new TwigTest('empty', 'twig_test_empty'),
258
+ new TwigTest('iterable', 'twig_test_iterable'),
259
  ];
260
  }
261
 
263
  {
264
  return [
265
  [
266
+ 'not' => ['precedence' => 50, 'class' => '\Twig\Node\Expression\Unary\NotUnary'],
267
+ '-' => ['precedence' => 500, 'class' => '\Twig\Node\Expression\Unary\NegUnary'],
268
+ '+' => ['precedence' => 500, 'class' => '\Twig\Node\Expression\Unary\PosUnary'],
269
  ],
270
  [
271
+ 'or' => ['precedence' => 10, 'class' => '\Twig\Node\Expression\Binary\OrBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
272
+ 'and' => ['precedence' => 15, 'class' => '\Twig\Node\Expression\Binary\AndBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
273
+ 'b-or' => ['precedence' => 16, 'class' => '\Twig\Node\Expression\Binary\BitwiseOrBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
274
+ 'b-xor' => ['precedence' => 17, 'class' => '\Twig\Node\Expression\Binary\BitwiseXorBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
275
+ 'b-and' => ['precedence' => 18, 'class' => '\Twig\Node\Expression\Binary\BitwiseAndBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
276
+ '==' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\EqualBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
277
+ '!=' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\NotEqualBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
278
+ '<' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\LessBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
279
+ '>' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\GreaterBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
280
+ '>=' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\GreaterEqualBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
281
+ '<=' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\LessEqualBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
282
+ 'not in' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\NotInBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
283
+ 'in' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\InBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
284
+ 'matches' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\MatchesBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
285
+ 'starts with' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\StartsWithBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
286
+ 'ends with' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\EndsWithBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
287
+ '..' => ['precedence' => 25, 'class' => '\Twig\Node\Expression\Binary\RangeBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
288
+ '+' => ['precedence' => 30, 'class' => '\Twig\Node\Expression\Binary\AddBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
289
+ '-' => ['precedence' => 30, 'class' => '\Twig\Node\Expression\Binary\SubBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
290
+ '~' => ['precedence' => 40, 'class' => '\Twig\Node\Expression\Binary\ConcatBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
291
+ '*' => ['precedence' => 60, 'class' => '\Twig\Node\Expression\Binary\MulBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
292
+ '/' => ['precedence' => 60, 'class' => '\Twig\Node\Expression\Binary\DivBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
293
+ '//' => ['precedence' => 60, 'class' => '\Twig\Node\Expression\Binary\FloorDivBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
294
+ '%' => ['precedence' => 60, 'class' => '\Twig\Node\Expression\Binary\ModBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
295
+ 'is' => ['precedence' => 100, 'associativity' => ExpressionParser::OPERATOR_LEFT],
296
+ 'is not' => ['precedence' => 100, 'associativity' => ExpressionParser::OPERATOR_LEFT],
297
+ '**' => ['precedence' => 200, 'class' => '\Twig\Node\Expression\Binary\PowerBinary', 'associativity' => ExpressionParser::OPERATOR_RIGHT],
298
+ '??' => ['precedence' => 300, 'class' => '\Twig\Node\Expression\NullCoalesceExpression', 'associativity' => ExpressionParser::OPERATOR_RIGHT],
299
  ],
300
  ];
301
  }
316
  */
317
  function twig_cycle($values, $position)
318
  {
319
+ if (!\is_array($values) && !$values instanceof ArrayAccess) {
320
  return $values;
321
  }
322
 
323
+ return $values[$position % \count($values)];
324
  }
325
 
326
  /**
327
  * Returns a random value depending on the supplied parameter type:
328
+ * - a random item from a \Traversable or array
329
  * - a random character from a string
330
  * - a random integer between 0 and the integer parameter.
331
  *
332
+ * @param \Traversable|array|int|float|string $values The values to pick a random item from
 
333
  *
334
+ * @throws RuntimeError when $values is an empty array (does not apply to an empty string which is returned as is)
335
  *
336
  * @return mixed A random value from the given sequence
337
  */
341
  return mt_rand();
342
  }
343
 
344
+ if (\is_int($values) || \is_float($values)) {
345
  return $values < 0 ? mt_rand($values, 0) : mt_rand(0, $values);
346
  }
347
 
348
+ if ($values instanceof \Traversable) {
349
  $values = iterator_to_array($values);
350
+ } elseif (\is_string($values)) {
351
  if ('' === $values) {
352
  return '';
353
  }
366
  }
367
  }
368
  } else {
369
+ return $values[mt_rand(0, \strlen($values) - 1)];
370
  }
371
  }
372
 
373
+ if (!\is_array($values)) {
374
  return $values;
375
  }
376
 
377
+ if (0 === \count($values)) {
378
+ throw new RuntimeError('The random function cannot pick from an empty array.');
379
  }
380
 
381
  return $values[array_rand($values, 1)];
384
  /**
385
  * Converts a date to the given format.
386
  *
 
387
  * {{ post.published_at|date("m/d/Y") }}
 
388
  *
389
+ * @param \DateTime|\DateTimeInterface|\DateInterval|string $date A date
390
+ * @param string|null $format The target format, null to use the default
391
+ * @param \DateTimeZone|string|false|null $timezone The target timezone, null to use the default, false to leave unchanged
 
392
  *
393
  * @return string The formatted date
394
  */
395
  function twig_date_format_filter(Twig_Environment $env, $date, $format = null, $timezone = null)
396
  {
397
  if (null === $format) {
398
+ $formats = $env->getExtension('\Twig\Extension\CoreExtension')->getDateFormat();
399
+ $format = $date instanceof \DateInterval ? $formats[1] : $formats[0];
400
  }
401
 
402
+ if ($date instanceof \DateInterval) {
403
  return $date->format($format);
404
  }
405
 
409
  /**
410
  * Returns a new date object modified.
411
  *
 
412
  * {{ post.published_at|date_modify("-1day")|date("m/d/Y") }}
 
413
  *
414
+ * @param \DateTime|string $date A date
 
415
  * @param string $modifier A modifier string
416
  *
417
+ * @return \DateTime A new date object
418
  */
419
  function twig_date_modify_filter(Twig_Environment $env, $date, $modifier)
420
  {
421
  $date = twig_date_converter($env, $date, false);
422
  $resultDate = $date->modify($modifier);
423
 
424
+ // This is a hack to ensure PHP 5.2 support and support for \DateTimeImmutable
425
+ // \DateTime::modify does not return the modified \DateTime object < 5.3.0
426
+ // and \DateTimeImmutable does not modify $date.
427
  return null === $resultDate ? $date : $resultDate;
428
  }
429
 
430
  /**
431
+ * Converts an input to a \DateTime instance.
432
  *
 
433
  * {% if date(user.created_at) < date('+2days') %}
434
  * {# do something #}
435
  * {% endif %}
 
436
  *
437
+ * @param \DateTime|\DateTimeInterface|string|null $date A date
438
+ * @param \DateTimeZone|string|false|null $timezone The target timezone, null to use the default, false to leave unchanged
 
439
  *
440
+ * @return \DateTime A \DateTime instance
441
  */
442
  function twig_date_converter(Twig_Environment $env, $date = null, $timezone = null)
443
  {
444
  // determine the timezone
445
  if (false !== $timezone) {
446
  if (null === $timezone) {
447
+ $timezone = $env->getExtension('\Twig\Extension\CoreExtension')->getTimezone();
448
+ } elseif (!$timezone instanceof \DateTimeZone) {
449
+ $timezone = new \DateTimeZone($timezone);
450
  }
451
  }
452
 
453
  // immutable dates
454
+ if ($date instanceof \DateTimeImmutable) {
455
  return false !== $timezone ? $date->setTimezone($timezone) : $date;
456
  }
457
 
458
+ if ($date instanceof \DateTime || $date instanceof \DateTimeInterface) {
459
  $date = clone $date;
460
  if (false !== $timezone) {
461
  $date->setTimezone($timezone);
465
  }
466
 
467
  if (null === $date || 'now' === $date) {
468
+ return new \DateTime($date, false !== $timezone ? $timezone : $env->getExtension('\Twig\Extension\CoreExtension')->getTimezone());
469
  }
470
 
471
  $asString = (string) $date;
472
  if (ctype_digit($asString) || (!empty($asString) && '-' === $asString[0] && ctype_digit(substr($asString, 1)))) {
473
+ $date = new \DateTime('@'.$date);
474
  } else {
475
+ $date = new \DateTime($date, $env->getExtension('\Twig\Extension\CoreExtension')->getTimezone());
476
  }
477
 
478
  if (false !== $timezone) {
485
  /**
486
  * Replaces strings within a string.
487
  *
488
+ * @param string $str String to replace in
489
+ * @param array|\Traversable $from Replace values
490
+ * @param string|null $to Replace to, deprecated (@see https://secure.php.net/manual/en/function.strtr.php)
491
  *
492
  * @return string
493
  */
494
  function twig_replace_filter($str, $from, $to = null)
495
  {
496
+ if ($from instanceof \Traversable) {
497
  $from = iterator_to_array($from);
498
+ } elseif (\is_string($from) && \is_string($to)) {
499
  @trigger_error('Using "replace" with character by character replacement is deprecated since version 1.22 and will be removed in Twig 2.0', E_USER_DEPRECATED);
500
 
501
  return strtr($str, $from, $to);
502
+ } elseif (!\is_array($from)) {
503
+ throw new RuntimeError(sprintf('The "replace" filter expects an array or "Traversable" as replace values, got "%s".', \is_object($from) ? \get_class($from) : \gettype($from)));
504
  }
505
 
506
  return strtr($str, $from);
522
  }
523
 
524
  if ('ceil' != $method && 'floor' != $method) {
525
+ throw new RuntimeError('The round filter only supports the "common", "ceil", and "floor" methods.');
526
  }
527
 
528
  return $method($value * pow(10, $precision)) / pow(10, $precision);
535
  * be used. Supplying any of the parameters will override the defaults set in the
536
  * environment object.
537
  *
538
+ * @param mixed $number A float/int/string of the number to format
539
+ * @param int $decimal the number of decimal points to display
540
+ * @param string $decimalPoint the character(s) to use for the decimal point
541
+ * @param string $thousandSep the character(s) to use for the thousands separator
 
542
  *
543
  * @return string The formatted number
544
  */
545
  function twig_number_format_filter(Twig_Environment $env, $number, $decimal = null, $decimalPoint = null, $thousandSep = null)
546
  {
547
+ $defaults = $env->getExtension('\Twig\Extension\CoreExtension')->getNumberFormat();
548
  if (null === $decimal) {
549
  $decimal = $defaults[0];
550
  }
569
  */
570
  function twig_urlencode_filter($url)
571
  {
572
+ if (\is_array($url)) {
573
+ if (\defined('PHP_QUERY_RFC3986')) {
574
  return http_build_query($url, '', '&', PHP_QUERY_RFC3986);
575
  }
576
 
590
  */
591
  function twig_jsonencode_filter($value, $options = 0)
592
  {
593
+ if ($value instanceof Markup) {
594
  $value = (string) $value;
595
+ } elseif (\is_array($value)) {
596
  array_walk_recursive($value, '_twig_markup2string');
597
  }
598
 
601
 
602
  function _twig_markup2string(&$value)
603
  {
604
+ if ($value instanceof Markup) {
605
  $value = (string) $value;
606
  }
607
  }
609
  /**
610
  * Merges an array with another one.
611
  *
 
612
  * {% set items = { 'apple': 'fruit', 'orange': 'fruit' } %}
613
  *
614
  * {% set items = items|merge({ 'peugeot': 'car' }) %}
615
  *
616
  * {# items now contains { 'apple': 'fruit', 'orange': 'fruit', 'peugeot': 'car' } #}
 
617
  *
618
+ * @param array|\Traversable $arr1 An array
619
+ * @param array|\Traversable $arr2 An array
620
  *
621
  * @return array The merged array
622
  */
623
  function twig_array_merge($arr1, $arr2)
624
  {
625
+ if ($arr1 instanceof \Traversable) {
626
  $arr1 = iterator_to_array($arr1);
627
+ } elseif (!\is_array($arr1)) {
628
+ throw new RuntimeError(sprintf('The merge filter only works with arrays or "Traversable", got "%s" as first argument.', \gettype($arr1)));
629
  }
630
 
631
+ if ($arr2 instanceof \Traversable) {
632
  $arr2 = iterator_to_array($arr2);
633
+ } elseif (!\is_array($arr2)) {
634
+ throw new RuntimeError(sprintf('The merge filter only works with arrays or "Traversable", got "%s" as second argument.', \gettype($arr2)));
635
  }
636
 
637
  return array_merge($arr1, $arr2);
640
  /**
641
  * Slices a variable.
642
  *
643
+ * @param mixed $item A variable
644
+ * @param int $start Start of the slice
645
+ * @param int $length Size of the slice
646
+ * @param bool $preserveKeys Whether to preserve key or not (when the input is an array)
 
647
  *
648
  * @return mixed The sliced variable
649
  */
650
  function twig_slice(Twig_Environment $env, $item, $start, $length = null, $preserveKeys = false)
651
  {
652
+ if ($item instanceof \Traversable) {
653
+ while ($item instanceof \IteratorAggregate) {
654
  $item = $item->getIterator();
655
  }
656
 
657
+ if ($start >= 0 && $length >= 0 && $item instanceof \Iterator) {
658
  try {
659
+ return iterator_to_array(new \LimitIterator($item, $start, null === $length ? -1 : $length), $preserveKeys);
660
+ } catch (\OutOfBoundsException $exception) {
661
  return [];
662
  }
663
  }
665
  $item = iterator_to_array($item, $preserveKeys);
666
  }
667
 
668
+ if (\is_array($item)) {
669
+ return \array_slice($item, $start, $length, $preserveKeys);
670
  }
671
 
672
  $item = (string) $item;
673
 
674
+ if (\function_exists('mb_get_info') && null !== $charset = $env->getCharset()) {
675
  return (string) mb_substr($item, $start, null === $length ? mb_strlen($item, $charset) - $start : $length, $charset);
676
  }
677
 
681
  /**
682
  * Returns the first element of the item.
683
  *
684
+ * @param mixed $item A variable
 
685
  *
686
  * @return mixed The first element of the item
687
  */
689
  {
690
  $elements = twig_slice($env, $item, 0, 1, false);
691
 
692
+ return \is_string($elements) ? $elements : current($elements);
693
  }
694
 
695
  /**
696
  * Returns the last element of the item.
697
  *
698
+ * @param mixed $item A variable
 
699
  *
700
  * @return mixed The last element of the item
701
  */
703
  {
704
  $elements = twig_slice($env, $item, -1, 1, false);
705
 
706
+ return \is_string($elements) ? $elements : current($elements);
707
  }
708
 
709
  /**
711
  *
712
  * The separators between elements are empty strings per default, you can define them with the optional parameters.
713
  *
 
714
  * {{ [1, 2, 3]|join(', ', ' and ') }}
715
  * {# returns 1, 2 and 3 #}
716
  *
719
  *
720
  * {{ [1, 2, 3]|join }}
721
  * {# returns 123 #}
 
722
  *
723
  * @param array $value An array
724
  * @param string $glue The separator
728
  */
729
  function twig_join_filter($value, $glue = '', $and = null)
730
  {
731
+ if ($value instanceof \Traversable) {
732
  $value = iterator_to_array($value, false);
733
  } else {
734
  $value = (array) $value;
735
  }
736
 
737
+ if (0 === \count($value)) {
738
  return '';
739
  }
740
 
743
  }
744
 
745
  $v = array_values($value);
746
+ if (1 === \count($v)) {
747
  return $v[0];
748
  }
749
 
750
+ return implode($glue, \array_slice($value, 0, -1)).$and.$v[\count($v) - 1];
751
  }
752
 
753
  /**
754
  * Splits the string into an array.
755
  *
 
756
  * {{ "one,two,three"|split(',') }}
757
  * {# returns [one, two, three] #}
758
  *
764
  *
765
  * {{ "aabbcc"|split('', 2) }}
766
  * {# returns [aa, bb, cc] #}
 
767
  *
768
+ * @param string $value A string
769
+ * @param string $delimiter The delimiter
770
+ * @param int $limit The limit
 
771
  *
772
  * @return array The split string as an array
773
  */
777
  return null === $limit ? explode($delimiter, $value) : explode($delimiter, $value, $limit);
778
  }
779
 
780
+ if (!\function_exists('mb_get_info') || null === $charset = $env->getCharset()) {
781
  return str_split($value, null === $limit ? 1 : $limit);
782
  }
783
 
818
  *
819
  * It is useful when you want to iterate over the keys of an array:
820
  *
 
821
  * {% for key in array|keys %}
822
  * {# ... #}
823
  * {% endfor %}
 
824
  *
825
  * @param array $array An array
826
  *
828
  */
829
  function twig_get_array_keys_filter($array)
830
  {
831
+ if ($array instanceof \Traversable) {
832
+ while ($array instanceof \IteratorAggregate) {
833
  $array = $array->getIterator();
834
  }
835
 
836
+ if ($array instanceof \Iterator) {
837
  $keys = [];
838
  $array->rewind();
839
  while ($array->valid()) {
852
  return $keys;
853
  }
854
 
855
+ if (!\is_array($array)) {
856
  return [];
857
  }
858
 
862
  /**
863
  * Reverses a variable.
864
  *
865
+ * @param array|\Traversable|string $item An array, a \Traversable instance, or a string
866
+ * @param bool $preserveKeys Whether to preserve key or not
 
867
  *
868
  * @return mixed The reversed input
869
  */
870
  function twig_reverse_filter(Twig_Environment $env, $item, $preserveKeys = false)
871
  {
872
+ if ($item instanceof \Traversable) {
873
  return array_reverse(iterator_to_array($item), $preserveKeys);
874
  }
875
 
876
+ if (\is_array($item)) {
877
  return array_reverse($item, $preserveKeys);
878
  }
879
 
901
  /**
902
  * Sorts an array.
903
  *
904
+ * @param array|\Traversable $array
905
  *
906
  * @return array
907
  */
908
  function twig_sort_filter($array)
909
  {
910
+ if ($array instanceof \Traversable) {
911
  $array = iterator_to_array($array);
912
+ } elseif (!\is_array($array)) {
913
+ throw new RuntimeError(sprintf('The sort filter only works with arrays or "Traversable", got "%s".', \gettype($array)));
914
  }
915
 
916
  asort($array);
923
  */
924
  function twig_in_filter($value, $compare)
925
  {
926
+ if (\is_array($compare)) {
927
+ return \in_array($value, $compare, \is_object($value) || \is_resource($value));
928
+ } elseif (\is_string($compare) && (\is_string($value) || \is_int($value) || \is_float($value))) {
929
  return '' === $value || false !== strpos($compare, (string) $value);
930
+ } elseif ($compare instanceof \Traversable) {
931
+ if (\is_object($value) || \is_resource($value)) {
932
  foreach ($compare as $item) {
933
  if ($item === $value) {
934
  return true;
953
  *
954
  * @return string
955
  *
956
+ * @throws RuntimeError When an invalid trimming side is used (not a string or not 'left', 'right', or 'both')
957
  */
958
  function twig_trim_filter($string, $characterMask = null, $side = 'both')
959
  {
969
  case 'right':
970
  return rtrim($string, $characterMask);
971
  default:
972
+ throw new RuntimeError('Trimming side must be "left", "right" or "both".');
973
  }
974
  }
975
 
976
  /**
977
  * Escapes a string.
978
  *
979
+ * @param mixed $string The value to be escaped
980
+ * @param string $strategy The escaping strategy
981
+ * @param string $charset The charset
982
+ * @param bool $autoescape Whether the function is called by the auto-escaping feature (true) or by the developer (false)
 
983
  *
984
  * @return string
985
  */
986
  function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html', $charset = null, $autoescape = false)
987
  {
988
+ if ($autoescape && $string instanceof Markup) {
989
  return $string;
990
  }
991
 
992
+ if (!\is_string($string)) {
993
+ if (\is_object($string) && method_exists($string, '__toString')) {
994
  $string = (string) $string;
995
+ } elseif (\in_array($strategy, ['html', 'js', 'css', 'html_attr', 'url'])) {
996
  return $string;
997
  }
998
  }
1053
  }
1054
 
1055
  if (!preg_match('//u', $string)) {
1056
+ throw new RuntimeError('The string to escape is not a valid UTF-8 string.');
1057
  }
1058
 
1059
  $string = preg_replace_callback('#[^a-zA-Z0-9,\._]#Su', '_twig_escape_js_callback', $string);
1070
  }
1071
 
1072
  if (!preg_match('//u', $string)) {
1073
+ throw new RuntimeError('The string to escape is not a valid UTF-8 string.');
1074
  }
1075
 
1076
  $string = preg_replace_callback('#[^a-zA-Z0-9]#Su', '_twig_escape_css_callback', $string);
1087
  }
1088
 
1089
  if (!preg_match('//u', $string)) {
1090
+ throw new RuntimeError('The string to escape is not a valid UTF-8 string.');
1091
  }
1092
 
1093
  $string = preg_replace_callback('#[^a-zA-Z0-9,\.\-_]#Su', '_twig_escape_html_attr_callback', $string);
1105
  static $escapers;
1106
 
1107
  if (null === $escapers) {
1108
+ $escapers = $env->getExtension('\Twig\Extension\CoreExtension')->getEscapers();
1109
  }
1110
 
1111
  if (isset($escapers[$strategy])) {
1112
+ return \call_user_func($escapers[$strategy], $env, $string, $charset);
1113
  }
1114
 
1115
  $validStrategies = implode(', ', array_merge(['html', 'js', 'url', 'css', 'html_attr'], array_keys($escapers)));
1116
 
1117
+ throw new RuntimeError(sprintf('Invalid escaping strategy "%s" (valid ones: %s).', $strategy, $validStrategies));
1118
  }
1119
  }
1120
 
1124
  function twig_escape_filter_is_safe(Twig_Node $filterArgs)
1125
  {
1126
  foreach ($filterArgs as $arg) {
1127
+ if ($arg instanceof ConstantExpression) {
1128
  return [$arg->getAttribute('value')];
1129
  }
1130
 
1134
  return ['html'];
1135
  }
1136
 
1137
+ if (\function_exists('mb_convert_encoding')) {
1138
  function twig_convert_encoding($string, $to, $from)
1139
  {
1140
  return mb_convert_encoding($string, $to, $from);
1141
  }
1142
+ } elseif (\function_exists('iconv')) {
1143
  function twig_convert_encoding($string, $to, $from)
1144
  {
1145
  return iconv($from, $to, $string);
1147
  } else {
1148
  function twig_convert_encoding($string, $to, $from)
1149
  {
1150
+ throw new RuntimeError('No suitable convert encoding function (use UTF-8 as your encoding or install the iconv or mbstring extension).');
1151
  }
1152
  }
1153
 
1154
+ if (\function_exists('mb_ord')) {
1155
  function twig_ord($string)
1156
  {
1157
  return mb_ord($string, 'UTF-8');
1201
  $char = twig_convert_encoding($char, 'UTF-16BE', 'UTF-8');
1202
  $char = strtoupper(bin2hex($char));
1203
 
1204
+ if (4 >= \strlen($char)) {
1205
  return sprintf('\u%04s', $char);
1206
  }
1207
 
1212
  {
1213
  $char = $matches[0];
1214
 
1215
+ return sprintf('\\%X ', 1 === \strlen($char) ? \ord($char) : twig_ord($char));
1216
  }
1217
 
1218
  /**
1224
  function _twig_escape_html_attr_callback($matches)
1225
  {
1226
  $chr = $matches[0];
1227
+ $ord = \ord($chr);
1228
 
1229
  /*
1230
  * The following replaces characters undefined in HTML with the
1238
  * Check if the current character to escape has a name entity we should
1239
  * replace it with while grabbing the hex value of the character.
1240
  */
1241
+ if (1 == \strlen($chr)) {
1242
  /*
1243
  * While HTML supports far more named entities, the lowest common denominator
1244
  * has become HTML5's XML Serialisation which is restricted to the those named
1267
  }
1268
 
1269
  // add multibyte extensions if possible
1270
+ if (\function_exists('mb_get_info')) {
1271
  /**
1272
  * Returns the length of a variable.
1273
  *
1274
+ * @param mixed $thing A variable
 
1275
  *
1276
  * @return int The length of the value
1277
  */
1278
+ function twig_length_filter(Environment $env, $thing)
1279
  {
1280
  if (null === $thing) {
1281
  return 0;
1286
  }
1287
 
1288
  if ($thing instanceof \SimpleXMLElement) {
1289
+ return \count($thing);
1290
  }
1291
 
1292
+ if (\is_object($thing) && method_exists($thing, '__toString') && !$thing instanceof \Countable) {
1293
  return mb_strlen((string) $thing, $env->getCharset());
1294
  }
1295
 
1296
+ if ($thing instanceof \Countable || \is_array($thing)) {
1297
+ return \count($thing);
1298
  }
1299
 
1300
  if ($thing instanceof \IteratorAggregate) {
1307
  /**
1308
  * Converts a string to uppercase.
1309
  *
1310
+ * @param string $string A string
 
1311
  *
1312
  * @return string The uppercased string
1313
  */
1314
+ function twig_upper_filter(Environment $env, $string)
1315
  {
1316
  if (null !== $charset = $env->getCharset()) {
1317
  return mb_strtoupper($string, $charset);
1323
  /**
1324
  * Converts a string to lowercase.
1325
  *
1326
+ * @param string $string A string
 
1327
  *
1328
  * @return string The lowercased string
1329
  */
1330
+ function twig_lower_filter(Environment $env, $string)
1331
  {
1332
  if (null !== $charset = $env->getCharset()) {
1333
  return mb_strtolower($string, $charset);
1339
  /**
1340
  * Returns a titlecased string.
1341
  *
1342
+ * @param string $string A string
 
1343
  *
1344
  * @return string The titlecased string
1345
  */
1346
+ function twig_title_string_filter(Environment $env, $string)
1347
  {
1348
  if (null !== $charset = $env->getCharset()) {
1349
  return mb_convert_case($string, MB_CASE_TITLE, $charset);
1355
  /**
1356
  * Returns a capitalized string.
1357
  *
1358
+ * @param string $string A string
 
1359
  *
1360
  * @return string The capitalized string
1361
  */
1362
+ function twig_capitalize_string_filter(Environment $env, $string)
1363
  {
1364
  if (null !== $charset = $env->getCharset()) {
1365
  return mb_strtoupper(mb_substr($string, 0, 1, $charset), $charset).mb_strtolower(mb_substr($string, 1, mb_strlen($string, $charset), $charset), $charset);
1373
  /**
1374
  * Returns the length of a variable.
1375
  *
1376
+ * @param mixed $thing A variable
 
1377
  *
1378
  * @return int The length of the value
1379
  */
1380
+ function twig_length_filter(Environment $env, $thing)
1381
  {
1382
  if (null === $thing) {
1383
  return 0;
1384
  }
1385
 
1386
  if (is_scalar($thing)) {
1387
+ return \strlen($thing);
1388
  }
1389
 
1390
  if ($thing instanceof \SimpleXMLElement) {
1391
+ return \count($thing);
1392
  }
1393
 
1394
+ if (\is_object($thing) && method_exists($thing, '__toString') && !$thing instanceof \Countable) {
1395
+ return \strlen((string) $thing);
1396
  }
1397
 
1398
+ if ($thing instanceof \Countable || \is_array($thing)) {
1399
+ return \count($thing);
1400
  }
1401
 
1402
  if ($thing instanceof \IteratorAggregate) {
1409
  /**
1410
  * Returns a titlecased string.
1411
  *
1412
+ * @param string $string A string
 
1413
  *
1414
  * @return string The titlecased string
1415
  */
1416
+ function twig_title_string_filter(Environment $env, $string)
1417
  {
1418
  return ucwords(strtolower($string));
1419
  }
1421
  /**
1422
  * Returns a capitalized string.
1423
  *
1424
+ * @param string $string A string
 
1425
  *
1426
  * @return string The capitalized string
1427
  */
1428
+ function twig_capitalize_string_filter(Environment $env, $string)
1429
  {
1430
  return ucfirst(strtolower($string));
1431
  }
1436
  */
1437
  function twig_ensure_traversable($seq)
1438
  {
1439
+ if ($seq instanceof \Traversable || \is_array($seq)) {
1440
  return $seq;
1441
  }
1442
 
1446
  /**
1447
  * Checks if a variable is empty.
1448
  *
1449
+ * {# evaluates to true if the foo variable is null, false, or the empty string #}
1450
+ * {% if foo is empty %}
1451
+ * {# ... #}
1452
+ * {% endif %}
 
 
1453
  *
1454
  * @param mixed $value A variable
1455
  *
1457
  */
1458
  function twig_test_empty($value)
1459
  {
1460
+ if ($value instanceof \Countable) {
1461
+ return 0 == \count($value);
1462
  }
1463
 
1464
+ if (\is_object($value) && method_exists($value, '__toString')) {
1465
  return '' === (string) $value;
1466
  }
1467
 
1471
  /**
1472
  * Checks if a variable is traversable.
1473
  *
1474
+ * {# evaluates to true if the foo variable is an array or a traversable object #}
1475
+ * {% if foo is iterable %}
1476
+ * {# ... #}
1477
+ * {% endif %}
 
 
1478
  *
1479
  * @param mixed $value A variable
1480
  *
1482
  */
1483
  function twig_test_iterable($value)
1484
  {
1485
+ return $value instanceof \Traversable || \is_array($value);
1486
  }
1487
 
1488
  /**
1489
  * Renders a template.
1490
  *
1491
+ * @param array $context
1492
+ * @param string|array $template The template to render or an array of templates to try consecutively
1493
+ * @param array $variables The variables to pass to the template
1494
+ * @param bool $withContext
1495
+ * @param bool $ignoreMissing Whether to ignore missing templates or not
1496
+ * @param bool $sandboxed Whether to sandbox the template or not
 
1497
  *
1498
  * @return string The rendered template
1499
  */
1505
  $variables = array_merge($context, $variables);
1506
  }
1507
 
1508
+ if ($isSandboxed = $sandboxed && $env->hasExtension('\Twig\Extension\SandboxExtension')) {
1509
+ $sandbox = $env->getExtension('\Twig\Extension\SandboxExtension');
1510
  if (!$alreadySandboxed = $sandbox->isSandboxed()) {
1511
  $sandbox->enableSandbox();
1512
  }
1515
  $result = '';
1516
  try {
1517
  $result = $env->resolveTemplate($template)->render($variables);
1518
+ } catch (LoaderError $e) {
1519
  if (!$ignoreMissing) {
1520
  if ($isSandboxed && !$alreadySandboxed) {
1521
  $sandbox->disableSandbox();
1523
 
1524
  throw $e;
1525
  }
1526
+ } catch (\Throwable $e) {
1527
  if ($isSandboxed && !$alreadySandboxed) {
1528
  $sandbox->disableSandbox();
1529
  }
1530
 
1531
  throw $e;
1532
+ } catch (\Exception $e) {
1533
  if ($isSandboxed && !$alreadySandboxed) {
1534
  $sandbox->disableSandbox();
1535
  }
1547
  /**
1548
  * Returns a template content without rendering it.
1549
  *
1550
+ * @param string $name The template name
1551
+ * @param bool $ignoreMissing Whether to ignore missing templates or not
 
1552
  *
1553
  * @return string The template source
1554
  */
1556
  {
1557
  $loader = $env->getLoader();
1558
  try {
1559
+ if (!$loader instanceof SourceContextLoaderInterface) {
1560
  return $loader->getSource($name);
1561
  } else {
1562
  return $loader->getSourceContext($name)->getCode();
1563
  }
1564
+ } catch (LoaderError $e) {
1565
  if (!$ignoreMissing) {
1566
  throw $e;
1567
  }
1579
  function twig_constant($constant, $object = null)
1580
  {
1581
  if (null !== $object) {
1582
+ $constant = \get_class($object).'::'.$constant;
1583
  }
1584
 
1585
+ return \constant($constant);
1586
  }
1587
 
1588
  /**
1596
  function twig_constant_is_defined($constant, $object = null)
1597
  {
1598
  if (null !== $object) {
1599
+ $constant = \get_class($object).'::'.$constant;
1600
  }
1601
 
1602
+ return \defined($constant);
1603
  }
1604
 
1605
  /**
1613
  */
1614
  function twig_array_batch($items, $size, $fill = null)
1615
  {
1616
+ if ($items instanceof \Traversable) {
1617
  $items = iterator_to_array($items, false);
1618
  }
1619
 
1622
  $result = array_chunk($items, $size, true);
1623
 
1624
  if (null !== $fill && !empty($result)) {
1625
+ $last = \count($result) - 1;
1626
+ if ($fillCount = $size - \count($result[$last])) {
1627
  $result[$last] = array_merge(
1628
  $result[$last],
1629
  array_fill(0, $fillCount, $fill)
vendor/twig/twig/lib/Twig/Extension/Debug.php CHANGED
@@ -9,15 +9,19 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
12
  /**
13
  * @final
14
  */
15
- class Twig_Extension_Debug extends Twig_Extension
16
  {
17
  public function getFunctions()
18
  {
19
  // dump is safe if var_dump is overridden by xdebug
20
- $isDumpOutputHtmlSafe = extension_loaded('xdebug')
21
  // false means that it was not set (and the default is on) or it explicitly enabled
22
  && (false === ini_get('xdebug.overload_var_dump') || ini_get('xdebug.overload_var_dump'))
23
  // false means that it was not set (and the default is on) or it explicitly enabled
@@ -27,7 +31,7 @@ class Twig_Extension_Debug extends Twig_Extension
27
  ;
28
 
29
  return [
30
- new Twig_SimpleFunction('dump', 'twig_var_dump', ['is_safe' => $isDumpOutputHtmlSafe ? ['html'] : [], 'needs_context' => true, 'needs_environment' => true]),
31
  ];
32
  }
33
 
@@ -45,11 +49,11 @@ function twig_var_dump(Twig_Environment $env, $context)
45
 
46
  ob_start();
47
 
48
- $count = func_num_args();
49
  if (2 === $count) {
50
  $vars = [];
51
  foreach ($context as $key => $value) {
52
- if (!$value instanceof Twig_Template) {
53
  $vars[$key] = $value;
54
  }
55
  }
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Extension\AbstractExtension;
13
+ use Twig\Template;
14
+ use Twig\TwigFunction;
15
+
16
  /**
17
  * @final
18
  */
19
+ class Twig_Extension_Debug extends AbstractExtension
20
  {
21
  public function getFunctions()
22
  {
23
  // dump is safe if var_dump is overridden by xdebug
24
+ $isDumpOutputHtmlSafe = \extension_loaded('xdebug')
25
  // false means that it was not set (and the default is on) or it explicitly enabled
26
  && (false === ini_get('xdebug.overload_var_dump') || ini_get('xdebug.overload_var_dump'))
27
  // false means that it was not set (and the default is on) or it explicitly enabled
31
  ;
32
 
33
  return [
34
+ new TwigFunction('dump', 'twig_var_dump', ['is_safe' => $isDumpOutputHtmlSafe ? ['html'] : [], 'needs_context' => true, 'needs_environment' => true]),
35
  ];
36
  }
37
 
49
 
50
  ob_start();
51
 
52
+ $count = \func_num_args();
53
  if (2 === $count) {
54
  $vars = [];
55
  foreach ($context as $key => $value) {
56
+ if (!$value instanceof Template) {
57
  $vars[$key] = $value;
58
  }
59
  }
vendor/twig/twig/lib/Twig/Extension/Escaper.php CHANGED
@@ -9,10 +9,15 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
 
12
  /**
13
  * @final
14
  */
15
- class Twig_Extension_Escaper extends Twig_Extension
16
  {
17
  protected $defaultStrategy;
18
 
@@ -28,18 +33,18 @@ class Twig_Extension_Escaper extends Twig_Extension
28
 
29
  public function getTokenParsers()
30
  {
31
- return [new Twig_TokenParser_AutoEscape()];
32
  }
33
 
34
  public function getNodeVisitors()
35
  {
36
- return [new Twig_NodeVisitor_Escaper()];
37
  }
38
 
39
  public function getFilters()
40
  {
41
  return [
42
- new Twig_SimpleFilter('raw', 'twig_raw_filter', ['is_safe' => ['all']]),
43
  ];
44
  }
45
 
@@ -67,7 +72,7 @@ class Twig_Extension_Escaper extends Twig_Extension
67
  }
68
 
69
  if ('name' === $defaultStrategy) {
70
- $defaultStrategy = ['Twig_FileExtensionEscapingStrategy', 'guess'];
71
  }
72
 
73
  $this->defaultStrategy = $defaultStrategy;
@@ -84,8 +89,8 @@ class Twig_Extension_Escaper extends Twig_Extension
84
  {
85
  // disable string callables to avoid calling a function named html or js,
86
  // or any other upcoming escaping strategy
87
- if (!is_string($this->defaultStrategy) && false !== $this->defaultStrategy) {
88
- return call_user_func($this->defaultStrategy, $name);
89
  }
90
 
91
  return $this->defaultStrategy;
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Extension\AbstractExtension;
13
+ use Twig\NodeVisitor\EscaperNodeVisitor;
14
+ use Twig\TokenParser\AutoEscapeTokenParser;
15
+ use Twig\TwigFilter;
16
+
17
  /**
18
  * @final
19
  */
20
+ class Twig_Extension_Escaper extends AbstractExtension
21
  {
22
  protected $defaultStrategy;
23
 
33
 
34
  public function getTokenParsers()
35
  {
36
+ return [new AutoEscapeTokenParser()];
37
  }
38
 
39
  public function getNodeVisitors()
40
  {
41
+ return [new EscaperNodeVisitor()];
42
  }
43
 
44
  public function getFilters()
45
  {
46
  return [
47
+ new TwigFilter('raw', 'twig_raw_filter', ['is_safe' => ['all']]),
48
  ];
49
  }
50
 
72
  }
73
 
74
  if ('name' === $defaultStrategy) {
75
+ $defaultStrategy = ['\Twig\FileExtensionEscapingStrategy', 'guess'];
76
  }
77
 
78
  $this->defaultStrategy = $defaultStrategy;
89
  {
90
  // disable string callables to avoid calling a function named html or js,
91
  // or any other upcoming escaping strategy
92
+ if (!\is_string($this->defaultStrategy) && false !== $this->defaultStrategy) {
93
+ return \call_user_func($this->defaultStrategy, $name);
94
  }
95
 
96
  return $this->defaultStrategy;
vendor/twig/twig/lib/Twig/Extension/GlobalsInterface.php CHANGED
@@ -10,7 +10,7 @@
10
  */
11
 
12
  /**
13
- * Enables usage of the deprecated Twig_Extension::getGlobals() method.
14
  *
15
  * Explicitly implement this interface if you really need to implement the
16
  * deprecated getGlobals() method in your extensions.
10
  */
11
 
12
  /**
13
+ * Enables usage of the deprecated Twig\Extension\AbstractExtension::getGlobals() method.
14
  *
15
  * Explicitly implement this interface if you really need to implement the
16
  * deprecated getGlobals() method in your extensions.
vendor/twig/twig/lib/Twig/Extension/InitRuntimeInterface.php CHANGED
@@ -10,7 +10,7 @@
10
  */
11
 
12
  /**
13
- * Enables usage of the deprecated Twig_Extension::initRuntime() method.
14
  *
15
  * Explicitly implement this interface if you really need to implement the
16
  * deprecated initRuntime() method in your extensions.
10
  */
11
 
12
  /**
13
+ * Enables usage of the deprecated Twig\Extension\AbstractExtension::initRuntime() method.
14
  *
15
  * Explicitly implement this interface if you really need to implement the
16
  * deprecated initRuntime() method in your extensions.
vendor/twig/twig/lib/Twig/Extension/Optimizer.php CHANGED
@@ -9,10 +9,13 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
12
  /**
13
  * @final
14
  */
15
- class Twig_Extension_Optimizer extends Twig_Extension
16
  {
17
  protected $optimizers;
18
 
@@ -23,7 +26,7 @@ class Twig_Extension_Optimizer extends Twig_Extension
23
 
24
  public function getNodeVisitors()
25
  {
26
- return [new Twig_NodeVisitor_Optimizer($this->optimizers)];
27
  }
28
 
29
  public function getName()
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Extension\AbstractExtension;
13
+ use Twig\NodeVisitor\OptimizerNodeVisitor;
14
+
15
  /**
16
  * @final
17
  */
18
+ class Twig_Extension_Optimizer extends AbstractExtension
19
  {
20
  protected $optimizers;
21
 
26
 
27
  public function getNodeVisitors()
28
  {
29
+ return [new OptimizerNodeVisitor($this->optimizers)];
30
  }
31
 
32
  public function getName()
vendor/twig/twig/lib/Twig/Extension/Profiler.php CHANGED
@@ -9,34 +9,38 @@
9
  * file that was distributed with this source code.
10
  */
11
 
12
- class Twig_Extension_Profiler extends Twig_Extension
 
 
 
 
13
  {
14
  private $actives = [];
15
 
16
- public function __construct(Twig_Profiler_Profile $profile)
17
  {
18
  $this->actives[] = $profile;
19
  }
20
 
21
- public function enter(Twig_Profiler_Profile $profile)
22
  {
23
  $this->actives[0]->addProfile($profile);
24
  array_unshift($this->actives, $profile);
25
  }
26
 
27
- public function leave(Twig_Profiler_Profile $profile)
28
  {
29
  $profile->leave();
30
  array_shift($this->actives);
31
 
32
- if (1 === count($this->actives)) {
33
  $this->actives[0]->leave();
34
  }
35
  }
36
 
37
  public function getNodeVisitors()
38
  {
39
- return [new Twig_Profiler_NodeVisitor_Profiler(get_class($this))];
40
  }
41
 
42
  public function getName()
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Extension\AbstractExtension;
13
+ use Twig\Profiler\NodeVisitor\ProfilerNodeVisitor;
14
+ use Twig\Profiler\Profile;
15
+
16
+ class Twig_Extension_Profiler extends AbstractExtension
17
  {
18
  private $actives = [];
19
 
20
+ public function __construct(Profile $profile)
21
  {
22
  $this->actives[] = $profile;
23
  }
24
 
25
+ public function enter(Profile $profile)
26
  {
27
  $this->actives[0]->addProfile($profile);
28
  array_unshift($this->actives, $profile);
29
  }
30
 
31
+ public function leave(Profile $profile)
32
  {
33
  $profile->leave();
34
  array_shift($this->actives);
35
 
36
+ if (1 === \count($this->actives)) {
37
  $this->actives[0]->leave();
38
  }
39
  }
40
 
41
  public function getNodeVisitors()
42
  {
43
+ return [new ProfilerNodeVisitor(\get_class($this))];
44
  }
45
 
46
  public function getName()
vendor/twig/twig/lib/Twig/Extension/Sandbox.php CHANGED
@@ -9,16 +9,21 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
 
12
  /**
13
  * @final
14
  */
15
- class Twig_Extension_Sandbox extends Twig_Extension
16
  {
17
  protected $sandboxedGlobally;
18
  protected $sandboxed;
19
  protected $policy;
20
 
21
- public function __construct(Twig_Sandbox_SecurityPolicyInterface $policy, $sandboxed = false)
22
  {
23
  $this->policy = $policy;
24
  $this->sandboxedGlobally = $sandboxed;
@@ -26,12 +31,12 @@ class Twig_Extension_Sandbox extends Twig_Extension
26
 
27
  public function getTokenParsers()
28
  {
29
- return [new Twig_TokenParser_Sandbox()];
30
  }
31
 
32
  public function getNodeVisitors()
33
  {
34
- return [new Twig_NodeVisitor_Sandbox()];
35
  }
36
 
37
  public function enableSandbox()
@@ -54,7 +59,7 @@ class Twig_Extension_Sandbox extends Twig_Extension
54
  return $this->sandboxedGlobally;
55
  }
56
 
57
- public function setSecurityPolicy(Twig_Sandbox_SecurityPolicyInterface $policy)
58
  {
59
  $this->policy = $policy;
60
  }
@@ -87,7 +92,7 @@ class Twig_Extension_Sandbox extends Twig_Extension
87
 
88
  public function ensureToStringAllowed($obj)
89
  {
90
- if ($this->isSandboxed() && is_object($obj)) {
91
  $this->policy->checkMethodAllowed($obj, '__toString');
92
  }
93
 
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Extension\AbstractExtension;
13
+ use Twig\NodeVisitor\SandboxNodeVisitor;
14
+ use Twig\Sandbox\SecurityPolicyInterface;
15
+ use Twig\TokenParser\SandboxTokenParser;
16
+
17
  /**
18
  * @final
19
  */
20
+ class Twig_Extension_Sandbox extends AbstractExtension
21
  {
22
  protected $sandboxedGlobally;
23
  protected $sandboxed;
24
  protected $policy;
25
 
26
+ public function __construct(SecurityPolicyInterface $policy, $sandboxed = false)
27
  {
28
  $this->policy = $policy;
29
  $this->sandboxedGlobally = $sandboxed;
31
 
32
  public function getTokenParsers()
33
  {
34
+ return [new SandboxTokenParser()];
35
  }
36
 
37
  public function getNodeVisitors()
38
  {
39
+ return [new SandboxNodeVisitor()];
40
  }
41
 
42
  public function enableSandbox()
59
  return $this->sandboxedGlobally;
60
  }
61
 
62
+ public function setSecurityPolicy(SecurityPolicyInterface $policy)
63
  {
64
  $this->policy = $policy;
65
  }
92
 
93
  public function ensureToStringAllowed($obj)
94
  {
95
+ if ($this->isSandboxed() && \is_object($obj)) {
96
  $this->policy->checkMethodAllowed($obj, '__toString');
97
  }
98
 
vendor/twig/twig/lib/Twig/Extension/Staging.php CHANGED
@@ -9,6 +9,10 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
12
  /**
13
  * Internal class.
14
  *
@@ -18,7 +22,7 @@
18
  *
19
  * @internal
20
  */
21
- class Twig_Extension_Staging extends Twig_Extension
22
  {
23
  protected $functions = [];
24
  protected $filters = [];
@@ -55,7 +59,7 @@ class Twig_Extension_Staging extends Twig_Extension
55
  return $this->filters;
56
  }
57
 
58
- public function addNodeVisitor(Twig_NodeVisitorInterface $visitor)
59
  {
60
  $this->visitors[] = $visitor;
61
  }
@@ -65,7 +69,7 @@ class Twig_Extension_Staging extends Twig_Extension
65
  return $this->visitors;
66
  }
67
 
68
- public function addTokenParser(Twig_TokenParserInterface $parser)
69
  {
70
  if (isset($this->tokenParsers[$parser->getTag()])) {
71
  @trigger_error(sprintf('Overriding tag "%s" that is already registered is deprecated since version 1.30 and won\'t be possible anymore in 2.0.', $parser->getTag()), E_USER_DEPRECATED);
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Extension\AbstractExtension;
13
+ use Twig\NodeVisitor\NodeVisitorInterface;
14
+ use Twig\TokenParser\TokenParserInterface;
15
+
16
  /**
17
  * Internal class.
18
  *
22
  *
23
  * @internal
24
  */
25
+ class Twig_Extension_Staging extends AbstractExtension
26
  {
27
  protected $functions = [];
28
  protected $filters = [];
59
  return $this->filters;
60
  }
61
 
62
+ public function addNodeVisitor(NodeVisitorInterface $visitor)
63
  {
64
  $this->visitors[] = $visitor;
65
  }
69
  return $this->visitors;
70
  }
71
 
72
+ public function addTokenParser(TokenParserInterface $parser)
73
  {
74
  if (isset($this->tokenParsers[$parser->getTag()])) {
75
  @trigger_error(sprintf('Overriding tag "%s" that is already registered is deprecated since version 1.30 and won\'t be possible anymore in 2.0.', $parser->getTag()), E_USER_DEPRECATED);
vendor/twig/twig/lib/Twig/Extension/StringLoader.php CHANGED
@@ -9,15 +9,19 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
12
  /**
13
  * @final
14
  */
15
- class Twig_Extension_StringLoader extends Twig_Extension
16
  {
17
  public function getFunctions()
18
  {
19
  return [
20
- new Twig_SimpleFunction('template_from_string', 'twig_template_from_string', ['needs_environment' => true]),
21
  ];
22
  }
23
 
@@ -30,14 +34,11 @@ class Twig_Extension_StringLoader extends Twig_Extension
30
  /**
31
  * Loads a template from a string.
32
  *
33
- * <pre>
34
- * {{ include(template_from_string("Hello {{ name }}")) }}
35
- * </pre>
36
  *
37
- * @param Twig_Environment $env A Twig_Environment instance
38
- * @param string $template A template as a string or object implementing __toString()
39
  *
40
- * @return Twig_Template
41
  */
42
  function twig_template_from_string(Twig_Environment $env, $template)
43
  {
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Extension\AbstractExtension;
13
+ use Twig\Template;
14
+ use Twig\TwigFunction;
15
+
16
  /**
17
  * @final
18
  */
19
+ class Twig_Extension_StringLoader extends AbstractExtension
20
  {
21
  public function getFunctions()
22
  {
23
  return [
24
+ new TwigFunction('template_from_string', 'twig_template_from_string', ['needs_environment' => true]),
25
  ];
26
  }
27
 
34
  /**
35
  * Loads a template from a string.
36
  *
37
+ * {{ include(template_from_string("Hello {{ name }}")) }}
 
 
38
  *
39
+ * @param string $template A template as a string or object implementing __toString()
 
40
  *
41
+ * @return Template
42
  */
43
  function twig_template_from_string(Twig_Environment $env, $template)
44
  {
vendor/twig/twig/lib/Twig/ExtensionInterface.php CHANGED
@@ -9,6 +9,13 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
 
 
 
12
  /**
13
  * Interface implemented by extension classes.
14
  *
@@ -23,40 +30,40 @@ interface Twig_ExtensionInterface
23
  *
24
  * @deprecated since 1.23 (to be removed in 2.0), implement Twig_Extension_InitRuntimeInterface instead
25
  */
26
- public function initRuntime(Twig_Environment $environment);
27
 
28
  /**
29
  * Returns the token parser instances to add to the existing list.
30
  *
31
- * @return Twig_TokenParserInterface[]
32
  */
33
  public function getTokenParsers();
34
 
35
  /**
36
  * Returns the node visitor instances to add to the existing list.
37
  *
38
- * @return Twig_NodeVisitorInterface[]
39
  */
40
  public function getNodeVisitors();
41
 
42
  /**
43
  * Returns a list of filters to add to the existing list.
44
  *
45
- * @return Twig_SimpleFilter[]
46
  */
47
  public function getFilters();
48
 
49
  /**
50
  * Returns a list of tests to add to the existing list.
51
  *
52
- * @return Twig_SimpleTest[]
53
  */
54
  public function getTests();
55
 
56
  /**
57
  * Returns a list of functions to add to the existing list.
58
  *
59
- * @return Twig_SimpleFunction[]
60
  */
61
  public function getFunctions();
62
 
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Environment;
13
+ use Twig\NodeVisitor\NodeVisitorInterface;
14
+ use Twig\TokenParser\TokenParserInterface;
15
+ use Twig\TwigFilter;
16
+ use Twig\TwigFunction;
17
+ use Twig\TwigTest;
18
+
19
  /**
20
  * Interface implemented by extension classes.
21
  *
30
  *
31
  * @deprecated since 1.23 (to be removed in 2.0), implement Twig_Extension_InitRuntimeInterface instead
32
  */
33
+ public function initRuntime(Environment $environment);
34
 
35
  /**
36
  * Returns the token parser instances to add to the existing list.
37
  *
38
+ * @return TokenParserInterface[]
39
  */
40
  public function getTokenParsers();
41
 
42
  /**
43
  * Returns the node visitor instances to add to the existing list.
44
  *
45
+ * @return NodeVisitorInterface[]
46
  */
47
  public function getNodeVisitors();
48
 
49
  /**
50
  * Returns a list of filters to add to the existing list.
51
  *
52
+ * @return TwigFilter[]
53
  */
54
  public function getFilters();
55
 
56
  /**
57
  * Returns a list of tests to add to the existing list.
58
  *
59
+ * @return TwigTest[]
60
  */
61
  public function getTests();
62
 
63
  /**
64
  * Returns a list of functions to add to the existing list.
65
  *
66
+ * @return TwigFunction[]
67
  */
68
  public function getFunctions();
69
 
vendor/twig/twig/lib/Twig/FactoryRuntimeLoader.php CHANGED
@@ -9,12 +9,14 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
12
  /**
13
  * Lazy loads the runtime implementations for a Twig element.
14
  *
15
  * @author Robin Chalas <robin.chalas@gmail.com>
16
  */
17
- class Twig_FactoryRuntimeLoader implements Twig_RuntimeLoaderInterface
18
  {
19
  private $map;
20
 
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\RuntimeLoader\RuntimeLoaderInterface;
13
+
14
  /**
15
  * Lazy loads the runtime implementations for a Twig element.
16
  *
17
  * @author Robin Chalas <robin.chalas@gmail.com>
18
  */
19
+ class Twig_FactoryRuntimeLoader implements RuntimeLoaderInterface
20
  {
21
  private $map;
22
 
vendor/twig/twig/lib/Twig/FileExtensionEscapingStrategy.php CHANGED
@@ -31,7 +31,7 @@ class Twig_FileExtensionEscapingStrategy
31
  */
32
  public static function guess($name)
33
  {
34
- if (in_array(substr($name, -1), ['/', '\\'])) {
35
  return 'html'; // return html for directories
36
  }
37
 
31
  */
32
  public static function guess($name)
33
  {
34
+ if (\in_array(substr($name, -1), ['/', '\\'])) {
35
  return 'html'; // return html for directories
36
  }
37
 
vendor/twig/twig/lib/Twig/Filter.php CHANGED
@@ -9,6 +9,8 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
12
  @trigger_error('The Twig_Filter class is deprecated since version 1.12 and will be removed in 2.0. Use Twig_SimpleFilter instead.', E_USER_DEPRECATED);
13
 
14
  /**
@@ -56,14 +58,14 @@ abstract class Twig_Filter implements Twig_FilterInterface, Twig_FilterCallableI
56
  return $this->options['needs_context'];
57
  }
58
 
59
- public function getSafe(Twig_Node $filterArgs)
60
  {
61
  if (isset($this->options['is_safe'])) {
62
  return $this->options['is_safe'];
63
  }
64
 
65
  if (isset($this->options['is_safe_callback'])) {
66
- return call_user_func($this->options['is_safe_callback'], $filterArgs);
67
  }
68
  }
69
 
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Node\Node;
13
+
14
  @trigger_error('The Twig_Filter class is deprecated since version 1.12 and will be removed in 2.0. Use Twig_SimpleFilter instead.', E_USER_DEPRECATED);
15
 
16
  /**
58
  return $this->options['needs_context'];
59
  }
60
 
61
+ public function getSafe(Node $filterArgs)
62
  {
63
  if (isset($this->options['is_safe'])) {
64
  return $this->options['is_safe'];
65
  }
66
 
67
  if (isset($this->options['is_safe_callback'])) {
68
+ return \call_user_func($this->options['is_safe_callback'], $filterArgs);
69
  }
70
  }
71
 
vendor/twig/twig/lib/Twig/Filter/Method.php CHANGED
@@ -9,6 +9,8 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
12
  @trigger_error('The Twig_Filter_Method class is deprecated since version 1.12 and will be removed in 2.0. Use Twig_SimpleFilter instead.', E_USER_DEPRECATED);
13
 
14
  /**
@@ -25,7 +27,7 @@ class Twig_Filter_Method extends Twig_Filter
25
  protected $extension;
26
  protected $method;
27
 
28
- public function __construct(Twig_ExtensionInterface $extension, $method, array $options = [])
29
  {
30
  $options['callable'] = [$extension, $method];
31
 
@@ -37,6 +39,6 @@ class Twig_Filter_Method extends Twig_Filter
37
 
38
  public function compile()
39
  {
40
- return sprintf('$this->env->getExtension(\'%s\')->%s', get_class($this->extension), $this->method);
41
  }
42
  }
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Extension\ExtensionInterface;
13
+
14
  @trigger_error('The Twig_Filter_Method class is deprecated since version 1.12 and will be removed in 2.0. Use Twig_SimpleFilter instead.', E_USER_DEPRECATED);
15
 
16
  /**
27
  protected $extension;
28
  protected $method;
29
 
30
+ public function __construct(ExtensionInterface $extension, $method, array $options = [])
31
  {
32
  $options['callable'] = [$extension, $method];
33
 
39
 
40
  public function compile()
41
  {
42
+ return sprintf('$this->env->getExtension(\'%s\')->%s', \get_class($this->extension), $this->method);
43
  }
44
  }
vendor/twig/twig/lib/Twig/FilterInterface.php CHANGED
@@ -9,6 +9,8 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
12
  /**
13
  * Represents a template filter.
14
  *
@@ -31,7 +33,7 @@ interface Twig_FilterInterface
31
 
32
  public function needsContext();
33
 
34
- public function getSafe(Twig_Node $filterArgs);
35
 
36
  public function getPreservesSafety();
37
 
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Node\Node;
13
+
14
  /**
15
  * Represents a template filter.
16
  *
33
 
34
  public function needsContext();
35
 
36
+ public function getSafe(Node $filterArgs);
37
 
38
  public function getPreservesSafety();
39
 
vendor/twig/twig/lib/Twig/Function.php CHANGED
@@ -9,6 +9,8 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
12
  @trigger_error('The Twig_Function class is deprecated since version 1.12 and will be removed in 2.0. Use Twig_SimpleFunction instead.', E_USER_DEPRECATED);
13
 
14
  /**
@@ -54,14 +56,14 @@ abstract class Twig_Function implements Twig_FunctionInterface, Twig_FunctionCal
54
  return $this->options['needs_context'];
55
  }
56
 
57
- public function getSafe(Twig_Node $functionArgs)
58
  {
59
  if (isset($this->options['is_safe'])) {
60
  return $this->options['is_safe'];
61
  }
62
 
63
  if (isset($this->options['is_safe_callback'])) {
64
- return call_user_func($this->options['is_safe_callback'], $functionArgs);
65
  }
66
 
67
  return [];
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Node\Node;
13
+
14
  @trigger_error('The Twig_Function class is deprecated since version 1.12 and will be removed in 2.0. Use Twig_SimpleFunction instead.', E_USER_DEPRECATED);
15
 
16
  /**
56
  return $this->options['needs_context'];
57
  }
58
 
59
+ public function getSafe(Node $functionArgs)
60
  {
61
  if (isset($this->options['is_safe'])) {
62
  return $this->options['is_safe'];
63
  }
64
 
65
  if (isset($this->options['is_safe_callback'])) {
66
+ return \call_user_func($this->options['is_safe_callback'], $functionArgs);
67
  }
68
 
69
  return [];
vendor/twig/twig/lib/Twig/Function/Method.php CHANGED
@@ -10,6 +10,8 @@
10
  * file that was distributed with this source code.
11
  */
12
 
 
 
13
  @trigger_error('The Twig_Function_Method class is deprecated since version 1.12 and will be removed in 2.0. Use Twig_SimpleFunction instead.', E_USER_DEPRECATED);
14
 
15
  /**
@@ -26,7 +28,7 @@ class Twig_Function_Method extends Twig_Function
26
  protected $extension;
27
  protected $method;
28
 
29
- public function __construct(Twig_ExtensionInterface $extension, $method, array $options = [])
30
  {
31
  $options['callable'] = [$extension, $method];
32
 
@@ -38,6 +40,6 @@ class Twig_Function_Method extends Twig_Function
38
 
39
  public function compile()
40
  {
41
- return sprintf('$this->env->getExtension(\'%s\')->%s', get_class($this->extension), $this->method);
42
  }
43
  }
10
  * file that was distributed with this source code.
11
  */
12
 
13
+ use Twig\Extension\ExtensionInterface;
14
+
15
  @trigger_error('The Twig_Function_Method class is deprecated since version 1.12 and will be removed in 2.0. Use Twig_SimpleFunction instead.', E_USER_DEPRECATED);
16
 
17
  /**
28
  protected $extension;
29
  protected $method;
30
 
31
+ public function __construct(ExtensionInterface $extension, $method, array $options = [])
32
  {
33
  $options['callable'] = [$extension, $method];
34
 
40
 
41
  public function compile()
42
  {
43
+ return sprintf('$this->env->getExtension(\'%s\')->%s', \get_class($this->extension), $this->method);
44
  }
45
  }
vendor/twig/twig/lib/Twig/FunctionInterface.php CHANGED
@@ -10,6 +10,8 @@
10
  * file that was distributed with this source code.
11
  */
12
 
 
 
13
  /**
14
  * Represents a template function.
15
  *
@@ -32,7 +34,7 @@ interface Twig_FunctionInterface
32
 
33
  public function needsContext();
34
 
35
- public function getSafe(Twig_Node $filterArgs);
36
 
37
  public function setArguments($arguments);
38
 
10
  * file that was distributed with this source code.
11
  */
12
 
13
+ use Twig\Node\Node;
14
+
15
  /**
16
  * Represents a template function.
17
  *
34
 
35
  public function needsContext();
36
 
37
+ public function getSafe(Node $filterArgs);
38
 
39
  public function setArguments($arguments);
40
 
vendor/twig/twig/lib/Twig/Lexer.php CHANGED
@@ -10,6 +10,12 @@
10
  * file that was distributed with this source code.
11
  */
12
 
 
 
 
 
 
 
13
  /**
14
  * Lexes a template string.
15
  *
@@ -49,7 +55,7 @@ class Twig_Lexer implements Twig_LexerInterface
49
  const REGEX_DQ_STRING_PART = '/[^#"\\\\]*(?:(?:\\\\.|#(?!\{))[^#"\\\\]*)*/As';
50
  const PUNCTUATION = '()[]{}?:.,|';
51
 
52
- public function __construct(Twig_Environment $env, array $options = [])
53
  {
54
  $this->env = $env;
55
 
@@ -77,9 +83,9 @@ class Twig_Lexer implements Twig_LexerInterface
77
 
78
  public function tokenize($code, $name = null)
79
  {
80
- if (!$code instanceof Twig_Source) {
81
  @trigger_error(sprintf('Passing a string as the $code argument of %s() is deprecated since version 1.27 and will be removed in 2.0. Pass a Twig_Source instance instead.', __METHOD__), E_USER_DEPRECATED);
82
- $this->source = new Twig_Source($code, $name);
83
  } else {
84
  $this->source = $code;
85
  }
@@ -88,7 +94,7 @@ class Twig_Lexer implements Twig_LexerInterface
88
  @trigger_error('Support for having "mbstring.func_overload" different from 0 is deprecated version 1.29 and will be removed in 2.0.', E_USER_DEPRECATED);
89
  }
90
 
91
- if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
92
  $mbEncoding = mb_internal_encoding();
93
  mb_internal_encoding('ASCII');
94
  } else {
@@ -99,7 +105,7 @@ class Twig_Lexer implements Twig_LexerInterface
99
  $this->filename = $this->source->getName();
100
  $this->cursor = 0;
101
  $this->lineno = 1;
102
- $this->end = strlen($this->code);
103
  $this->tokens = [];
104
  $this->state = self::STATE_DATA;
105
  $this->states = [];
@@ -136,25 +142,25 @@ class Twig_Lexer implements Twig_LexerInterface
136
  }
137
  }
138
 
139
- $this->pushToken(Twig_Token::EOF_TYPE);
140
 
141
  if (!empty($this->brackets)) {
142
  list($expect, $lineno) = array_pop($this->brackets);
143
- throw new Twig_Error_Syntax(sprintf('Unclosed "%s".', $expect), $lineno, $this->source);
144
  }
145
 
146
  if ($mbEncoding) {
147
  mb_internal_encoding($mbEncoding);
148
  }
149
 
150
- return new Twig_TokenStream($this->tokens, $this->source);
151
  }
152
 
153
  protected function lexData()
154
  {
155
  // if no matches are left we return the rest of the template as simple text token
156
- if ($this->position == count($this->positions[0]) - 1) {
157
- $this->pushToken(Twig_Token::TEXT_TYPE, substr($this->code, $this->cursor));
158
  $this->cursor = $this->end;
159
 
160
  return;
@@ -163,7 +169,7 @@ class Twig_Lexer implements Twig_LexerInterface
163
  // Find the first token after the current cursor
164
  $position = $this->positions[0][++$this->position];
165
  while ($position[1] < $this->cursor) {
166
- if ($this->position == count($this->positions[0]) - 1) {
167
  return;
168
  }
169
  $position = $this->positions[0][++$this->position];
@@ -174,7 +180,7 @@ class Twig_Lexer implements Twig_LexerInterface
174
  if (isset($this->positions[2][$this->position][0])) {
175
  $text = rtrim($text);
176
  }
177
- $this->pushToken(Twig_Token::TEXT_TYPE, $text);
178
  $this->moveCursor($textContent.$position[0]);
179
 
180
  switch ($this->positions[1][$this->position][0]) {
@@ -192,14 +198,14 @@ class Twig_Lexer implements Twig_LexerInterface
192
  $this->moveCursor($match[0]);
193
  $this->lineno = (int) $match[1];
194
  } else {
195
- $this->pushToken(Twig_Token::BLOCK_START_TYPE);
196
  $this->pushState(self::STATE_BLOCK);
197
  $this->currentVarBlockLine = $this->lineno;
198
  }
199
  break;
200
 
201
  case $this->options['tag_variable'][0]:
202
- $this->pushToken(Twig_Token::VAR_START_TYPE);
203
  $this->pushState(self::STATE_VAR);
204
  $this->currentVarBlockLine = $this->lineno;
205
  break;
@@ -209,7 +215,7 @@ class Twig_Lexer implements Twig_LexerInterface
209
  protected function lexBlock()
210
  {
211
  if (empty($this->brackets) && preg_match($this->regexes['lex_block'], $this->code, $match, null, $this->cursor)) {
212
- $this->pushToken(Twig_Token::BLOCK_END_TYPE);
213
  $this->moveCursor($match[0]);
214
  $this->popState();
215
  } else {
@@ -220,7 +226,7 @@ class Twig_Lexer implements Twig_LexerInterface
220
  protected function lexVar()
221
  {
222
  if (empty($this->brackets) && preg_match($this->regexes['lex_var'], $this->code, $match, null, $this->cursor)) {
223
- $this->pushToken(Twig_Token::VAR_END_TYPE);
224
  $this->moveCursor($match[0]);
225
  $this->popState();
226
  } else {
@@ -235,18 +241,18 @@ class Twig_Lexer implements Twig_LexerInterface
235
  $this->moveCursor($match[0]);
236
 
237
  if ($this->cursor >= $this->end) {
238
- throw new Twig_Error_Syntax(sprintf('Unclosed "%s".', self::STATE_BLOCK === $this->state ? 'block' : 'variable'), $this->currentVarBlockLine, $this->source);
239
  }
240
  }
241
 
242
  // operators
243
  if (preg_match($this->regexes['operator'], $this->code, $match, null, $this->cursor)) {
244
- $this->pushToken(Twig_Token::OPERATOR_TYPE, preg_replace('/\s+/', ' ', $match[0]));
245
  $this->moveCursor($match[0]);
246
  }
247
  // names
248
  elseif (preg_match(self::REGEX_NAME, $this->code, $match, null, $this->cursor)) {
249
- $this->pushToken(Twig_Token::NAME_TYPE, $match[0]);
250
  $this->moveCursor($match[0]);
251
  }
252
  // numbers
@@ -255,7 +261,7 @@ class Twig_Lexer implements Twig_LexerInterface
255
  if (ctype_digit($match[0]) && $number <= PHP_INT_MAX) {
256
  $number = (int) $match[0]; // integers lower than the maximum
257
  }
258
- $this->pushToken(Twig_Token::NUMBER_TYPE, $number);
259
  $this->moveCursor($match[0]);
260
  }
261
  // punctuation
@@ -267,21 +273,21 @@ class Twig_Lexer implements Twig_LexerInterface
267
  // closing bracket
268
  elseif (false !== strpos(')]}', $this->code[$this->cursor])) {
269
  if (empty($this->brackets)) {
270
- throw new Twig_Error_Syntax(sprintf('Unexpected "%s".', $this->code[$this->cursor]), $this->lineno, $this->source);
271
  }
272
 
273
  list($expect, $lineno) = array_pop($this->brackets);
274
  if ($this->code[$this->cursor] != strtr($expect, '([{', ')]}')) {
275
- throw new Twig_Error_Syntax(sprintf('Unclosed "%s".', $expect), $lineno, $this->source);
276
  }
277
  }
278
 
279
- $this->pushToken(Twig_Token::PUNCTUATION_TYPE, $this->code[$this->cursor]);
280
  ++$this->cursor;
281
  }
282
  // strings
283
  elseif (preg_match(self::REGEX_STRING, $this->code, $match, null, $this->cursor)) {
284
- $this->pushToken(Twig_Token::STRING_TYPE, stripcslashes(substr($match[0], 1, -1)));
285
  $this->moveCursor($match[0]);
286
  }
287
  // opening double quoted string
@@ -292,7 +298,7 @@ class Twig_Lexer implements Twig_LexerInterface
292
  }
293
  // unlexable
294
  else {
295
- throw new Twig_Error_Syntax(sprintf('Unexpected character "%s".', $this->code[$this->cursor]), $this->lineno, $this->source);
296
  }
297
  }
298
 
@@ -303,7 +309,7 @@ class Twig_Lexer implements Twig_LexerInterface
303
  }
304
 
305
  if (!preg_match(str_replace('%s', $tag, $this->regexes['lex_raw_data']), $this->code, $match, PREG_OFFSET_CAPTURE, $this->cursor)) {
306
- throw new Twig_Error_Syntax(sprintf('Unexpected end of file: Unclosed "%s" block.', $tag), $this->lineno, $this->source);
307
  }
308
 
309
  $text = substr($this->code, $this->cursor, $match[0][1] - $this->cursor);
@@ -313,13 +319,13 @@ class Twig_Lexer implements Twig_LexerInterface
313
  $text = rtrim($text);
314
  }
315
 
316
- $this->pushToken(Twig_Token::TEXT_TYPE, $text);
317
  }
318
 
319
  protected function lexComment()
320
  {
321
  if (!preg_match($this->regexes['lex_comment'], $this->code, $match, PREG_OFFSET_CAPTURE, $this->cursor)) {
322
- throw new Twig_Error_Syntax('Unclosed comment.', $this->lineno, $this->source);
323
  }
324
 
325
  $this->moveCursor(substr($this->code, $this->cursor, $match[0][1] - $this->cursor).$match[0][0]);
@@ -329,23 +335,23 @@ class Twig_Lexer implements Twig_LexerInterface
329
  {
330
  if (preg_match($this->regexes['interpolation_start'], $this->code, $match, null, $this->cursor)) {
331
  $this->brackets[] = [$this->options['interpolation'][0], $this->lineno];
332
- $this->pushToken(Twig_Token::INTERPOLATION_START_TYPE);
333
  $this->moveCursor($match[0]);
334
  $this->pushState(self::STATE_INTERPOLATION);
335
- } elseif (preg_match(self::REGEX_DQ_STRING_PART, $this->code, $match, null, $this->cursor) && strlen($match[0]) > 0) {
336
- $this->pushToken(Twig_Token::STRING_TYPE, stripcslashes($match[0]));
337
  $this->moveCursor($match[0]);
338
  } elseif (preg_match(self::REGEX_DQ_STRING_DELIM, $this->code, $match, null, $this->cursor)) {
339
  list($expect, $lineno) = array_pop($this->brackets);
340
  if ('"' != $this->code[$this->cursor]) {
341
- throw new Twig_Error_Syntax(sprintf('Unclosed "%s".', $expect), $lineno, $this->source);
342
  }
343
 
344
  $this->popState();
345
  ++$this->cursor;
346
  } else {
347
  // unlexable
348
- throw new Twig_Error_Syntax(sprintf('Unexpected character "%s".', $this->code[$this->cursor]), $this->lineno, $this->source);
349
  }
350
  }
351
 
@@ -354,7 +360,7 @@ class Twig_Lexer implements Twig_LexerInterface
354
  $bracket = end($this->brackets);
355
  if ($this->options['interpolation'][0] === $bracket[0] && preg_match($this->regexes['interpolation_end'], $this->code, $match, null, $this->cursor)) {
356
  array_pop($this->brackets);
357
- $this->pushToken(Twig_Token::INTERPOLATION_END_TYPE);
358
  $this->moveCursor($match[0]);
359
  $this->popState();
360
  } else {
@@ -365,16 +371,16 @@ class Twig_Lexer implements Twig_LexerInterface
365
  protected function pushToken($type, $value = '')
366
  {
367
  // do not push empty text tokens
368
- if (Twig_Token::TEXT_TYPE === $type && '' === $value) {
369
  return;
370
  }
371
 
372
- $this->tokens[] = new Twig_Token($type, $value, $this->lineno);
373
  }
374
 
375
  protected function moveCursor($text)
376
  {
377
- $this->cursor += strlen($text);
378
  $this->lineno += substr_count($text, "\n");
379
  }
380
 
@@ -416,8 +422,8 @@ class Twig_Lexer implements Twig_LexerInterface
416
 
417
  protected function popState()
418
  {
419
- if (0 === count($this->states)) {
420
- throw new Exception('Cannot pop state without a previous state.');
421
  }
422
 
423
  $this->state = array_pop($this->states);
10
  * file that was distributed with this source code.
11
  */
12
 
13
+ use Twig\Environment;
14
+ use Twig\Error\SyntaxError;
15
+ use Twig\Source;
16
+ use Twig\Token;
17
+ use Twig\TokenStream;
18
+
19
  /**
20
  * Lexes a template string.
21
  *
55
  const REGEX_DQ_STRING_PART = '/[^#"\\\\]*(?:(?:\\\\.|#(?!\{))[^#"\\\\]*)*/As';
56
  const PUNCTUATION = '()[]{}?:.,|';
57
 
58
+ public function __construct(Environment $env, array $options = [])
59
  {
60
  $this->env = $env;
61
 
83
 
84
  public function tokenize($code, $name = null)
85
  {
86
+ if (!$code instanceof Source) {
87
  @trigger_error(sprintf('Passing a string as the $code argument of %s() is deprecated since version 1.27 and will be removed in 2.0. Pass a Twig_Source instance instead.', __METHOD__), E_USER_DEPRECATED);
88
+ $this->source = new Source($code, $name);
89
  } else {
90
  $this->source = $code;
91
  }
94
  @trigger_error('Support for having "mbstring.func_overload" different from 0 is deprecated version 1.29 and will be removed in 2.0.', E_USER_DEPRECATED);
95
  }
96
 
97
+ if (\function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
98
  $mbEncoding = mb_internal_encoding();
99
  mb_internal_encoding('ASCII');
100
  } else {
105
  $this->filename = $this->source->getName();
106
  $this->cursor = 0;
107
  $this->lineno = 1;
108
+ $this->end = \strlen($this->code);
109
  $this->tokens = [];
110
  $this->state = self::STATE_DATA;
111
  $this->states = [];
142
  }
143
  }
144
 
145
+ $this->pushToken(Token::EOF_TYPE);
146
 
147
  if (!empty($this->brackets)) {
148
  list($expect, $lineno) = array_pop($this->brackets);
149
+ throw new SyntaxError(sprintf('Unclosed "%s".', $expect), $lineno, $this->source);
150
  }
151
 
152
  if ($mbEncoding) {
153
  mb_internal_encoding($mbEncoding);
154
  }
155
 
156
+ return new TokenStream($this->tokens, $this->source);
157
  }
158
 
159
  protected function lexData()
160
  {
161
  // if no matches are left we return the rest of the template as simple text token
162
+ if ($this->position == \count($this->positions[0]) - 1) {
163
+ $this->pushToken(Token::TEXT_TYPE, substr($this->code, $this->cursor));
164
  $this->cursor = $this->end;
165
 
166
  return;
169
  // Find the first token after the current cursor
170
  $position = $this->positions[0][++$this->position];
171
  while ($position[1] < $this->cursor) {
172
+ if ($this->position == \count($this->positions[0]) - 1) {
173
  return;
174
  }
175
  $position = $this->positions[0][++$this->position];
180
  if (isset($this->positions[2][$this->position][0])) {
181
  $text = rtrim($text);
182
  }
183
+ $this->pushToken(Token::TEXT_TYPE, $text);
184
  $this->moveCursor($textContent.$position[0]);
185
 
186
  switch ($this->positions[1][$this->position][0]) {
198
  $this->moveCursor($match[0]);
199
  $this->lineno = (int) $match[1];
200
  } else {
201
+ $this->pushToken(Token::BLOCK_START_TYPE);
202
  $this->pushState(self::STATE_BLOCK);
203
  $this->currentVarBlockLine = $this->lineno;
204
  }
205
  break;
206
 
207
  case $this->options['tag_variable'][0]:
208
+ $this->pushToken(Token::VAR_START_TYPE);
209
  $this->pushState(self::STATE_VAR);
210
  $this->currentVarBlockLine = $this->lineno;
211
  break;
215
  protected function lexBlock()
216
  {
217
  if (empty($this->brackets) && preg_match($this->regexes['lex_block'], $this->code, $match, null, $this->cursor)) {
218
+ $this->pushToken(Token::BLOCK_END_TYPE);
219
  $this->moveCursor($match[0]);
220
  $this->popState();
221
  } else {
226
  protected function lexVar()
227
  {
228
  if (empty($this->brackets) && preg_match($this->regexes['lex_var'], $this->code, $match, null, $this->cursor)) {
229
+ $this->pushToken(Token::VAR_END_TYPE);
230
  $this->moveCursor($match[0]);
231
  $this->popState();
232
  } else {
241
  $this->moveCursor($match[0]);
242
 
243
  if ($this->cursor >= $this->end) {
244
+ throw new SyntaxError(sprintf('Unclosed "%s".', self::STATE_BLOCK === $this->state ? 'block' : 'variable'), $this->currentVarBlockLine, $this->source);
245
  }
246
  }
247
 
248
  // operators
249
  if (preg_match($this->regexes['operator'], $this->code, $match, null, $this->cursor)) {
250
+ $this->pushToken(Token::OPERATOR_TYPE, preg_replace('/\s+/', ' ', $match[0]));
251
  $this->moveCursor($match[0]);
252
  }
253
  // names
254
  elseif (preg_match(self::REGEX_NAME, $this->code, $match, null, $this->cursor)) {
255
+ $this->pushToken(Token::NAME_TYPE, $match[0]);
256
  $this->moveCursor($match[0]);
257
  }
258
  // numbers
261
  if (ctype_digit($match[0]) && $number <= PHP_INT_MAX) {
262
  $number = (int) $match[0]; // integers lower than the maximum
263
  }
264
+ $this->pushToken(Token::NUMBER_TYPE, $number);
265
  $this->moveCursor($match[0]);
266
  }
267
  // punctuation
273
  // closing bracket
274
  elseif (false !== strpos(')]}', $this->code[$this->cursor])) {
275
  if (empty($this->brackets)) {
276
+ throw new SyntaxError(sprintf('Unexpected "%s".', $this->code[$this->cursor]), $this->lineno, $this->source);
277
  }
278
 
279
  list($expect, $lineno) = array_pop($this->brackets);
280
  if ($this->code[$this->cursor] != strtr($expect, '([{', ')]}')) {
281
+ throw new SyntaxError(sprintf('Unclosed "%s".', $expect), $lineno, $this->source);
282
  }
283
  }
284
 
285
+ $this->pushToken(Token::PUNCTUATION_TYPE, $this->code[$this->cursor]);
286
  ++$this->cursor;
287
  }
288
  // strings
289
  elseif (preg_match(self::REGEX_STRING, $this->code, $match, null, $this->cursor)) {
290
+ $this->pushToken(Token::STRING_TYPE, stripcslashes(substr($match[0], 1, -1)));
291
  $this->moveCursor($match[0]);
292
  }
293
  // opening double quoted string
298
  }
299
  // unlexable
300
  else {
301
+ throw new SyntaxError(sprintf('Unexpected character "%s".', $this->code[$this->cursor]), $this->lineno, $this->source);
302
  }
303
  }
304
 
309
  }
310
 
311
  if (!preg_match(str_replace('%s', $tag, $this->regexes['lex_raw_data']), $this->code, $match, PREG_OFFSET_CAPTURE, $this->cursor)) {
312
+ throw new SyntaxError(sprintf('Unexpected end of file: Unclosed "%s" block.', $tag), $this->lineno, $this->source);
313
  }
314
 
315
  $text = substr($this->code, $this->cursor, $match[0][1] - $this->cursor);
319
  $text = rtrim($text);
320
  }
321
 
322
+ $this->pushToken(Token::TEXT_TYPE, $text);
323
  }
324
 
325
  protected function lexComment()
326
  {
327
  if (!preg_match($this->regexes['lex_comment'], $this->code, $match, PREG_OFFSET_CAPTURE, $this->cursor)) {
328
+ throw new SyntaxError('Unclosed comment.', $this->lineno, $this->source);
329
  }
330
 
331
  $this->moveCursor(substr($this->code, $this->cursor, $match[0][1] - $this->cursor).$match[0][0]);
335
  {
336
  if (preg_match($this->regexes['interpolation_start'], $this->code, $match, null, $this->cursor)) {
337
  $this->brackets[] = [$this->options['interpolation'][0], $this->lineno];
338
+ $this->pushToken(Token::INTERPOLATION_START_TYPE);
339
  $this->moveCursor($match[0]);
340
  $this->pushState(self::STATE_INTERPOLATION);
341
+ } elseif (preg_match(self::REGEX_DQ_STRING_PART, $this->code, $match, null, $this->cursor) && \strlen($match[0]) > 0) {
342
+ $this->pushToken(Token::STRING_TYPE, stripcslashes($match[0]));
343
  $this->moveCursor($match[0]);
344
  } elseif (preg_match(self::REGEX_DQ_STRING_DELIM, $this->code, $match, null, $this->cursor)) {
345
  list($expect, $lineno) = array_pop($this->brackets);
346
  if ('"' != $this->code[$this->cursor]) {
347
+ throw new SyntaxError(sprintf('Unclosed "%s".', $expect), $lineno, $this->source);
348
  }
349
 
350
  $this->popState();
351
  ++$this->cursor;
352
  } else {
353
  // unlexable
354
+ throw new SyntaxError(sprintf('Unexpected character "%s".', $this->code[$this->cursor]), $this->lineno, $this->source);
355
  }
356
  }
357
 
360
  $bracket = end($this->brackets);
361
  if ($this->options['interpolation'][0] === $bracket[0] && preg_match($this->regexes['interpolation_end'], $this->code, $match, null, $this->cursor)) {
362
  array_pop($this->brackets);
363
+ $this->pushToken(Token::INTERPOLATION_END_TYPE);
364
  $this->moveCursor($match[0]);
365
  $this->popState();
366
  } else {
371
  protected function pushToken($type, $value = '')
372
  {
373
  // do not push empty text tokens
374
+ if (Token::TEXT_TYPE === $type && '' === $value) {
375
  return;
376
  }
377
 
378
+ $this->tokens[] = new Token($type, $value, $this->lineno);
379
  }
380
 
381
  protected function moveCursor($text)
382
  {
383
+ $this->cursor += \strlen($text);
384
  $this->lineno += substr_count($text, "\n");
385
  }
386
 
422
 
423
  protected function popState()
424
  {
425
+ if (0 === \count($this->states)) {
426
+ throw new \LogicException('Cannot pop state without a previous state.');
427
  }
428
 
429
  $this->state = array_pop($this->states);
vendor/twig/twig/lib/Twig/LexerInterface.php CHANGED
@@ -9,6 +9,10 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
12
  /**
13
  * Interface implemented by lexer classes.
14
  *
@@ -21,12 +25,12 @@ interface Twig_LexerInterface
21
  /**
22
  * Tokenizes a source code.
23
  *
24
- * @param string|Twig_Source $code The source code
25
- * @param string $name A unique identifier for the source code
26
  *
27
- * @return Twig_TokenStream
28
  *
29
- * @throws Twig_Error_Syntax When the code is syntactically wrong
30
  */
31
  public function tokenize($code, $name = null);
32
  }
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Error\SyntaxError;
13
+ use Twig\Source;
14
+ use Twig\TokenStream;
15
+
16
  /**
17
  * Interface implemented by lexer classes.
18
  *
25
  /**
26
  * Tokenizes a source code.
27
  *
28
+ * @param string|Source $code The source code
29
+ * @param string $name A unique identifier for the source code
30
  *
31
+ * @return TokenStream
32
  *
33
+ * @throws SyntaxError When the code is syntactically wrong
34
  */
35
  public function tokenize($code, $name = null);
36
  }
vendor/twig/twig/lib/Twig/Loader/Array.php CHANGED
@@ -9,6 +9,10 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
12
  /**
13
  * Loads a template from an array.
14
  *
@@ -23,7 +27,7 @@
23
  *
24
  * @author Fabien Potencier <fabien@symfony.com>
25
  */
26
- class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterface, Twig_SourceContextLoaderInterface
27
  {
28
  protected $templates = [];
29
 
@@ -48,11 +52,11 @@ class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
48
 
49
  public function getSource($name)
50
  {
51
- @trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', get_class($this)), E_USER_DEPRECATED);
52
 
53
  $name = (string) $name;
54
  if (!isset($this->templates[$name])) {
55
- throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name));
56
  }
57
 
58
  return $this->templates[$name];
@@ -62,10 +66,10 @@ class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
62
  {
63
  $name = (string) $name;
64
  if (!isset($this->templates[$name])) {
65
- throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name));
66
  }
67
 
68
- return new Twig_Source($this->templates[$name], $name);
69
  }
70
 
71
  public function exists($name)
@@ -77,7 +81,7 @@ class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
77
  {
78
  $name = (string) $name;
79
  if (!isset($this->templates[$name])) {
80
- throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name));
81
  }
82
 
83
  return $name.':'.$this->templates[$name];
@@ -87,7 +91,7 @@ class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
87
  {
88
  $name = (string) $name;
89
  if (!isset($this->templates[$name])) {
90
- throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name));
91
  }
92
 
93
  return true;
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Error\LoaderError;
13
+ use Twig\Loader\LoaderInterface;
14
+ use Twig\Source;
15
+
16
  /**
17
  * Loads a template from an array.
18
  *
27
  *
28
  * @author Fabien Potencier <fabien@symfony.com>
29
  */
30
+ class Twig_Loader_Array implements LoaderInterface, Twig_ExistsLoaderInterface, Twig_SourceContextLoaderInterface
31
  {
32
  protected $templates = [];
33
 
52
 
53
  public function getSource($name)
54
  {
55
+ @trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', \get_class($this)), E_USER_DEPRECATED);
56
 
57
  $name = (string) $name;
58
  if (!isset($this->templates[$name])) {
59
+ throw new LoaderError(sprintf('Template "%s" is not defined.', $name));
60
  }
61
 
62
  return $this->templates[$name];
66
  {
67
  $name = (string) $name;
68
  if (!isset($this->templates[$name])) {
69
+ throw new LoaderError(sprintf('Template "%s" is not defined.', $name));
70
  }
71
 
72
+ return new Source($this->templates[$name], $name);
73
  }
74
 
75
  public function exists($name)
81
  {
82
  $name = (string) $name;
83
  if (!isset($this->templates[$name])) {
84
+ throw new LoaderError(sprintf('Template "%s" is not defined.', $name));
85
  }
86
 
87
  return $name.':'.$this->templates[$name];
91
  {
92
  $name = (string) $name;
93
  if (!isset($this->templates[$name])) {
94
+ throw new LoaderError(sprintf('Template "%s" is not defined.', $name));
95
  }
96
 
97
  return true;
vendor/twig/twig/lib/Twig/Loader/Chain.php CHANGED
@@ -9,6 +9,12 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
 
 
12
  /**
13
  * Loads templates from other loaders.
14
  *
@@ -16,13 +22,13 @@
16
  *
17
  * @author Fabien Potencier <fabien@symfony.com>
18
  */
19
- class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterface, Twig_SourceContextLoaderInterface
20
  {
21
  private $hasSourceCache = [];
22
  protected $loaders = [];
23
 
24
  /**
25
- * @param Twig_LoaderInterface[] $loaders
26
  */
27
  public function __construct(array $loaders = [])
28
  {
@@ -31,7 +37,7 @@ class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
31
  }
32
  }
33
 
34
- public function addLoader(Twig_LoaderInterface $loader)
35
  {
36
  $this->loaders[] = $loader;
37
  $this->hasSourceCache = [];
@@ -39,44 +45,44 @@ class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
39
 
40
  public function getSource($name)
41
  {
42
- @trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', get_class($this)), E_USER_DEPRECATED);
43
 
44
  $exceptions = [];
45
  foreach ($this->loaders as $loader) {
46
- if ($loader instanceof Twig_ExistsLoaderInterface && !$loader->exists($name)) {
47
  continue;
48
  }
49
 
50
  try {
51
  return $loader->getSource($name);
52
- } catch (Twig_Error_Loader $e) {
53
  $exceptions[] = $e->getMessage();
54
  }
55
  }
56
 
57
- throw new Twig_Error_Loader(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : ''));
58
  }
59
 
60
  public function getSourceContext($name)
61
  {
62
  $exceptions = [];
63
  foreach ($this->loaders as $loader) {
64
- if ($loader instanceof Twig_ExistsLoaderInterface && !$loader->exists($name)) {
65
  continue;
66
  }
67
 
68
  try {
69
- if ($loader instanceof Twig_SourceContextLoaderInterface) {
70
  return $loader->getSourceContext($name);
71
  }
72
 
73
- return new Twig_Source($loader->getSource($name), $name);
74
- } catch (Twig_Error_Loader $e) {
75
  $exceptions[] = $e->getMessage();
76
  }
77
  }
78
 
79
- throw new Twig_Error_Loader(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : ''));
80
  }
81
 
82
  public function exists($name)
@@ -88,7 +94,7 @@ class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
88
  }
89
 
90
  foreach ($this->loaders as $loader) {
91
- if ($loader instanceof Twig_ExistsLoaderInterface) {
92
  if ($loader->exists($name)) {
93
  return $this->hasSourceCache[$name] = true;
94
  }
@@ -97,14 +103,14 @@ class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
97
  }
98
 
99
  try {
100
- if ($loader instanceof Twig_SourceContextLoaderInterface) {
101
  $loader->getSourceContext($name);
102
  } else {
103
  $loader->getSource($name);
104
  }
105
 
106
  return $this->hasSourceCache[$name] = true;
107
- } catch (Twig_Error_Loader $e) {
108
  }
109
  }
110
 
@@ -115,36 +121,36 @@ class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
115
  {
116
  $exceptions = [];
117
  foreach ($this->loaders as $loader) {
118
- if ($loader instanceof Twig_ExistsLoaderInterface && !$loader->exists($name)) {
119
  continue;
120
  }
121
 
122
  try {
123
  return $loader->getCacheKey($name);
124
- } catch (Twig_Error_Loader $e) {
125
- $exceptions[] = get_class($loader).': '.$e->getMessage();
126
  }
127
  }
128
 
129
- throw new Twig_Error_Loader(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : ''));
130
  }
131
 
132
  public function isFresh($name, $time)
133
  {
134
  $exceptions = [];
135
  foreach ($this->loaders as $loader) {
136
- if ($loader instanceof Twig_ExistsLoaderInterface && !$loader->exists($name)) {
137
  continue;
138
  }
139
 
140
  try {
141
  return $loader->isFresh($name, $time);
142
- } catch (Twig_Error_Loader $e) {
143
- $exceptions[] = get_class($loader).': '.$e->getMessage();
144
  }
145
  }
146
 
147
- throw new Twig_Error_Loader(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : ''));
148
  }
149
  }
150
 
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Error\LoaderError;
13
+ use Twig\Loader\ExistsLoaderInterface;
14
+ use Twig\Loader\LoaderInterface;
15
+ use Twig\Loader\SourceContextLoaderInterface;
16
+ use Twig\Source;
17
+
18
  /**
19
  * Loads templates from other loaders.
20
  *
22
  *
23
  * @author Fabien Potencier <fabien@symfony.com>
24
  */
25
+ class Twig_Loader_Chain implements LoaderInterface, Twig_ExistsLoaderInterface, Twig_SourceContextLoaderInterface
26
  {
27
  private $hasSourceCache = [];
28
  protected $loaders = [];
29
 
30
  /**
31
+ * @param LoaderInterface[] $loaders
32
  */
33
  public function __construct(array $loaders = [])
34
  {
37
  }
38
  }
39
 
40
+ public function addLoader(LoaderInterface $loader)
41
  {
42
  $this->loaders[] = $loader;
43
  $this->hasSourceCache = [];
45
 
46
  public function getSource($name)
47
  {
48
+ @trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', \get_class($this)), E_USER_DEPRECATED);
49
 
50
  $exceptions = [];
51
  foreach ($this->loaders as $loader) {
52
+ if ($loader instanceof ExistsLoaderInterface && !$loader->exists($name)) {
53
  continue;
54
  }
55
 
56
  try {
57
  return $loader->getSource($name);
58
+ } catch (LoaderError $e) {
59
  $exceptions[] = $e->getMessage();
60
  }
61
  }
62
 
63
+ throw new LoaderError(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : ''));
64
  }
65
 
66
  public function getSourceContext($name)
67
  {
68
  $exceptions = [];
69
  foreach ($this->loaders as $loader) {
70
+ if ($loader instanceof ExistsLoaderInterface && !$loader->exists($name)) {
71
  continue;
72
  }
73
 
74
  try {
75
+ if ($loader instanceof SourceContextLoaderInterface) {
76
  return $loader->getSourceContext($name);
77
  }
78
 
79
+ return new Source($loader->getSource($name), $name);
80
+ } catch (LoaderError $e) {
81
  $exceptions[] = $e->getMessage();
82
  }
83
  }
84
 
85
+ throw new LoaderError(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : ''));
86
  }
87
 
88
  public function exists($name)
94
  }
95
 
96
  foreach ($this->loaders as $loader) {
97
+ if ($loader instanceof ExistsLoaderInterface) {
98
  if ($loader->exists($name)) {
99
  return $this->hasSourceCache[$name] = true;
100
  }
103
  }
104
 
105
  try {
106
+ if ($loader instanceof SourceContextLoaderInterface) {
107
  $loader->getSourceContext($name);
108
  } else {
109
  $loader->getSource($name);
110
  }
111
 
112
  return $this->hasSourceCache[$name] = true;
113
+ } catch (LoaderError $e) {
114
  }
115
  }
116
 
121
  {
122
  $exceptions = [];
123
  foreach ($this->loaders as $loader) {
124
+ if ($loader instanceof ExistsLoaderInterface && !$loader->exists($name)) {
125
  continue;
126
  }
127
 
128
  try {
129
  return $loader->getCacheKey($name);
130
+ } catch (LoaderError $e) {
131
+ $exceptions[] = \get_class($loader).': '.$e->getMessage();
132
  }
133
  }
134
 
135
+ throw new LoaderError(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : ''));
136
  }
137
 
138
  public function isFresh($name, $time)
139
  {
140
  $exceptions = [];
141
  foreach ($this->loaders as $loader) {
142
+ if ($loader instanceof ExistsLoaderInterface && !$loader->exists($name)) {
143
  continue;
144
  }
145
 
146
  try {
147
  return $loader->isFresh($name, $time);
148
+ } catch (LoaderError $e) {
149
+ $exceptions[] = \get_class($loader).': '.$e->getMessage();
150
  }
151
  }
152
 
153
+ throw new LoaderError(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : ''));
154
  }
155
  }
156
 
vendor/twig/twig/lib/Twig/Loader/Filesystem.php CHANGED
@@ -9,12 +9,16 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
12
  /**
13
  * Loads template from the filesystem.
14
  *
15
  * @author Fabien Potencier <fabien@symfony.com>
16
  */
17
- class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderInterface, Twig_SourceContextLoaderInterface
18
  {
19
  /** Identifier of the main namespace. */
20
  const MAIN_NAMESPACE = '__main__';
@@ -73,7 +77,7 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
73
  */
74
  public function setPaths($paths, $namespace = self::MAIN_NAMESPACE)
75
  {
76
- if (!is_array($paths)) {
77
  $paths = [$paths];
78
  }
79
 
@@ -89,7 +93,7 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
89
  * @param string $path A path where to look for templates
90
  * @param string $namespace A path namespace
91
  *
92
- * @throws Twig_Error_Loader
93
  */
94
  public function addPath($path, $namespace = self::MAIN_NAMESPACE)
95
  {
@@ -98,7 +102,7 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
98
 
99
  $checkPath = $this->isAbsolutePath($path) ? $path : $this->rootPath.$path;
100
  if (!is_dir($checkPath)) {
101
- throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist ("%s").', $path, $checkPath));
102
  }
103
 
104
  $this->paths[$namespace][] = rtrim($path, '/\\');
@@ -110,7 +114,7 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
110
  * @param string $path A path where to look for templates
111
  * @param string $namespace A path namespace
112
  *
113
- * @throws Twig_Error_Loader
114
  */
115
  public function prependPath($path, $namespace = self::MAIN_NAMESPACE)
116
  {
@@ -119,7 +123,7 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
119
 
120
  $checkPath = $this->isAbsolutePath($path) ? $path : $this->rootPath.$path;
121
  if (!is_dir($checkPath)) {
122
- throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist ("%s").', $path, $checkPath));
123
  }
124
 
125
  $path = rtrim($path, '/\\');
@@ -133,7 +137,7 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
133
 
134
  public function getSource($name)
135
  {
136
- @trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', get_class($this)), E_USER_DEPRECATED);
137
 
138
  return file_get_contents($this->findTemplate($name));
139
  }
@@ -142,13 +146,13 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
142
  {
143
  $path = $this->findTemplate($name);
144
 
145
- return new Twig_Source(file_get_contents($path), $name, $path);
146
  }
147
 
148
  public function getCacheKey($name)
149
  {
150
  $path = $this->findTemplate($name);
151
- $len = strlen($this->rootPath);
152
  if (0 === strncmp($this->rootPath, $path, $len)) {
153
  return substr($path, $len);
154
  }
@@ -166,8 +170,8 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
166
 
167
  try {
168
  return false !== $this->findTemplate($name, false);
169
- } catch (Twig_Error_Loader $exception) {
170
- @trigger_error(sprintf('In %s::findTemplate(), you must accept a second argument that when set to "false" returns "false" instead of throwing an exception. Not supporting this argument is deprecated since version 1.27.', get_class($this)), E_USER_DEPRECATED);
171
 
172
  return false;
173
  }
@@ -180,7 +184,7 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
180
 
181
  protected function findTemplate($name)
182
  {
183
- $throw = func_num_args() > 1 ? func_get_arg(1) : true;
184
  $name = $this->normalizeName($name);
185
 
186
  if (isset($this->cache[$name])) {
@@ -192,14 +196,14 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
192
  return false;
193
  }
194
 
195
- throw new Twig_Error_Loader($this->errorCache[$name]);
196
  }
197
 
198
  try {
199
  $this->validateName($name);
200
 
201
  list($namespace, $shortname) = $this->parseName($name);
202
- } catch (Twig_Error_Loader $e) {
203
  if (!$throw) {
204
  return false;
205
  }
@@ -214,12 +218,12 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
214
  return false;
215
  }
216
 
217
- throw new Twig_Error_Loader($this->errorCache[$name]);
218
  }
219
 
220
  foreach ($this->paths[$namespace] as $path) {
221
  if (!$this->isAbsolutePath($path)) {
222
- $path = $this->rootPath.'/'.$path;
223
  }
224
 
225
  if (is_file($path.'/'.$shortname)) {
@@ -237,14 +241,14 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
237
  return false;
238
  }
239
 
240
- throw new Twig_Error_Loader($this->errorCache[$name]);
241
  }
242
 
243
  protected function parseName($name, $default = self::MAIN_NAMESPACE)
244
  {
245
  if (isset($name[0]) && '@' == $name[0]) {
246
  if (false === $pos = strpos($name, '/')) {
247
- throw new Twig_Error_Loader(sprintf('Malformed namespaced template name "%s" (expecting "@namespace/template_name").', $name));
248
  }
249
 
250
  $namespace = substr($name, 1, $pos - 1);
@@ -264,7 +268,7 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
264
  protected function validateName($name)
265
  {
266
  if (false !== strpos($name, "\0")) {
267
- throw new Twig_Error_Loader('A template name cannot contain NUL bytes.');
268
  }
269
 
270
  $name = ltrim($name, '/');
@@ -278,7 +282,7 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
278
  }
279
 
280
  if ($level < 0) {
281
- throw new Twig_Error_Loader(sprintf('Looks like you try to load a template outside configured directories (%s).', $name));
282
  }
283
  }
284
  }
@@ -286,7 +290,7 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
286
  private function isAbsolutePath($file)
287
  {
288
  return strspn($file, '/\\', 0, 1)
289
- || (strlen($file) > 3 && ctype_alpha($file[0])
290
  && ':' === substr($file, 1, 1)
291
  && strspn($file, '/\\', 2, 1)
292
  )
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Error\LoaderError;
13
+ use Twig\Loader\LoaderInterface;
14
+ use Twig\Source;
15
+
16
  /**
17
  * Loads template from the filesystem.
18
  *
19
  * @author Fabien Potencier <fabien@symfony.com>
20
  */
21
+ class Twig_Loader_Filesystem implements LoaderInterface, Twig_ExistsLoaderInterface, Twig_SourceContextLoaderInterface
22
  {
23
  /** Identifier of the main namespace. */
24
  const MAIN_NAMESPACE = '__main__';
77
  */
78
  public function setPaths($paths, $namespace = self::MAIN_NAMESPACE)
79
  {
80
+ if (!\is_array($paths)) {
81
  $paths = [$paths];
82
  }
83
 
93
  * @param string $path A path where to look for templates
94
  * @param string $namespace A path namespace
95
  *
96
+ * @throws LoaderError
97
  */
98
  public function addPath($path, $namespace = self::MAIN_NAMESPACE)
99
  {
102
 
103
  $checkPath = $this->isAbsolutePath($path) ? $path : $this->rootPath.$path;
104
  if (!is_dir($checkPath)) {
105
+ throw new LoaderError(sprintf('The "%s" directory does not exist ("%s").', $path, $checkPath));
106
  }
107
 
108
  $this->paths[$namespace][] = rtrim($path, '/\\');
114
  * @param string $path A path where to look for templates
115
  * @param string $namespace A path namespace
116
  *
117
+ * @throws LoaderError
118
  */
119
  public function prependPath($path, $namespace = self::MAIN_NAMESPACE)
120
  {
123
 
124
  $checkPath = $this->isAbsolutePath($path) ? $path : $this->rootPath.$path;
125
  if (!is_dir($checkPath)) {
126
+ throw new LoaderError(sprintf('The "%s" directory does not exist ("%s").', $path, $checkPath));
127
  }
128
 
129
  $path = rtrim($path, '/\\');
137
 
138
  public function getSource($name)
139
  {
140
+ @trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', \get_class($this)), E_USER_DEPRECATED);
141
 
142
  return file_get_contents($this->findTemplate($name));
143
  }
146
  {
147
  $path = $this->findTemplate($name);
148
 
149
+ return new Source(file_get_contents($path), $name, $path);
150
  }
151
 
152
  public function getCacheKey($name)
153
  {
154
  $path = $this->findTemplate($name);
155
+ $len = \strlen($this->rootPath);
156
  if (0 === strncmp($this->rootPath, $path, $len)) {
157
  return substr($path, $len);
158
  }
170
 
171
  try {
172
  return false !== $this->findTemplate($name, false);
173
+ } catch (LoaderError $exception) {
174
+ @trigger_error(sprintf('In %s::findTemplate(), you must accept a second argument that when set to "false" returns "false" instead of throwing an exception. Not supporting this argument is deprecated since version 1.27.', \get_class($this)), E_USER_DEPRECATED);
175
 
176
  return false;
177
  }
184
 
185
  protected function findTemplate($name)
186
  {
187
+ $throw = \func_num_args() > 1 ? func_get_arg(1) : true;
188
  $name = $this->normalizeName($name);
189
 
190
  if (isset($this->cache[$name])) {
196
  return false;
197
  }
198
 
199
+ throw new LoaderError($this->errorCache[$name]);
200
  }
201
 
202
  try {
203
  $this->validateName($name);
204
 
205
  list($namespace, $shortname) = $this->parseName($name);
206
+ } catch (LoaderError $e) {
207
  if (!$throw) {
208
  return false;
209
  }
218
  return false;
219
  }
220
 
221
+ throw new LoaderError($this->errorCache[$name]);
222
  }
223
 
224
  foreach ($this->paths[$namespace] as $path) {
225
  if (!$this->isAbsolutePath($path)) {
226
+ $path = $this->rootPath.$path;
227
  }
228
 
229
  if (is_file($path.'/'.$shortname)) {
241
  return false;
242
  }
243
 
244
+ throw new LoaderError($this->errorCache[$name]);
245
  }
246
 
247
  protected function parseName($name, $default = self::MAIN_NAMESPACE)
248
  {
249
  if (isset($name[0]) && '@' == $name[0]) {
250
  if (false === $pos = strpos($name, '/')) {
251
+ throw new LoaderError(sprintf('Malformed namespaced template name "%s" (expecting "@namespace/template_name").', $name));
252
  }
253
 
254
  $namespace = substr($name, 1, $pos - 1);
268
  protected function validateName($name)
269
  {
270
  if (false !== strpos($name, "\0")) {
271
+ throw new LoaderError('A template name cannot contain NUL bytes.');
272
  }
273
 
274
  $name = ltrim($name, '/');
282
  }
283
 
284
  if ($level < 0) {
285
+ throw new LoaderError(sprintf('Looks like you try to load a template outside configured directories (%s).', $name));
286
  }
287
  }
288
  }
290
  private function isAbsolutePath($file)
291
  {
292
  return strspn($file, '/\\', 0, 1)
293
+ || (\strlen($file) > 3 && ctype_alpha($file[0])
294
  && ':' === substr($file, 1, 1)
295
  && strspn($file, '/\\', 2, 1)
296
  )
vendor/twig/twig/lib/Twig/Loader/String.php CHANGED
@@ -9,7 +9,10 @@
9
  * file that was distributed with this source code.
10
  */
11
 
12
- @trigger_error('The Twig_Loader_String class is deprecated since version 1.18.1 and will be removed in 2.0. Use Twig_Loader_Array instead or Twig_Environment::createTemplate().', E_USER_DEPRECATED);
 
 
 
13
 
14
  /**
15
  * Loads a template from a string.
@@ -27,18 +30,18 @@
27
  *
28
  * @author Fabien Potencier <fabien@symfony.com>
29
  */
30
- class Twig_Loader_String implements Twig_LoaderInterface, Twig_ExistsLoaderInterface, Twig_SourceContextLoaderInterface
31
  {
32
  public function getSource($name)
33
  {
34
- @trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', get_class($this)), E_USER_DEPRECATED);
35
 
36
  return $name;
37
  }
38
 
39
  public function getSourceContext($name)
40
  {
41
- return new Twig_Source($name, $name);
42
  }
43
 
44
  public function exists($name)
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Loader\LoaderInterface;
13
+ use Twig\Source;
14
+
15
+ @trigger_error('The Twig_Loader_String class is deprecated since version 1.18.1 and will be removed in 2.0. Use "Twig\Loader\ArrayLoader" instead or "Twig\Environment::createTemplate()".', E_USER_DEPRECATED);
16
 
17
  /**
18
  * Loads a template from a string.
30
  *
31
  * @author Fabien Potencier <fabien@symfony.com>
32
  */
33
+ class Twig_Loader_String implements LoaderInterface, Twig_ExistsLoaderInterface, Twig_SourceContextLoaderInterface
34
  {
35
  public function getSource($name)
36
  {
37
+ @trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', \get_class($this)), E_USER_DEPRECATED);
38
 
39
  return $name;
40
  }
41
 
42
  public function getSourceContext($name)
43
  {
44
+ return new Source($name, $name);
45
  }
46
 
47
  public function exists($name)
vendor/twig/twig/lib/Twig/LoaderInterface.php CHANGED
@@ -9,6 +9,8 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
12
  /**
13
  * Interface all loaders must implement.
14
  *
@@ -23,7 +25,7 @@ interface Twig_LoaderInterface
23
  *
24
  * @return string The template source code
25
  *
26
- * @throws Twig_Error_Loader When $name is not found
27
  *
28
  * @deprecated since 1.27 (to be removed in 2.0), implement Twig_SourceContextLoaderInterface
29
  */
@@ -36,7 +38,7 @@ interface Twig_LoaderInterface
36
  *
37
  * @return string The cache key
38
  *
39
- * @throws Twig_Error_Loader When $name is not found
40
  */
41
  public function getCacheKey($name);
42
 
@@ -49,7 +51,7 @@ interface Twig_LoaderInterface
49
  *
50
  * @return bool true if the template is fresh, false otherwise
51
  *
52
- * @throws Twig_Error_Loader When $name is not found
53
  */
54
  public function isFresh($name, $time);
55
  }
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Error\LoaderError;
13
+
14
  /**
15
  * Interface all loaders must implement.
16
  *
25
  *
26
  * @return string The template source code
27
  *
28
+ * @throws LoaderError When $name is not found
29
  *
30
  * @deprecated since 1.27 (to be removed in 2.0), implement Twig_SourceContextLoaderInterface
31
  */
38
  *
39
  * @return string The cache key
40
  *
41
+ * @throws LoaderError When $name is not found
42
  */
43
  public function getCacheKey($name);
44
 
51
  *
52
  * @return bool true if the template is fresh, false otherwise
53
  *
54
+ * @throws LoaderError When $name is not found
55
  */
56
  public function isFresh($name, $time);
57
  }
vendor/twig/twig/lib/Twig/Markup.php CHANGED
@@ -14,7 +14,7 @@
14
  *
15
  * @author Fabien Potencier <fabien@symfony.com>
16
  */
17
- class Twig_Markup implements Countable
18
  {
19
  protected $content;
20
  protected $charset;
@@ -32,7 +32,7 @@ class Twig_Markup implements Countable
32
 
33
  public function count()
34
  {
35
- return function_exists('mb_get_info') ? mb_strlen($this->content, $this->charset) : strlen($this->content);
36
  }
37
  }
38
 
14
  *
15
  * @author Fabien Potencier <fabien@symfony.com>
16
  */
17
+ class Twig_Markup implements \Countable
18
  {
19
  protected $content;
20
  protected $charset;
32
 
33
  public function count()
34
  {
35
+ return \function_exists('mb_get_info') ? mb_strlen($this->content, $this->charset) : \strlen($this->content);
36
  }
37
  }
38
 
vendor/twig/twig/lib/Twig/Node.php CHANGED
@@ -10,6 +10,9 @@
10
  * file that was distributed with this source code.
11
  */
12
 
 
 
 
13
  /**
14
  * Represents a node in the AST.
15
  *
@@ -39,7 +42,7 @@ class Twig_Node implements Twig_NodeInterface
39
  {
40
  foreach ($nodes as $name => $node) {
41
  if (!$node instanceof Twig_NodeInterface) {
42
- @trigger_error(sprintf('Using "%s" for the value of node "%s" of "%s" is deprecated since version 1.25 and will be removed in 2.0.', is_object($node) ? get_class($node) : null === $node ? 'null' : gettype($node), $name, get_class($this)), E_USER_DEPRECATED);
43
  }
44
  }
45
  $this->nodes = $nodes;
@@ -55,11 +58,11 @@ class Twig_Node implements Twig_NodeInterface
55
  $attributes[] = sprintf('%s: %s', $name, str_replace("\n", '', var_export($value, true)));
56
  }
57
 
58
- $repr = [get_class($this).'('.implode(', ', $attributes)];
59
 
60
- if (count($this->nodes)) {
61
  foreach ($this->nodes as $name => $node) {
62
- $len = strlen($name) + 4;
63
  $noderepr = [];
64
  foreach (explode("\n", (string) $node) as $line) {
65
  $noderepr[] = str_repeat(' ', $len).$line;
@@ -83,12 +86,12 @@ class Twig_Node implements Twig_NodeInterface
83
  {
84
  @trigger_error(sprintf('%s is deprecated since version 1.16.1 and will be removed in 2.0.', __METHOD__), E_USER_DEPRECATED);
85
 
86
- $dom = new DOMDocument('1.0', 'UTF-8');
87
  $dom->formatOutput = true;
88
  $dom->appendChild($xml = $dom->createElement('twig'));
89
 
90
  $xml->appendChild($node = $dom->createElement('node'));
91
- $node->setAttribute('class', get_class($this));
92
 
93
  foreach ($this->attributes as $name => $value) {
94
  $node->appendChild($attribute = $dom->createElement('attribute'));
@@ -111,7 +114,7 @@ class Twig_Node implements Twig_NodeInterface
111
  return $asDom ? $dom : $dom->saveXML();
112
  }
113
 
114
- public function compile(Twig_Compiler $compiler)
115
  {
116
  foreach ($this->nodes as $node) {
117
  $node->compile($compiler);
@@ -143,7 +146,7 @@ class Twig_Node implements Twig_NodeInterface
143
  */
144
  public function hasAttribute($name)
145
  {
146
- return array_key_exists($name, $this->attributes);
147
  }
148
 
149
  /**
@@ -151,8 +154,8 @@ class Twig_Node implements Twig_NodeInterface
151
  */
152
  public function getAttribute($name)
153
  {
154
- if (!array_key_exists($name, $this->attributes)) {
155
- throw new LogicException(sprintf('Attribute "%s" does not exist for Node "%s".', $name, get_class($this)));
156
  }
157
 
158
  return $this->attributes[$name];
@@ -177,16 +180,16 @@ class Twig_Node implements Twig_NodeInterface
177
  */
178
  public function hasNode($name)
179
  {
180
- return array_key_exists($name, $this->nodes);
181
  }
182
 
183
  /**
184
- * @return Twig_Node
185
  */
186
  public function getNode($name)
187
  {
188
- if (!array_key_exists($name, $this->nodes)) {
189
- throw new LogicException(sprintf('Node "%s" does not exist for Node "%s".', $name, get_class($this)));
190
  }
191
 
192
  return $this->nodes[$name];
@@ -195,7 +198,7 @@ class Twig_Node implements Twig_NodeInterface
195
  public function setNode($name, $node = null)
196
  {
197
  if (!$node instanceof Twig_NodeInterface) {
198
- @trigger_error(sprintf('Using "%s" for the value of node "%s" of "%s" is deprecated since version 1.25 and will be removed in 2.0.', is_object($node) ? get_class($node) : null === $node ? 'null' : gettype($node), $name, get_class($this)), E_USER_DEPRECATED);
199
  }
200
 
201
  $this->nodes[$name] = $node;
@@ -208,12 +211,12 @@ class Twig_Node implements Twig_NodeInterface
208
 
209
  public function count()
210
  {
211
- return count($this->nodes);
212
  }
213
 
214
  public function getIterator()
215
  {
216
- return new ArrayIterator($this->nodes);
217
  }
218
 
219
  public function setTemplateName($name)
10
  * file that was distributed with this source code.
11
  */
12
 
13
+ use Twig\Compiler;
14
+ use Twig\Node\Node;
15
+
16
  /**
17
  * Represents a node in the AST.
18
  *
42
  {
43
  foreach ($nodes as $name => $node) {
44
  if (!$node instanceof Twig_NodeInterface) {
45
+ @trigger_error(sprintf('Using "%s" for the value of node "%s" of "%s" is deprecated since version 1.25 and will be removed in 2.0.', \is_object($node) ? \get_class($node) : null === $node ? 'null' : \gettype($node), $name, \get_class($this)), E_USER_DEPRECATED);
46
  }
47
  }
48
  $this->nodes = $nodes;
58
  $attributes[] = sprintf('%s: %s', $name, str_replace("\n", '', var_export($value, true)));
59
  }
60
 
61
+ $repr = [\get_class($this).'('.implode(', ', $attributes)];
62
 
63
+ if (\count($this->nodes)) {
64
  foreach ($this->nodes as $name => $node) {
65
+ $len = \strlen($name) + 4;
66
  $noderepr = [];
67
  foreach (explode("\n", (string) $node) as $line) {
68
  $noderepr[] = str_repeat(' ', $len).$line;
86
  {
87
  @trigger_error(sprintf('%s is deprecated since version 1.16.1 and will be removed in 2.0.', __METHOD__), E_USER_DEPRECATED);
88
 
89
+ $dom = new \DOMDocument('1.0', 'UTF-8');
90
  $dom->formatOutput = true;
91
  $dom->appendChild($xml = $dom->createElement('twig'));
92
 
93
  $xml->appendChild($node = $dom->createElement('node'));
94
+ $node->setAttribute('class', \get_class($this));
95
 
96
  foreach ($this->attributes as $name => $value) {
97
  $node->appendChild($attribute = $dom->createElement('attribute'));
114
  return $asDom ? $dom : $dom->saveXML();
115
  }
116
 
117
+ public function compile(Compiler $compiler)
118
  {
119
  foreach ($this->nodes as $node) {
120
  $node->compile($compiler);
146
  */
147
  public function hasAttribute($name)
148
  {
149
+ return \array_key_exists($name, $this->attributes);
150
  }
151
 
152
  /**
154
  */
155
  public function getAttribute($name)
156
  {
157
+ if (!\array_key_exists($name, $this->attributes)) {
158
+ throw new \LogicException(sprintf('Attribute "%s" does not exist for Node "%s".', $name, \get_class($this)));
159
  }
160
 
161
  return $this->attributes[$name];
180
  */
181
  public function hasNode($name)
182
  {
183
+ return \array_key_exists($name, $this->nodes);
184
  }
185
 
186
  /**
187
+ * @return Node
188
  */
189
  public function getNode($name)
190
  {
191
+ if (!\array_key_exists($name, $this->nodes)) {
192
+ throw new \LogicException(sprintf('Node "%s" does not exist for Node "%s".', $name, \get_class($this)));
193
  }
194
 
195
  return $this->nodes[$name];
198
  public function setNode($name, $node = null)
199
  {
200
  if (!$node instanceof Twig_NodeInterface) {
201
+ @trigger_error(sprintf('Using "%s" for the value of node "%s" of "%s" is deprecated since version 1.25 and will be removed in 2.0.', \is_object($node) ? \get_class($node) : null === $node ? 'null' : \gettype($node), $name, \get_class($this)), E_USER_DEPRECATED);
202
  }
203
 
204
  $this->nodes[$name] = $node;
211
 
212
  public function count()
213
  {
214
+ return \count($this->nodes);
215
  }
216
 
217
  public function getIterator()
218
  {
219
+ return new \ArrayIterator($this->nodes);
220
  }
221
 
222
  public function setTemplateName($name)
vendor/twig/twig/lib/Twig/Node/AutoEscape.php CHANGED
@@ -9,6 +9,9 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
12
  /**
13
  * Represents an autoescape node.
14
  *
@@ -20,14 +23,14 @@
20
  *
21
  * @author Fabien Potencier <fabien@symfony.com>
22
  */
23
- class Twig_Node_AutoEscape extends Twig_Node
24
  {
25
  public function __construct($value, Twig_NodeInterface $body, $lineno, $tag = 'autoescape')
26
  {
27
  parent::__construct(['body' => $body], ['value' => $value], $lineno, $tag);
28
  }
29
 
30
- public function compile(Twig_Compiler $compiler)
31
  {
32
  $compiler->subcompile($this->getNode('body'));
33
  }
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Compiler;
13
+ use Twig\Node\Node;
14
+
15
  /**
16
  * Represents an autoescape node.
17
  *
23
  *
24
  * @author Fabien Potencier <fabien@symfony.com>
25
  */
26
+ class Twig_Node_AutoEscape extends Node
27
  {
28
  public function __construct($value, Twig_NodeInterface $body, $lineno, $tag = 'autoescape')
29
  {
30
  parent::__construct(['body' => $body], ['value' => $value], $lineno, $tag);
31
  }
32
 
33
+ public function compile(Compiler $compiler)
34
  {
35
  $compiler->subcompile($this->getNode('body'));
36
  }
vendor/twig/twig/lib/Twig/Node/Block.php CHANGED
@@ -10,19 +10,22 @@
10
  * file that was distributed with this source code.
11
  */
12
 
 
 
 
13
  /**
14
  * Represents a block node.
15
  *
16
  * @author Fabien Potencier <fabien@symfony.com>
17
  */
18
- class Twig_Node_Block extends Twig_Node
19
  {
20
  public function __construct($name, Twig_NodeInterface $body, $lineno, $tag = null)
21
  {
22
  parent::__construct(['body' => $body], ['name' => $name], $lineno, $tag);
23
  }
24
 
25
- public function compile(Twig_Compiler $compiler)
26
  {
27
  $compiler
28
  ->addDebugInfo($this)
10
  * file that was distributed with this source code.
11
  */
12
 
13
+ use Twig\Compiler;
14
+ use Twig\Node\Node;
15
+
16
  /**
17
  * Represents a block node.
18
  *
19
  * @author Fabien Potencier <fabien@symfony.com>
20
  */
21
+ class Twig_Node_Block extends Node
22
  {
23
  public function __construct($name, Twig_NodeInterface $body, $lineno, $tag = null)
24
  {
25
  parent::__construct(['body' => $body], ['name' => $name], $lineno, $tag);
26
  }
27
 
28
+ public function compile(Compiler $compiler)
29
  {
30
  $compiler
31
  ->addDebugInfo($this)
vendor/twig/twig/lib/Twig/Node/BlockReference.php CHANGED
@@ -10,19 +10,23 @@
10
  * file that was distributed with this source code.
11
  */
12
 
 
 
 
 
13
  /**
14
  * Represents a block call node.
15
  *
16
  * @author Fabien Potencier <fabien@symfony.com>
17
  */
18
- class Twig_Node_BlockReference extends Twig_Node implements Twig_NodeOutputInterface
19
  {
20
  public function __construct($name, $lineno, $tag = null)
21
  {
22
  parent::__construct([], ['name' => $name], $lineno, $tag);
23
  }
24
 
25
- public function compile(Twig_Compiler $compiler)
26
  {
27
  $compiler
28
  ->addDebugInfo($this)
10
  * file that was distributed with this source code.
11
  */
12
 
13
+ use Twig\Compiler;
14
+ use Twig\Node\Node;
15
+ use Twig\Node\NodeOutputInterface;
16
+
17
  /**
18
  * Represents a block call node.
19
  *
20
  * @author Fabien Potencier <fabien@symfony.com>
21
  */
22
+ class Twig_Node_BlockReference extends Node implements NodeOutputInterface
23
  {
24
  public function __construct($name, $lineno, $tag = null)
25
  {
26
  parent::__construct([], ['name' => $name], $lineno, $tag);
27
  }
28
 
29
+ public function compile(Compiler $compiler)
30
  {
31
  $compiler
32
  ->addDebugInfo($this)
vendor/twig/twig/lib/Twig/Node/Body.php CHANGED
@@ -9,12 +9,14 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
12
  /**
13
  * Represents a body node.
14
  *
15
  * @author Fabien Potencier <fabien@symfony.com>
16
  */
17
- class Twig_Node_Body extends Twig_Node
18
  {
19
  }
20
 
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Node\Node;
13
+
14
  /**
15
  * Represents a body node.
16
  *
17
  * @author Fabien Potencier <fabien@symfony.com>
18
  */
19
+ class Twig_Node_Body extends Node
20
  {
21
  }
22
 
vendor/twig/twig/lib/Twig/Node/CheckSecurity.php CHANGED
@@ -9,10 +9,13 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
12
  /**
13
  * @author Fabien Potencier <fabien@symfony.com>
14
  */
15
- class Twig_Node_CheckSecurity extends Twig_Node
16
  {
17
  protected $usedFilters;
18
  protected $usedTags;
@@ -27,12 +30,12 @@ class Twig_Node_CheckSecurity extends Twig_Node
27
  parent::__construct();
28
  }
29
 
30
- public function compile(Twig_Compiler $compiler)
31
  {
32
  $tags = $filters = $functions = [];
33
  foreach (['tags', 'filters', 'functions'] as $type) {
34
  foreach ($this->{'used'.ucfirst($type)} as $name => $node) {
35
- if ($node instanceof Twig_Node) {
36
  ${$type}[$name] = $node->getTemplateLine();
37
  } else {
38
  ${$type}[$node] = null;
@@ -46,7 +49,7 @@ class Twig_Node_CheckSecurity extends Twig_Node
46
  ->write('$functions = ')->repr(array_filter($functions))->raw(";\n\n")
47
  ->write("try {\n")
48
  ->indent()
49
- ->write("\$this->env->getExtension('Twig_Extension_Sandbox')->checkSecurity(\n")
50
  ->indent()
51
  ->write(!$tags ? "[],\n" : "['".implode("', '", array_keys($tags))."'],\n")
52
  ->write(!$filters ? "[],\n" : "['".implode("', '", array_keys($filters))."'],\n")
@@ -54,18 +57,18 @@ class Twig_Node_CheckSecurity extends Twig_Node
54
  ->outdent()
55
  ->write(");\n")
56
  ->outdent()
57
- ->write("} catch (Twig_Sandbox_SecurityError \$e) {\n")
58
  ->indent()
59
  ->write("\$e->setSourceContext(\$this->getSourceContext());\n\n")
60
- ->write("if (\$e instanceof Twig_Sandbox_SecurityNotAllowedTagError && isset(\$tags[\$e->getTagName()])) {\n")
61
  ->indent()
62
  ->write("\$e->setTemplateLine(\$tags[\$e->getTagName()]);\n")
63
  ->outdent()
64
- ->write("} elseif (\$e instanceof Twig_Sandbox_SecurityNotAllowedFilterError && isset(\$filters[\$e->getFilterName()])) {\n")
65
  ->indent()
66
  ->write("\$e->setTemplateLine(\$filters[\$e->getFilterName()]);\n")
67
  ->outdent()
68
- ->write("} elseif (\$e instanceof Twig_Sandbox_SecurityNotAllowedFunctionError && isset(\$functions[\$e->getFunctionName()])) {\n")
69
  ->indent()
70
  ->write("\$e->setTemplateLine(\$functions[\$e->getFunctionName()]);\n")
71
  ->outdent()
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Compiler;
13
+ use Twig\Node\Node;
14
+
15
  /**
16
  * @author Fabien Potencier <fabien@symfony.com>
17
  */
18
+ class Twig_Node_CheckSecurity extends Node
19
  {
20
  protected $usedFilters;
21
  protected $usedTags;
30
  parent::__construct();
31
  }
32
 
33
+ public function compile(Compiler $compiler)
34
  {
35
  $tags = $filters = $functions = [];
36
  foreach (['tags', 'filters', 'functions'] as $type) {
37
  foreach ($this->{'used'.ucfirst($type)} as $name => $node) {
38
+ if ($node instanceof Node) {
39
  ${$type}[$name] = $node->getTemplateLine();
40
  } else {
41
  ${$type}[$node] = null;
49
  ->write('$functions = ')->repr(array_filter($functions))->raw(";\n\n")
50
  ->write("try {\n")
51
  ->indent()
52
+ ->write("\$this->env->getExtension('\Twig\Extension\SandboxExtension')->checkSecurity(\n")
53
  ->indent()
54
  ->write(!$tags ? "[],\n" : "['".implode("', '", array_keys($tags))."'],\n")
55
  ->write(!$filters ? "[],\n" : "['".implode("', '", array_keys($filters))."'],\n")
57
  ->outdent()
58
  ->write(");\n")
59
  ->outdent()
60
+ ->write("} catch (SecurityError \$e) {\n")
61
  ->indent()
62
  ->write("\$e->setSourceContext(\$this->getSourceContext());\n\n")
63
+ ->write("if (\$e instanceof SecurityNotAllowedTagError && isset(\$tags[\$e->getTagName()])) {\n")
64
  ->indent()
65
  ->write("\$e->setTemplateLine(\$tags[\$e->getTagName()]);\n")
66
  ->outdent()
67
+ ->write("} elseif (\$e instanceof SecurityNotAllowedFilterError && isset(\$filters[\$e->getFilterName()])) {\n")
68
  ->indent()
69
  ->write("\$e->setTemplateLine(\$filters[\$e->getFilterName()]);\n")
70
  ->outdent()
71
+ ->write("} elseif (\$e instanceof SecurityNotAllowedFunctionError && isset(\$functions[\$e->getFunctionName()])) {\n")
72
  ->indent()
73
  ->write("\$e->setTemplateLine(\$functions[\$e->getFunctionName()]);\n")
74
  ->outdent()
vendor/twig/twig/lib/Twig/Node/Deprecated.php CHANGED
@@ -9,25 +9,30 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
 
12
  /**
13
  * Represents a deprecated node.
14
  *
15
  * @author Yonel Ceruto <yonelceruto@gmail.com>
16
  */
17
- class Twig_Node_Deprecated extends Twig_Node
18
  {
19
- public function __construct(Twig_Node_Expression $expr, $lineno, $tag = null)
20
  {
21
  parent::__construct(['expr' => $expr], [], $lineno, $tag);
22
  }
23
 
24
- public function compile(Twig_Compiler $compiler)
25
  {
26
  $compiler->addDebugInfo($this);
27
 
28
  $expr = $this->getNode('expr');
29
 
30
- if ($expr instanceof Twig_Node_Expression_Constant) {
31
  $compiler->write('@trigger_error(')
32
  ->subcompile($expr);
33
  } else {
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\AbstractExpression;
14
+ use Twig\Node\Expression\ConstantExpression;
15
+ use Twig\Node\Node;
16
+
17
  /**
18
  * Represents a deprecated node.
19
  *
20
  * @author Yonel Ceruto <yonelceruto@gmail.com>
21
  */
22
+ class Twig_Node_Deprecated extends Node
23
  {
24
+ public function __construct(AbstractExpression $expr, $lineno, $tag = null)
25
  {
26
  parent::__construct(['expr' => $expr], [], $lineno, $tag);
27
  }
28
 
29
+ public function compile(Compiler $compiler)
30
  {
31
  $compiler->addDebugInfo($this);
32
 
33
  $expr = $this->getNode('expr');
34
 
35
+ if ($expr instanceof ConstantExpression) {
36
  $compiler->write('@trigger_error(')
37
  ->subcompile($expr);
38
  } else {
vendor/twig/twig/lib/Twig/Node/Do.php CHANGED
@@ -9,19 +9,23 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
12
  /**
13
  * Represents a do node.
14
  *
15
  * @author Fabien Potencier <fabien@symfony.com>
16
  */
17
- class Twig_Node_Do extends Twig_Node
18
  {
19
- public function __construct(Twig_Node_Expression $expr, $lineno, $tag = null)
20
  {
21
  parent::__construct(['expr' => $expr], [], $lineno, $tag);
22
  }
23
 
24
- public function compile(Twig_Compiler $compiler)
25
  {
26
  $compiler
27
  ->addDebugInfo($this)
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\AbstractExpression;
14
+ use Twig\Node\Node;
15
+
16
  /**
17
  * Represents a do node.
18
  *
19
  * @author Fabien Potencier <fabien@symfony.com>
20
  */
21
+ class Twig_Node_Do extends Node
22
  {
23
+ public function __construct(AbstractExpression $expr, $lineno, $tag = null)
24
  {
25
  parent::__construct(['expr' => $expr], [], $lineno, $tag);
26
  }
27
 
28
+ public function compile(Compiler $compiler)
29
  {
30
  $compiler
31
  ->addDebugInfo($this)
vendor/twig/twig/lib/Twig/Node/Embed.php CHANGED
@@ -9,17 +9,22 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
 
12
  /**
13
  * Represents an embed node.
14
  *
15
  * @author Fabien Potencier <fabien@symfony.com>
16
  */
17
- class Twig_Node_Embed extends Twig_Node_Include
18
  {
19
  // we don't inject the module to avoid node visitors to traverse it twice (as it will be already visited in the main module)
20
- public function __construct($name, $index, Twig_Node_Expression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null)
21
  {
22
- parent::__construct(new Twig_Node_Expression_Constant('not_used', $lineno), $variables, $only, $ignoreMissing, $lineno, $tag);
23
 
24
  $this->setAttribute('name', $name);
25
  // to be removed in 2.0, used name instead
@@ -27,7 +32,7 @@ class Twig_Node_Embed extends Twig_Node_Include
27
  $this->setAttribute('index', $index);
28
  }
29
 
30
- protected function addGetTemplate(Twig_Compiler $compiler)
31
  {
32
  $compiler
33
  ->write('$this->loadTemplate(')
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\AbstractExpression;
14
+ use Twig\Node\Expression\ConstantExpression;
15
+ use Twig\Node\IncludeNode;
16
+
17
  /**
18
  * Represents an embed node.
19
  *
20
  * @author Fabien Potencier <fabien@symfony.com>
21
  */
22
+ class Twig_Node_Embed extends IncludeNode
23
  {
24
  // we don't inject the module to avoid node visitors to traverse it twice (as it will be already visited in the main module)
25
+ public function __construct($name, $index, AbstractExpression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null)
26
  {
27
+ parent::__construct(new ConstantExpression('not_used', $lineno), $variables, $only, $ignoreMissing, $lineno, $tag);
28
 
29
  $this->setAttribute('name', $name);
30
  // to be removed in 2.0, used name instead
32
  $this->setAttribute('index', $index);
33
  }
34
 
35
+ protected function addGetTemplate(Compiler $compiler)
36
  {
37
  $compiler
38
  ->write('$this->loadTemplate(')
vendor/twig/twig/lib/Twig/Node/Expression.php CHANGED
@@ -10,12 +10,14 @@
10
  * file that was distributed with this source code.
11
  */
12
 
 
 
13
  /**
14
  * Abstract class for all nodes that represents an expression.
15
  *
16
  * @author Fabien Potencier <fabien@symfony.com>
17
  */
18
- abstract class Twig_Node_Expression extends Twig_Node
19
  {
20
  }
21
 
10
  * file that was distributed with this source code.
11
  */
12
 
13
+ use Twig\Node\Node;
14
+
15
  /**
16
  * Abstract class for all nodes that represents an expression.
17
  *
18
  * @author Fabien Potencier <fabien@symfony.com>
19
  */
20
+ abstract class Twig_Node_Expression extends Node
21
  {
22
  }
23
 
vendor/twig/twig/lib/Twig/Node/Expression/Array.php CHANGED
@@ -8,7 +8,12 @@
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
- class Twig_Node_Expression_Array extends Twig_Node_Expression
 
 
 
 
 
12
  {
13
  protected $index;
14
 
@@ -18,7 +23,7 @@ class Twig_Node_Expression_Array extends Twig_Node_Expression
18
 
19
  $this->index = -1;
20
  foreach ($this->getKeyValuePairs() as $pair) {
21
- if ($pair['key'] instanceof Twig_Node_Expression_Constant && ctype_digit((string) $pair['key']->getAttribute('value')) && $pair['key']->getAttribute('value') > $this->index) {
22
  $this->index = $pair['key']->getAttribute('value');
23
  }
24
  }
@@ -38,7 +43,7 @@ class Twig_Node_Expression_Array extends Twig_Node_Expression
38
  return $pairs;
39
  }
40
 
41
- public function hasElement(Twig_Node_Expression $key)
42
  {
43
  foreach ($this->getKeyValuePairs() as $pair) {
44
  // we compare the string representation of the keys
@@ -51,16 +56,16 @@ class Twig_Node_Expression_Array extends Twig_Node_Expression
51
  return false;
52
  }
53
 
54
- public function addElement(Twig_Node_Expression $value, Twig_Node_Expression $key = null)
55
  {
56
  if (null === $key) {
57
- $key = new Twig_Node_Expression_Constant(++$this->index, $value->getTemplateLine());
58
  }
59
 
60
  array_push($this->nodes, $key, $value);
61
  }
62
 
63
- public function compile(Twig_Compiler $compiler)
64
  {
65
  $compiler->raw('[');
66
  $first = true;
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
+
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\AbstractExpression;
14
+ use Twig\Node\Expression\ConstantExpression;
15
+
16
+ class Twig_Node_Expression_Array extends AbstractExpression
17
  {
18
  protected $index;
19
 
23
 
24
  $this->index = -1;
25
  foreach ($this->getKeyValuePairs() as $pair) {
26
+ if ($pair['key'] instanceof ConstantExpression && ctype_digit((string) $pair['key']->getAttribute('value')) && $pair['key']->getAttribute('value') > $this->index) {
27
  $this->index = $pair['key']->getAttribute('value');
28
  }
29
  }
43
  return $pairs;
44
  }
45
 
46
+ public function hasElement(AbstractExpression $key)
47
  {
48
  foreach ($this->getKeyValuePairs() as $pair) {
49
  // we compare the string representation of the keys
56
  return false;
57
  }
58
 
59
+ public function addElement(AbstractExpression $value, AbstractExpression $key = null)
60
  {
61
  if (null === $key) {
62
+ $key = new ConstantExpression(++$this->index, $value->getTemplateLine());
63
  }
64
 
65
  array_push($this->nodes, $key, $value);
66
  }
67
 
68
+ public function compile(Compiler $compiler)
69
  {
70
  $compiler->raw('[');
71
  $first = true;
vendor/twig/twig/lib/Twig/Node/Expression/AssignName.php CHANGED
@@ -10,9 +10,12 @@
10
  * file that was distributed with this source code.
11
  */
12
 
13
- class Twig_Node_Expression_AssignName extends Twig_Node_Expression_Name
 
 
 
14
  {
15
- public function compile(Twig_Compiler $compiler)
16
  {
17
  $compiler
18
  ->raw('$context[')
10
  * file that was distributed with this source code.
11
  */
12
 
13
+ use Twig\Compiler;
14
+ use Twig\Node\Expression\NameExpression;
15
+
16
+ class Twig_Node_Expression_AssignName extends NameExpression
17
  {
18
+ public function compile(Compiler $compiler)
19
  {
20
  $compiler
21
  ->raw('$context[')
vendor/twig/twig/lib/Twig/Node/Expression/Binary.php CHANGED
@@ -9,14 +9,18 @@
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
- abstract class Twig_Node_Expression_Binary extends Twig_Node_Expression
 
 
 
 
13
  {
14
  public function __construct(Twig_NodeInterface $left, Twig_NodeInterface $right, $lineno)
15
  {
16
  parent::__construct(['left' => $left, 'right' => $right], [], $lineno);
17
  }
18
 
19
- public function compile(Twig_Compiler $compiler)
20
  {
21
  $compiler
22
  ->raw('(')
@@ -31,7 +35,7 @@ abstract class Twig_Node_Expression_Binary extends Twig_Node_Expression
31
  ;
32
  }
33
 
34
- abstract public function operator(Twig_Compiler $compiler);
35
  }
36
 
37
  class_alias('Twig_Node_Expression_Binary', 'Twig\Node\Expression\Binary\AbstractBinary', false);
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
+
13
+ use Twig\Compiler;
14
+ use Twig\Node\Expression\AbstractExpression;
15
+
16
+ abstract class Twig_Node_Expression_Binary extends AbstractExpression
17
  {
18
  public function __construct(Twig_NodeInterface $left, Twig_NodeInterface $right, $lineno)
19
  {
20
  parent::__construct(['left' => $left, 'right' => $right], [], $lineno);
21
  }
22
 
23
+ public function compile(Compiler $compiler)
24
  {
25
  $compiler
26
  ->raw('(')
35
  ;
36
  }
37
 
38
+ abstract public function operator(Compiler $compiler);
39
  }
40
 
41
  class_alias('Twig_Node_Expression_Binary', 'Twig\Node\Expression\Binary\AbstractBinary', false);
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Add.php CHANGED
@@ -9,9 +9,13 @@
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
- class Twig_Node_Expression_Binary_Add extends Twig_Node_Expression_Binary
 
 
 
 
13
  {
14
- public function operator(Twig_Compiler $compiler)
15
  {
16
  return $compiler->raw('+');
17
  }
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
+
13
+ use Twig\Compiler;
14
+ use Twig\Node\Expression\Binary\AbstractBinary;
15
+
16
+ class Twig_Node_Expression_Binary_Add extends AbstractBinary
17
  {
18
+ public function operator(Compiler $compiler)
19
  {
20
  return $compiler->raw('+');
21
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/And.php CHANGED
@@ -9,9 +9,13 @@
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
- class Twig_Node_Expression_Binary_And extends Twig_Node_Expression_Binary
 
 
 
 
13
  {
14
- public function operator(Twig_Compiler $compiler)
15
  {
16
  return $compiler->raw('&&');
17
  }
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
+
13
+ use Twig\Compiler;
14
+ use Twig\Node\Expression\Binary\AbstractBinary;
15
+
16
+ class Twig_Node_Expression_Binary_And extends AbstractBinary
17
  {
18
+ public function operator(Compiler $compiler)
19
  {
20
  return $compiler->raw('&&');
21
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php CHANGED
@@ -9,9 +9,13 @@
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
- class Twig_Node_Expression_Binary_BitwiseAnd extends Twig_Node_Expression_Binary
 
 
 
 
13
  {
14
- public function operator(Twig_Compiler $compiler)
15
  {
16
  return $compiler->raw('&');
17
  }
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
+
13
+ use Twig\Compiler;
14
+ use Twig\Node\Expression\Binary\AbstractBinary;
15
+
16
+ class Twig_Node_Expression_Binary_BitwiseAnd extends AbstractBinary
17
  {
18
+ public function operator(Compiler $compiler)
19
  {
20
  return $compiler->raw('&');
21
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php CHANGED
@@ -9,9 +9,13 @@
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
- class Twig_Node_Expression_Binary_BitwiseOr extends Twig_Node_Expression_Binary
 
 
 
 
13
  {
14
- public function operator(Twig_Compiler $compiler)
15
  {
16
  return $compiler->raw('|');
17
  }
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
+
13
+ use Twig\Compiler;
14
+ use Twig\Node\Expression\Binary\AbstractBinary;
15
+
16
+ class Twig_Node_Expression_Binary_BitwiseOr extends AbstractBinary
17
  {
18
+ public function operator(Compiler $compiler)
19
  {
20
  return $compiler->raw('|');
21
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php CHANGED
@@ -9,9 +9,13 @@
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
- class Twig_Node_Expression_Binary_BitwiseXor extends Twig_Node_Expression_Binary
 
 
 
 
13
  {
14
- public function operator(Twig_Compiler $compiler)
15
  {
16
  return $compiler->raw('^');
17
  }
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
+
13
+ use Twig\Compiler;
14
+ use Twig\Node\Expression\Binary\AbstractBinary;
15
+
16
+ class Twig_Node_Expression_Binary_BitwiseXor extends AbstractBinary
17
  {
18
+ public function operator(Compiler $compiler)
19
  {
20
  return $compiler->raw('^');
21
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Concat.php CHANGED
@@ -9,9 +9,13 @@
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
- class Twig_Node_Expression_Binary_Concat extends Twig_Node_Expression_Binary
 
 
 
 
13
  {
14
- public function operator(Twig_Compiler $compiler)
15
  {
16
  return $compiler->raw('.');
17
  }
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
+
13
+ use Twig\Compiler;
14
+ use Twig\Node\Expression\Binary\AbstractBinary;
15
+
16
+ class Twig_Node_Expression_Binary_Concat extends AbstractBinary
17
  {
18
+ public function operator(Compiler $compiler)
19
  {
20
  return $compiler->raw('.');
21
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Div.php CHANGED
@@ -9,9 +9,13 @@
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
- class Twig_Node_Expression_Binary_Div extends Twig_Node_Expression_Binary
 
 
 
 
13
  {
14
- public function operator(Twig_Compiler $compiler)
15
  {
16
  return $compiler->raw('/');
17
  }
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
+
13
+ use Twig\Compiler;
14
+ use Twig\Node\Expression\Binary\AbstractBinary;
15
+
16
+ class Twig_Node_Expression_Binary_Div extends AbstractBinary
17
  {
18
+ public function operator(Compiler $compiler)
19
  {
20
  return $compiler->raw('/');
21
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/EndsWith.php CHANGED
@@ -8,9 +8,13 @@
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
- class Twig_Node_Expression_Binary_EndsWith extends Twig_Node_Expression_Binary
 
 
 
 
12
  {
13
- public function compile(Twig_Compiler $compiler)
14
  {
15
  $left = $compiler->getVarName();
16
  $right = $compiler->getVarName();
@@ -23,7 +27,7 @@ class Twig_Node_Expression_Binary_EndsWith extends Twig_Node_Expression_Binary
23
  ;
24
  }
25
 
26
- public function operator(Twig_Compiler $compiler)
27
  {
28
  return $compiler->raw('');
29
  }
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
+
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\Binary\AbstractBinary;
14
+
15
+ class Twig_Node_Expression_Binary_EndsWith extends AbstractBinary
16
  {
17
+ public function compile(Compiler $compiler)
18
  {
19
  $left = $compiler->getVarName();
20
  $right = $compiler->getVarName();
27
  ;
28
  }
29
 
30
+ public function operator(Compiler $compiler)
31
  {
32
  return $compiler->raw('');
33
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Equal.php CHANGED
@@ -8,9 +8,13 @@
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
- class Twig_Node_Expression_Binary_Equal extends Twig_Node_Expression_Binary
 
 
 
 
12
  {
13
- public function operator(Twig_Compiler $compiler)
14
  {
15
  return $compiler->raw('==');
16
  }
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
+
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\Binary\AbstractBinary;
14
+
15
+ class Twig_Node_Expression_Binary_Equal extends AbstractBinary
16
  {
17
+ public function operator(Compiler $compiler)
18
  {
19
  return $compiler->raw('==');
20
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php CHANGED
@@ -8,16 +8,20 @@
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
- class Twig_Node_Expression_Binary_FloorDiv extends Twig_Node_Expression_Binary
 
 
 
 
12
  {
13
- public function compile(Twig_Compiler $compiler)
14
  {
15
  $compiler->raw('(int) floor(');
16
  parent::compile($compiler);
17
  $compiler->raw(')');
18
  }
19
 
20
- public function operator(Twig_Compiler $compiler)
21
  {
22
  return $compiler->raw('/');
23
  }
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
+
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\Binary\AbstractBinary;
14
+
15
+ class Twig_Node_Expression_Binary_FloorDiv extends AbstractBinary
16
  {
17
+ public function compile(Compiler $compiler)
18
  {
19
  $compiler->raw('(int) floor(');
20
  parent::compile($compiler);
21
  $compiler->raw(')');
22
  }
23
 
24
+ public function operator(Compiler $compiler)
25
  {
26
  return $compiler->raw('/');
27
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Greater.php CHANGED
@@ -8,9 +8,13 @@
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
- class Twig_Node_Expression_Binary_Greater extends Twig_Node_Expression_Binary
 
 
 
 
12
  {
13
- public function operator(Twig_Compiler $compiler)
14
  {
15
  return $compiler->raw('>');
16
  }
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
+
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\Binary\AbstractBinary;
14
+
15
+ class Twig_Node_Expression_Binary_Greater extends AbstractBinary
16
  {
17
+ public function operator(Compiler $compiler)
18
  {
19
  return $compiler->raw('>');
20
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php CHANGED
@@ -8,9 +8,13 @@
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
- class Twig_Node_Expression_Binary_GreaterEqual extends Twig_Node_Expression_Binary
 
 
 
 
12
  {
13
- public function operator(Twig_Compiler $compiler)
14
  {
15
  return $compiler->raw('>=');
16
  }
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
+
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\Binary\AbstractBinary;
14
+
15
+ class Twig_Node_Expression_Binary_GreaterEqual extends AbstractBinary
16
  {
17
+ public function operator(Compiler $compiler)
18
  {
19
  return $compiler->raw('>=');
20
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/In.php CHANGED
@@ -8,9 +8,13 @@
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
- class Twig_Node_Expression_Binary_In extends Twig_Node_Expression_Binary
 
 
 
 
12
  {
13
- public function compile(Twig_Compiler $compiler)
14
  {
15
  $compiler
16
  ->raw('twig_in_filter(')
@@ -21,7 +25,7 @@ class Twig_Node_Expression_Binary_In extends Twig_Node_Expression_Binary
21
  ;
22
  }
23
 
24
- public function operator(Twig_Compiler $compiler)
25
  {
26
  return $compiler->raw('in');
27
  }
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
+
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\Binary\AbstractBinary;
14
+
15
+ class Twig_Node_Expression_Binary_In extends AbstractBinary
16
  {
17
+ public function compile(Compiler $compiler)
18
  {
19
  $compiler
20
  ->raw('twig_in_filter(')
25
  ;
26
  }
27
 
28
+ public function operator(Compiler $compiler)
29
  {
30
  return $compiler->raw('in');
31
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Less.php CHANGED
@@ -8,9 +8,13 @@
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
- class Twig_Node_Expression_Binary_Less extends Twig_Node_Expression_Binary
 
 
 
 
12
  {
13
- public function operator(Twig_Compiler $compiler)
14
  {
15
  return $compiler->raw('<');
16
  }
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
+
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\Binary\AbstractBinary;
14
+
15
+ class Twig_Node_Expression_Binary_Less extends AbstractBinary
16
  {
17
+ public function operator(Compiler $compiler)
18
  {
19
  return $compiler->raw('<');
20
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/LessEqual.php CHANGED
@@ -8,9 +8,13 @@
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
- class Twig_Node_Expression_Binary_LessEqual extends Twig_Node_Expression_Binary
 
 
 
 
12
  {
13
- public function operator(Twig_Compiler $compiler)
14
  {
15
  return $compiler->raw('<=');
16
  }
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
+
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\Binary\AbstractBinary;
14
+
15
+ class Twig_Node_Expression_Binary_LessEqual extends AbstractBinary
16
  {
17
+ public function operator(Compiler $compiler)
18
  {
19
  return $compiler->raw('<=');
20
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Matches.php CHANGED
@@ -8,9 +8,13 @@
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
- class Twig_Node_Expression_Binary_Matches extends Twig_Node_Expression_Binary
 
 
 
 
12
  {
13
- public function compile(Twig_Compiler $compiler)
14
  {
15
  $compiler
16
  ->raw('preg_match(')
@@ -21,7 +25,7 @@ class Twig_Node_Expression_Binary_Matches extends Twig_Node_Expression_Binary
21
  ;
22
  }
23
 
24
- public function operator(Twig_Compiler $compiler)
25
  {
26
  return $compiler->raw('');
27
  }
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
+
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\Binary\AbstractBinary;
14
+
15
+ class Twig_Node_Expression_Binary_Matches extends AbstractBinary
16
  {
17
+ public function compile(Compiler $compiler)
18
  {
19
  $compiler
20
  ->raw('preg_match(')
25
  ;
26
  }
27
 
28
+ public function operator(Compiler $compiler)
29
  {
30
  return $compiler->raw('');
31
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mod.php CHANGED
@@ -9,9 +9,13 @@
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
- class Twig_Node_Expression_Binary_Mod extends Twig_Node_Expression_Binary
 
 
 
 
13
  {
14
- public function operator(Twig_Compiler $compiler)
15
  {
16
  return $compiler->raw('%');
17
  }
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
+
13
+ use Twig\Compiler;
14
+ use Twig\Node\Expression\Binary\AbstractBinary;
15
+
16
+ class Twig_Node_Expression_Binary_Mod extends AbstractBinary
17
  {
18
+ public function operator(Compiler $compiler)
19
  {
20
  return $compiler->raw('%');
21
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mul.php CHANGED
@@ -9,9 +9,13 @@
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
- class Twig_Node_Expression_Binary_Mul extends Twig_Node_Expression_Binary
 
 
 
 
13
  {
14
- public function operator(Twig_Compiler $compiler)
15
  {
16
  return $compiler->raw('*');
17
  }
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
+
13
+ use Twig\Compiler;
14
+ use Twig\Node\Expression\Binary\AbstractBinary;
15
+
16
+ class Twig_Node_Expression_Binary_Mul extends AbstractBinary
17
  {
18
+ public function operator(Compiler $compiler)
19
  {
20
  return $compiler->raw('*');
21
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotEqual.php CHANGED
@@ -8,9 +8,13 @@
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
- class Twig_Node_Expression_Binary_NotEqual extends Twig_Node_Expression_Binary
 
 
 
 
12
  {
13
- public function operator(Twig_Compiler $compiler)
14
  {
15
  return $compiler->raw('!=');
16
  }
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
+
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\Binary\AbstractBinary;
14
+
15
+ class Twig_Node_Expression_Binary_NotEqual extends AbstractBinary
16
  {
17
+ public function operator(Compiler $compiler)
18
  {
19
  return $compiler->raw('!=');
20
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotIn.php CHANGED
@@ -8,9 +8,13 @@
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
- class Twig_Node_Expression_Binary_NotIn extends Twig_Node_Expression_Binary
 
 
 
 
12
  {
13
- public function compile(Twig_Compiler $compiler)
14
  {
15
  $compiler
16
  ->raw('!twig_in_filter(')
@@ -21,7 +25,7 @@ class Twig_Node_Expression_Binary_NotIn extends Twig_Node_Expression_Binary
21
  ;
22
  }
23
 
24
- public function operator(Twig_Compiler $compiler)
25
  {
26
  return $compiler->raw('not in');
27
  }
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
+
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\Binary\AbstractBinary;
14
+
15
+ class Twig_Node_Expression_Binary_NotIn extends AbstractBinary
16
  {
17
+ public function compile(Compiler $compiler)
18
  {
19
  $compiler
20
  ->raw('!twig_in_filter(')
25
  ;
26
  }
27
 
28
+ public function operator(Compiler $compiler)
29
  {
30
  return $compiler->raw('not in');
31
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Or.php CHANGED
@@ -9,9 +9,13 @@
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
- class Twig_Node_Expression_Binary_Or extends Twig_Node_Expression_Binary
 
 
 
 
13
  {
14
- public function operator(Twig_Compiler $compiler)
15
  {
16
  return $compiler->raw('||');
17
  }
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
+
13
+ use Twig\Compiler;
14
+ use Twig\Node\Expression\Binary\AbstractBinary;
15
+
16
+ class Twig_Node_Expression_Binary_Or extends AbstractBinary
17
  {
18
+ public function operator(Compiler $compiler)
19
  {
20
  return $compiler->raw('||');
21
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Power.php CHANGED
@@ -8,9 +8,13 @@
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
- class Twig_Node_Expression_Binary_Power extends Twig_Node_Expression_Binary
 
 
 
 
12
  {
13
- public function compile(Twig_Compiler $compiler)
14
  {
15
  if (PHP_VERSION_ID >= 50600) {
16
  return parent::compile($compiler);
@@ -25,7 +29,7 @@ class Twig_Node_Expression_Binary_Power extends Twig_Node_Expression_Binary
25
  ;
26
  }
27
 
28
- public function operator(Twig_Compiler $compiler)
29
  {
30
  return $compiler->raw('**');
31
  }
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
+
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\Binary\AbstractBinary;
14
+
15
+ class Twig_Node_Expression_Binary_Power extends AbstractBinary
16
  {
17
+ public function compile(Compiler $compiler)
18
  {
19
  if (PHP_VERSION_ID >= 50600) {
20
  return parent::compile($compiler);
29
  ;
30
  }
31
 
32
+ public function operator(Compiler $compiler)
33
  {
34
  return $compiler->raw('**');
35
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Range.php CHANGED
@@ -8,9 +8,13 @@
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
- class Twig_Node_Expression_Binary_Range extends Twig_Node_Expression_Binary
 
 
 
 
12
  {
13
- public function compile(Twig_Compiler $compiler)
14
  {
15
  $compiler
16
  ->raw('range(')
@@ -21,7 +25,7 @@ class Twig_Node_Expression_Binary_Range extends Twig_Node_Expression_Binary
21
  ;
22
  }
23
 
24
- public function operator(Twig_Compiler $compiler)
25
  {
26
  return $compiler->raw('..');
27
  }
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
+
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\Binary\AbstractBinary;
14
+
15
+ class Twig_Node_Expression_Binary_Range extends AbstractBinary
16
  {
17
+ public function compile(Compiler $compiler)
18
  {
19
  $compiler
20
  ->raw('range(')
25
  ;
26
  }
27
 
28
+ public function operator(Compiler $compiler)
29
  {
30
  return $compiler->raw('..');
31
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/StartsWith.php CHANGED
@@ -8,9 +8,13 @@
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
- class Twig_Node_Expression_Binary_StartsWith extends Twig_Node_Expression_Binary
 
 
 
 
12
  {
13
- public function compile(Twig_Compiler $compiler)
14
  {
15
  $left = $compiler->getVarName();
16
  $right = $compiler->getVarName();
@@ -23,7 +27,7 @@ class Twig_Node_Expression_Binary_StartsWith extends Twig_Node_Expression_Binary
23
  ;
24
  }
25
 
26
- public function operator(Twig_Compiler $compiler)
27
  {
28
  return $compiler->raw('');
29
  }
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
+
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\Binary\AbstractBinary;
14
+
15
+ class Twig_Node_Expression_Binary_StartsWith extends AbstractBinary
16
  {
17
+ public function compile(Compiler $compiler)
18
  {
19
  $left = $compiler->getVarName();
20
  $right = $compiler->getVarName();
27
  ;
28
  }
29
 
30
+ public function operator(Compiler $compiler)
31
  {
32
  return $compiler->raw('');
33
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Sub.php CHANGED
@@ -9,9 +9,13 @@
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
- class Twig_Node_Expression_Binary_Sub extends Twig_Node_Expression_Binary
 
 
 
 
13
  {
14
- public function operator(Twig_Compiler $compiler)
15
  {
16
  return $compiler->raw('-');
17
  }
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
+
13
+ use Twig\Compiler;
14
+ use Twig\Node\Expression\Binary\AbstractBinary;
15
+
16
+ class Twig_Node_Expression_Binary_Sub extends AbstractBinary
17
  {
18
+ public function operator(Compiler $compiler)
19
  {
20
  return $compiler->raw('-');
21
  }
vendor/twig/twig/lib/Twig/Node/Expression/BlockReference.php CHANGED
@@ -10,19 +10,23 @@
10
  * file that was distributed with this source code.
11
  */
12
 
 
 
 
 
13
  /**
14
  * Represents a block call node.
15
  *
16
  * @author Fabien Potencier <fabien@symfony.com>
17
  */
18
- class Twig_Node_Expression_BlockReference extends Twig_Node_Expression
19
  {
20
  /**
21
- * @param Twig_Node|null $template
22
  */
23
  public function __construct(Twig_NodeInterface $name, $template = null, $lineno, $tag = null)
24
  {
25
- if (is_bool($template)) {
26
  @trigger_error(sprintf('The %s method "$asString" argument is deprecated since version 1.28 and will be removed in 2.0.', __METHOD__), E_USER_DEPRECATED);
27
 
28
  $template = null;
@@ -36,7 +40,7 @@ class Twig_Node_Expression_BlockReference extends Twig_Node_Expression
36
  parent::__construct($nodes, ['is_defined_test' => false, 'output' => false], $lineno, $tag);
37
  }
38
 
39
- public function compile(Twig_Compiler $compiler)
40
  {
41
  if ($this->getAttribute('is_defined_test')) {
42
  $this->compileTemplateCall($compiler, 'hasBlock');
@@ -53,7 +57,7 @@ class Twig_Node_Expression_BlockReference extends Twig_Node_Expression
53
  }
54
  }
55
 
56
- private function compileTemplateCall(Twig_Compiler $compiler, $method)
57
  {
58
  if (!$this->hasNode('template')) {
59
  $compiler->write('$this');
@@ -75,7 +79,7 @@ class Twig_Node_Expression_BlockReference extends Twig_Node_Expression
75
  return $compiler;
76
  }
77
 
78
- private function compileBlockArguments(Twig_Compiler $compiler)
79
  {
80
  $compiler
81
  ->raw('(')
10
  * file that was distributed with this source code.
11
  */
12
 
13
+ use Twig\Compiler;
14
+ use Twig\Node\Expression\AbstractExpression;
15
+ use Twig\Node\Node;
16
+
17
  /**
18
  * Represents a block call node.
19
  *
20
  * @author Fabien Potencier <fabien@symfony.com>
21
  */
22
+ class Twig_Node_Expression_BlockReference extends AbstractExpression
23
  {
24
  /**
25
+ * @param Node|null $template
26
  */
27
  public function __construct(Twig_NodeInterface $name, $template = null, $lineno, $tag = null)
28
  {
29
+ if (\is_bool($template)) {
30
  @trigger_error(sprintf('The %s method "$asString" argument is deprecated since version 1.28 and will be removed in 2.0.', __METHOD__), E_USER_DEPRECATED);
31
 
32
  $template = null;
40
  parent::__construct($nodes, ['is_defined_test' => false, 'output' => false], $lineno, $tag);
41
  }
42
 
43
+ public function compile(Compiler $compiler)
44
  {
45
  if ($this->getAttribute('is_defined_test')) {
46
  $this->compileTemplateCall($compiler, 'hasBlock');
57
  }
58
  }
59
 
60
+ private function compileTemplateCall(Compiler $compiler, $method)
61
  {
62
  if (!$this->hasNode('template')) {
63
  $compiler->write('$this');
79
  return $compiler;
80
  }
81
 
82
+ private function compileBlockArguments(Compiler $compiler)
83
  {
84
  $compiler
85
  ->raw('(')
vendor/twig/twig/lib/Twig/Node/Expression/Call.php CHANGED
@@ -8,27 +8,36 @@
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
- abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
 
 
 
 
 
 
 
 
 
12
  {
13
  private $reflector;
14
 
15
- protected function compileCallable(Twig_Compiler $compiler)
16
  {
17
  $closingParenthesis = false;
18
  $isArray = false;
19
  if ($this->hasAttribute('callable') && $callable = $this->getAttribute('callable')) {
20
- if (is_string($callable) && false === strpos($callable, '::')) {
21
  $compiler->raw($callable);
22
  } else {
23
  list($r, $callable) = $this->reflectCallable($callable);
24
- if ($r instanceof ReflectionMethod && is_string($callable[0])) {
25
  if ($r->isStatic()) {
26
  $compiler->raw(sprintf('%s::%s', $callable[0], $callable[1]));
27
  } else {
28
  $compiler->raw(sprintf('$this->env->getRuntime(\'%s\')->%s', $callable[0], $callable[1]));
29
  }
30
- } elseif ($r instanceof ReflectionMethod && $callable[0] instanceof Twig_ExtensionInterface) {
31
- $compiler->raw(sprintf('$this->env->getExtension(\'%s\')->%s', get_class($callable[0]), $callable[1]));
32
  } else {
33
  $type = ucfirst($this->getAttribute('type'));
34
  $compiler->raw(sprintf('call_user_func_array($this->env->get%s(\'%s\')->getCallable(), ', $type, $this->getAttribute('name')));
@@ -47,7 +56,7 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
47
  }
48
  }
49
 
50
- protected function compileArguments(Twig_Compiler $compiler, $isArray = false)
51
  {
52
  $compiler->raw($isArray ? '[' : '(');
53
 
@@ -109,11 +118,11 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
109
  $parameters = [];
110
  $named = false;
111
  foreach ($arguments as $name => $node) {
112
- if (!is_int($name)) {
113
  $named = true;
114
  $name = $this->normalizeName($name);
115
  } elseif ($named) {
116
- throw new Twig_Error_Syntax(sprintf('Positional arguments cannot be used after named arguments for %s "%s".', $callType, $callName), $this->getTemplateLine());
117
  }
118
 
119
  $parameters[$name] = $node;
@@ -131,7 +140,7 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
131
  $message = sprintf('Arbitrary positional arguments are not supported for %s "%s".', $callType, $callName);
132
  }
133
 
134
- throw new LogicException($message);
135
  }
136
 
137
  $callableParameters = $this->getCallableParameters($callable, $isVariadic);
@@ -143,15 +152,15 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
143
  foreach ($callableParameters as $callableParameter) {
144
  $names[] = $name = $this->normalizeName($callableParameter->name);
145
 
146
- if (array_key_exists($name, $parameters)) {
147
- if (array_key_exists($pos, $parameters)) {
148
- throw new Twig_Error_Syntax(sprintf('Argument "%s" is defined twice for %s "%s".', $name, $callType, $callName), $this->getTemplateLine());
149
  }
150
 
151
- if (count($missingArguments)) {
152
- throw new Twig_Error_Syntax(sprintf(
153
  'Argument "%s" could not be assigned for %s "%s(%s)" because it is mapped to an internal PHP function which cannot determine default value for optional argument%s "%s".',
154
- $name, $callType, $callName, implode(', ', $names), count($missingArguments) > 1 ? 's' : '', implode('", "', $missingArguments)
155
  ), $this->getTemplateLine());
156
  }
157
 
@@ -159,14 +168,14 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
159
  $arguments[] = $parameters[$name];
160
  unset($parameters[$name]);
161
  $optionalArguments = [];
162
- } elseif (array_key_exists($pos, $parameters)) {
163
  $arguments = array_merge($arguments, $optionalArguments);
164
  $arguments[] = $parameters[$pos];
165
  unset($parameters[$pos]);
166
  $optionalArguments = [];
167
  ++$pos;
168
  } elseif ($callableParameter->isDefaultValueAvailable()) {
169
- $optionalArguments[] = new Twig_Node_Expression_Constant($callableParameter->getDefaultValue(), -1);
170
  } elseif ($callableParameter->isOptional()) {
171
  if (empty($parameters)) {
172
  break;
@@ -174,17 +183,17 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
174
  $missingArguments[] = $name;
175
  }
176
  } else {
177
- throw new Twig_Error_Syntax(sprintf('Value for argument "%s" is required for %s "%s".', $name, $callType, $callName), $this->getTemplateLine());
178
  }
179
  }
180
 
181
  if ($isVariadic) {
182
- $arbitraryArguments = new Twig_Node_Expression_Array([], -1);
183
  foreach ($parameters as $key => $value) {
184
- if (is_int($key)) {
185
  $arbitraryArguments->addElement($value);
186
  } else {
187
- $arbitraryArguments->addElement($value, new Twig_Node_Expression_Constant($key, -1));
188
  }
189
  unset($parameters[$key]);
190
  }
@@ -198,15 +207,15 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
198
  if (!empty($parameters)) {
199
  $unknownParameter = null;
200
  foreach ($parameters as $parameter) {
201
- if ($parameter instanceof Twig_Node) {
202
  $unknownParameter = $parameter;
203
  break;
204
  }
205
  }
206
 
207
- throw new Twig_Error_Syntax(sprintf(
208
  'Unknown argument%s "%s" for %s "%s(%s)".',
209
- count($parameters) > 1 ? 's' : '', implode('", "', array_keys($parameters)), $callType, $callName, implode(', ', $names)
210
  ), $unknownParameter ? $unknownParameter->getTemplateLine() : $this->getTemplateLine());
211
  }
212
 
@@ -246,11 +255,11 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
246
  array_pop($parameters);
247
  } else {
248
  $callableName = $r->name;
249
- if ($r instanceof ReflectionMethod) {
250
  $callableName = $r->getDeclaringClass()->name.'::'.$callableName;
251
  }
252
 
253
- throw new LogicException(sprintf('The last parameter of "%s" for %s "%s" must be an array with default value, eg. "array $arg = []".', $callableName, $this->getAttribute('type'), $this->getAttribute('name')));
254
  }
255
  }
256
 
@@ -263,27 +272,27 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
263
  return $this->reflector;
264
  }
265
 
266
- if (is_array($callable)) {
267
  if (!method_exists($callable[0], $callable[1])) {
268
  // __call()
269
  return [null, []];
270
  }
271
- $r = new ReflectionMethod($callable[0], $callable[1]);
272
- } elseif (is_object($callable) && !$callable instanceof Closure) {
273
- $r = new ReflectionObject($callable);
274
  $r = $r->getMethod('__invoke');
275
  $callable = [$callable, '__invoke'];
276
- } elseif (is_string($callable) && false !== $pos = strpos($callable, '::')) {
277
  $class = substr($callable, 0, $pos);
278
  $method = substr($callable, $pos + 2);
279
  if (!method_exists($class, $method)) {
280
  // __staticCall()
281
  return [null, []];
282
  }
283
- $r = new ReflectionMethod($callable);
284
  $callable = [$class, $method];
285
  } else {
286
- $r = new ReflectionFunction($callable);
287
  }
288
 
289
  return $this->reflector = [$r, $callable];
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
+
12
+ use Twig\Compiler;
13
+ use Twig\Error\SyntaxError;
14
+ use Twig\Extension\ExtensionInterface;
15
+ use Twig\Node\Expression\AbstractExpression;
16
+ use Twig\Node\Expression\ArrayExpression;
17
+ use Twig\Node\Expression\ConstantExpression;
18
+ use Twig\Node\Node;
19
+
20
+ abstract class Twig_Node_Expression_Call extends AbstractExpression
21
  {
22
  private $reflector;
23
 
24
+ protected function compileCallable(Compiler $compiler)
25
  {
26
  $closingParenthesis = false;
27
  $isArray = false;
28
  if ($this->hasAttribute('callable') && $callable = $this->getAttribute('callable')) {
29
+ if (\is_string($callable) && false === strpos($callable, '::')) {
30
  $compiler->raw($callable);
31
  } else {
32
  list($r, $callable) = $this->reflectCallable($callable);
33
+ if ($r instanceof \ReflectionMethod && \is_string($callable[0])) {
34
  if ($r->isStatic()) {
35
  $compiler->raw(sprintf('%s::%s', $callable[0], $callable[1]));
36
  } else {
37
  $compiler->raw(sprintf('$this->env->getRuntime(\'%s\')->%s', $callable[0], $callable[1]));
38
  }
39
+ } elseif ($r instanceof \ReflectionMethod && $callable[0] instanceof ExtensionInterface) {
40
+ $compiler->raw(sprintf('$this->env->getExtension(\'%s\')->%s', \get_class($callable[0]), $callable[1]));
41
  } else {
42
  $type = ucfirst($this->getAttribute('type'));
43
  $compiler->raw(sprintf('call_user_func_array($this->env->get%s(\'%s\')->getCallable(), ', $type, $this->getAttribute('name')));
56
  }
57
  }
58
 
59
+ protected function compileArguments(Compiler $compiler, $isArray = false)
60
  {
61
  $compiler->raw($isArray ? '[' : '(');
62
 
118
  $parameters = [];
119
  $named = false;
120
  foreach ($arguments as $name => $node) {
121
+ if (!\is_int($name)) {
122
  $named = true;
123
  $name = $this->normalizeName($name);
124
  } elseif ($named) {
125
+ throw new SyntaxError(sprintf('Positional arguments cannot be used after named arguments for %s "%s".', $callType, $callName), $this->getTemplateLine());
126
  }
127
 
128
  $parameters[$name] = $node;
140
  $message = sprintf('Arbitrary positional arguments are not supported for %s "%s".', $callType, $callName);
141
  }
142
 
143
+ throw new \LogicException($message);
144
  }
145
 
146
  $callableParameters = $this->getCallableParameters($callable, $isVariadic);
152
  foreach ($callableParameters as $callableParameter) {
153
  $names[] = $name = $this->normalizeName($callableParameter->name);
154
 
155
+ if (\array_key_exists($name, $parameters)) {
156
+ if (\array_key_exists($pos, $parameters)) {
157
+ throw new SyntaxError(sprintf('Argument "%s" is defined twice for %s "%s".', $name, $callType, $callName), $this->getTemplateLine());
158
  }
159
 
160
+ if (\count($missingArguments)) {
161
+ throw new SyntaxError(sprintf(
162
  'Argument "%s" could not be assigned for %s "%s(%s)" because it is mapped to an internal PHP function which cannot determine default value for optional argument%s "%s".',
163
+ $name, $callType, $callName, implode(', ', $names), \count($missingArguments) > 1 ? 's' : '', implode('", "', $missingArguments)
164
  ), $this->getTemplateLine());
165
  }
166
 
168
  $arguments[] = $parameters[$name];
169
  unset($parameters[$name]);
170
  $optionalArguments = [];
171
+ } elseif (\array_key_exists($pos, $parameters)) {
172
  $arguments = array_merge($arguments, $optionalArguments);
173
  $arguments[] = $parameters[$pos];
174
  unset($parameters[$pos]);
175
  $optionalArguments = [];
176
  ++$pos;
177
  } elseif ($callableParameter->isDefaultValueAvailable()) {
178
+ $optionalArguments[] = new ConstantExpression($callableParameter->getDefaultValue(), -1);
179
  } elseif ($callableParameter->isOptional()) {
180
  if (empty($parameters)) {
181
  break;
183
  $missingArguments[] = $name;
184
  }
185
  } else {
186
+ throw new SyntaxError(sprintf('Value for argument "%s" is required for %s "%s".', $name, $callType, $callName), $this->getTemplateLine());
187
  }
188
  }
189
 
190
  if ($isVariadic) {
191
+ $arbitraryArguments = new ArrayExpression([], -1);
192
  foreach ($parameters as $key => $value) {
193
+ if (\is_int($key)) {
194
  $arbitraryArguments->addElement($value);
195
  } else {
196
+ $arbitraryArguments->addElement($value, new ConstantExpression($key, -1));
197
  }
198
  unset($parameters[$key]);
199
  }
207
  if (!empty($parameters)) {
208
  $unknownParameter = null;
209
  foreach ($parameters as $parameter) {
210
+ if ($parameter instanceof Node) {
211
  $unknownParameter = $parameter;
212
  break;
213
  }
214
  }
215
 
216
+ throw new SyntaxError(sprintf(
217
  'Unknown argument%s "%s" for %s "%s(%s)".',
218
+ \count($parameters) > 1 ? 's' : '', implode('", "', array_keys($parameters)), $callType, $callName, implode(', ', $names)
219
  ), $unknownParameter ? $unknownParameter->getTemplateLine() : $this->getTemplateLine());
220
  }
221
 
255
  array_pop($parameters);
256
  } else {
257
  $callableName = $r->name;
258
+ if ($r instanceof \ReflectionMethod) {
259
  $callableName = $r->getDeclaringClass()->name.'::'.$callableName;
260
  }
261
 
262
+ throw new \LogicException(sprintf('The last parameter of "%s" for %s "%s" must be an array with default value, eg. "array $arg = []".', $callableName, $this->getAttribute('type'), $this->getAttribute('name')));
263
  }
264
  }
265
 
272
  return $this->reflector;
273
  }
274
 
275
+ if (\is_array($callable)) {
276
  if (!method_exists($callable[0], $callable[1])) {
277
  // __call()
278
  return [null, []];
279
  }
280
+ $r = new \ReflectionMethod($callable[0], $callable[1]);
281
+ } elseif (\is_object($callable) && !$callable instanceof Closure) {
282
+ $r = new \ReflectionObject($callable);
283
  $r = $r->getMethod('__invoke');
284
  $callable = [$callable, '__invoke'];
285
+ } elseif (\is_string($callable) && false !== $pos = strpos($callable, '::')) {
286
  $class = substr($callable, 0, $pos);
287
  $method = substr($callable, $pos + 2);
288
  if (!method_exists($class, $method)) {
289
  // __staticCall()
290
  return [null, []];
291
  }
292
+ $r = new \ReflectionMethod($callable);
293
  $callable = [$class, $method];
294
  } else {
295
+ $r = new \ReflectionFunction($callable);
296
  }
297
 
298
  return $this->reflector = [$r, $callable];
vendor/twig/twig/lib/Twig/Node/Expression/Conditional.php CHANGED
@@ -9,14 +9,18 @@
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
- class Twig_Node_Expression_Conditional extends Twig_Node_Expression
 
 
 
 
13
  {
14
- public function __construct(Twig_Node_Expression $expr1, Twig_Node_Expression $expr2, Twig_Node_Expression $expr3, $lineno)
15
  {
16
  parent::__construct(['expr1' => $expr1, 'expr2' => $expr2, 'expr3' => $expr3], [], $lineno);
17
  }
18
 
19
- public function compile(Twig_Compiler $compiler)
20
  {
21
  $compiler
22
  ->raw('((')
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
+
13
+ use Twig\Compiler;
14
+ use Twig\Node\Expression\AbstractExpression;
15
+
16
+ class Twig_Node_Expression_Conditional extends AbstractExpression
17
  {
18
+ public function __construct(AbstractExpression $expr1, AbstractExpression $expr2, AbstractExpression $expr3, $lineno)
19
  {
20
  parent::__construct(['expr1' => $expr1, 'expr2' => $expr2, 'expr3' => $expr3], [], $lineno);
21
  }
22
 
23
+ public function compile(Compiler $compiler)
24
  {
25
  $compiler
26
  ->raw('((')
vendor/twig/twig/lib/Twig/Node/Expression/Constant.php CHANGED
@@ -9,14 +9,18 @@
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
- class Twig_Node_Expression_Constant extends Twig_Node_Expression
 
 
 
 
13
  {
14
  public function __construct($value, $lineno)
15
  {
16
  parent::__construct([], ['value' => $value], $lineno);
17
  }
18
 
19
- public function compile(Twig_Compiler $compiler)
20
  {
21
  $compiler->repr($this->getAttribute('value'));
22
  }
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
+
13
+ use Twig\Compiler;
14
+ use Twig\Node\Expression\AbstractExpression;
15
+
16
+ class Twig_Node_Expression_Constant extends AbstractExpression
17
  {
18
  public function __construct($value, $lineno)
19
  {
20
  parent::__construct([], ['value' => $value], $lineno);
21
  }
22
 
23
+ public function compile(Compiler $compiler)
24
  {
25
  $compiler->repr($this->getAttribute('value'));
26
  }
vendor/twig/twig/lib/Twig/Node/Expression/ExtensionReference.php CHANGED
@@ -9,6 +9,9 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
12
  @trigger_error('The Twig_Node_Expression_ExtensionReference class is deprecated since version 1.23 and will be removed in 2.0.', E_USER_DEPRECATED);
13
 
14
  /**
@@ -18,14 +21,14 @@
18
  *
19
  * @deprecated since 1.23 and will be removed in 2.0.
20
  */
21
- class Twig_Node_Expression_ExtensionReference extends Twig_Node_Expression
22
  {
23
  public function __construct($name, $lineno, $tag = null)
24
  {
25
  parent::__construct([], ['name' => $name], $lineno, $tag);
26
  }
27
 
28
- public function compile(Twig_Compiler $compiler)
29
  {
30
  $compiler->raw(sprintf("\$this->env->getExtension('%s')", $this->getAttribute('name')));
31
  }
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\AbstractExpression;
14
+
15
  @trigger_error('The Twig_Node_Expression_ExtensionReference class is deprecated since version 1.23 and will be removed in 2.0.', E_USER_DEPRECATED);
16
 
17
  /**
21
  *
22
  * @deprecated since 1.23 and will be removed in 2.0.
23
  */
24
+ class Twig_Node_Expression_ExtensionReference extends AbstractExpression
25
  {
26
  public function __construct($name, $lineno, $tag = null)
27
  {
28
  parent::__construct([], ['name' => $name], $lineno, $tag);
29
  }
30
 
31
+ public function compile(Compiler $compiler)
32
  {
33
  $compiler->raw(sprintf("\$this->env->getExtension('%s')", $this->getAttribute('name')));
34
  }
vendor/twig/twig/lib/Twig/Node/Expression/Filter.php CHANGED
@@ -9,14 +9,20 @@
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
- class Twig_Node_Expression_Filter extends Twig_Node_Expression_Call
 
 
 
 
 
 
13
  {
14
- public function __construct(Twig_NodeInterface $node, Twig_Node_Expression_Constant $filterName, Twig_NodeInterface $arguments, $lineno, $tag = null)
15
  {
16
  parent::__construct(['node' => $node, 'filter' => $filterName, 'arguments' => $arguments], [], $lineno, $tag);
17
  }
18
 
19
- public function compile(Twig_Compiler $compiler)
20
  {
21
  $name = $this->getNode('filter')->getAttribute('value');
22
  $filter = $compiler->getEnvironment()->getFilter($name);
@@ -27,10 +33,10 @@ class Twig_Node_Expression_Filter extends Twig_Node_Expression_Call
27
  $this->setAttribute('needs_environment', $filter->needsEnvironment());
28
  $this->setAttribute('needs_context', $filter->needsContext());
29
  $this->setAttribute('arguments', $filter->getArguments());
30
- if ($filter instanceof Twig_FilterCallableInterface || $filter instanceof Twig_SimpleFilter) {
31
  $this->setAttribute('callable', $filter->getCallable());
32
  }
33
- if ($filter instanceof Twig_SimpleFilter) {
34
  $this->setAttribute('is_variadic', $filter->isVariadic());
35
  }
36
 
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
+
13
+ use Twig\Compiler;
14
+ use Twig\Node\Expression\CallExpression;
15
+ use Twig\Node\Expression\ConstantExpression;
16
+ use Twig\TwigFilter;
17
+
18
+ class Twig_Node_Expression_Filter extends CallExpression
19
  {
20
+ public function __construct(Twig_NodeInterface $node, ConstantExpression $filterName, Twig_NodeInterface $arguments, $lineno, $tag = null)
21
  {
22
  parent::__construct(['node' => $node, 'filter' => $filterName, 'arguments' => $arguments], [], $lineno, $tag);
23
  }
24
 
25
+ public function compile(Compiler $compiler)
26
  {
27
  $name = $this->getNode('filter')->getAttribute('value');
28
  $filter = $compiler->getEnvironment()->getFilter($name);
33
  $this->setAttribute('needs_environment', $filter->needsEnvironment());
34
  $this->setAttribute('needs_context', $filter->needsContext());
35
  $this->setAttribute('arguments', $filter->getArguments());
36
+ if ($filter instanceof Twig_FilterCallableInterface || $filter instanceof TwigFilter) {
37
  $this->setAttribute('callable', $filter->getCallable());
38
  }
39
+ if ($filter instanceof TwigFilter) {
40
  $this->setAttribute('is_variadic', $filter->isVariadic());
41
  }
42
 
vendor/twig/twig/lib/Twig/Node/Expression/Filter/Default.php CHANGED
@@ -9,26 +9,33 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
 
 
 
 
 
12
  /**
13
  * Returns the value or the default value when it is undefined or empty.
14
  *
15
- * <pre>
16
  * {{ var.foo|default('foo item on var is not defined') }}
17
- * </pre>
18
  *
19
  * @author Fabien Potencier <fabien@symfony.com>
20
  */
21
- class Twig_Node_Expression_Filter_Default extends Twig_Node_Expression_Filter
22
  {
23
- public function __construct(Twig_NodeInterface $node, Twig_Node_Expression_Constant $filterName, Twig_NodeInterface $arguments, $lineno, $tag = null)
24
  {
25
- $default = new Twig_Node_Expression_Filter($node, new Twig_Node_Expression_Constant('default', $node->getTemplateLine()), $arguments, $node->getTemplateLine());
26
 
27
- if ('default' === $filterName->getAttribute('value') && ($node instanceof Twig_Node_Expression_Name || $node instanceof Twig_Node_Expression_GetAttr)) {
28
- $test = new Twig_Node_Expression_Test_Defined(clone $node, 'defined', new Twig_Node(), $node->getTemplateLine());
29
- $false = count($arguments) ? $arguments->getNode(0) : new Twig_Node_Expression_Constant('', $node->getTemplateLine());
30
 
31
- $node = new Twig_Node_Expression_Conditional($test, $default, $false, $node->getTemplateLine());
32
  } else {
33
  $node = $default;
34
  }
@@ -36,7 +43,7 @@ class Twig_Node_Expression_Filter_Default extends Twig_Node_Expression_Filter
36
  parent::__construct($node, $filterName, $arguments, $lineno, $tag);
37
  }
38
 
39
- public function compile(Twig_Compiler $compiler)
40
  {
41
  $compiler->subcompile($this->getNode('node'));
42
  }
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\ConditionalExpression;
14
+ use Twig\Node\Expression\ConstantExpression;
15
+ use Twig\Node\Expression\FilterExpression;
16
+ use Twig\Node\Expression\GetAttrExpression;
17
+ use Twig\Node\Expression\NameExpression;
18
+ use Twig\Node\Expression\Test\DefinedTest;
19
+ use Twig\Node\Node;
20
+
21
  /**
22
  * Returns the value or the default value when it is undefined or empty.
23
  *
 
24
  * {{ var.foo|default('foo item on var is not defined') }}
 
25
  *
26
  * @author Fabien Potencier <fabien@symfony.com>
27
  */
28
+ class Twig_Node_Expression_Filter_Default extends FilterExpression
29
  {
30
+ public function __construct(Twig_NodeInterface $node, ConstantExpression $filterName, Twig_NodeInterface $arguments, $lineno, $tag = null)
31
  {
32
+ $default = new FilterExpression($node, new ConstantExpression('default', $node->getTemplateLine()), $arguments, $node->getTemplateLine());
33
 
34
+ if ('default' === $filterName->getAttribute('value') && ($node instanceof NameExpression || $node instanceof GetAttrExpression)) {
35
+ $test = new DefinedTest(clone $node, 'defined', new Node(), $node->getTemplateLine());
36
+ $false = \count($arguments) ? $arguments->getNode(0) : new ConstantExpression('', $node->getTemplateLine());
37
 
38
+ $node = new ConditionalExpression($test, $default, $false, $node->getTemplateLine());
39
  } else {
40
  $node = $default;
41
  }
43
  parent::__construct($node, $filterName, $arguments, $lineno, $tag);
44
  }
45
 
46
+ public function compile(Compiler $compiler)
47
  {
48
  $compiler->subcompile($this->getNode('node'));
49
  }
vendor/twig/twig/lib/Twig/Node/Expression/Function.php CHANGED
@@ -8,14 +8,19 @@
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
- class Twig_Node_Expression_Function extends Twig_Node_Expression_Call
 
 
 
 
 
12
  {
13
  public function __construct($name, Twig_NodeInterface $arguments, $lineno)
14
  {
15
  parent::__construct(['arguments' => $arguments], ['name' => $name, 'is_defined_test' => false], $lineno);
16
  }
17
 
18
- public function compile(Twig_Compiler $compiler)
19
  {
20
  $name = $this->getAttribute('name');
21
  $function = $compiler->getEnvironment()->getFunction($name);
@@ -26,7 +31,7 @@ class Twig_Node_Expression_Function extends Twig_Node_Expression_Call
26
  $this->setAttribute('needs_environment', $function->needsEnvironment());
27
  $this->setAttribute('needs_context', $function->needsContext());
28
  $this->setAttribute('arguments', $function->getArguments());
29
- if ($function instanceof Twig_FunctionCallableInterface || $function instanceof Twig_SimpleFunction) {
30
  $callable = $function->getCallable();
31
  if ('constant' === $name && $this->getAttribute('is_defined_test')) {
32
  $callable = 'twig_constant_is_defined';
@@ -34,7 +39,7 @@ class Twig_Node_Expression_Function extends Twig_Node_Expression_Call
34
 
35
  $this->setAttribute('callable', $callable);
36
  }
37
- if ($function instanceof Twig_SimpleFunction) {
38
  $this->setAttribute('is_variadic', $function->isVariadic());
39
  }
40
 
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
+
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\CallExpression;
14
+ use Twig\TwigFunction;
15
+
16
+ class Twig_Node_Expression_Function extends CallExpression
17
  {
18
  public function __construct($name, Twig_NodeInterface $arguments, $lineno)
19
  {
20
  parent::__construct(['arguments' => $arguments], ['name' => $name, 'is_defined_test' => false], $lineno);
21
  }
22
 
23
+ public function compile(Compiler $compiler)
24
  {
25
  $name = $this->getAttribute('name');
26
  $function = $compiler->getEnvironment()->getFunction($name);
31
  $this->setAttribute('needs_environment', $function->needsEnvironment());
32
  $this->setAttribute('needs_context', $function->needsContext());
33
  $this->setAttribute('arguments', $function->getArguments());
34
+ if ($function instanceof Twig_FunctionCallableInterface || $function instanceof TwigFunction) {
35
  $callable = $function->getCallable();
36
  if ('constant' === $name && $this->getAttribute('is_defined_test')) {
37
  $callable = 'twig_constant_is_defined';
39
 
40
  $this->setAttribute('callable', $callable);
41
  }
42
+ if ($function instanceof TwigFunction) {
43
  $this->setAttribute('is_variadic', $function->isVariadic());
44
  }
45
 
vendor/twig/twig/lib/Twig/Node/Expression/GetAttr.php CHANGED
@@ -9,9 +9,14 @@
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
- class Twig_Node_Expression_GetAttr extends Twig_Node_Expression
 
 
 
 
 
13
  {
14
- public function __construct(Twig_Node_Expression $node, Twig_Node_Expression $attribute, Twig_Node_Expression $arguments = null, $type, $lineno)
15
  {
16
  $nodes = ['node' => $node, 'attribute' => $attribute];
17
  if (null !== $arguments) {
@@ -21,13 +26,13 @@ class Twig_Node_Expression_GetAttr extends Twig_Node_Expression
21
  parent::__construct($nodes, ['type' => $type, 'is_defined_test' => false, 'ignore_strict_check' => false, 'disable_c_ext' => false], $lineno);
22
  }
23
 
24
- public function compile(Twig_Compiler $compiler)
25
  {
26
  if ($this->getAttribute('disable_c_ext')) {
27
  @trigger_error(sprintf('Using the "disable_c_ext" attribute on %s is deprecated since version 1.30 and will be removed in 2.0.', __CLASS__), E_USER_DEPRECATED);
28
  }
29
 
30
- if (function_exists('twig_template_get_attributes') && !$this->getAttribute('disable_c_ext')) {
31
  $compiler->raw('twig_template_get_attributes($this, ');
32
  } else {
33
  $compiler->raw('$this->getAttribute(');
@@ -44,7 +49,7 @@ class Twig_Node_Expression_GetAttr extends Twig_Node_Expression
44
  // only generate optional arguments when needed (to make generated code more readable)
45
  $needFourth = $this->getAttribute('ignore_strict_check');
46
  $needThird = $needFourth || $this->getAttribute('is_defined_test');
47
- $needSecond = $needThird || Twig_Template::ANY_CALL !== $this->getAttribute('type');
48
  $needFirst = $needSecond || $this->hasNode('arguments');
49
 
50
  if ($needFirst) {
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
+
13
+ use Twig\Compiler;
14
+ use Twig\Node\Expression\AbstractExpression;
15
+ use Twig\Template;
16
+
17
+ class Twig_Node_Expression_GetAttr extends AbstractExpression
18
  {
19
+ public function __construct(AbstractExpression $node, AbstractExpression $attribute, AbstractExpression $arguments = null, $type, $lineno)
20
  {
21
  $nodes = ['node' => $node, 'attribute' => $attribute];
22
  if (null !== $arguments) {
26
  parent::__construct($nodes, ['type' => $type, 'is_defined_test' => false, 'ignore_strict_check' => false, 'disable_c_ext' => false], $lineno);
27
  }
28
 
29
+ public function compile(Compiler $compiler)
30
  {
31
  if ($this->getAttribute('disable_c_ext')) {
32
  @trigger_error(sprintf('Using the "disable_c_ext" attribute on %s is deprecated since version 1.30 and will be removed in 2.0.', __CLASS__), E_USER_DEPRECATED);
33
  }
34
 
35
+ if (\function_exists('twig_template_get_attributes') && !$this->getAttribute('disable_c_ext')) {
36
  $compiler->raw('twig_template_get_attributes($this, ');
37
  } else {
38
  $compiler->raw('$this->getAttribute(');
49
  // only generate optional arguments when needed (to make generated code more readable)
50
  $needFourth = $this->getAttribute('ignore_strict_check');
51
  $needThird = $needFourth || $this->getAttribute('is_defined_test');
52
+ $needSecond = $needThird || Template::ANY_CALL !== $this->getAttribute('type');
53
  $needFirst = $needSecond || $this->hasNode('arguments');
54
 
55
  if ($needFirst) {
vendor/twig/twig/lib/Twig/Node/Expression/MethodCall.php CHANGED
@@ -8,18 +8,24 @@
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
- class Twig_Node_Expression_MethodCall extends Twig_Node_Expression
 
 
 
 
 
 
12
  {
13
- public function __construct(Twig_Node_Expression $node, $method, Twig_Node_Expression_Array $arguments, $lineno)
14
  {
15
  parent::__construct(['node' => $node, 'arguments' => $arguments], ['method' => $method, 'safe' => false], $lineno);
16
 
17
- if ($node instanceof Twig_Node_Expression_Name) {
18
  $node->setAttribute('always_defined', true);
19
  }
20
  }
21
 
22
- public function compile(Twig_Compiler $compiler)
23
  {
24
  $compiler
25
  ->subcompile($this->getNode('node'))
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
+
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\AbstractExpression;
14
+ use Twig\Node\Expression\ArrayExpression;
15
+ use Twig\Node\Expression\NameExpression;
16
+
17
+ class Twig_Node_Expression_MethodCall extends AbstractExpression
18
  {
19
+ public function __construct(AbstractExpression $node, $method, ArrayExpression $arguments, $lineno)
20
  {
21
  parent::__construct(['node' => $node, 'arguments' => $arguments], ['method' => $method, 'safe' => false], $lineno);
22
 
23
+ if ($node instanceof NameExpression) {
24
  $node->setAttribute('always_defined', true);
25
  }
26
  }
27
 
28
+ public function compile(Compiler $compiler)
29
  {
30
  $compiler
31
  ->subcompile($this->getNode('node'))
vendor/twig/twig/lib/Twig/Node/Expression/Name.php CHANGED
@@ -9,7 +9,11 @@
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
- class Twig_Node_Expression_Name extends Twig_Node_Expression
 
 
 
 
13
  {
14
  protected $specialVars = [
15
  '_self' => '$this',
@@ -22,7 +26,7 @@ class Twig_Node_Expression_Name extends Twig_Node_Expression
22
  parent::__construct([], ['name' => $name, 'is_defined_test' => false, 'ignore_strict_check' => false, 'always_defined' => false], $lineno);
23
  }
24
 
25
- public function compile(Twig_Compiler $compiler)
26
  {
27
  $name = $this->getAttribute('name');
28
 
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
+
13
+ use Twig\Compiler;
14
+ use Twig\Node\Expression\AbstractExpression;
15
+
16
+ class Twig_Node_Expression_Name extends AbstractExpression
17
  {
18
  protected $specialVars = [
19
  '_self' => '$this',
26
  parent::__construct([], ['name' => $name, 'is_defined_test' => false, 'ignore_strict_check' => false, 'always_defined' => false], $lineno);
27
  }
28
 
29
+ public function compile(Compiler $compiler)
30
  {
31
  $name = $this->getAttribute('name');
32
 
vendor/twig/twig/lib/Twig/Node/Expression/NullCoalesce.php CHANGED
@@ -8,20 +8,30 @@
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
- class Twig_Node_Expression_NullCoalesce extends Twig_Node_Expression_Conditional
 
 
 
 
 
 
 
 
 
 
12
  {
13
  public function __construct(Twig_NodeInterface $left, Twig_NodeInterface $right, $lineno)
14
  {
15
- $test = new Twig_Node_Expression_Binary_And(
16
- new Twig_Node_Expression_Test_Defined(clone $left, 'defined', new Twig_Node(), $left->getTemplateLine()),
17
- new Twig_Node_Expression_Unary_Not(new Twig_Node_Expression_Test_Null($left, 'null', new Twig_Node(), $left->getTemplateLine()), $left->getTemplateLine()),
18
  $left->getTemplateLine()
19
  );
20
 
21
  parent::__construct($test, $left, $right, $lineno);
22
  }
23
 
24
- public function compile(Twig_Compiler $compiler)
25
  {
26
  /*
27
  * This optimizes only one case. PHP 7 also supports more complex expressions
@@ -30,7 +40,7 @@ class Twig_Node_Expression_NullCoalesce extends Twig_Node_Expression_Conditional
30
  * cases might be implemented as an optimizer node visitor, but has not been done
31
  * as benefits are probably not worth the added complexity.
32
  */
33
- if (PHP_VERSION_ID >= 70000 && $this->getNode('expr2') instanceof Twig_Node_Expression_Name) {
34
  $this->getNode('expr2')->setAttribute('always_defined', true);
35
  $compiler
36
  ->raw('((')
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
+
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\Binary\AndBinary;
14
+ use Twig\Node\Expression\ConditionalExpression;
15
+ use Twig\Node\Expression\NameExpression;
16
+ use Twig\Node\Expression\Test\DefinedTest;
17
+ use Twig\Node\Expression\Test\NullTest;
18
+ use Twig\Node\Expression\Unary\NotUnary;
19
+ use Twig\Node\Node;
20
+
21
+ class Twig_Node_Expression_NullCoalesce extends ConditionalExpression
22
  {
23
  public function __construct(Twig_NodeInterface $left, Twig_NodeInterface $right, $lineno)
24
  {
25
+ $test = new AndBinary(
26
+ new DefinedTest(clone $left, 'defined', new Node(), $left->getTemplateLine()),
27
+ new NotUnary(new NullTest($left, 'null', new Node(), $left->getTemplateLine()), $left->getTemplateLine()),
28
  $left->getTemplateLine()
29
  );
30
 
31
  parent::__construct($test, $left, $right, $lineno);
32
  }
33
 
34
+ public function compile(Compiler $compiler)
35
  {
36
  /*
37
  * This optimizes only one case. PHP 7 also supports more complex expressions
40
  * cases might be implemented as an optimizer node visitor, but has not been done
41
  * as benefits are probably not worth the added complexity.
42
  */
43
+ if (PHP_VERSION_ID >= 70000 && $this->getNode('expr2') instanceof NameExpression) {
44
  $this->getNode('expr2')->setAttribute('always_defined', true);
45
  $compiler
46
  ->raw('((')
vendor/twig/twig/lib/Twig/Node/Expression/Parent.php CHANGED
@@ -10,19 +10,22 @@
10
  * file that was distributed with this source code.
11
  */
12
 
 
 
 
13
  /**
14
  * Represents a parent node.
15
  *
16
  * @author Fabien Potencier <fabien@symfony.com>
17
  */
18
- class Twig_Node_Expression_Parent extends Twig_Node_Expression
19
  {
20
  public function __construct($name, $lineno, $tag = null)
21
  {
22
  parent::__construct([], ['output' => false, 'name' => $name], $lineno, $tag);
23
  }
24
 
25
- public function compile(Twig_Compiler $compiler)
26
  {
27
  if ($this->getAttribute('output')) {
28
  $compiler
10
  * file that was distributed with this source code.
11
  */
12
 
13
+ use Twig\Compiler;
14
+ use Twig\Node\Expression\AbstractExpression;
15
+
16
  /**
17
  * Represents a parent node.
18
  *
19
  * @author Fabien Potencier <fabien@symfony.com>
20
  */
21
+ class Twig_Node_Expression_Parent extends AbstractExpression
22
  {
23
  public function __construct($name, $lineno, $tag = null)
24
  {
25
  parent::__construct([], ['output' => false, 'name' => $name], $lineno, $tag);
26
  }
27
 
28
+ public function compile(Compiler $compiler)
29
  {
30
  if ($this->getAttribute('output')) {
31
  $compiler
vendor/twig/twig/lib/Twig/Node/Expression/TempName.php CHANGED
@@ -8,14 +8,18 @@
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
- class Twig_Node_Expression_TempName extends Twig_Node_Expression
 
 
 
 
12
  {
13
  public function __construct($name, $lineno)
14
  {
15
  parent::__construct([], ['name' => $name], $lineno);
16
  }
17
 
18
- public function compile(Twig_Compiler $compiler)
19
  {
20
  $compiler
21
  ->raw('$_')
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
+
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\AbstractExpression;
14
+
15
+ class Twig_Node_Expression_TempName extends AbstractExpression
16
  {
17
  public function __construct($name, $lineno)
18
  {
19
  parent::__construct([], ['name' => $name], $lineno);
20
  }
21
 
22
+ public function compile(Compiler $compiler)
23
  {
24
  $compiler
25
  ->raw('$_')
vendor/twig/twig/lib/Twig/Node/Expression/Test.php CHANGED
@@ -8,7 +8,12 @@
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
- class Twig_Node_Expression_Test extends Twig_Node_Expression_Call
 
 
 
 
 
12
  {
13
  public function __construct(Twig_NodeInterface $node, $name, Twig_NodeInterface $arguments = null, $lineno)
14
  {
@@ -20,7 +25,7 @@ class Twig_Node_Expression_Test extends Twig_Node_Expression_Call
20
  parent::__construct($nodes, ['name' => $name], $lineno);
21
  }
22
 
23
- public function compile(Twig_Compiler $compiler)
24
  {
25
  $name = $this->getAttribute('name');
26
  $test = $compiler->getEnvironment()->getTest($name);
@@ -28,13 +33,13 @@ class Twig_Node_Expression_Test extends Twig_Node_Expression_Call
28
  $this->setAttribute('name', $name);
29
  $this->setAttribute('type', 'test');
30
  $this->setAttribute('thing', $test);
31
- if ($test instanceof Twig_SimpleTest) {
32
  $this->setAttribute('arguments', $test->getArguments());
33
  }
34
- if ($test instanceof Twig_TestCallableInterface || $test instanceof Twig_SimpleTest) {
35
  $this->setAttribute('callable', $test->getCallable());
36
  }
37
- if ($test instanceof Twig_SimpleTest) {
38
  $this->setAttribute('is_variadic', $test->isVariadic());
39
  }
40
 
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
+
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\CallExpression;
14
+ use Twig\TwigTest;
15
+
16
+ class Twig_Node_Expression_Test extends CallExpression
17
  {
18
  public function __construct(Twig_NodeInterface $node, $name, Twig_NodeInterface $arguments = null, $lineno)
19
  {
25
  parent::__construct($nodes, ['name' => $name], $lineno);
26
  }
27
 
28
+ public function compile(Compiler $compiler)
29
  {
30
  $name = $this->getAttribute('name');
31
  $test = $compiler->getEnvironment()->getTest($name);
33
  $this->setAttribute('name', $name);
34
  $this->setAttribute('type', 'test');
35
  $this->setAttribute('thing', $test);
36
+ if ($test instanceof TwigTest) {
37
  $this->setAttribute('arguments', $test->getArguments());
38
  }
39
+ if ($test instanceof Twig_TestCallableInterface || $test instanceof TwigTest) {
40
  $this->setAttribute('callable', $test->getCallable());
41
  }
42
+ if ($test instanceof TwigTest) {
43
  $this->setAttribute('is_variadic', $test->isVariadic());
44
  }
45
 
vendor/twig/twig/lib/Twig/Node/Expression/Test/Constant.php CHANGED
@@ -9,20 +9,21 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
12
  /**
13
  * Checks if a variable is the exact same value as a constant.
14
  *
15
- * <pre>
16
- * {% if post.status is constant('Post::PUBLISHED') %}
17
- * the status attribute is exactly the same as Post::PUBLISHED
18
- * {% endif %}
19
- * </pre>
20
  *
21
  * @author Fabien Potencier <fabien@symfony.com>
22
  */
23
- class Twig_Node_Expression_Test_Constant extends Twig_Node_Expression_Test
24
  {
25
- public function compile(Twig_Compiler $compiler)
26
  {
27
  $compiler
28
  ->raw('(')
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\TestExpression;
14
+
15
  /**
16
  * Checks if a variable is the exact same value as a constant.
17
  *
18
+ * {% if post.status is constant('Post::PUBLISHED') %}
19
+ * the status attribute is exactly the same as Post::PUBLISHED
20
+ * {% endif %}
 
 
21
  *
22
  * @author Fabien Potencier <fabien@symfony.com>
23
  */
24
+ class Twig_Node_Expression_Test_Constant extends TestExpression
25
  {
26
+ public function compile(Compiler $compiler)
27
  {
28
  $compiler
29
  ->raw('(')
vendor/twig/twig/lib/Twig/Node/Expression/Test/Defined.php CHANGED
@@ -9,50 +9,58 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
 
 
 
 
 
 
12
  /**
13
  * Checks if a variable is defined in the current context.
14
  *
15
- * <pre>
16
- * {# defined works with variable names and variable attributes #}
17
- * {% if foo is defined %}
18
- * {# ... #}
19
- * {% endif %}
20
- * </pre>
21
  *
22
  * @author Fabien Potencier <fabien@symfony.com>
23
  */
24
- class Twig_Node_Expression_Test_Defined extends Twig_Node_Expression_Test
25
  {
26
  public function __construct(Twig_NodeInterface $node, $name, Twig_NodeInterface $arguments = null, $lineno)
27
  {
28
- if ($node instanceof Twig_Node_Expression_Name) {
29
  $node->setAttribute('is_defined_test', true);
30
- } elseif ($node instanceof Twig_Node_Expression_GetAttr) {
31
  $node->setAttribute('is_defined_test', true);
32
  $this->changeIgnoreStrictCheck($node);
33
- } elseif ($node instanceof Twig_Node_Expression_BlockReference) {
34
  $node->setAttribute('is_defined_test', true);
35
- } elseif ($node instanceof Twig_Node_Expression_Function && 'constant' === $node->getAttribute('name')) {
36
  $node->setAttribute('is_defined_test', true);
37
- } elseif ($node instanceof Twig_Node_Expression_Constant || $node instanceof Twig_Node_Expression_Array) {
38
- $node = new Twig_Node_Expression_Constant(true, $node->getTemplateLine());
39
  } else {
40
- throw new Twig_Error_Syntax('The "defined" test only works with simple variables.', $this->getTemplateLine());
41
  }
42
 
43
  parent::__construct($node, $name, $arguments, $lineno);
44
  }
45
 
46
- protected function changeIgnoreStrictCheck(Twig_Node_Expression_GetAttr $node)
47
  {
48
  $node->setAttribute('ignore_strict_check', true);
49
 
50
- if ($node->getNode('node') instanceof Twig_Node_Expression_GetAttr) {
51
  $this->changeIgnoreStrictCheck($node->getNode('node'));
52
  }
53
  }
54
 
55
- public function compile(Twig_Compiler $compiler)
56
  {
57
  $compiler->subcompile($this->getNode('node'));
58
  }
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Compiler;
13
+ use Twig\Error\SyntaxError;
14
+ use Twig\Node\Expression\ArrayExpression;
15
+ use Twig\Node\Expression\BlockReferenceExpression;
16
+ use Twig\Node\Expression\ConstantExpression;
17
+ use Twig\Node\Expression\FunctionExpression;
18
+ use Twig\Node\Expression\GetAttrExpression;
19
+ use Twig\Node\Expression\NameExpression;
20
+ use Twig\Node\Expression\TestExpression;
21
+
22
  /**
23
  * Checks if a variable is defined in the current context.
24
  *
25
+ * {# defined works with variable names and variable attributes #}
26
+ * {% if foo is defined %}
27
+ * {# ... #}
28
+ * {% endif %}
 
 
29
  *
30
  * @author Fabien Potencier <fabien@symfony.com>
31
  */
32
+ class Twig_Node_Expression_Test_Defined extends TestExpression
33
  {
34
  public function __construct(Twig_NodeInterface $node, $name, Twig_NodeInterface $arguments = null, $lineno)
35
  {
36
+ if ($node instanceof NameExpression) {
37
  $node->setAttribute('is_defined_test', true);
38
+ } elseif ($node instanceof GetAttrExpression) {
39
  $node->setAttribute('is_defined_test', true);
40
  $this->changeIgnoreStrictCheck($node);
41
+ } elseif ($node instanceof BlockReferenceExpression) {
42
  $node->setAttribute('is_defined_test', true);
43
+ } elseif ($node instanceof FunctionExpression && 'constant' === $node->getAttribute('name')) {
44
  $node->setAttribute('is_defined_test', true);
45
+ } elseif ($node instanceof ConstantExpression || $node instanceof ArrayExpression) {
46
+ $node = new ConstantExpression(true, $node->getTemplateLine());
47
  } else {
48
+ throw new SyntaxError('The "defined" test only works with simple variables.', $this->getTemplateLine());
49
  }
50
 
51
  parent::__construct($node, $name, $arguments, $lineno);
52
  }
53
 
54
+ protected function changeIgnoreStrictCheck(GetAttrExpression $node)
55
  {
56
  $node->setAttribute('ignore_strict_check', true);
57
 
58
+ if ($node->getNode('node') instanceof GetAttrExpression) {
59
  $this->changeIgnoreStrictCheck($node->getNode('node'));
60
  }
61
  }
62
 
63
+ public function compile(Compiler $compiler)
64
  {
65
  $compiler->subcompile($this->getNode('node'));
66
  }
vendor/twig/twig/lib/Twig/Node/Expression/Test/Divisibleby.php CHANGED
@@ -9,18 +9,19 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
12
  /**
13
  * Checks if a variable is divisible by a number.
14
  *
15
- * <pre>
16
  * {% if loop.index is divisible by(3) %}
17
- * </pre>
18
  *
19
  * @author Fabien Potencier <fabien@symfony.com>
20
  */
21
- class Twig_Node_Expression_Test_Divisibleby extends Twig_Node_Expression_Test
22
  {
23
- public function compile(Twig_Compiler $compiler)
24
  {
25
  $compiler
26
  ->raw('(0 == ')
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\TestExpression;
14
+
15
  /**
16
  * Checks if a variable is divisible by a number.
17
  *
 
18
  * {% if loop.index is divisible by(3) %}
 
19
  *
20
  * @author Fabien Potencier <fabien@symfony.com>
21
  */
22
+ class Twig_Node_Expression_Test_Divisibleby extends TestExpression
23
  {
24
+ public function compile(Compiler $compiler)
25
  {
26
  $compiler
27
  ->raw('(0 == ')
vendor/twig/twig/lib/Twig/Node/Expression/Test/Even.php CHANGED
@@ -9,18 +9,19 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
12
  /**
13
  * Checks if a number is even.
14
  *
15
- * <pre>
16
  * {{ var is even }}
17
- * </pre>
18
  *
19
  * @author Fabien Potencier <fabien@symfony.com>
20
  */
21
- class Twig_Node_Expression_Test_Even extends Twig_Node_Expression_Test
22
  {
23
- public function compile(Twig_Compiler $compiler)
24
  {
25
  $compiler
26
  ->raw('(')
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\TestExpression;
14
+
15
  /**
16
  * Checks if a number is even.
17
  *
 
18
  * {{ var is even }}
 
19
  *
20
  * @author Fabien Potencier <fabien@symfony.com>
21
  */
22
+ class Twig_Node_Expression_Test_Even extends TestExpression
23
  {
24
+ public function compile(Compiler $compiler)
25
  {
26
  $compiler
27
  ->raw('(')
vendor/twig/twig/lib/Twig/Node/Expression/Test/Null.php CHANGED
@@ -9,18 +9,19 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
12
  /**
13
  * Checks that a variable is null.
14
  *
15
- * <pre>
16
  * {{ var is none }}
17
- * </pre>
18
  *
19
  * @author Fabien Potencier <fabien@symfony.com>
20
  */
21
- class Twig_Node_Expression_Test_Null extends Twig_Node_Expression_Test
22
  {
23
- public function compile(Twig_Compiler $compiler)
24
  {
25
  $compiler
26
  ->raw('(null === ')
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\TestExpression;
14
+
15
  /**
16
  * Checks that a variable is null.
17
  *
 
18
  * {{ var is none }}
 
19
  *
20
  * @author Fabien Potencier <fabien@symfony.com>
21
  */
22
+ class Twig_Node_Expression_Test_Null extends TestExpression
23
  {
24
+ public function compile(Compiler $compiler)
25
  {
26
  $compiler
27
  ->raw('(null === ')
vendor/twig/twig/lib/Twig/Node/Expression/Test/Odd.php CHANGED
@@ -9,18 +9,19 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
12
  /**
13
  * Checks if a number is odd.
14
  *
15
- * <pre>
16
  * {{ var is odd }}
17
- * </pre>
18
  *
19
  * @author Fabien Potencier <fabien@symfony.com>
20
  */
21
- class Twig_Node_Expression_Test_Odd extends Twig_Node_Expression_Test
22
  {
23
- public function compile(Twig_Compiler $compiler)
24
  {
25
  $compiler
26
  ->raw('(')
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\TestExpression;
14
+
15
  /**
16
  * Checks if a number is odd.
17
  *
 
18
  * {{ var is odd }}
 
19
  *
20
  * @author Fabien Potencier <fabien@symfony.com>
21
  */
22
+ class Twig_Node_Expression_Test_Odd extends TestExpression
23
  {
24
+ public function compile(Compiler $compiler)
25
  {
26
  $compiler
27
  ->raw('(')
vendor/twig/twig/lib/Twig/Node/Expression/Test/Sameas.php CHANGED
@@ -9,14 +9,17 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
12
  /**
13
  * Checks if a variable is the same as another one (=== in PHP).
14
  *
15
  * @author Fabien Potencier <fabien@symfony.com>
16
  */
17
- class Twig_Node_Expression_Test_Sameas extends Twig_Node_Expression_Test
18
  {
19
- public function compile(Twig_Compiler $compiler)
20
  {
21
  $compiler
22
  ->raw('(')
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\TestExpression;
14
+
15
  /**
16
  * Checks if a variable is the same as another one (=== in PHP).
17
  *
18
  * @author Fabien Potencier <fabien@symfony.com>
19
  */
20
+ class Twig_Node_Expression_Test_Sameas extends TestExpression
21
  {
22
+ public function compile(Compiler $compiler)
23
  {
24
  $compiler
25
  ->raw('(')
vendor/twig/twig/lib/Twig/Node/Expression/Unary.php CHANGED
@@ -9,21 +9,25 @@
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
- abstract class Twig_Node_Expression_Unary extends Twig_Node_Expression
 
 
 
 
13
  {
14
  public function __construct(Twig_NodeInterface $node, $lineno)
15
  {
16
  parent::__construct(['node' => $node], [], $lineno);
17
  }
18
 
19
- public function compile(Twig_Compiler $compiler)
20
  {
21
  $compiler->raw(' ');
22
  $this->operator($compiler);
23
  $compiler->subcompile($this->getNode('node'));
24
  }
25
 
26
- abstract public function operator(Twig_Compiler $compiler);
27
  }
28
 
29
  class_alias('Twig_Node_Expression_Unary', 'Twig\Node\Expression\Unary\AbstractUnary', false);
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
+
13
+ use Twig\Compiler;
14
+ use Twig\Node\Expression\AbstractExpression;
15
+
16
+ abstract class Twig_Node_Expression_Unary extends AbstractExpression
17
  {
18
  public function __construct(Twig_NodeInterface $node, $lineno)
19
  {
20
  parent::__construct(['node' => $node], [], $lineno);
21
  }
22
 
23
+ public function compile(Compiler $compiler)
24
  {
25
  $compiler->raw(' ');
26
  $this->operator($compiler);
27
  $compiler->subcompile($this->getNode('node'));
28
  }
29
 
30
+ abstract public function operator(Compiler $compiler);
31
  }
32
 
33
  class_alias('Twig_Node_Expression_Unary', 'Twig\Node\Expression\Unary\AbstractUnary', false);
vendor/twig/twig/lib/Twig/Node/Expression/Unary/Neg.php CHANGED
@@ -9,9 +9,13 @@
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
- class Twig_Node_Expression_Unary_Neg extends Twig_Node_Expression_Unary
 
 
 
 
13
  {
14
- public function operator(Twig_Compiler $compiler)
15
  {
16
  $compiler->raw('-');
17
  }
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
+
13
+ use Twig\Compiler;
14
+ use Twig\Node\Expression\Unary\AbstractUnary;
15
+
16
+ class Twig_Node_Expression_Unary_Neg extends AbstractUnary
17
  {
18
+ public function operator(Compiler $compiler)
19
  {
20
  $compiler->raw('-');
21
  }
vendor/twig/twig/lib/Twig/Node/Expression/Unary/Not.php CHANGED
@@ -9,9 +9,13 @@
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
- class Twig_Node_Expression_Unary_Not extends Twig_Node_Expression_Unary
 
 
 
 
13
  {
14
- public function operator(Twig_Compiler $compiler)
15
  {
16
  $compiler->raw('!');
17
  }
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
+
13
+ use Twig\Compiler;
14
+ use Twig\Node\Expression\Unary\AbstractUnary;
15
+
16
+ class Twig_Node_Expression_Unary_Not extends AbstractUnary
17
  {
18
+ public function operator(Compiler $compiler)
19
  {
20
  $compiler->raw('!');
21
  }
vendor/twig/twig/lib/Twig/Node/Expression/Unary/Pos.php CHANGED
@@ -9,9 +9,13 @@
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
- class Twig_Node_Expression_Unary_Pos extends Twig_Node_Expression_Unary
 
 
 
 
13
  {
14
- public function operator(Twig_Compiler $compiler)
15
  {
16
  $compiler->raw('+');
17
  }
9
  * For the full copyright and license information, please view the LICENSE
10
  * file that was distributed with this source code.
11
  */
12
+
13
+ use Twig\Compiler;
14
+ use Twig\Node\Expression\Unary\AbstractUnary;
15
+
16
+ class Twig_Node_Expression_Unary_Pos extends AbstractUnary
17
  {
18
+ public function operator(Compiler $compiler)
19
  {
20
  $compiler->raw('+');
21
  }
vendor/twig/twig/lib/Twig/Node/Flush.php CHANGED
@@ -9,19 +9,22 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
12
  /**
13
  * Represents a flush node.
14
  *
15
  * @author Fabien Potencier <fabien@symfony.com>
16
  */
17
- class Twig_Node_Flush extends Twig_Node
18
  {
19
  public function __construct($lineno, $tag)
20
  {
21
  parent::__construct([], [], $lineno, $tag);
22
  }
23
 
24
- public function compile(Twig_Compiler $compiler)
25
  {
26
  $compiler
27
  ->addDebugInfo($this)
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Compiler;
13
+ use Twig\Node\Node;
14
+
15
  /**
16
  * Represents a flush node.
17
  *
18
  * @author Fabien Potencier <fabien@symfony.com>
19
  */
20
+ class Twig_Node_Flush extends Node
21
  {
22
  public function __construct($lineno, $tag)
23
  {
24
  parent::__construct([], [], $lineno, $tag);
25
  }
26
 
27
+ public function compile(Compiler $compiler)
28
  {
29
  $compiler
30
  ->addDebugInfo($this)
vendor/twig/twig/lib/Twig/Node/For.php CHANGED
@@ -10,21 +10,28 @@
10
  * file that was distributed with this source code.
11
  */
12
 
 
 
 
 
 
 
 
13
  /**
14
  * Represents a for node.
15
  *
16
  * @author Fabien Potencier <fabien@symfony.com>
17
  */
18
- class Twig_Node_For extends Twig_Node
19
  {
20
  protected $loop;
21
 
22
- public function __construct(Twig_Node_Expression_AssignName $keyTarget, Twig_Node_Expression_AssignName $valueTarget, Twig_Node_Expression $seq, Twig_Node_Expression $ifexpr = null, Twig_NodeInterface $body, Twig_NodeInterface $else = null, $lineno, $tag = null)
23
  {
24
- $body = new Twig_Node([$body, $this->loop = new Twig_Node_ForLoop($lineno, $tag)]);
25
 
26
  if (null !== $ifexpr) {
27
- $body = new Twig_Node_If(new Twig_Node([$ifexpr, $body]), null, $lineno, $tag);
28
  }
29
 
30
  $nodes = ['key_target' => $keyTarget, 'value_target' => $valueTarget, 'seq' => $seq, 'body' => $body];
@@ -35,7 +42,7 @@ class Twig_Node_For extends Twig_Node
35
  parent::__construct($nodes, ['with_loop' => true, 'ifexpr' => null !== $ifexpr], $lineno, $tag);
36
  }
37
 
38
- public function compile(Twig_Compiler $compiler)
39
  {
40
  $compiler
41
  ->addDebugInfo($this)
@@ -61,7 +68,7 @@ class Twig_Node_For extends Twig_Node
61
 
62
  if (!$this->getAttribute('ifexpr')) {
63
  $compiler
64
- ->write("if (is_array(\$context['_seq']) || (is_object(\$context['_seq']) && \$context['_seq'] instanceof Countable)) {\n")
65
  ->indent()
66
  ->write("\$length = count(\$context['_seq']);\n")
67
  ->write("\$context['loop']['revindex0'] = \$length - 1;\n")
10
  * file that was distributed with this source code.
11
  */
12
 
13
+ use Twig\Compiler;
14
+ use Twig\Node\Expression\AbstractExpression;
15
+ use Twig\Node\Expression\AssignNameExpression;
16
+ use Twig\Node\ForLoopNode;
17
+ use Twig\Node\IfNode;
18
+ use Twig\Node\Node;
19
+
20
  /**
21
  * Represents a for node.
22
  *
23
  * @author Fabien Potencier <fabien@symfony.com>
24
  */
25
+ class Twig_Node_For extends Node
26
  {
27
  protected $loop;
28
 
29
+ public function __construct(AssignNameExpression $keyTarget, AssignNameExpression $valueTarget, AbstractExpression $seq, AbstractExpression $ifexpr = null, Twig_NodeInterface $body, Twig_NodeInterface $else = null, $lineno, $tag = null)
30
  {
31
+ $body = new Node([$body, $this->loop = new ForLoopNode($lineno, $tag)]);
32
 
33
  if (null !== $ifexpr) {
34
+ $body = new IfNode(new Node([$ifexpr, $body]), null, $lineno, $tag);
35
  }
36
 
37
  $nodes = ['key_target' => $keyTarget, 'value_target' => $valueTarget, 'seq' => $seq, 'body' => $body];
42
  parent::__construct($nodes, ['with_loop' => true, 'ifexpr' => null !== $ifexpr], $lineno, $tag);
43
  }
44
 
45
+ public function compile(Compiler $compiler)
46
  {
47
  $compiler
48
  ->addDebugInfo($this)
68
 
69
  if (!$this->getAttribute('ifexpr')) {
70
  $compiler
71
+ ->write("if (is_array(\$context['_seq']) || (is_object(\$context['_seq']) && \$context['_seq'] instanceof \Countable)) {\n")
72
  ->indent()
73
  ->write("\$length = count(\$context['_seq']);\n")
74
  ->write("\$context['loop']['revindex0'] = \$length - 1;\n")
vendor/twig/twig/lib/Twig/Node/ForLoop.php CHANGED
@@ -9,19 +9,22 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
12
  /**
13
  * Internal node used by the for node.
14
  *
15
  * @author Fabien Potencier <fabien@symfony.com>
16
  */
17
- class Twig_Node_ForLoop extends Twig_Node
18
  {
19
  public function __construct($lineno, $tag = null)
20
  {
21
  parent::__construct([], ['with_loop' => false, 'ifexpr' => false, 'else' => false], $lineno, $tag);
22
  }
23
 
24
- public function compile(Twig_Compiler $compiler)
25
  {
26
  if ($this->getAttribute('else')) {
27
  $compiler->write("\$context['_iterated'] = true;\n");
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Compiler;
13
+ use Twig\Node\Node;
14
+
15
  /**
16
  * Internal node used by the for node.
17
  *
18
  * @author Fabien Potencier <fabien@symfony.com>
19
  */
20
+ class Twig_Node_ForLoop extends Node
21
  {
22
  public function __construct($lineno, $tag = null)
23
  {
24
  parent::__construct([], ['with_loop' => false, 'ifexpr' => false, 'else' => false], $lineno, $tag);
25
  }
26
 
27
+ public function compile(Compiler $compiler)
28
  {
29
  if ($this->getAttribute('else')) {
30
  $compiler->write("\$context['_iterated'] = true;\n");
vendor/twig/twig/lib/Twig/Node/If.php CHANGED
@@ -10,12 +10,15 @@
10
  * file that was distributed with this source code.
11
  */
12
 
 
 
 
13
  /**
14
  * Represents an if node.
15
  *
16
  * @author Fabien Potencier <fabien@symfony.com>
17
  */
18
- class Twig_Node_If extends Twig_Node
19
  {
20
  public function __construct(Twig_NodeInterface $tests, Twig_NodeInterface $else = null, $lineno, $tag = null)
21
  {
@@ -27,10 +30,10 @@ class Twig_Node_If extends Twig_Node
27
  parent::__construct($nodes, [], $lineno, $tag);
28
  }
29
 
30
- public function compile(Twig_Compiler $compiler)
31
  {
32
  $compiler->addDebugInfo($this);
33
- for ($i = 0, $count = count($this->getNode('tests')); $i < $count; $i += 2) {
34
  if ($i > 0) {
35
  $compiler
36
  ->outdent()
10
  * file that was distributed with this source code.
11
  */
12
 
13
+ use Twig\Compiler;
14
+ use Twig\Node\Node;
15
+
16
  /**
17
  * Represents an if node.
18
  *
19
  * @author Fabien Potencier <fabien@symfony.com>
20
  */
21
+ class Twig_Node_If extends Node
22
  {
23
  public function __construct(Twig_NodeInterface $tests, Twig_NodeInterface $else = null, $lineno, $tag = null)
24
  {
30
  parent::__construct($nodes, [], $lineno, $tag);
31
  }
32
 
33
+ public function compile(Compiler $compiler)
34
  {
35
  $compiler->addDebugInfo($this);
36
+ for ($i = 0, $count = \count($this->getNode('tests')); $i < $count; $i += 2) {
37
  if ($i > 0) {
38
  $compiler
39
  ->outdent()
vendor/twig/twig/lib/Twig/Node/Import.php CHANGED
@@ -9,19 +9,24 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
 
12
  /**
13
  * Represents an import node.
14
  *
15
  * @author Fabien Potencier <fabien@symfony.com>
16
  */
17
- class Twig_Node_Import extends Twig_Node
18
  {
19
- public function __construct(Twig_Node_Expression $expr, Twig_Node_Expression $var, $lineno, $tag = null)
20
  {
21
  parent::__construct(['expr' => $expr, 'var' => $var], [], $lineno, $tag);
22
  }
23
 
24
- public function compile(Twig_Compiler $compiler)
25
  {
26
  $compiler
27
  ->addDebugInfo($this)
@@ -30,7 +35,7 @@ class Twig_Node_Import extends Twig_Node
30
  ->raw(' = ')
31
  ;
32
 
33
- if ($this->getNode('expr') instanceof Twig_Node_Expression_Name && '_self' === $this->getNode('expr')->getAttribute('name')) {
34
  $compiler->raw('$this');
35
  } else {
36
  $compiler
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\AbstractExpression;
14
+ use Twig\Node\Expression\NameExpression;
15
+ use Twig\Node\Node;
16
+
17
  /**
18
  * Represents an import node.
19
  *
20
  * @author Fabien Potencier <fabien@symfony.com>
21
  */
22
+ class Twig_Node_Import extends Node
23
  {
24
+ public function __construct(AbstractExpression $expr, AbstractExpression $var, $lineno, $tag = null)
25
  {
26
  parent::__construct(['expr' => $expr, 'var' => $var], [], $lineno, $tag);
27
  }
28
 
29
+ public function compile(Compiler $compiler)
30
  {
31
  $compiler
32
  ->addDebugInfo($this)
35
  ->raw(' = ')
36
  ;
37
 
38
+ if ($this->getNode('expr') instanceof NameExpression && '_self' === $this->getNode('expr')->getAttribute('name')) {
39
  $compiler->raw('$this');
40
  } else {
41
  $compiler
vendor/twig/twig/lib/Twig/Node/Include.php CHANGED
@@ -10,14 +10,19 @@
10
  * file that was distributed with this source code.
11
  */
12
 
 
 
 
 
 
13
  /**
14
  * Represents an include node.
15
  *
16
  * @author Fabien Potencier <fabien@symfony.com>
17
  */
18
- class Twig_Node_Include extends Twig_Node implements Twig_NodeOutputInterface
19
  {
20
- public function __construct(Twig_Node_Expression $expr, Twig_Node_Expression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null)
21
  {
22
  $nodes = ['expr' => $expr];
23
  if (null !== $variables) {
@@ -27,7 +32,7 @@ class Twig_Node_Include extends Twig_Node implements Twig_NodeOutputInterface
27
  parent::__construct($nodes, ['only' => (bool) $only, 'ignore_missing' => (bool) $ignoreMissing], $lineno, $tag);
28
  }
29
 
30
- public function compile(Twig_Compiler $compiler)
31
  {
32
  $compiler->addDebugInfo($this);
33
 
@@ -49,7 +54,7 @@ class Twig_Node_Include extends Twig_Node implements Twig_NodeOutputInterface
49
  if ($this->getAttribute('ignore_missing')) {
50
  $compiler
51
  ->outdent()
52
- ->write("} catch (Twig_Error_Loader \$e) {\n")
53
  ->indent()
54
  ->write("// ignore missing template\n")
55
  ->outdent()
@@ -58,7 +63,7 @@ class Twig_Node_Include extends Twig_Node implements Twig_NodeOutputInterface
58
  }
59
  }
60
 
61
- protected function addGetTemplate(Twig_Compiler $compiler)
62
  {
63
  $compiler
64
  ->write('$this->loadTemplate(')
@@ -71,7 +76,7 @@ class Twig_Node_Include extends Twig_Node implements Twig_NodeOutputInterface
71
  ;
72
  }
73
 
74
- protected function addTemplateArguments(Twig_Compiler $compiler)
75
  {
76
  if (!$this->hasNode('variables')) {
77
  $compiler->raw(false === $this->getAttribute('only') ? '$context' : '[]');
10
  * file that was distributed with this source code.
11
  */
12
 
13
+ use Twig\Compiler;
14
+ use Twig\Node\Expression\AbstractExpression;
15
+ use Twig\Node\Node;
16
+ use Twig\Node\NodeOutputInterface;
17
+
18
  /**
19
  * Represents an include node.
20
  *
21
  * @author Fabien Potencier <fabien@symfony.com>
22
  */
23
+ class Twig_Node_Include extends Node implements NodeOutputInterface
24
  {
25
+ public function __construct(AbstractExpression $expr, AbstractExpression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null)
26
  {
27
  $nodes = ['expr' => $expr];
28
  if (null !== $variables) {
32
  parent::__construct($nodes, ['only' => (bool) $only, 'ignore_missing' => (bool) $ignoreMissing], $lineno, $tag);
33
  }
34
 
35
+ public function compile(Compiler $compiler)
36
  {
37
  $compiler->addDebugInfo($this);
38
 
54
  if ($this->getAttribute('ignore_missing')) {
55
  $compiler
56
  ->outdent()
57
+ ->write("} catch (LoaderError \$e) {\n")
58
  ->indent()
59
  ->write("// ignore missing template\n")
60
  ->outdent()
63
  }
64
  }
65
 
66
+ protected function addGetTemplate(Compiler $compiler)
67
  {
68
  $compiler
69
  ->write('$this->loadTemplate(')
76
  ;
77
  }
78
 
79
+ protected function addTemplateArguments(Compiler $compiler)
80
  {
81
  if (!$this->hasNode('variables')) {
82
  $compiler->raw(false === $this->getAttribute('only') ? '$context' : '[]');
vendor/twig/twig/lib/Twig/Node/Macro.php CHANGED
@@ -9,12 +9,16 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
12
  /**
13
  * Represents a macro node.
14
  *
15
  * @author Fabien Potencier <fabien@symfony.com>
16
  */
17
- class Twig_Node_Macro extends Twig_Node
18
  {
19
  const VARARGS_NAME = 'varargs';
20
 
@@ -22,21 +26,21 @@ class Twig_Node_Macro extends Twig_Node
22
  {
23
  foreach ($arguments as $argumentName => $argument) {
24
  if (self::VARARGS_NAME === $argumentName) {
25
- throw new Twig_Error_Syntax(sprintf('The argument "%s" in macro "%s" cannot be defined because the variable "%s" is reserved for arbitrary arguments.', self::VARARGS_NAME, $name, self::VARARGS_NAME), $argument->getTemplateLine());
26
  }
27
  }
28
 
29
  parent::__construct(['body' => $body, 'arguments' => $arguments], ['name' => $name], $lineno, $tag);
30
  }
31
 
32
- public function compile(Twig_Compiler $compiler)
33
  {
34
  $compiler
35
  ->addDebugInfo($this)
36
  ->write(sprintf('public function get%s(', $this->getAttribute('name')))
37
  ;
38
 
39
- $count = count($this->getNode('arguments'));
40
  $pos = 0;
41
  foreach ($this->getNode('arguments') as $name => $default) {
42
  $compiler
@@ -104,18 +108,18 @@ class Twig_Node_Macro extends Twig_Node
104
  ->indent()
105
  ->subcompile($this->getNode('body'))
106
  ->outdent()
107
- ->write("} catch (Exception \$e) {\n")
108
  ->indent()
109
  ->write("ob_end_clean();\n\n")
110
  ->write("throw \$e;\n")
111
  ->outdent()
112
- ->write("} catch (Throwable \$e) {\n")
113
  ->indent()
114
  ->write("ob_end_clean();\n\n")
115
  ->write("throw \$e;\n")
116
  ->outdent()
117
  ->write("}\n\n")
118
- ->write("return ('' === \$tmp = ob_get_clean()) ? '' : new Twig_Markup(\$tmp, \$this->env->getCharset());\n")
119
  ->outdent()
120
  ->write("}\n\n")
121
  ;
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Compiler;
13
+ use Twig\Error\SyntaxError;
14
+ use Twig\Node\Node;
15
+
16
  /**
17
  * Represents a macro node.
18
  *
19
  * @author Fabien Potencier <fabien@symfony.com>
20
  */
21
+ class Twig_Node_Macro extends Node
22
  {
23
  const VARARGS_NAME = 'varargs';
24
 
26
  {
27
  foreach ($arguments as $argumentName => $argument) {
28
  if (self::VARARGS_NAME === $argumentName) {
29
+ throw new SyntaxError(sprintf('The argument "%s" in macro "%s" cannot be defined because the variable "%s" is reserved for arbitrary arguments.', self::VARARGS_NAME, $name, self::VARARGS_NAME), $argument->getTemplateLine());
30
  }
31
  }
32
 
33
  parent::__construct(['body' => $body, 'arguments' => $arguments], ['name' => $name], $lineno, $tag);
34
  }
35
 
36
+ public function compile(Compiler $compiler)
37
  {
38
  $compiler
39
  ->addDebugInfo($this)
40
  ->write(sprintf('public function get%s(', $this->getAttribute('name')))
41
  ;
42
 
43
+ $count = \count($this->getNode('arguments'));
44
  $pos = 0;
45
  foreach ($this->getNode('arguments') as $name => $default) {
46
  $compiler
108
  ->indent()
109
  ->subcompile($this->getNode('body'))
110
  ->outdent()
111
+ ->write("} catch (\Exception \$e) {\n")
112
  ->indent()
113
  ->write("ob_end_clean();\n\n")
114
  ->write("throw \$e;\n")
115
  ->outdent()
116
+ ->write("} catch (\Throwable \$e) {\n")
117
  ->indent()
118
  ->write("ob_end_clean();\n\n")
119
  ->write("throw \$e;\n")
120
  ->outdent()
121
  ->write("}\n\n")
122
+ ->write("return ('' === \$tmp = ob_get_clean()) ? '' : new Markup(\$tmp, \$this->env->getCharset());\n")
123
  ->outdent()
124
  ->write("}\n\n")
125
  ;
vendor/twig/twig/lib/Twig/Node/Module.php CHANGED
@@ -10,6 +10,15 @@
10
  * file that was distributed with this source code.
11
  */
12
 
 
 
 
 
 
 
 
 
 
13
  /**
14
  * Represents a module node.
15
  *
@@ -19,15 +28,15 @@
19
  *
20
  * @author Fabien Potencier <fabien@symfony.com>
21
  */
22
- class Twig_Node_Module extends Twig_Node
23
  {
24
  private $source;
25
 
26
- public function __construct(Twig_NodeInterface $body, Twig_Node_Expression $parent = null, Twig_NodeInterface $blocks, Twig_NodeInterface $macros, Twig_NodeInterface $traits, $embeddedTemplates, $name, $source = '')
27
  {
28
- if (!$name instanceof Twig_Source) {
29
  @trigger_error(sprintf('Passing a string as the $name argument of %s() is deprecated since version 1.27. Pass a Twig_Source instance instead.', __METHOD__), E_USER_DEPRECATED);
30
- $this->source = new Twig_Source($source, $name);
31
  } else {
32
  $this->source = $name;
33
  }
@@ -37,11 +46,11 @@ class Twig_Node_Module extends Twig_Node
37
  'blocks' => $blocks,
38
  'macros' => $macros,
39
  'traits' => $traits,
40
- 'display_start' => new Twig_Node(),
41
- 'display_end' => new Twig_Node(),
42
- 'constructor_start' => new Twig_Node(),
43
- 'constructor_end' => new Twig_Node(),
44
- 'class_end' => new Twig_Node(),
45
  ];
46
  if (null !== $parent) {
47
  $nodes['parent'] = $parent;
@@ -66,7 +75,7 @@ class Twig_Node_Module extends Twig_Node
66
  $this->setAttribute('index', $index);
67
  }
68
 
69
- public function compile(Twig_Compiler $compiler)
70
  {
71
  $this->compileTemplate($compiler);
72
 
@@ -75,7 +84,7 @@ class Twig_Node_Module extends Twig_Node
75
  }
76
  }
77
 
78
- protected function compileTemplate(Twig_Compiler $compiler)
79
  {
80
  if (!$this->getAttribute('index')) {
81
  $compiler->write('<?php');
@@ -84,12 +93,12 @@ class Twig_Node_Module extends Twig_Node
84
  $this->compileClassHeader($compiler);
85
 
86
  if (
87
- count($this->getNode('blocks'))
88
- || count($this->getNode('traits'))
89
  || !$this->hasNode('parent')
90
- || $this->getNode('parent') instanceof Twig_Node_Expression_Constant
91
- || count($this->getNode('constructor_start'))
92
- || count($this->getNode('constructor_end'))
93
  ) {
94
  $this->compileConstructor($compiler);
95
  }
@@ -115,7 +124,7 @@ class Twig_Node_Module extends Twig_Node
115
  $this->compileClassFooter($compiler);
116
  }
117
 
118
- protected function compileGetParent(Twig_Compiler $compiler)
119
  {
120
  if (!$this->hasNode('parent')) {
121
  return;
@@ -129,7 +138,7 @@ class Twig_Node_Module extends Twig_Node
129
  ->write('return ')
130
  ;
131
 
132
- if ($parent instanceof Twig_Node_Expression_Constant) {
133
  $compiler->subcompile($parent);
134
  } else {
135
  $compiler
@@ -150,10 +159,26 @@ class Twig_Node_Module extends Twig_Node
150
  ;
151
  }
152
 
153
- protected function compileClassHeader(Twig_Compiler $compiler)
154
  {
155
  $compiler
156
  ->write("\n\n")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
  // if the template name contains */, add a blank to avoid a PHP parse error
158
  ->write('/* '.str_replace('*/', '* /', $this->source->getName())." */\n")
159
  ->write('class '.$compiler->getEnvironment()->getTemplateClass($this->source->getName(), $this->getAttribute('index')))
@@ -163,10 +188,10 @@ class Twig_Node_Module extends Twig_Node
163
  ;
164
  }
165
 
166
- protected function compileConstructor(Twig_Compiler $compiler)
167
  {
168
  $compiler
169
- ->write("public function __construct(Twig_Environment \$env)\n", "{\n")
170
  ->indent()
171
  ->subcompile($this->getNode('constructor_start'))
172
  ->write("parent::__construct(\$env);\n\n")
@@ -175,7 +200,7 @@ class Twig_Node_Module extends Twig_Node
175
  // parent
176
  if (!$this->hasNode('parent')) {
177
  $compiler->write("\$this->parent = false;\n\n");
178
- } elseif (($parent = $this->getNode('parent')) && $parent instanceof Twig_Node_Expression_Constant) {
179
  $compiler
180
  ->addDebugInfo($parent)
181
  ->write('$this->parent = $this->loadTemplate(')
@@ -188,7 +213,7 @@ class Twig_Node_Module extends Twig_Node
188
  ;
189
  }
190
 
191
- $countTraits = count($this->getNode('traits'));
192
  if ($countTraits) {
193
  // traits
194
  foreach ($this->getNode('traits') as $i => $trait) {
@@ -198,7 +223,7 @@ class Twig_Node_Module extends Twig_Node
198
  ->addDebugInfo($trait->getNode('template'))
199
  ->write(sprintf("if (!\$_trait_%s->isTraitable()) {\n", $i))
200
  ->indent()
201
- ->write("throw new Twig_Error_Runtime('Template \"'.")
202
  ->subcompile($trait->getNode('template'))
203
  ->raw(".'\" cannot be used as a trait.');\n")
204
  ->outdent()
@@ -212,7 +237,7 @@ class Twig_Node_Module extends Twig_Node
212
  ->string($key)
213
  ->raw("])) {\n")
214
  ->indent()
215
- ->write("throw new Twig_Error_Runtime(sprintf('Block ")
216
  ->string($key)
217
  ->raw(' is not defined in trait ')
218
  ->subcompile($trait->getNode('template'))
@@ -297,7 +322,7 @@ class Twig_Node_Module extends Twig_Node
297
  ;
298
  }
299
 
300
- protected function compileDisplay(Twig_Compiler $compiler)
301
  {
302
  $compiler
303
  ->write("protected function doDisplay(array \$context, array \$blocks = [])\n", "{\n")
@@ -309,7 +334,7 @@ class Twig_Node_Module extends Twig_Node
309
  if ($this->hasNode('parent')) {
310
  $parent = $this->getNode('parent');
311
  $compiler->addDebugInfo($parent);
312
- if ($parent instanceof Twig_Node_Expression_Constant) {
313
  $compiler->write('$this->parent');
314
  } else {
315
  $compiler->write('$this->getParent($context)');
@@ -324,7 +349,7 @@ class Twig_Node_Module extends Twig_Node
324
  ;
325
  }
326
 
327
- protected function compileClassFooter(Twig_Compiler $compiler)
328
  {
329
  $compiler
330
  ->subcompile($this->getNode('class_end'))
@@ -333,12 +358,12 @@ class Twig_Node_Module extends Twig_Node
333
  ;
334
  }
335
 
336
- protected function compileMacros(Twig_Compiler $compiler)
337
  {
338
  $compiler->subcompile($this->getNode('macros'));
339
  }
340
 
341
- protected function compileGetTemplateName(Twig_Compiler $compiler)
342
  {
343
  $compiler
344
  ->write("public function getTemplateName()\n", "{\n")
@@ -351,7 +376,7 @@ class Twig_Node_Module extends Twig_Node
351
  ;
352
  }
353
 
354
- protected function compileIsTraitable(Twig_Compiler $compiler)
355
  {
356
  // A template can be used as a trait if:
357
  // * it has no parent
@@ -360,28 +385,28 @@ class Twig_Node_Module extends Twig_Node
360
  //
361
  // Put another way, a template can be used as a trait if it
362
  // only contains blocks and use statements.
363
- $traitable = !$this->hasNode('parent') && 0 === count($this->getNode('macros'));
364
  if ($traitable) {
365
- if ($this->getNode('body') instanceof Twig_Node_Body) {
366
  $nodes = $this->getNode('body')->getNode(0);
367
  } else {
368
  $nodes = $this->getNode('body');
369
  }
370
 
371
- if (!count($nodes)) {
372
- $nodes = new Twig_Node([$nodes]);
373
  }
374
 
375
  foreach ($nodes as $node) {
376
- if (!count($node)) {
377
  continue;
378
  }
379
 
380
- if ($node instanceof Twig_Node_Text && ctype_space($node->getAttribute('data'))) {
381
  continue;
382
  }
383
 
384
- if ($node instanceof Twig_Node_BlockReference) {
385
  continue;
386
  }
387
 
@@ -403,7 +428,7 @@ class Twig_Node_Module extends Twig_Node
403
  ;
404
  }
405
 
406
- protected function compileDebugInfo(Twig_Compiler $compiler)
407
  {
408
  $compiler
409
  ->write("public function getDebugInfo()\n", "{\n")
@@ -414,7 +439,7 @@ class Twig_Node_Module extends Twig_Node
414
  ;
415
  }
416
 
417
- protected function compileGetSource(Twig_Compiler $compiler)
418
  {
419
  $compiler
420
  ->write("/** @deprecated since 1.27 (to be removed in 2.0). Use getSourceContext() instead */\n")
@@ -428,12 +453,12 @@ class Twig_Node_Module extends Twig_Node
428
  ;
429
  }
430
 
431
- protected function compileGetSourceContext(Twig_Compiler $compiler)
432
  {
433
  $compiler
434
  ->write("public function getSourceContext()\n", "{\n")
435
  ->indent()
436
- ->write('return new Twig_Source(')
437
  ->string($compiler->getEnvironment()->isDebug() ? $this->source->getCode() : '')
438
  ->raw(', ')
439
  ->string($this->source->getName())
@@ -445,9 +470,9 @@ class Twig_Node_Module extends Twig_Node
445
  ;
446
  }
447
 
448
- protected function compileLoadTemplate(Twig_Compiler $compiler, $node, $var)
449
  {
450
- if ($node instanceof Twig_Node_Expression_Constant) {
451
  $compiler
452
  ->write(sprintf('%s = $this->loadTemplate(', $var))
453
  ->subcompile($node)
@@ -458,7 +483,7 @@ class Twig_Node_Module extends Twig_Node
458
  ->raw(");\n")
459
  ;
460
  } else {
461
- throw new LogicException('Trait templates can only be constant nodes.');
462
  }
463
  }
464
  }
10
  * file that was distributed with this source code.
11
  */
12
 
13
+ use Twig\Compiler;
14
+ use Twig\Node\BlockReferenceNode;
15
+ use Twig\Node\BodyNode;
16
+ use Twig\Node\Expression\AbstractExpression;
17
+ use Twig\Node\Expression\ConstantExpression;
18
+ use Twig\Node\Node;
19
+ use Twig\Node\TextNode;
20
+ use Twig\Source;
21
+
22
  /**
23
  * Represents a module node.
24
  *
28
  *
29
  * @author Fabien Potencier <fabien@symfony.com>
30
  */
31
+ class Twig_Node_Module extends Node
32
  {
33
  private $source;
34
 
35
+ public function __construct(Twig_NodeInterface $body, AbstractExpression $parent = null, Twig_NodeInterface $blocks, Twig_NodeInterface $macros, Twig_NodeInterface $traits, $embeddedTemplates, $name, $source = '')
36
  {
37
+ if (!$name instanceof Source) {
38
  @trigger_error(sprintf('Passing a string as the $name argument of %s() is deprecated since version 1.27. Pass a Twig_Source instance instead.', __METHOD__), E_USER_DEPRECATED);
39
+ $this->source = new Source($source, $name);
40
  } else {
41
  $this->source = $name;
42
  }
46
  'blocks' => $blocks,
47
  'macros' => $macros,
48
  'traits' => $traits,
49
+ 'display_start' => new Node(),
50
+ 'display_end' => new Node(),
51
+ 'constructor_start' => new Node(),
52
+ 'constructor_end' => new Node(),
53
+ 'class_end' => new Node(),
54
  ];
55
  if (null !== $parent) {
56
  $nodes['parent'] = $parent;
75
  $this->setAttribute('index', $index);
76
  }
77
 
78
+ public function compile(Compiler $compiler)
79
  {
80
  $this->compileTemplate($compiler);
81
 
84
  }
85
  }
86
 
87
+ protected function compileTemplate(Compiler $compiler)
88
  {
89
  if (!$this->getAttribute('index')) {
90
  $compiler->write('<?php');
93
  $this->compileClassHeader($compiler);
94
 
95
  if (
96
+ \count($this->getNode('blocks'))
97
+ || \count($this->getNode('traits'))
98
  || !$this->hasNode('parent')
99
+ || $this->getNode('parent') instanceof ConstantExpression
100
+ || \count($this->getNode('constructor_start'))
101
+ || \count($this->getNode('constructor_end'))
102
  ) {
103
  $this->compileConstructor($compiler);
104
  }
124
  $this->compileClassFooter($compiler);
125
  }
126
 
127
+ protected function compileGetParent(Compiler $compiler)
128
  {
129
  if (!$this->hasNode('parent')) {
130
  return;
138
  ->write('return ')
139
  ;
140
 
141
+ if ($parent instanceof ConstantExpression) {
142
  $compiler->subcompile($parent);
143
  } else {
144
  $compiler
159
  ;
160
  }
161
 
162
+ protected function compileClassHeader(Compiler $compiler)
163
  {
164
  $compiler
165
  ->write("\n\n")
166
+ ;
167
+ if (!$this->getAttribute('index')) {
168
+ $compiler
169
+ ->write("use Twig\Environment;\n")
170
+ ->write("use Twig\Error\LoaderError;\n")
171
+ ->write("use Twig\Error\RuntimeError;\n")
172
+ ->write("use Twig\Markup;\n")
173
+ ->write("use Twig\Sandbox\SecurityError;\n")
174
+ ->write("use Twig\Sandbox\SecurityNotAllowedTagError;\n")
175
+ ->write("use Twig\Sandbox\SecurityNotAllowedFilterError;\n")
176
+ ->write("use Twig\Sandbox\SecurityNotAllowedFunctionError;\n")
177
+ ->write("use Twig\Source;\n")
178
+ ->write("use Twig\Template;\n\n")
179
+ ;
180
+ }
181
+ $compiler
182
  // if the template name contains */, add a blank to avoid a PHP parse error
183
  ->write('/* '.str_replace('*/', '* /', $this->source->getName())." */\n")
184
  ->write('class '.$compiler->getEnvironment()->getTemplateClass($this->source->getName(), $this->getAttribute('index')))
188
  ;
189
  }
190
 
191
+ protected function compileConstructor(Compiler $compiler)
192
  {
193
  $compiler
194
+ ->write("public function __construct(Environment \$env)\n", "{\n")
195
  ->indent()
196
  ->subcompile($this->getNode('constructor_start'))
197
  ->write("parent::__construct(\$env);\n\n")
200
  // parent
201
  if (!$this->hasNode('parent')) {
202
  $compiler->write("\$this->parent = false;\n\n");
203
+ } elseif (($parent = $this->getNode('parent')) && $parent instanceof ConstantExpression) {
204
  $compiler
205
  ->addDebugInfo($parent)
206
  ->write('$this->parent = $this->loadTemplate(')
213
  ;
214
  }
215
 
216
+ $countTraits = \count($this->getNode('traits'));
217
  if ($countTraits) {
218
  // traits
219
  foreach ($this->getNode('traits') as $i => $trait) {
223
  ->addDebugInfo($trait->getNode('template'))
224
  ->write(sprintf("if (!\$_trait_%s->isTraitable()) {\n", $i))
225
  ->indent()
226
+ ->write("throw new RuntimeError('Template \"'.")
227
  ->subcompile($trait->getNode('template'))
228
  ->raw(".'\" cannot be used as a trait.');\n")
229
  ->outdent()
237
  ->string($key)
238
  ->raw("])) {\n")
239
  ->indent()
240
+ ->write("throw new RuntimeError(sprintf('Block ")
241
  ->string($key)
242
  ->raw(' is not defined in trait ')
243
  ->subcompile($trait->getNode('template'))
322
  ;
323
  }
324
 
325
+ protected function compileDisplay(Compiler $compiler)
326
  {
327
  $compiler
328
  ->write("protected function doDisplay(array \$context, array \$blocks = [])\n", "{\n")
334
  if ($this->hasNode('parent')) {
335
  $parent = $this->getNode('parent');
336
  $compiler->addDebugInfo($parent);
337
+ if ($parent instanceof ConstantExpression) {
338
  $compiler->write('$this->parent');
339
  } else {
340
  $compiler->write('$this->getParent($context)');
349
  ;
350
  }
351
 
352
+ protected function compileClassFooter(Compiler $compiler)
353
  {
354
  $compiler
355
  ->subcompile($this->getNode('class_end'))
358
  ;
359
  }
360
 
361
+ protected function compileMacros(Compiler $compiler)
362
  {
363
  $compiler->subcompile($this->getNode('macros'));
364
  }
365
 
366
+ protected function compileGetTemplateName(Compiler $compiler)
367
  {
368
  $compiler
369
  ->write("public function getTemplateName()\n", "{\n")
376
  ;
377
  }
378
 
379
+ protected function compileIsTraitable(Compiler $compiler)
380
  {
381
  // A template can be used as a trait if:
382
  // * it has no parent
385
  //
386
  // Put another way, a template can be used as a trait if it
387
  // only contains blocks and use statements.
388
+ $traitable = !$this->hasNode('parent') && 0 === \count($this->getNode('macros'));
389
  if ($traitable) {
390
+ if ($this->getNode('body') instanceof BodyNode) {
391
  $nodes = $this->getNode('body')->getNode(0);
392
  } else {
393
  $nodes = $this->getNode('body');
394
  }
395
 
396
+ if (!\count($nodes)) {
397
+ $nodes = new Node([$nodes]);
398
  }
399
 
400
  foreach ($nodes as $node) {
401
+ if (!\count($node)) {
402
  continue;
403
  }
404
 
405
+ if ($node instanceof TextNode && ctype_space($node->getAttribute('data'))) {
406
  continue;
407
  }
408
 
409
+ if ($node instanceof BlockReferenceNode) {
410
  continue;
411
  }
412
 
428
  ;
429
  }
430
 
431
+ protected function compileDebugInfo(Compiler $compiler)
432
  {
433
  $compiler
434
  ->write("public function getDebugInfo()\n", "{\n")
439
  ;
440
  }
441
 
442
+ protected function compileGetSource(Compiler $compiler)
443
  {
444
  $compiler
445
  ->write("/** @deprecated since 1.27 (to be removed in 2.0). Use getSourceContext() instead */\n")
453
  ;
454
  }
455
 
456
+ protected function compileGetSourceContext(Compiler $compiler)
457
  {
458
  $compiler
459
  ->write("public function getSourceContext()\n", "{\n")
460
  ->indent()
461
+ ->write('return new Source(')
462
  ->string($compiler->getEnvironment()->isDebug() ? $this->source->getCode() : '')
463
  ->raw(', ')
464
  ->string($this->source->getName())
470
  ;
471
  }
472
 
473
+ protected function compileLoadTemplate(Compiler $compiler, $node, $var)
474
  {
475
+ if ($node instanceof ConstantExpression) {
476
  $compiler
477
  ->write(sprintf('%s = $this->loadTemplate(', $var))
478
  ->subcompile($node)
483
  ->raw(");\n")
484
  ;
485
  } else {
486
+ throw new \LogicException('Trait templates can only be constant nodes.');
487
  }
488
  }
489
  }
vendor/twig/twig/lib/Twig/Node/Print.php CHANGED
@@ -10,19 +10,24 @@
10
  * file that was distributed with this source code.
11
  */
12
 
 
 
 
 
 
13
  /**
14
  * Represents a node that outputs an expression.
15
  *
16
  * @author Fabien Potencier <fabien@symfony.com>
17
  */
18
- class Twig_Node_Print extends Twig_Node implements Twig_NodeOutputInterface
19
  {
20
- public function __construct(Twig_Node_Expression $expr, $lineno, $tag = null)
21
  {
22
  parent::__construct(['expr' => $expr], [], $lineno, $tag);
23
  }
24
 
25
- public function compile(Twig_Compiler $compiler)
26
  {
27
  $compiler
28
  ->addDebugInfo($this)
10
  * file that was distributed with this source code.
11
  */
12
 
13
+ use Twig\Compiler;
14
+ use Twig\Node\Expression\AbstractExpression;
15
+ use Twig\Node\Node;
16
+ use Twig\Node\NodeOutputInterface;
17
+
18
  /**
19
  * Represents a node that outputs an expression.
20
  *
21
  * @author Fabien Potencier <fabien@symfony.com>
22
  */
23
+ class Twig_Node_Print extends Node implements NodeOutputInterface
24
  {
25
+ public function __construct(AbstractExpression $expr, $lineno, $tag = null)
26
  {
27
  parent::__construct(['expr' => $expr], [], $lineno, $tag);
28
  }
29
 
30
+ public function compile(Compiler $compiler)
31
  {
32
  $compiler
33
  ->addDebugInfo($this)
vendor/twig/twig/lib/Twig/Node/Sandbox.php CHANGED
@@ -9,23 +9,26 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
12
  /**
13
  * Represents a sandbox node.
14
  *
15
  * @author Fabien Potencier <fabien@symfony.com>
16
  */
17
- class Twig_Node_Sandbox extends Twig_Node
18
  {
19
  public function __construct(Twig_NodeInterface $body, $lineno, $tag = null)
20
  {
21
  parent::__construct(['body' => $body], [], $lineno, $tag);
22
  }
23
 
24
- public function compile(Twig_Compiler $compiler)
25
  {
26
  $compiler
27
  ->addDebugInfo($this)
28
- ->write("\$sandbox = \$this->env->getExtension('Twig_Extension_Sandbox');\n")
29
  ->write("if (!\$alreadySandboxed = \$sandbox->isSandboxed()) {\n")
30
  ->indent()
31
  ->write("\$sandbox->enableSandbox();\n")
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Compiler;
13
+ use Twig\Node\Node;
14
+
15
  /**
16
  * Represents a sandbox node.
17
  *
18
  * @author Fabien Potencier <fabien@symfony.com>
19
  */
20
+ class Twig_Node_Sandbox extends Node
21
  {
22
  public function __construct(Twig_NodeInterface $body, $lineno, $tag = null)
23
  {
24
  parent::__construct(['body' => $body], [], $lineno, $tag);
25
  }
26
 
27
+ public function compile(Compiler $compiler)
28
  {
29
  $compiler
30
  ->addDebugInfo($this)
31
+ ->write("\$sandbox = \$this->env->getExtension('\Twig\Extension\SandboxExtension');\n")
32
  ->write("if (!\$alreadySandboxed = \$sandbox->isSandboxed()) {\n")
33
  ->indent()
34
  ->write("\$sandbox->enableSandbox();\n")
vendor/twig/twig/lib/Twig/Node/SandboxedPrint.php CHANGED
@@ -9,6 +9,11 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
 
12
  /**
13
  * Twig_Node_SandboxedPrint adds a check for the __toString() method
14
  * when the variable is an object and the sandbox is activated.
@@ -19,13 +24,13 @@
19
  *
20
  * @author Fabien Potencier <fabien@symfony.com>
21
  */
22
- class Twig_Node_SandboxedPrint extends Twig_Node_Print
23
  {
24
- public function compile(Twig_Compiler $compiler)
25
  {
26
  $compiler
27
  ->addDebugInfo($this)
28
- ->write('echo $this->env->getExtension(\'Twig_Extension_Sandbox\')->ensureToStringAllowed(')
29
  ->subcompile($this->getNode('expr'))
30
  ->raw(");\n")
31
  ;
@@ -36,11 +41,11 @@ class Twig_Node_SandboxedPrint extends Twig_Node_Print
36
  *
37
  * This is mostly needed when another visitor adds filters (like the escaper one).
38
  *
39
- * @return Twig_Node
40
  */
41
- protected function removeNodeFilter(Twig_Node $node)
42
  {
43
- if ($node instanceof Twig_Node_Expression_Filter) {
44
  return $this->removeNodeFilter($node->getNode('node'));
45
  }
46
 
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\FilterExpression;
14
+ use Twig\Node\Node;
15
+ use Twig\Node\PrintNode;
16
+
17
  /**
18
  * Twig_Node_SandboxedPrint adds a check for the __toString() method
19
  * when the variable is an object and the sandbox is activated.
24
  *
25
  * @author Fabien Potencier <fabien@symfony.com>
26
  */
27
+ class Twig_Node_SandboxedPrint extends PrintNode
28
  {
29
+ public function compile(Compiler $compiler)
30
  {
31
  $compiler
32
  ->addDebugInfo($this)
33
+ ->write('echo $this->env->getExtension(\'\Twig\Extension\SandboxExtension\')->ensureToStringAllowed(')
34
  ->subcompile($this->getNode('expr'))
35
  ->raw(");\n")
36
  ;
41
  *
42
  * This is mostly needed when another visitor adds filters (like the escaper one).
43
  *
44
+ * @return Node
45
  */
46
+ protected function removeNodeFilter(Node $node)
47
  {
48
+ if ($node instanceof FilterExpression) {
49
  return $this->removeNodeFilter($node->getNode('node'));
50
  }
51
 
vendor/twig/twig/lib/Twig/Node/Set.php CHANGED
@@ -9,12 +9,18 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
 
 
12
  /**
13
  * Represents a set node.
14
  *
15
  * @author Fabien Potencier <fabien@symfony.com>
16
  */
17
- class Twig_Node_Set extends Twig_Node implements Twig_NodeCaptureInterface
18
  {
19
  public function __construct($capture, Twig_NodeInterface $names, Twig_NodeInterface $values, $lineno, $tag = null)
20
  {
@@ -23,24 +29,24 @@ class Twig_Node_Set extends Twig_Node implements Twig_NodeCaptureInterface
23
  /*
24
  * Optimizes the node when capture is used for a large block of text.
25
  *
26
- * {% set foo %}foo{% endset %} is compiled to $context['foo'] = new Twig_Markup("foo");
27
  */
28
  if ($this->getAttribute('capture')) {
29
  $this->setAttribute('safe', true);
30
 
31
  $values = $this->getNode('values');
32
- if ($values instanceof Twig_Node_Text) {
33
- $this->setNode('values', new Twig_Node_Expression_Constant($values->getAttribute('data'), $values->getTemplateLine()));
34
  $this->setAttribute('capture', false);
35
  }
36
  }
37
  }
38
 
39
- public function compile(Twig_Compiler $compiler)
40
  {
41
  $compiler->addDebugInfo($this);
42
 
43
- if (count($this->getNode('names')) > 1) {
44
  $compiler->write('list(');
45
  foreach ($this->getNode('names') as $idx => $node) {
46
  if ($idx) {
@@ -61,14 +67,14 @@ class Twig_Node_Set extends Twig_Node implements Twig_NodeCaptureInterface
61
  $compiler->subcompile($this->getNode('names'), false);
62
 
63
  if ($this->getAttribute('capture')) {
64
- $compiler->raw(" = ('' === \$tmp = ob_get_clean()) ? '' : new Twig_Markup(\$tmp, \$this->env->getCharset())");
65
  }
66
  }
67
 
68
  if (!$this->getAttribute('capture')) {
69
  $compiler->raw(' = ');
70
 
71
- if (count($this->getNode('names')) > 1) {
72
  $compiler->write('[');
73
  foreach ($this->getNode('values') as $idx => $value) {
74
  if ($idx) {
@@ -83,7 +89,7 @@ class Twig_Node_Set extends Twig_Node implements Twig_NodeCaptureInterface
83
  $compiler
84
  ->raw("('' === \$tmp = ")
85
  ->subcompile($this->getNode('values'))
86
- ->raw(") ? '' : new Twig_Markup(\$tmp, \$this->env->getCharset())")
87
  ;
88
  } else {
89
  $compiler->subcompile($this->getNode('values'));
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Compiler;
13
+ use Twig\Node\Expression\ConstantExpression;
14
+ use Twig\Node\Node;
15
+ use Twig\Node\NodeCaptureInterface;
16
+ use Twig\Node\TextNode;
17
+
18
  /**
19
  * Represents a set node.
20
  *
21
  * @author Fabien Potencier <fabien@symfony.com>
22
  */
23
+ class Twig_Node_Set extends Node implements NodeCaptureInterface
24
  {
25
  public function __construct($capture, Twig_NodeInterface $names, Twig_NodeInterface $values, $lineno, $tag = null)
26
  {
29
  /*
30
  * Optimizes the node when capture is used for a large block of text.
31
  *
32
+ * {% set foo %}foo{% endset %} is compiled to $context['foo'] = new Twig\Markup("foo");
33
  */
34
  if ($this->getAttribute('capture')) {
35
  $this->setAttribute('safe', true);
36
 
37
  $values = $this->getNode('values');
38
+ if ($values instanceof TextNode) {
39
+ $this->setNode('values', new ConstantExpression($values->getAttribute('data'), $values->getTemplateLine()));
40
  $this->setAttribute('capture', false);
41
  }
42
  }
43
  }
44
 
45
+ public function compile(Compiler $compiler)
46
  {
47
  $compiler->addDebugInfo($this);
48
 
49
+ if (\count($this->getNode('names')) > 1) {
50
  $compiler->write('list(');
51
  foreach ($this->getNode('names') as $idx => $node) {
52
  if ($idx) {
67
  $compiler->subcompile($this->getNode('names'), false);
68
 
69
  if ($this->getAttribute('capture')) {
70
+ $compiler->raw(" = ('' === \$tmp = ob_get_clean()) ? '' : new Markup(\$tmp, \$this->env->getCharset())");
71
  }
72
  }
73
 
74
  if (!$this->getAttribute('capture')) {
75
  $compiler->raw(' = ');
76
 
77
+ if (\count($this->getNode('names')) > 1) {
78
  $compiler->write('[');
79
  foreach ($this->getNode('values') as $idx => $value) {
80
  if ($idx) {
89
  $compiler
90
  ->raw("('' === \$tmp = ")
91
  ->subcompile($this->getNode('values'))
92
+ ->raw(") ? '' : new Markup(\$tmp, \$this->env->getCharset())")
93
  ;
94
  } else {
95
  $compiler->subcompile($this->getNode('values'));
vendor/twig/twig/lib/Twig/Node/SetTemp.php CHANGED
@@ -9,17 +9,20 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
12
  /**
13
  * @internal
14
  */
15
- class Twig_Node_SetTemp extends Twig_Node
16
  {
17
  public function __construct($name, $lineno)
18
  {
19
  parent::__construct([], ['name' => $name], $lineno);
20
  }
21
 
22
- public function compile(Twig_Compiler $compiler)
23
  {
24
  $name = $this->getAttribute('name');
25
  $compiler
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Compiler;
13
+ use Twig\Node\Node;
14
+
15
  /**
16
  * @internal
17
  */
18
+ class Twig_Node_SetTemp extends Node
19
  {
20
  public function __construct($name, $lineno)
21
  {
22
  parent::__construct([], ['name' => $name], $lineno);
23
  }
24
 
25
+ public function compile(Compiler $compiler)
26
  {
27
  $name = $this->getAttribute('name');
28
  $compiler
vendor/twig/twig/lib/Twig/Node/Spaceless.php CHANGED
@@ -9,6 +9,9 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
12
  /**
13
  * Represents a spaceless node.
14
  *
@@ -16,14 +19,14 @@
16
  *
17
  * @author Fabien Potencier <fabien@symfony.com>
18
  */
19
- class Twig_Node_Spaceless extends Twig_Node
20
  {
21
  public function __construct(Twig_NodeInterface $body, $lineno, $tag = 'spaceless')
22
  {
23
  parent::__construct(['body' => $body], [], $lineno, $tag);
24
  }
25
 
26
- public function compile(Twig_Compiler $compiler)
27
  {
28
  $compiler
29
  ->addDebugInfo($this)
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Compiler;
13
+ use Twig\Node\Node;
14
+
15
  /**
16
  * Represents a spaceless node.
17
  *
19
  *
20
  * @author Fabien Potencier <fabien@symfony.com>
21
  */
22
+ class Twig_Node_Spaceless extends Node
23
  {
24
  public function __construct(Twig_NodeInterface $body, $lineno, $tag = 'spaceless')
25
  {
26
  parent::__construct(['body' => $body], [], $lineno, $tag);
27
  }
28
 
29
+ public function compile(Compiler $compiler)
30
  {
31
  $compiler
32
  ->addDebugInfo($this)
vendor/twig/twig/lib/Twig/Node/Text.php CHANGED
@@ -10,19 +10,23 @@
10
  * file that was distributed with this source code.
11
  */
12
 
 
 
 
 
13
  /**
14
  * Represents a text node.
15
  *
16
  * @author Fabien Potencier <fabien@symfony.com>
17
  */
18
- class Twig_Node_Text extends Twig_Node implements Twig_NodeOutputInterface
19
  {
20
  public function __construct($data, $lineno)
21
  {
22
  parent::__construct([], ['data' => $data], $lineno);
23
  }
24
 
25
- public function compile(Twig_Compiler $compiler)
26
  {
27
  $compiler
28
  ->addDebugInfo($this)
10
  * file that was distributed with this source code.
11
  */
12
 
13
+ use Twig\Compiler;
14
+ use Twig\Node\Node;
15
+ use Twig\Node\NodeOutputInterface;
16
+
17
  /**
18
  * Represents a text node.
19
  *
20
  * @author Fabien Potencier <fabien@symfony.com>
21
  */
22
+ class Twig_Node_Text extends Node implements NodeOutputInterface
23
  {
24
  public function __construct($data, $lineno)
25
  {
26
  parent::__construct([], ['data' => $data], $lineno);
27
  }
28
 
29
+ public function compile(Compiler $compiler)
30
  {
31
  $compiler
32
  ->addDebugInfo($this)
vendor/twig/twig/lib/Twig/Node/With.php CHANGED
@@ -9,14 +9,17 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
12
  /**
13
  * Represents a nested "with" scope.
14
  *
15
  * @author Fabien Potencier <fabien@symfony.com>
16
  */
17
- class Twig_Node_With extends Twig_Node
18
  {
19
- public function __construct(Twig_Node $body, Twig_Node $variables = null, $only = false, $lineno, $tag = null)
20
  {
21
  $nodes = ['body' => $body];
22
  if (null !== $variables) {
@@ -26,7 +29,7 @@ class Twig_Node_With extends Twig_Node
26
  parent::__construct($nodes, ['only' => (bool) $only], $lineno, $tag);
27
  }
28
 
29
- public function compile(Twig_Compiler $compiler)
30
  {
31
  $compiler->addDebugInfo($this);
32
 
@@ -38,7 +41,7 @@ class Twig_Node_With extends Twig_Node
38
  ->raw(";\n")
39
  ->write(sprintf("if (!is_array(\$%s)) {\n", $varsName))
40
  ->indent()
41
- ->write("throw new Twig_Error_Runtime('Variables passed to the \"with\" tag must be a hash.');\n")
42
  ->outdent()
43
  ->write("}\n")
44
  ;
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Compiler;
13
+ use Twig\Node\Node;
14
+
15
  /**
16
  * Represents a nested "with" scope.
17
  *
18
  * @author Fabien Potencier <fabien@symfony.com>
19
  */
20
+ class Twig_Node_With extends Node
21
  {
22
+ public function __construct(Node $body, Node $variables = null, $only = false, $lineno, $tag = null)
23
  {
24
  $nodes = ['body' => $body];
25
  if (null !== $variables) {
29
  parent::__construct($nodes, ['only' => (bool) $only], $lineno, $tag);
30
  }
31
 
32
+ public function compile(Compiler $compiler)
33
  {
34
  $compiler->addDebugInfo($this);
35
 
41
  ->raw(";\n")
42
  ->write(sprintf("if (!is_array(\$%s)) {\n", $varsName))
43
  ->indent()
44
+ ->write("throw new RuntimeError('Variables passed to the \"with\" tag must be a hash.');\n")
45
  ->outdent()
46
  ->write("}\n")
47
  ;
vendor/twig/twig/lib/Twig/NodeInterface.php CHANGED
@@ -9,6 +9,8 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
12
  /**
13
  * Represents a node in the AST.
14
  *
@@ -16,12 +18,12 @@
16
  *
17
  * @deprecated since 1.12 (to be removed in 3.0)
18
  */
19
- interface Twig_NodeInterface extends Countable, IteratorAggregate
20
  {
21
  /**
22
  * Compiles the node to PHP.
23
  */
24
- public function compile(Twig_Compiler $compiler);
25
 
26
  /**
27
  * @deprecated since 1.27 (to be removed in 2.0)
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Compiler;
13
+
14
  /**
15
  * Represents a node in the AST.
16
  *
18
  *
19
  * @deprecated since 1.12 (to be removed in 3.0)
20
  */
21
+ interface Twig_NodeInterface extends \Countable, \IteratorAggregate
22
  {
23
  /**
24
  * Compiles the node to PHP.
25
  */
26
+ public function compile(Compiler $compiler);
27
 
28
  /**
29
  * @deprecated since 1.27 (to be removed in 2.0)
vendor/twig/twig/lib/Twig/NodeTraverser.php CHANGED
@@ -9,6 +9,9 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
12
  /**
13
  * Twig_NodeTraverser is a node traverser.
14
  *
@@ -24,10 +27,9 @@ class Twig_NodeTraverser
24
  protected $visitors = [];
25
 
26
  /**
27
- * @param Twig_Environment $env
28
- * @param Twig_NodeVisitorInterface[] $visitors
29
  */
30
- public function __construct(Twig_Environment $env, array $visitors = [])
31
  {
32
  $this->env = $env;
33
  foreach ($visitors as $visitor) {
@@ -35,7 +37,7 @@ class Twig_NodeTraverser
35
  }
36
  }
37
 
38
- public function addVisitor(Twig_NodeVisitorInterface $visitor)
39
  {
40
  if (!isset($this->visitors[$visitor->getPriority()])) {
41
  $this->visitors[$visitor->getPriority()] = [];
@@ -61,7 +63,7 @@ class Twig_NodeTraverser
61
  return $node;
62
  }
63
 
64
- protected function traverseForVisitor(Twig_NodeVisitorInterface $visitor, Twig_NodeInterface $node = null)
65
  {
66
  if (null === $node) {
67
  return;
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Environment;
13
+ use Twig\NodeVisitor\NodeVisitorInterface;
14
+
15
  /**
16
  * Twig_NodeTraverser is a node traverser.
17
  *
27
  protected $visitors = [];
28
 
29
  /**
30
+ * @param NodeVisitorInterface[] $visitors
 
31
  */
32
+ public function __construct(Environment $env, array $visitors = [])
33
  {
34
  $this->env = $env;
35
  foreach ($visitors as $visitor) {
37
  }
38
  }
39
 
40
+ public function addVisitor(NodeVisitorInterface $visitor)
41
  {
42
  if (!isset($this->visitors[$visitor->getPriority()])) {
43
  $this->visitors[$visitor->getPriority()] = [];
63
  return $node;
64
  }
65
 
66
+ protected function traverseForVisitor(NodeVisitorInterface $visitor, Twig_NodeInterface $node = null)
67
  {
68
  if (null === $node) {
69
  return;
vendor/twig/twig/lib/Twig/NodeVisitor/Escaper.php CHANGED
@@ -9,6 +9,20 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  /**
13
  * Twig_NodeVisitor_Escaper implements output escaping.
14
  *
@@ -16,7 +30,7 @@
16
  *
17
  * @author Fabien Potencier <fabien@symfony.com>
18
  */
19
- class Twig_NodeVisitor_Escaper extends Twig_BaseNodeVisitor
20
  {
21
  protected $statusStack = [];
22
  protected $blocks = [];
@@ -27,50 +41,50 @@ class Twig_NodeVisitor_Escaper extends Twig_BaseNodeVisitor
27
 
28
  public function __construct()
29
  {
30
- $this->safeAnalysis = new Twig_NodeVisitor_SafeAnalysis();
31
  }
32
 
33
- protected function doEnterNode(Twig_Node $node, Twig_Environment $env)
34
  {
35
- if ($node instanceof Twig_Node_Module) {
36
- if ($env->hasExtension('Twig_Extension_Escaper') && $defaultStrategy = $env->getExtension('Twig_Extension_Escaper')->getDefaultStrategy($node->getTemplateName())) {
37
  $this->defaultStrategy = $defaultStrategy;
38
  }
39
  $this->safeVars = [];
40
  $this->blocks = [];
41
- } elseif ($node instanceof Twig_Node_AutoEscape) {
42
  $this->statusStack[] = $node->getAttribute('value');
43
- } elseif ($node instanceof Twig_Node_Block) {
44
  $this->statusStack[] = isset($this->blocks[$node->getAttribute('name')]) ? $this->blocks[$node->getAttribute('name')] : $this->needEscaping($env);
45
- } elseif ($node instanceof Twig_Node_Import) {
46
  $this->safeVars[] = $node->getNode('var')->getAttribute('name');
47
  }
48
 
49
  return $node;
50
  }
51
 
52
- protected function doLeaveNode(Twig_Node $node, Twig_Environment $env)
53
  {
54
- if ($node instanceof Twig_Node_Module) {
55
  $this->defaultStrategy = false;
56
  $this->safeVars = [];
57
  $this->blocks = [];
58
- } elseif ($node instanceof Twig_Node_Expression_Filter) {
59
  return $this->preEscapeFilterNode($node, $env);
60
- } elseif ($node instanceof Twig_Node_Print) {
61
  return $this->escapePrintNode($node, $env, $this->needEscaping($env));
62
  }
63
 
64
- if ($node instanceof Twig_Node_AutoEscape || $node instanceof Twig_Node_Block) {
65
  array_pop($this->statusStack);
66
- } elseif ($node instanceof Twig_Node_BlockReference) {
67
  $this->blocks[$node->getAttribute('name')] = $this->needEscaping($env);
68
  }
69
 
70
  return $node;
71
  }
72
 
73
- protected function escapePrintNode(Twig_Node_Print $node, Twig_Environment $env, $type)
74
  {
75
  if (false === $type) {
76
  return $node;
@@ -82,7 +96,7 @@ class Twig_NodeVisitor_Escaper extends Twig_BaseNodeVisitor
82
  return $node;
83
  }
84
 
85
- $class = get_class($node);
86
 
87
  return new $class(
88
  $this->getEscaperFilter($type, $expression),
@@ -90,7 +104,7 @@ class Twig_NodeVisitor_Escaper extends Twig_BaseNodeVisitor
90
  );
91
  }
92
 
93
- protected function preEscapeFilterNode(Twig_Node_Expression_Filter $filter, Twig_Environment $env)
94
  {
95
  $name = $filter->getNode('filter')->getAttribute('value');
96
 
@@ -115,7 +129,7 @@ class Twig_NodeVisitor_Escaper extends Twig_BaseNodeVisitor
115
 
116
  if (null === $safe) {
117
  if (null === $this->traverser) {
118
- $this->traverser = new Twig_NodeTraverser($env, [$this->safeAnalysis]);
119
  }
120
 
121
  $this->safeAnalysis->setSafeVars($this->safeVars);
@@ -124,13 +138,13 @@ class Twig_NodeVisitor_Escaper extends Twig_BaseNodeVisitor
124
  $safe = $this->safeAnalysis->getSafe($expression);
125
  }
126
 
127
- return in_array($type, $safe) || in_array('all', $safe);
128
  }
129
 
130
- protected function needEscaping(Twig_Environment $env)
131
  {
132
- if (count($this->statusStack)) {
133
- return $this->statusStack[count($this->statusStack) - 1];
134
  }
135
 
136
  return $this->defaultStrategy ? $this->defaultStrategy : false;
@@ -139,10 +153,10 @@ class Twig_NodeVisitor_Escaper extends Twig_BaseNodeVisitor
139
  protected function getEscaperFilter($type, Twig_NodeInterface $node)
140
  {
141
  $line = $node->getTemplateLine();
142
- $name = new Twig_Node_Expression_Constant('escape', $line);
143
- $args = new Twig_Node([new Twig_Node_Expression_Constant((string) $type, $line), new Twig_Node_Expression_Constant(null, $line), new Twig_Node_Expression_Constant(true, $line)]);
144
 
145
- return new Twig_Node_Expression_Filter($node, $name, $args, $line);
146
  }
147
 
148
  public function getPriority()
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Environment;
13
+ use Twig\Node\AutoEscapeNode;
14
+ use Twig\Node\BlockNode;
15
+ use Twig\Node\BlockReferenceNode;
16
+ use Twig\Node\Expression\ConstantExpression;
17
+ use Twig\Node\Expression\FilterExpression;
18
+ use Twig\Node\ImportNode;
19
+ use Twig\Node\ModuleNode;
20
+ use Twig\Node\Node;
21
+ use Twig\Node\PrintNode;
22
+ use Twig\NodeTraverser;
23
+ use Twig\NodeVisitor\AbstractNodeVisitor;
24
+ use Twig\NodeVisitor\SafeAnalysisNodeVisitor;
25
+
26
  /**
27
  * Twig_NodeVisitor_Escaper implements output escaping.
28
  *
30
  *
31
  * @author Fabien Potencier <fabien@symfony.com>
32
  */
33
+ class Twig_NodeVisitor_Escaper extends AbstractNodeVisitor
34
  {
35
  protected $statusStack = [];
36
  protected $blocks = [];
41
 
42
  public function __construct()
43
  {
44
+ $this->safeAnalysis = new SafeAnalysisNodeVisitor();
45
  }
46
 
47
+ protected function doEnterNode(Node $node, Environment $env)
48
  {
49
+ if ($node instanceof ModuleNode) {
50
+ if ($env->hasExtension('\Twig\Extension\EscaperExtension') && $defaultStrategy = $env->getExtension('\Twig\Extension\EscaperExtension')->getDefaultStrategy($node->getTemplateName())) {
51
  $this->defaultStrategy = $defaultStrategy;
52
  }
53
  $this->safeVars = [];
54
  $this->blocks = [];
55
+ } elseif ($node instanceof AutoEscapeNode) {
56
  $this->statusStack[] = $node->getAttribute('value');
57
+ } elseif ($node instanceof BlockNode) {
58
  $this->statusStack[] = isset($this->blocks[$node->getAttribute('name')]) ? $this->blocks[$node->getAttribute('name')] : $this->needEscaping($env);
59
+ } elseif ($node instanceof ImportNode) {
60
  $this->safeVars[] = $node->getNode('var')->getAttribute('name');
61
  }
62
 
63
  return $node;
64
  }
65
 
66
+ protected function doLeaveNode(Node $node, Environment $env)
67
  {
68
+ if ($node instanceof ModuleNode) {
69
  $this->defaultStrategy = false;
70
  $this->safeVars = [];
71
  $this->blocks = [];
72
+ } elseif ($node instanceof FilterExpression) {
73
  return $this->preEscapeFilterNode($node, $env);
74
+ } elseif ($node instanceof PrintNode) {
75
  return $this->escapePrintNode($node, $env, $this->needEscaping($env));
76
  }
77
 
78
+ if ($node instanceof AutoEscapeNode || $node instanceof BlockNode) {
79
  array_pop($this->statusStack);
80
+ } elseif ($node instanceof BlockReferenceNode) {
81
  $this->blocks[$node->getAttribute('name')] = $this->needEscaping($env);
82
  }
83
 
84
  return $node;
85
  }
86
 
87
+ protected function escapePrintNode(PrintNode $node, Environment $env, $type)
88
  {
89
  if (false === $type) {
90
  return $node;
96
  return $node;
97
  }
98
 
99
+ $class = \get_class($node);
100
 
101
  return new $class(
102
  $this->getEscaperFilter($type, $expression),
104
  );
105
  }
106
 
107
+ protected function preEscapeFilterNode(FilterExpression $filter, Environment $env)
108
  {
109
  $name = $filter->getNode('filter')->getAttribute('value');
110
 
129
 
130
  if (null === $safe) {
131
  if (null === $this->traverser) {
132
+ $this->traverser = new NodeTraverser($env, [$this->safeAnalysis]);
133
  }
134
 
135
  $this->safeAnalysis->setSafeVars($this->safeVars);
138
  $safe = $this->safeAnalysis->getSafe($expression);
139
  }
140
 
141
+ return \in_array($type, $safe) || \in_array('all', $safe);
142
  }
143
 
144
+ protected function needEscaping(Environment $env)
145
  {
146
+ if (\count($this->statusStack)) {
147
+ return $this->statusStack[\count($this->statusStack) - 1];
148
  }
149
 
150
  return $this->defaultStrategy ? $this->defaultStrategy : false;
153
  protected function getEscaperFilter($type, Twig_NodeInterface $node)
154
  {
155
  $line = $node->getTemplateLine();
156
+ $name = new ConstantExpression('escape', $line);
157
+ $args = new Node([new ConstantExpression((string) $type, $line), new ConstantExpression(null, $line), new ConstantExpression(true, $line)]);
158
 
159
+ return new FilterExpression($node, $name, $args, $line);
160
  }
161
 
162
  public function getPriority()
vendor/twig/twig/lib/Twig/NodeVisitor/Optimizer.php CHANGED
@@ -9,6 +9,25 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  /**
13
  * Twig_NodeVisitor_Optimizer tries to optimizes the AST.
14
  *
@@ -21,7 +40,7 @@
21
  *
22
  * @author Fabien Potencier <fabien@symfony.com>
23
  */
24
- class Twig_NodeVisitor_Optimizer extends Twig_BaseNodeVisitor
25
  {
26
  const OPTIMIZE_ALL = -1;
27
  const OPTIMIZE_NONE = 0;
@@ -40,29 +59,29 @@ class Twig_NodeVisitor_Optimizer extends Twig_BaseNodeVisitor
40
  */
41
  public function __construct($optimizers = -1)
42
  {
43
- if (!is_int($optimizers) || $optimizers > (self::OPTIMIZE_FOR | self::OPTIMIZE_RAW_FILTER | self::OPTIMIZE_VAR_ACCESS)) {
44
- throw new InvalidArgumentException(sprintf('Optimizer mode "%s" is not valid.', $optimizers));
45
  }
46
 
47
  $this->optimizers = $optimizers;
48
  }
49
 
50
- protected function doEnterNode(Twig_Node $node, Twig_Environment $env)
51
  {
52
  if (self::OPTIMIZE_FOR === (self::OPTIMIZE_FOR & $this->optimizers)) {
53
  $this->enterOptimizeFor($node, $env);
54
  }
55
 
56
- if (PHP_VERSION_ID < 50400 && self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('Twig_Extension_Sandbox')) {
57
  if ($this->inABody) {
58
- if (!$node instanceof Twig_Node_Expression) {
59
- if ('Twig_Node' !== get_class($node)) {
60
  array_unshift($this->prependedNodes, []);
61
  }
62
  } else {
63
  $node = $this->optimizeVariables($node, $env);
64
  }
65
- } elseif ($node instanceof Twig_Node_Body) {
66
  $this->inABody = true;
67
  }
68
  }
@@ -70,9 +89,9 @@ class Twig_NodeVisitor_Optimizer extends Twig_BaseNodeVisitor
70
  return $node;
71
  }
72
 
73
- protected function doLeaveNode(Twig_Node $node, Twig_Environment $env)
74
  {
75
- $expression = $node instanceof Twig_Node_Expression;
76
 
77
  if (self::OPTIMIZE_FOR === (self::OPTIMIZE_FOR & $this->optimizers)) {
78
  $this->leaveOptimizeFor($node, $env);
@@ -84,18 +103,18 @@ class Twig_NodeVisitor_Optimizer extends Twig_BaseNodeVisitor
84
 
85
  $node = $this->optimizePrintNode($node, $env);
86
 
87
- if (self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('Twig_Extension_Sandbox')) {
88
- if ($node instanceof Twig_Node_Body) {
89
  $this->inABody = false;
90
  } elseif ($this->inABody) {
91
- if (!$expression && 'Twig_Node' !== get_class($node) && $prependedNodes = array_shift($this->prependedNodes)) {
92
  $nodes = [];
93
  foreach (array_unique($prependedNodes) as $name) {
94
- $nodes[] = new Twig_Node_SetTemp($name, $node->getTemplateLine());
95
  }
96
 
97
  $nodes[] = $node;
98
- $node = new Twig_Node($nodes);
99
  }
100
  }
101
  }
@@ -103,12 +122,12 @@ class Twig_NodeVisitor_Optimizer extends Twig_BaseNodeVisitor
103
  return $node;
104
  }
105
 
106
- protected function optimizeVariables(Twig_NodeInterface $node, Twig_Environment $env)
107
  {
108
- if ('Twig_Node_Expression_Name' === get_class($node) && $node->isSimple()) {
109
  $this->prependedNodes[0][] = $node->getAttribute('name');
110
 
111
- return new Twig_Node_Expression_TempName($node->getAttribute('name'), $node->getTemplateLine());
112
  }
113
 
114
  return $node;
@@ -123,16 +142,16 @@ class Twig_NodeVisitor_Optimizer extends Twig_BaseNodeVisitor
123
  *
124
  * @return Twig_NodeInterface
125
  */
126
- protected function optimizePrintNode(Twig_NodeInterface $node, Twig_Environment $env)
127
  {
128
- if (!$node instanceof Twig_Node_Print) {
129
  return $node;
130
  }
131
 
132
  $exprNode = $node->getNode('expr');
133
  if (
134
- $exprNode instanceof Twig_Node_Expression_BlockReference ||
135
- $exprNode instanceof Twig_Node_Expression_Parent
136
  ) {
137
  $exprNode->setAttribute('output', true);
138
 
@@ -147,9 +166,9 @@ class Twig_NodeVisitor_Optimizer extends Twig_BaseNodeVisitor
147
  *
148
  * @return Twig_NodeInterface
149
  */
150
- protected function optimizeRawFilter(Twig_NodeInterface $node, Twig_Environment $env)
151
  {
152
- if ($node instanceof Twig_Node_Expression_Filter && 'raw' == $node->getNode('filter')->getAttribute('value')) {
153
  return $node->getNode('node');
154
  }
155
 
@@ -159,9 +178,9 @@ class Twig_NodeVisitor_Optimizer extends Twig_BaseNodeVisitor
159
  /**
160
  * Optimizes "for" tag by removing the "loop" variable creation whenever possible.
161
  */
162
- protected function enterOptimizeFor(Twig_NodeInterface $node, Twig_Environment $env)
163
  {
164
- if ($node instanceof Twig_Node_For) {
165
  // disable the loop variable by default
166
  $node->setAttribute('with_loop', false);
167
  array_unshift($this->loops, $node);
@@ -175,28 +194,28 @@ class Twig_NodeVisitor_Optimizer extends Twig_BaseNodeVisitor
175
  // when do we need to add the loop variable back?
176
 
177
  // the loop variable is referenced for the current loop
178
- elseif ($node instanceof Twig_Node_Expression_Name && 'loop' === $node->getAttribute('name')) {
179
  $node->setAttribute('always_defined', true);
180
  $this->addLoopToCurrent();
181
  }
182
 
183
  // optimize access to loop targets
184
- elseif ($node instanceof Twig_Node_Expression_Name && in_array($node->getAttribute('name'), $this->loopsTargets)) {
185
  $node->setAttribute('always_defined', true);
186
  }
187
 
188
  // block reference
189
- elseif ($node instanceof Twig_Node_BlockReference || $node instanceof Twig_Node_Expression_BlockReference) {
190
  $this->addLoopToCurrent();
191
  }
192
 
193
  // include without the only attribute
194
- elseif ($node instanceof Twig_Node_Include && !$node->getAttribute('only')) {
195
  $this->addLoopToAll();
196
  }
197
 
198
  // include function without the with_context=false parameter
199
- elseif ($node instanceof Twig_Node_Expression_Function
200
  && 'include' === $node->getAttribute('name')
201
  && (!$node->getNode('arguments')->hasNode('with_context')
202
  || false !== $node->getNode('arguments')->getNode('with_context')->getAttribute('value')
@@ -206,12 +225,12 @@ class Twig_NodeVisitor_Optimizer extends Twig_BaseNodeVisitor
206
  }
207
 
208
  // the loop variable is referenced via an attribute
209
- elseif ($node instanceof Twig_Node_Expression_GetAttr
210
- && (!$node->getNode('attribute') instanceof Twig_Node_Expression_Constant
211
  || 'parent' === $node->getNode('attribute')->getAttribute('value')
212
  )
213
  && (true === $this->loops[0]->getAttribute('with_loop')
214
- || ($node->getNode('node') instanceof Twig_Node_Expression_Name
215
  && 'loop' === $node->getNode('node')->getAttribute('name')
216
  )
217
  )
@@ -223,9 +242,9 @@ class Twig_NodeVisitor_Optimizer extends Twig_BaseNodeVisitor
223
  /**
224
  * Optimizes "for" tag by removing the "loop" variable creation whenever possible.
225
  */
226
- protected function leaveOptimizeFor(Twig_NodeInterface $node, Twig_Environment $env)
227
  {
228
- if ($node instanceof Twig_Node_For) {
229
  array_shift($this->loops);
230
  array_shift($this->loopsTargets);
231
  array_shift($this->loopsTargets);
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Environment;
13
+ use Twig\Node\BlockReferenceNode;
14
+ use Twig\Node\BodyNode;
15
+ use Twig\Node\Expression\AbstractExpression;
16
+ use Twig\Node\Expression\BlockReferenceExpression;
17
+ use Twig\Node\Expression\ConstantExpression;
18
+ use Twig\Node\Expression\FilterExpression;
19
+ use Twig\Node\Expression\FunctionExpression;
20
+ use Twig\Node\Expression\GetAttrExpression;
21
+ use Twig\Node\Expression\NameExpression;
22
+ use Twig\Node\Expression\ParentExpression;
23
+ use Twig\Node\Expression\TempNameExpression;
24
+ use Twig\Node\ForNode;
25
+ use Twig\Node\IncludeNode;
26
+ use Twig\Node\Node;
27
+ use Twig\Node\PrintNode;
28
+ use Twig\Node\SetTempNode;
29
+ use Twig\NodeVisitor\AbstractNodeVisitor;
30
+
31
  /**
32
  * Twig_NodeVisitor_Optimizer tries to optimizes the AST.
33
  *
40
  *
41
  * @author Fabien Potencier <fabien@symfony.com>
42
  */
43
+ class Twig_NodeVisitor_Optimizer extends AbstractNodeVisitor
44
  {
45
  const OPTIMIZE_ALL = -1;
46
  const OPTIMIZE_NONE = 0;
59
  */
60
  public function __construct($optimizers = -1)
61
  {
62
+ if (!\is_int($optimizers) || $optimizers > (self::OPTIMIZE_FOR | self::OPTIMIZE_RAW_FILTER | self::OPTIMIZE_VAR_ACCESS)) {
63
+ throw new \InvalidArgumentException(sprintf('Optimizer mode "%s" is not valid.', $optimizers));
64
  }
65
 
66
  $this->optimizers = $optimizers;
67
  }
68
 
69
+ protected function doEnterNode(Node $node, Environment $env)
70
  {
71
  if (self::OPTIMIZE_FOR === (self::OPTIMIZE_FOR & $this->optimizers)) {
72
  $this->enterOptimizeFor($node, $env);
73
  }
74
 
75
+ if (PHP_VERSION_ID < 50400 && self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('\Twig\Extension\SandboxExtension')) {
76
  if ($this->inABody) {
77
+ if (!$node instanceof AbstractExpression) {
78
+ if ('Twig_Node' !== \get_class($node)) {
79
  array_unshift($this->prependedNodes, []);
80
  }
81
  } else {
82
  $node = $this->optimizeVariables($node, $env);
83
  }
84
+ } elseif ($node instanceof BodyNode) {
85
  $this->inABody = true;
86
  }
87
  }
89
  return $node;
90
  }
91
 
92
+ protected function doLeaveNode(Node $node, Environment $env)
93
  {
94
+ $expression = $node instanceof AbstractExpression;
95
 
96
  if (self::OPTIMIZE_FOR === (self::OPTIMIZE_FOR & $this->optimizers)) {
97
  $this->leaveOptimizeFor($node, $env);
103
 
104
  $node = $this->optimizePrintNode($node, $env);
105
 
106
+ if (self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('\Twig\Extension\SandboxExtension')) {
107
+ if ($node instanceof BodyNode) {
108
  $this->inABody = false;
109
  } elseif ($this->inABody) {
110
+ if (!$expression && 'Twig_Node' !== \get_class($node) && $prependedNodes = array_shift($this->prependedNodes)) {
111
  $nodes = [];
112
  foreach (array_unique($prependedNodes) as $name) {
113
+ $nodes[] = new SetTempNode($name, $node->getTemplateLine());
114
  }
115
 
116
  $nodes[] = $node;
117
+ $node = new Node($nodes);
118
  }
119
  }
120
  }
122
  return $node;
123
  }
124
 
125
+ protected function optimizeVariables(Twig_NodeInterface $node, Environment $env)
126
  {
127
+ if ('Twig_Node_Expression_Name' === \get_class($node) && $node->isSimple()) {
128
  $this->prependedNodes[0][] = $node->getAttribute('name');
129
 
130
+ return new TempNameExpression($node->getAttribute('name'), $node->getTemplateLine());
131
  }
132
 
133
  return $node;
142
  *
143
  * @return Twig_NodeInterface
144
  */
145
+ protected function optimizePrintNode(Twig_NodeInterface $node, Environment $env)
146
  {
147
+ if (!$node instanceof PrintNode) {
148
  return $node;
149
  }
150
 
151
  $exprNode = $node->getNode('expr');
152
  if (
153
+ $exprNode instanceof BlockReferenceExpression ||
154
+ $exprNode instanceof ParentExpression
155
  ) {
156
  $exprNode->setAttribute('output', true);
157
 
166
  *
167
  * @return Twig_NodeInterface
168
  */
169
+ protected function optimizeRawFilter(Twig_NodeInterface $node, Environment $env)
170
  {
171
+ if ($node instanceof FilterExpression && 'raw' == $node->getNode('filter')->getAttribute('value')) {
172
  return $node->getNode('node');
173
  }
174
 
178
  /**
179
  * Optimizes "for" tag by removing the "loop" variable creation whenever possible.
180
  */
181
+ protected function enterOptimizeFor(Twig_NodeInterface $node, Environment $env)
182
  {
183
+ if ($node instanceof ForNode) {
184
  // disable the loop variable by default
185
  $node->setAttribute('with_loop', false);
186
  array_unshift($this->loops, $node);
194
  // when do we need to add the loop variable back?
195
 
196
  // the loop variable is referenced for the current loop
197
+ elseif ($node instanceof NameExpression && 'loop' === $node->getAttribute('name')) {
198
  $node->setAttribute('always_defined', true);
199
  $this->addLoopToCurrent();
200
  }
201
 
202
  // optimize access to loop targets
203
+ elseif ($node instanceof NameExpression && \in_array($node->getAttribute('name'), $this->loopsTargets)) {
204
  $node->setAttribute('always_defined', true);
205
  }
206
 
207
  // block reference
208
+ elseif ($node instanceof BlockReferenceNode || $node instanceof BlockReferenceExpression) {
209
  $this->addLoopToCurrent();
210
  }
211
 
212
  // include without the only attribute
213
+ elseif ($node instanceof IncludeNode && !$node->getAttribute('only')) {
214
  $this->addLoopToAll();
215
  }
216
 
217
  // include function without the with_context=false parameter
218
+ elseif ($node instanceof FunctionExpression
219
  && 'include' === $node->getAttribute('name')
220
  && (!$node->getNode('arguments')->hasNode('with_context')
221
  || false !== $node->getNode('arguments')->getNode('with_context')->getAttribute('value')
225
  }
226
 
227
  // the loop variable is referenced via an attribute
228
+ elseif ($node instanceof GetAttrExpression
229
+ && (!$node->getNode('attribute') instanceof ConstantExpression
230
  || 'parent' === $node->getNode('attribute')->getAttribute('value')
231
  )
232
  && (true === $this->loops[0]->getAttribute('with_loop')
233
+ || ($node->getNode('node') instanceof NameExpression
234
  && 'loop' === $node->getNode('node')->getAttribute('name')
235
  )
236
  )
242
  /**
243
  * Optimizes "for" tag by removing the "loop" variable creation whenever possible.
244
  */
245
+ protected function leaveOptimizeFor(Twig_NodeInterface $node, Environment $env)
246
  {
247
+ if ($node instanceof ForNode) {
248
  array_shift($this->loops);
249
  array_shift($this->loopsTargets);
250
  array_shift($this->loopsTargets);
vendor/twig/twig/lib/Twig/NodeVisitor/SafeAnalysis.php CHANGED
@@ -9,10 +9,23 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  /**
13
  * @final
14
  */
15
- class Twig_NodeVisitor_SafeAnalysis extends Twig_BaseNodeVisitor
16
  {
17
  protected $data = [];
18
  protected $safeVars = [];
@@ -34,7 +47,7 @@ class Twig_NodeVisitor_SafeAnalysis extends Twig_BaseNodeVisitor
34
  continue;
35
  }
36
 
37
- if (in_array('html_attr', $bucket['value'])) {
38
  $bucket['value'][] = 'html';
39
  }
40
 
@@ -60,27 +73,27 @@ class Twig_NodeVisitor_SafeAnalysis extends Twig_BaseNodeVisitor
60
  ];
61
  }
62
 
63
- protected function doEnterNode(Twig_Node $node, Twig_Environment $env)
64
  {
65
  return $node;
66
  }
67
 
68
- protected function doLeaveNode(Twig_Node $node, Twig_Environment $env)
69
  {
70
- if ($node instanceof Twig_Node_Expression_Constant) {
71
  // constants are marked safe for all
72
  $this->setSafe($node, ['all']);
73
- } elseif ($node instanceof Twig_Node_Expression_BlockReference) {
74
  // blocks are safe by definition
75
  $this->setSafe($node, ['all']);
76
- } elseif ($node instanceof Twig_Node_Expression_Parent) {
77
  // parent block is safe by definition
78
  $this->setSafe($node, ['all']);
79
- } elseif ($node instanceof Twig_Node_Expression_Conditional) {
80
  // intersect safeness of both operands
81
  $safe = $this->intersectSafe($this->getSafe($node->getNode('expr2')), $this->getSafe($node->getNode('expr3')));
82
  $this->setSafe($node, $safe);
83
- } elseif ($node instanceof Twig_Node_Expression_Filter) {
84
  // filter expression is safe when the filter is safe
85
  $name = $node->getNode('filter')->getAttribute('value');
86
  $args = $node->getNode('arguments');
@@ -93,7 +106,7 @@ class Twig_NodeVisitor_SafeAnalysis extends Twig_BaseNodeVisitor
93
  } else {
94
  $this->setSafe($node, []);
95
  }
96
- } elseif ($node instanceof Twig_Node_Expression_Function) {
97
  // function expression is safe when the function is safe
98
  $name = $node->getAttribute('name');
99
  $args = $node->getNode('arguments');
@@ -103,16 +116,16 @@ class Twig_NodeVisitor_SafeAnalysis extends Twig_BaseNodeVisitor
103
  } else {
104
  $this->setSafe($node, []);
105
  }
106
- } elseif ($node instanceof Twig_Node_Expression_MethodCall) {
107
  if ($node->getAttribute('safe')) {
108
  $this->setSafe($node, ['all']);
109
  } else {
110
  $this->setSafe($node, []);
111
  }
112
- } elseif ($node instanceof Twig_Node_Expression_GetAttr && $node->getNode('node') instanceof Twig_Node_Expression_Name) {
113
  $name = $node->getNode('node')->getAttribute('name');
114
  // attributes on template instances are safe
115
- if ('_self' == $name || in_array($name, $this->safeVars)) {
116
  $this->setSafe($node, ['all']);
117
  } else {
118
  $this->setSafe($node, []);
@@ -130,11 +143,11 @@ class Twig_NodeVisitor_SafeAnalysis extends Twig_BaseNodeVisitor
130
  return [];
131
  }
132
 
133
- if (in_array('all', $a)) {
134
  return $b;
135
  }
136
 
137
- if (in_array('all', $b)) {
138
  return $a;
139
  }
140
 
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Environment;
13
+ use Twig\Node\Expression\BlockReferenceExpression;
14
+ use Twig\Node\Expression\ConditionalExpression;
15
+ use Twig\Node\Expression\ConstantExpression;
16
+ use Twig\Node\Expression\FilterExpression;
17
+ use Twig\Node\Expression\FunctionExpression;
18
+ use Twig\Node\Expression\GetAttrExpression;
19
+ use Twig\Node\Expression\MethodCallExpression;
20
+ use Twig\Node\Expression\NameExpression;
21
+ use Twig\Node\Expression\ParentExpression;
22
+ use Twig\Node\Node;
23
+ use Twig\NodeVisitor\AbstractNodeVisitor;
24
+
25
  /**
26
  * @final
27
  */
28
+ class Twig_NodeVisitor_SafeAnalysis extends AbstractNodeVisitor
29
  {
30
  protected $data = [];
31
  protected $safeVars = [];
47
  continue;
48
  }
49
 
50
+ if (\in_array('html_attr', $bucket['value'])) {
51
  $bucket['value'][] = 'html';
52
  }
53
 
73
  ];
74
  }
75
 
76
+ protected function doEnterNode(Node $node, Environment $env)
77
  {
78
  return $node;
79
  }
80
 
81
+ protected function doLeaveNode(Node $node, Environment $env)
82
  {
83
+ if ($node instanceof ConstantExpression) {
84
  // constants are marked safe for all
85
  $this->setSafe($node, ['all']);
86
+ } elseif ($node instanceof BlockReferenceExpression) {
87
  // blocks are safe by definition
88
  $this->setSafe($node, ['all']);
89
+ } elseif ($node instanceof ParentExpression) {
90
  // parent block is safe by definition
91
  $this->setSafe($node, ['all']);
92
+ } elseif ($node instanceof ConditionalExpression) {
93
  // intersect safeness of both operands
94
  $safe = $this->intersectSafe($this->getSafe($node->getNode('expr2')), $this->getSafe($node->getNode('expr3')));
95
  $this->setSafe($node, $safe);
96
+ } elseif ($node instanceof FilterExpression) {
97
  // filter expression is safe when the filter is safe
98
  $name = $node->getNode('filter')->getAttribute('value');
99
  $args = $node->getNode('arguments');
106
  } else {
107
  $this->setSafe($node, []);
108
  }
109
+ } elseif ($node instanceof FunctionExpression) {
110
  // function expression is safe when the function is safe
111
  $name = $node->getAttribute('name');
112
  $args = $node->getNode('arguments');
116
  } else {
117
  $this->setSafe($node, []);
118
  }
119
+ } elseif ($node instanceof MethodCallExpression) {
120
  if ($node->getAttribute('safe')) {
121
  $this->setSafe($node, ['all']);
122
  } else {
123
  $this->setSafe($node, []);
124
  }
125
+ } elseif ($node instanceof GetAttrExpression && $node->getNode('node') instanceof NameExpression) {
126
  $name = $node->getNode('node')->getAttribute('name');
127
  // attributes on template instances are safe
128
+ if ('_self' == $name || \in_array($name, $this->safeVars)) {
129
  $this->setSafe($node, ['all']);
130
  } else {
131
  $this->setSafe($node, []);
143
  return [];
144
  }
145
 
146
+ if (\in_array('all', $a)) {
147
  return $b;
148
  }
149
 
150
+ if (\in_array('all', $b)) {
151
  return $a;
152
  }
153
 
vendor/twig/twig/lib/Twig/NodeVisitor/Sandbox.php CHANGED
@@ -9,6 +9,17 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
 
 
 
 
 
 
 
12
  /**
13
  * Twig_NodeVisitor_Sandbox implements sandboxing.
14
  *
@@ -16,16 +27,16 @@
16
  *
17
  * @author Fabien Potencier <fabien@symfony.com>
18
  */
19
- class Twig_NodeVisitor_Sandbox extends Twig_BaseNodeVisitor
20
  {
21
  protected $inAModule = false;
22
  protected $tags;
23
  protected $filters;
24
  protected $functions;
25
 
26
- protected function doEnterNode(Twig_Node $node, Twig_Environment $env)
27
  {
28
- if ($node instanceof Twig_Node_Module) {
29
  $this->inAModule = true;
30
  $this->tags = [];
31
  $this->filters = [];
@@ -39,35 +50,35 @@ class Twig_NodeVisitor_Sandbox extends Twig_BaseNodeVisitor
39
  }
40
 
41
  // look for filters
42
- if ($node instanceof Twig_Node_Expression_Filter && !isset($this->filters[$node->getNode('filter')->getAttribute('value')])) {
43
  $this->filters[$node->getNode('filter')->getAttribute('value')] = $node;
44
  }
45
 
46
  // look for functions
47
- if ($node instanceof Twig_Node_Expression_Function && !isset($this->functions[$node->getAttribute('name')])) {
48
  $this->functions[$node->getAttribute('name')] = $node;
49
  }
50
 
51
  // the .. operator is equivalent to the range() function
52
- if ($node instanceof Twig_Node_Expression_Binary_Range && !isset($this->functions['range'])) {
53
  $this->functions['range'] = $node;
54
  }
55
 
56
  // wrap print to check __toString() calls
57
- if ($node instanceof Twig_Node_Print) {
58
- return new Twig_Node_SandboxedPrint($node->getNode('expr'), $node->getTemplateLine(), $node->getNodeTag());
59
  }
60
  }
61
 
62
  return $node;
63
  }
64
 
65
- protected function doLeaveNode(Twig_Node $node, Twig_Environment $env)
66
  {
67
- if ($node instanceof Twig_Node_Module) {
68
  $this->inAModule = false;
69
 
70
- $node->setNode('display_start', new Twig_Node([new Twig_Node_CheckSecurity($this->filters, $this->tags, $this->functions), $node->getNode('display_start')]));
71
  }
72
 
73
  return $node;
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Environment;
13
+ use Twig\Node\CheckSecurityNode;
14
+ use Twig\Node\Expression\Binary\RangeBinary;
15
+ use Twig\Node\Expression\FilterExpression;
16
+ use Twig\Node\Expression\FunctionExpression;
17
+ use Twig\Node\ModuleNode;
18
+ use Twig\Node\Node;
19
+ use Twig\Node\PrintNode;
20
+ use Twig\Node\SandboxedPrintNode;
21
+ use Twig\NodeVisitor\AbstractNodeVisitor;
22
+
23
  /**
24
  * Twig_NodeVisitor_Sandbox implements sandboxing.
25
  *
27
  *
28
  * @author Fabien Potencier <fabien@symfony.com>
29
  */
30
+ class Twig_NodeVisitor_Sandbox extends AbstractNodeVisitor
31
  {
32
  protected $inAModule = false;
33
  protected $tags;
34
  protected $filters;
35
  protected $functions;
36
 
37
+ protected function doEnterNode(Node $node, Environment $env)
38
  {
39
+ if ($node instanceof ModuleNode) {
40
  $this->inAModule = true;
41
  $this->tags = [];
42
  $this->filters = [];
50
  }
51
 
52
  // look for filters
53
+ if ($node instanceof FilterExpression && !isset($this->filters[$node->getNode('filter')->getAttribute('value')])) {
54
  $this->filters[$node->getNode('filter')->getAttribute('value')] = $node;
55
  }
56
 
57
  // look for functions
58
+ if ($node instanceof FunctionExpression && !isset($this->functions[$node->getAttribute('name')])) {
59
  $this->functions[$node->getAttribute('name')] = $node;
60
  }
61
 
62
  // the .. operator is equivalent to the range() function
63
+ if ($node instanceof RangeBinary && !isset($this->functions['range'])) {
64
  $this->functions['range'] = $node;
65
  }
66
 
67
  // wrap print to check __toString() calls
68
+ if ($node instanceof PrintNode) {
69
+ return new SandboxedPrintNode($node->getNode('expr'), $node->getTemplateLine(), $node->getNodeTag());
70
  }
71
  }
72
 
73
  return $node;
74
  }
75
 
76
+ protected function doLeaveNode(Node $node, Environment $env)
77
  {
78
+ if ($node instanceof ModuleNode) {
79
  $this->inAModule = false;
80
 
81
+ $node->setNode('display_start', new Node([new CheckSecurityNode($this->filters, $this->tags, $this->functions), $node->getNode('display_start')]));
82
  }
83
 
84
  return $node;
vendor/twig/twig/lib/Twig/NodeVisitorInterface.php CHANGED
@@ -9,6 +9,8 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
12
  /**
13
  * Twig_NodeVisitorInterface is the interface the all node visitor classes must implement.
14
  *
@@ -21,14 +23,14 @@ interface Twig_NodeVisitorInterface
21
  *
22
  * @return Twig_NodeInterface The modified node
23
  */
24
- public function enterNode(Twig_NodeInterface $node, Twig_Environment $env);
25
 
26
  /**
27
  * Called after child nodes are visited.
28
  *
29
  * @return Twig_NodeInterface|false The modified node or false if the node must be removed
30
  */
31
- public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env);
32
 
33
  /**
34
  * Returns the priority for this visitor.
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Environment;
13
+
14
  /**
15
  * Twig_NodeVisitorInterface is the interface the all node visitor classes must implement.
16
  *
23
  *
24
  * @return Twig_NodeInterface The modified node
25
  */
26
+ public function enterNode(Twig_NodeInterface $node, Environment $env);
27
 
28
  /**
29
  * Called after child nodes are visited.
30
  *
31
  * @return Twig_NodeInterface|false The modified node or false if the node must be removed
32
  */
33
+ public function leaveNode(Twig_NodeInterface $node, Environment $env);
34
 
35
  /**
36
  * Returns the priority for this visitor.
vendor/twig/twig/lib/Twig/Parser.php CHANGED
@@ -10,6 +10,26 @@
10
  * file that was distributed with this source code.
11
  */
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  /**
14
  * Default parser implementation.
15
  *
@@ -33,7 +53,7 @@ class Twig_Parser implements Twig_ParserInterface
33
  protected $embeddedTemplates = [];
34
  private $varNameSalt = 0;
35
 
36
- public function __construct(Twig_Environment $env)
37
  {
38
  $this->env = $env;
39
  }
@@ -63,7 +83,7 @@ class Twig_Parser implements Twig_ParserInterface
63
  return $this->stream->getSourceContext()->getName();
64
  }
65
 
66
- public function parse(Twig_TokenStream $stream, $test = null, $dropNeedle = false)
67
  {
68
  // push all variables into the stack to keep the current state of the parser
69
  // using get_object_vars() instead of foreach would lead to https://bugs.php.net/71336
@@ -88,7 +108,7 @@ class Twig_Parser implements Twig_ParserInterface
88
  }
89
 
90
  if (null === $this->expressionParser) {
91
- $this->expressionParser = new Twig_ExpressionParser($this, $this->env);
92
  }
93
 
94
  $this->stream = $stream;
@@ -105,9 +125,9 @@ class Twig_Parser implements Twig_ParserInterface
105
  $body = $this->subparse($test, $dropNeedle);
106
 
107
  if (null !== $this->parent && null === $body = $this->filterBodyNodes($body)) {
108
- $body = new Twig_Node();
109
  }
110
- } catch (Twig_Error_Syntax $e) {
111
  if (!$e->getSourceContext()) {
112
  $e->setSourceContext($this->stream->getSourceContext());
113
  }
@@ -119,9 +139,9 @@ class Twig_Parser implements Twig_ParserInterface
119
  throw $e;
120
  }
121
 
122
- $node = new Twig_Node_Module(new Twig_Node_Body([$body]), $this->parent, new Twig_Node($this->blocks), new Twig_Node($this->macros), new Twig_Node($this->traits), $this->embeddedTemplates, $stream->getSourceContext());
123
 
124
- $traverser = new Twig_NodeTraverser($this->env, $this->visitors);
125
 
126
  $node = $traverser->traverse($node);
127
 
@@ -139,48 +159,48 @@ class Twig_Parser implements Twig_ParserInterface
139
  $rv = [];
140
  while (!$this->stream->isEOF()) {
141
  switch ($this->getCurrentToken()->getType()) {
142
- case Twig_Token::TEXT_TYPE:
143
  $token = $this->stream->next();
144
- $rv[] = new Twig_Node_Text($token->getValue(), $token->getLine());
145
  break;
146
 
147
- case Twig_Token::VAR_START_TYPE:
148
  $token = $this->stream->next();
149
  $expr = $this->expressionParser->parseExpression();
150
- $this->stream->expect(Twig_Token::VAR_END_TYPE);
151
- $rv[] = new Twig_Node_Print($expr, $token->getLine());
152
  break;
153
 
154
- case Twig_Token::BLOCK_START_TYPE:
155
  $this->stream->next();
156
  $token = $this->getCurrentToken();
157
 
158
- if (Twig_Token::NAME_TYPE !== $token->getType()) {
159
- throw new Twig_Error_Syntax('A block must start with a tag name.', $token->getLine(), $this->stream->getSourceContext());
160
  }
161
 
162
- if (null !== $test && call_user_func($test, $token)) {
163
  if ($dropNeedle) {
164
  $this->stream->next();
165
  }
166
 
167
- if (1 === count($rv)) {
168
  return $rv[0];
169
  }
170
 
171
- return new Twig_Node($rv, [], $lineno);
172
  }
173
 
174
  $subparser = $this->handlers->getTokenParser($token->getValue());
175
  if (null === $subparser) {
176
  if (null !== $test) {
177
- $e = new Twig_Error_Syntax(sprintf('Unexpected "%s" tag', $token->getValue()), $token->getLine(), $this->stream->getSourceContext());
178
 
179
- if (is_array($test) && isset($test[0]) && $test[0] instanceof Twig_TokenParserInterface) {
180
  $e->appendMessage(sprintf(' (expecting closing tag for the "%s" tag defined near line %s).', $test[0]->getTag(), $lineno));
181
  }
182
  } else {
183
- $e = new Twig_Error_Syntax(sprintf('Unknown "%s" tag.', $token->getValue()), $token->getLine(), $this->stream->getSourceContext());
184
  $e->addSuggestions($token->getValue(), array_keys($this->env->getTags()));
185
  }
186
 
@@ -196,15 +216,15 @@ class Twig_Parser implements Twig_ParserInterface
196
  break;
197
 
198
  default:
199
- throw new Twig_Error_Syntax('Lexer or parser ended up in unsupported state.', $this->getCurrentToken()->getLine(), $this->stream->getSourceContext());
200
  }
201
  }
202
 
203
- if (1 === count($rv)) {
204
  return $rv[0];
205
  }
206
 
207
- return new Twig_Node($rv, [], $lineno);
208
  }
209
 
210
  /**
@@ -220,7 +240,7 @@ class Twig_Parser implements Twig_ParserInterface
220
  /**
221
  * @deprecated since 1.27 (to be removed in 2.0)
222
  */
223
- public function addNodeVisitor(Twig_NodeVisitorInterface $visitor)
224
  {
225
  @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0.', E_USER_DEPRECATED);
226
 
@@ -234,7 +254,7 @@ class Twig_Parser implements Twig_ParserInterface
234
 
235
  public function peekBlockStack()
236
  {
237
- return $this->blockStack[count($this->blockStack) - 1];
238
  }
239
 
240
  public function popBlockStack()
@@ -257,9 +277,9 @@ class Twig_Parser implements Twig_ParserInterface
257
  return $this->blocks[$name];
258
  }
259
 
260
- public function setBlock($name, Twig_Node_Block $value)
261
  {
262
- $this->blocks[$name] = new Twig_Node_Body([$value], [], $value->getTemplateLine());
263
  }
264
 
265
  public function hasMacro($name)
@@ -267,10 +287,10 @@ class Twig_Parser implements Twig_ParserInterface
267
  return isset($this->macros[$name]);
268
  }
269
 
270
- public function setMacro($name, Twig_Node_Macro $node)
271
  {
272
  if ($this->isReservedMacroName($name)) {
273
- throw new Twig_Error_Syntax(sprintf('"%s" cannot be used as a macro name as it is a reserved keyword.', $name), $node->getTemplateLine(), $this->stream->getSourceContext());
274
  }
275
 
276
  $this->macros[$name] = $node;
@@ -280,7 +300,7 @@ class Twig_Parser implements Twig_ParserInterface
280
  {
281
  if (null === $this->reservedMacroNames) {
282
  $this->reservedMacroNames = [];
283
- $r = new ReflectionClass($this->env->getBaseTemplateClass());
284
  foreach ($r->getMethods() as $method) {
285
  $methodName = strtolower($method->getName());
286
 
@@ -290,7 +310,7 @@ class Twig_Parser implements Twig_ParserInterface
290
  }
291
  }
292
 
293
- return in_array(strtolower($name), $this->reservedMacroNames);
294
  }
295
 
296
  public function addTrait($trait)
@@ -300,17 +320,17 @@ class Twig_Parser implements Twig_ParserInterface
300
 
301
  public function hasTraits()
302
  {
303
- return count($this->traits) > 0;
304
  }
305
 
306
- public function embedTemplate(Twig_Node_Module $template)
307
  {
308
  $template->setIndex(mt_rand());
309
 
310
  $this->embeddedTemplates[] = $template;
311
  }
312
 
313
- public function addImportedSymbol($type, $alias, $name = null, Twig_Node_Expression $node = null)
314
  {
315
  $this->importedSymbols[0][$type][$alias] = ['name' => $name, 'node' => $node];
316
  }
@@ -326,7 +346,7 @@ class Twig_Parser implements Twig_ParserInterface
326
 
327
  public function isMainScope()
328
  {
329
- return 1 === count($this->importedSymbols);
330
  }
331
 
332
  public function pushLocalScope()
@@ -340,7 +360,7 @@ class Twig_Parser implements Twig_ParserInterface
340
  }
341
 
342
  /**
343
- * @return Twig_ExpressionParser
344
  */
345
  public function getExpressionParser()
346
  {
@@ -358,7 +378,7 @@ class Twig_Parser implements Twig_ParserInterface
358
  }
359
 
360
  /**
361
- * @return Twig_TokenStream
362
  */
363
  public function getStream()
364
  {
@@ -366,7 +386,7 @@ class Twig_Parser implements Twig_ParserInterface
366
  }
367
 
368
  /**
369
- * @return Twig_Token
370
  */
371
  public function getCurrentToken()
372
  {
@@ -377,11 +397,11 @@ class Twig_Parser implements Twig_ParserInterface
377
  {
378
  // check that the body does not contain non-empty output nodes
379
  if (
380
- ($node instanceof Twig_Node_Text && !ctype_space($node->getAttribute('data')))
381
  ||
382
- (!$node instanceof Twig_Node_Text && !$node instanceof Twig_Node_BlockReference && $node instanceof Twig_NodeOutputInterface)
383
  ) {
384
- if (false !== strpos((string) $node, chr(0xEF).chr(0xBB).chr(0xBF))) {
385
  $t = substr($node->getAttribute('data'), 3);
386
  if ('' === $t || ctype_space($t)) {
387
  // bypass empty nodes starting with a BOM
@@ -389,15 +409,15 @@ class Twig_Parser implements Twig_ParserInterface
389
  }
390
  }
391
 
392
- throw new Twig_Error_Syntax('A template that extends another one cannot include content outside Twig blocks. Did you forget to put the content inside a {% block %} tag?', $node->getTemplateLine(), $this->stream->getSourceContext());
393
  }
394
 
395
  // bypass nodes that will "capture" the output
396
- if ($node instanceof Twig_NodeCaptureInterface) {
397
  return $node;
398
  }
399
 
400
- if ($node instanceof Twig_NodeOutputInterface) {
401
  return;
402
  }
403
 
10
  * file that was distributed with this source code.
11
  */
12
 
13
+ use Twig\Environment;
14
+ use Twig\Error\SyntaxError;
15
+ use Twig\ExpressionParser;
16
+ use Twig\Node\BlockNode;
17
+ use Twig\Node\BlockReferenceNode;
18
+ use Twig\Node\BodyNode;
19
+ use Twig\Node\Expression\AbstractExpression;
20
+ use Twig\Node\MacroNode;
21
+ use Twig\Node\ModuleNode;
22
+ use Twig\Node\Node;
23
+ use Twig\Node\NodeCaptureInterface;
24
+ use Twig\Node\NodeOutputInterface;
25
+ use Twig\Node\PrintNode;
26
+ use Twig\Node\TextNode;
27
+ use Twig\NodeTraverser;
28
+ use Twig\NodeVisitor\NodeVisitorInterface;
29
+ use Twig\Token;
30
+ use Twig\TokenParser\TokenParserInterface;
31
+ use Twig\TokenStream;
32
+
33
  /**
34
  * Default parser implementation.
35
  *
53
  protected $embeddedTemplates = [];
54
  private $varNameSalt = 0;
55
 
56
+ public function __construct(Environment $env)
57
  {
58
  $this->env = $env;
59
  }
83
  return $this->stream->getSourceContext()->getName();
84
  }
85
 
86
+ public function parse(TokenStream $stream, $test = null, $dropNeedle = false)
87
  {
88
  // push all variables into the stack to keep the current state of the parser
89
  // using get_object_vars() instead of foreach would lead to https://bugs.php.net/71336
108
  }
109
 
110
  if (null === $this->expressionParser) {
111
+ $this->expressionParser = new ExpressionParser($this, $this->env);
112
  }
113
 
114
  $this->stream = $stream;
125
  $body = $this->subparse($test, $dropNeedle);
126
 
127
  if (null !== $this->parent && null === $body = $this->filterBodyNodes($body)) {
128
+ $body = new Node();
129
  }
130
+ } catch (SyntaxError $e) {
131
  if (!$e->getSourceContext()) {
132
  $e->setSourceContext($this->stream->getSourceContext());
133
  }
139
  throw $e;
140
  }
141
 
142
+ $node = new ModuleNode(new BodyNode([$body]), $this->parent, new Node($this->blocks), new Node($this->macros), new Node($this->traits), $this->embeddedTemplates, $stream->getSourceContext());
143
 
144
+ $traverser = new NodeTraverser($this->env, $this->visitors);
145
 
146
  $node = $traverser->traverse($node);
147
 
159
  $rv = [];
160
  while (!$this->stream->isEOF()) {
161
  switch ($this->getCurrentToken()->getType()) {
162
+ case Token::TEXT_TYPE:
163
  $token = $this->stream->next();
164
+ $rv[] = new TextNode($token->getValue(), $token->getLine());
165
  break;
166
 
167
+ case Token::VAR_START_TYPE:
168
  $token = $this->stream->next();
169
  $expr = $this->expressionParser->parseExpression();
170
+ $this->stream->expect(Token::VAR_END_TYPE);
171
+ $rv[] = new PrintNode($expr, $token->getLine());
172
  break;
173
 
174
+ case Token::BLOCK_START_TYPE:
175
  $this->stream->next();
176
  $token = $this->getCurrentToken();
177
 
178
+ if (Token::NAME_TYPE !== $token->getType()) {
179
+ throw new SyntaxError('A block must start with a tag name.', $token->getLine(), $this->stream->getSourceContext());
180
  }
181
 
182
+ if (null !== $test && \call_user_func($test, $token)) {
183
  if ($dropNeedle) {
184
  $this->stream->next();
185
  }
186
 
187
+ if (1 === \count($rv)) {
188
  return $rv[0];
189
  }
190
 
191
+ return new Node($rv, [], $lineno);
192
  }
193
 
194
  $subparser = $this->handlers->getTokenParser($token->getValue());
195
  if (null === $subparser) {
196
  if (null !== $test) {
197
+ $e = new SyntaxError(sprintf('Unexpected "%s" tag', $token->getValue()), $token->getLine(), $this->stream->getSourceContext());
198
 
199
+ if (\is_array($test) && isset($test[0]) && $test[0] instanceof TokenParserInterface) {
200
  $e->appendMessage(sprintf(' (expecting closing tag for the "%s" tag defined near line %s).', $test[0]->getTag(), $lineno));
201
  }
202
  } else {
203
+ $e = new SyntaxError(sprintf('Unknown "%s" tag.', $token->getValue()), $token->getLine(), $this->stream->getSourceContext());
204
  $e->addSuggestions($token->getValue(), array_keys($this->env->getTags()));
205
  }
206
 
216
  break;
217
 
218
  default:
219
+ throw new SyntaxError('Lexer or parser ended up in unsupported state.', $this->getCurrentToken()->getLine(), $this->stream->getSourceContext());
220
  }
221
  }
222
 
223
+ if (1 === \count($rv)) {
224
  return $rv[0];
225
  }
226
 
227
+ return new Node($rv, [], $lineno);
228
  }
229
 
230
  /**
240
  /**
241
  * @deprecated since 1.27 (to be removed in 2.0)
242
  */
243
+ public function addNodeVisitor(NodeVisitorInterface $visitor)
244
  {
245
  @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0.', E_USER_DEPRECATED);
246
 
254
 
255
  public function peekBlockStack()
256
  {
257
+ return $this->blockStack[\count($this->blockStack) - 1];
258
  }
259
 
260
  public function popBlockStack()
277
  return $this->blocks[$name];
278
  }
279
 
280
+ public function setBlock($name, BlockNode $value)
281
  {
282
+ $this->blocks[$name] = new BodyNode([$value], [], $value->getTemplateLine());
283
  }
284
 
285
  public function hasMacro($name)
287
  return isset($this->macros[$name]);
288
  }
289
 
290
+ public function setMacro($name, MacroNode $node)
291
  {
292
  if ($this->isReservedMacroName($name)) {
293
+ throw new SyntaxError(sprintf('"%s" cannot be used as a macro name as it is a reserved keyword.', $name), $node->getTemplateLine(), $this->stream->getSourceContext());
294
  }
295
 
296
  $this->macros[$name] = $node;
300
  {
301
  if (null === $this->reservedMacroNames) {
302
  $this->reservedMacroNames = [];
303
+ $r = new \ReflectionClass($this->env->getBaseTemplateClass());
304
  foreach ($r->getMethods() as $method) {
305
  $methodName = strtolower($method->getName());
306
 
310
  }
311
  }
312
 
313
+ return \in_array(strtolower($name), $this->reservedMacroNames);
314
  }
315
 
316
  public function addTrait($trait)
320
 
321
  public function hasTraits()
322
  {
323
+ return \count($this->traits) > 0;
324
  }
325
 
326
+ public function embedTemplate(ModuleNode $template)
327
  {
328
  $template->setIndex(mt_rand());
329
 
330
  $this->embeddedTemplates[] = $template;
331
  }
332
 
333
+ public function addImportedSymbol($type, $alias, $name = null, AbstractExpression $node = null)
334
  {
335
  $this->importedSymbols[0][$type][$alias] = ['name' => $name, 'node' => $node];
336
  }
346
 
347
  public function isMainScope()
348
  {
349
+ return 1 === \count($this->importedSymbols);
350
  }
351
 
352
  public function pushLocalScope()
360
  }
361
 
362
  /**
363
+ * @return ExpressionParser
364
  */
365
  public function getExpressionParser()
366
  {
378
  }
379
 
380
  /**
381
+ * @return TokenStream
382
  */
383
  public function getStream()
384
  {
386
  }
387
 
388
  /**
389
+ * @return Token
390
  */
391
  public function getCurrentToken()
392
  {
397
  {
398
  // check that the body does not contain non-empty output nodes
399
  if (
400
+ ($node instanceof TextNode && !ctype_space($node->getAttribute('data')))
401
  ||
402
+ (!$node instanceof TextNode && !$node instanceof BlockReferenceNode && $node instanceof NodeOutputInterface)
403
  ) {
404
+ if (false !== strpos((string) $node, \chr(0xEF).\chr(0xBB).\chr(0xBF))) {
405
  $t = substr($node->getAttribute('data'), 3);
406
  if ('' === $t || ctype_space($t)) {
407
  // bypass empty nodes starting with a BOM
409
  }
410
  }
411
 
412
+ throw new SyntaxError('A template that extends another one cannot include content outside Twig blocks. Did you forget to put the content inside a {% block %} tag?', $node->getTemplateLine(), $this->stream->getSourceContext());
413
  }
414
 
415
  // bypass nodes that will "capture" the output
416
+ if ($node instanceof NodeCaptureInterface) {
417
  return $node;
418
  }
419
 
420
+ if ($node instanceof NodeOutputInterface) {
421
  return;
422
  }
423
 
vendor/twig/twig/lib/Twig/ParserInterface.php CHANGED
@@ -9,6 +9,10 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
12
  /**
13
  * Interface implemented by parser classes.
14
  *
@@ -21,9 +25,9 @@ interface Twig_ParserInterface
21
  /**
22
  * Converts a token stream to a node tree.
23
  *
24
- * @return Twig_Node_Module
25
  *
26
- * @throws Twig_Error_Syntax When the token stream is syntactically or semantically wrong
27
  */
28
- public function parse(Twig_TokenStream $stream);
29
  }
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Error\SyntaxError;
13
+ use Twig\Node\ModuleNode;
14
+ use Twig\TokenStream;
15
+
16
  /**
17
  * Interface implemented by parser classes.
18
  *
25
  /**
26
  * Converts a token stream to a node tree.
27
  *
28
+ * @return ModuleNode
29
  *
30
+ * @throws SyntaxError When the token stream is syntactically or semantically wrong
31
  */
32
+ public function parse(TokenStream $stream);
33
  }
vendor/twig/twig/lib/Twig/Profiler/Dumper/Base.php CHANGED
@@ -9,6 +9,8 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
12
  /**
13
  * @author Fabien Potencier <fabien@symfony.com>
14
  */
@@ -16,18 +18,18 @@ abstract class Twig_Profiler_Dumper_Base
16
  {
17
  private $root;
18
 
19
- public function dump(Twig_Profiler_Profile $profile)
20
  {
21
  return $this->dumpProfile($profile);
22
  }
23
 
24
- abstract protected function formatTemplate(Twig_Profiler_Profile $profile, $prefix);
25
 
26
- abstract protected function formatNonTemplate(Twig_Profiler_Profile $profile, $prefix);
27
 
28
- abstract protected function formatTime(Twig_Profiler_Profile $profile, $percent);
29
 
30
- private function dumpProfile(Twig_Profiler_Profile $profile, $prefix = '', $sibling = false)
31
  {
32
  if ($profile->isRoot()) {
33
  $this->root = $profile->getDuration();
@@ -49,7 +51,7 @@ abstract class Twig_Profiler_Dumper_Base
49
  $str = sprintf("%s %s\n", $start, $this->formatTime($profile, $percent));
50
  }
51
 
52
- $nCount = count($profile->getProfiles());
53
  foreach ($profile as $i => $p) {
54
  $str .= $this->dumpProfile($p, $prefix, $i + 1 !== $nCount);
55
  }
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Profiler\Profile;
13
+
14
  /**
15
  * @author Fabien Potencier <fabien@symfony.com>
16
  */
18
  {
19
  private $root;
20
 
21
+ public function dump(Profile $profile)
22
  {
23
  return $this->dumpProfile($profile);
24
  }
25
 
26
+ abstract protected function formatTemplate(Profile $profile, $prefix);
27
 
28
+ abstract protected function formatNonTemplate(Profile $profile, $prefix);
29
 
30
+ abstract protected function formatTime(Profile $profile, $percent);
31
 
32
+ private function dumpProfile(Profile $profile, $prefix = '', $sibling = false)
33
  {
34
  if ($profile->isRoot()) {
35
  $this->root = $profile->getDuration();
51
  $str = sprintf("%s %s\n", $start, $this->formatTime($profile, $percent));
52
  }
53
 
54
+ $nCount = \count($profile->getProfiles());
55
  foreach ($profile as $i => $p) {
56
  $str .= $this->dumpProfile($p, $prefix, $i + 1 !== $nCount);
57
  }
vendor/twig/twig/lib/Twig/Profiler/Dumper/Blackfire.php CHANGED
@@ -9,6 +9,8 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
12
  /**
13
  * @author Fabien Potencier <fabien@symfony.com>
14
  *
@@ -16,7 +18,7 @@
16
  */
17
  class Twig_Profiler_Dumper_Blackfire
18
  {
19
- public function dump(Twig_Profiler_Profile $profile)
20
  {
21
  $data = [];
22
  $this->dumpProfile('main()', $profile, $data);
@@ -38,7 +40,7 @@ EOF;
38
  return $str;
39
  }
40
 
41
- private function dumpChildren($parent, Twig_Profiler_Profile $profile, &$data)
42
  {
43
  foreach ($profile as $p) {
44
  if ($p->isTemplate()) {
@@ -51,7 +53,7 @@ EOF;
51
  }
52
  }
53
 
54
- private function dumpProfile($edge, Twig_Profiler_Profile $profile, &$data)
55
  {
56
  if (isset($data[$edge])) {
57
  ++$data[$edge]['ct'];
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Profiler\Profile;
13
+
14
  /**
15
  * @author Fabien Potencier <fabien@symfony.com>
16
  *
18
  */
19
  class Twig_Profiler_Dumper_Blackfire
20
  {
21
+ public function dump(Profile $profile)
22
  {
23
  $data = [];
24
  $this->dumpProfile('main()', $profile, $data);
40
  return $str;
41
  }
42
 
43
+ private function dumpChildren($parent, Profile $profile, &$data)
44
  {
45
  foreach ($profile as $p) {
46
  if ($p->isTemplate()) {
53
  }
54
  }
55
 
56
+ private function dumpProfile($edge, Profile $profile, &$data)
57
  {
58
  if (isset($data[$edge])) {
59
  ++$data[$edge]['ct'];
vendor/twig/twig/lib/Twig/Profiler/Dumper/Html.php CHANGED
@@ -9,12 +9,15 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
12
  /**
13
  * @author Fabien Potencier <fabien@symfony.com>
14
  *
15
  * @final
16
  */
17
- class Twig_Profiler_Dumper_Html extends Twig_Profiler_Dumper_Base
18
  {
19
  private static $colors = [
20
  'block' => '#dfd',
@@ -23,22 +26,22 @@ class Twig_Profiler_Dumper_Html extends Twig_Profiler_Dumper_Base
23
  'big' => '#d44',
24
  ];
25
 
26
- public function dump(Twig_Profiler_Profile $profile)
27
  {
28
  return '<pre>'.parent::dump($profile).'</pre>';
29
  }
30
 
31
- protected function formatTemplate(Twig_Profiler_Profile $profile, $prefix)
32
  {
33
  return sprintf('%s└ <span style="background-color: %s">%s</span>', $prefix, self::$colors['template'], $profile->getTemplate());
34
  }
35
 
36
- protected function formatNonTemplate(Twig_Profiler_Profile $profile, $prefix)
37
  {
38
  return sprintf('%s└ %s::%s(<span style="background-color: %s">%s</span>)', $prefix, $profile->getTemplate(), $profile->getType(), isset(self::$colors[$profile->getType()]) ? self::$colors[$profile->getType()] : 'auto', $profile->getName());
39
  }
40
 
41
- protected function formatTime(Twig_Profiler_Profile $profile, $percent)
42
  {
43
  return sprintf('<span style="color: %s">%.2fms/%.0f%%</span>', $percent > 20 ? self::$colors['big'] : 'auto', $profile->getDuration() * 1000, $percent);
44
  }
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Profiler\Dumper\BaseDumper;
13
+ use Twig\Profiler\Profile;
14
+
15
  /**
16
  * @author Fabien Potencier <fabien@symfony.com>
17
  *
18
  * @final
19
  */
20
+ class Twig_Profiler_Dumper_Html extends BaseDumper
21
  {
22
  private static $colors = [
23
  'block' => '#dfd',
26
  'big' => '#d44',
27
  ];
28
 
29
+ public function dump(Profile $profile)
30
  {
31
  return '<pre>'.parent::dump($profile).'</pre>';
32
  }
33
 
34
+ protected function formatTemplate(Profile $profile, $prefix)
35
  {
36
  return sprintf('%s└ <span style="background-color: %s">%s</span>', $prefix, self::$colors['template'], $profile->getTemplate());
37
  }
38
 
39
+ protected function formatNonTemplate(Profile $profile, $prefix)
40
  {
41
  return sprintf('%s└ %s::%s(<span style="background-color: %s">%s</span>)', $prefix, $profile->getTemplate(), $profile->getType(), isset(self::$colors[$profile->getType()]) ? self::$colors[$profile->getType()] : 'auto', $profile->getName());
42
  }
43
 
44
+ protected function formatTime(Profile $profile, $percent)
45
  {
46
  return sprintf('<span style="color: %s">%.2fms/%.0f%%</span>', $percent > 20 ? self::$colors['big'] : 'auto', $profile->getDuration() * 1000, $percent);
47
  }
vendor/twig/twig/lib/Twig/Profiler/Dumper/Text.php CHANGED
@@ -9,24 +9,27 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
12
  /**
13
  * @author Fabien Potencier <fabien@symfony.com>
14
  *
15
  * @final
16
  */
17
- class Twig_Profiler_Dumper_Text extends Twig_Profiler_Dumper_Base
18
  {
19
- protected function formatTemplate(Twig_Profiler_Profile $profile, $prefix)
20
  {
21
  return sprintf('%s└ %s', $prefix, $profile->getTemplate());
22
  }
23
 
24
- protected function formatNonTemplate(Twig_Profiler_Profile $profile, $prefix)
25
  {
26
  return sprintf('%s└ %s::%s(%s)', $prefix, $profile->getTemplate(), $profile->getType(), $profile->getName());
27
  }
28
 
29
- protected function formatTime(Twig_Profiler_Profile $profile, $percent)
30
  {
31
  return sprintf('%.2fms/%.0f%%', $profile->getDuration() * 1000, $percent);
32
  }
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Profiler\Dumper\BaseDumper;
13
+ use Twig\Profiler\Profile;
14
+
15
  /**
16
  * @author Fabien Potencier <fabien@symfony.com>
17
  *
18
  * @final
19
  */
20
+ class Twig_Profiler_Dumper_Text extends BaseDumper
21
  {
22
+ protected function formatTemplate(Profile $profile, $prefix)
23
  {
24
  return sprintf('%s└ %s', $prefix, $profile->getTemplate());
25
  }
26
 
27
+ protected function formatNonTemplate(Profile $profile, $prefix)
28
  {
29
  return sprintf('%s└ %s::%s(%s)', $prefix, $profile->getTemplate(), $profile->getType(), $profile->getName());
30
  }
31
 
32
+ protected function formatTime(Profile $profile, $percent)
33
  {
34
  return sprintf('%.2fms/%.0f%%', $profile->getDuration() * 1000, $percent);
35
  }
vendor/twig/twig/lib/Twig/Profiler/Node/EnterProfile.php CHANGED
@@ -9,25 +9,28 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
12
  /**
13
  * Represents a profile enter node.
14
  *
15
  * @author Fabien Potencier <fabien@symfony.com>
16
  */
17
- class Twig_Profiler_Node_EnterProfile extends Twig_Node
18
  {
19
  public function __construct($extensionName, $type, $name, $varName)
20
  {
21
  parent::__construct([], ['extension_name' => $extensionName, 'name' => $name, 'type' => $type, 'var_name' => $varName]);
22
  }
23
 
24
- public function compile(Twig_Compiler $compiler)
25
  {
26
  $compiler
27
  ->write(sprintf('$%s = $this->env->getExtension(', $this->getAttribute('var_name')))
28
  ->repr($this->getAttribute('extension_name'))
29
  ->raw(");\n")
30
- ->write(sprintf('$%s->enter($%s = new Twig_Profiler_Profile($this->getTemplateName(), ', $this->getAttribute('var_name'), $this->getAttribute('var_name').'_prof'))
31
  ->repr($this->getAttribute('type'))
32
  ->raw(', ')
33
  ->repr($this->getAttribute('name'))
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Compiler;
13
+ use Twig\Node\Node;
14
+
15
  /**
16
  * Represents a profile enter node.
17
  *
18
  * @author Fabien Potencier <fabien@symfony.com>
19
  */
20
+ class Twig_Profiler_Node_EnterProfile extends Node
21
  {
22
  public function __construct($extensionName, $type, $name, $varName)
23
  {
24
  parent::__construct([], ['extension_name' => $extensionName, 'name' => $name, 'type' => $type, 'var_name' => $varName]);
25
  }
26
 
27
+ public function compile(Compiler $compiler)
28
  {
29
  $compiler
30
  ->write(sprintf('$%s = $this->env->getExtension(', $this->getAttribute('var_name')))
31
  ->repr($this->getAttribute('extension_name'))
32
  ->raw(");\n")
33
+ ->write(sprintf('$%s->enter($%s = new \Twig\Profiler\Profile($this->getTemplateName(), ', $this->getAttribute('var_name'), $this->getAttribute('var_name').'_prof'))
34
  ->repr($this->getAttribute('type'))
35
  ->raw(', ')
36
  ->repr($this->getAttribute('name'))
vendor/twig/twig/lib/Twig/Profiler/Node/LeaveProfile.php CHANGED
@@ -9,19 +9,22 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
12
  /**
13
  * Represents a profile leave node.
14
  *
15
  * @author Fabien Potencier <fabien@symfony.com>
16
  */
17
- class Twig_Profiler_Node_LeaveProfile extends Twig_Node
18
  {
19
  public function __construct($varName)
20
  {
21
  parent::__construct([], ['var_name' => $varName]);
22
  }
23
 
24
- public function compile(Twig_Compiler $compiler)
25
  {
26
  $compiler
27
  ->write("\n")
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Compiler;
13
+ use Twig\Node\Node;
14
+
15
  /**
16
  * Represents a profile leave node.
17
  *
18
  * @author Fabien Potencier <fabien@symfony.com>
19
  */
20
+ class Twig_Profiler_Node_LeaveProfile extends Node
21
  {
22
  public function __construct($varName)
23
  {
24
  parent::__construct([], ['var_name' => $varName]);
25
  }
26
 
27
+ public function compile(Compiler $compiler)
28
  {
29
  $compiler
30
  ->write("\n")
vendor/twig/twig/lib/Twig/Profiler/NodeVisitor/Profiler.php CHANGED
@@ -9,12 +9,23 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
 
 
 
 
 
 
 
12
  /**
13
  * @author Fabien Potencier <fabien@symfony.com>
14
  *
15
  * @final
16
  */
17
- class Twig_Profiler_NodeVisitor_Profiler extends Twig_BaseNodeVisitor
18
  {
19
  private $extensionName;
20
 
@@ -23,30 +34,30 @@ class Twig_Profiler_NodeVisitor_Profiler extends Twig_BaseNodeVisitor
23
  $this->extensionName = $extensionName;
24
  }
25
 
26
- protected function doEnterNode(Twig_Node $node, Twig_Environment $env)
27
  {
28
  return $node;
29
  }
30
 
31
- protected function doLeaveNode(Twig_Node $node, Twig_Environment $env)
32
  {
33
- if ($node instanceof Twig_Node_Module) {
34
  $varName = $this->getVarName();
35
- $node->setNode('display_start', new Twig_Node([new Twig_Profiler_Node_EnterProfile($this->extensionName, Twig_Profiler_Profile::TEMPLATE, $node->getTemplateName(), $varName), $node->getNode('display_start')]));
36
- $node->setNode('display_end', new Twig_Node([new Twig_Profiler_Node_LeaveProfile($varName), $node->getNode('display_end')]));
37
- } elseif ($node instanceof Twig_Node_Block) {
38
  $varName = $this->getVarName();
39
- $node->setNode('body', new Twig_Node_Body([
40
- new Twig_Profiler_Node_EnterProfile($this->extensionName, Twig_Profiler_Profile::BLOCK, $node->getAttribute('name'), $varName),
41
  $node->getNode('body'),
42
- new Twig_Profiler_Node_LeaveProfile($varName),
43
  ]));
44
- } elseif ($node instanceof Twig_Node_Macro) {
45
  $varName = $this->getVarName();
46
- $node->setNode('body', new Twig_Node_Body([
47
- new Twig_Profiler_Node_EnterProfile($this->extensionName, Twig_Profiler_Profile::MACRO, $node->getAttribute('name'), $varName),
48
  $node->getNode('body'),
49
- new Twig_Profiler_Node_LeaveProfile($varName),
50
  ]));
51
  }
52
 
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Environment;
13
+ use Twig\Node\BlockNode;
14
+ use Twig\Node\BodyNode;
15
+ use Twig\Node\MacroNode;
16
+ use Twig\Node\ModuleNode;
17
+ use Twig\Node\Node;
18
+ use Twig\NodeVisitor\AbstractNodeVisitor;
19
+ use Twig\Profiler\Node\EnterProfileNode;
20
+ use Twig\Profiler\Node\LeaveProfileNode;
21
+ use Twig\Profiler\Profile;
22
+
23
  /**
24
  * @author Fabien Potencier <fabien@symfony.com>
25
  *
26
  * @final
27
  */
28
+ class Twig_Profiler_NodeVisitor_Profiler extends AbstractNodeVisitor
29
  {
30
  private $extensionName;
31
 
34
  $this->extensionName = $extensionName;
35
  }
36
 
37
+ protected function doEnterNode(Node $node, Environment $env)
38
  {
39
  return $node;
40
  }
41
 
42
+ protected function doLeaveNode(Node $node, Environment $env)
43
  {
44
+ if ($node instanceof ModuleNode) {
45
  $varName = $this->getVarName();
46
+ $node->setNode('display_start', new Node([new EnterProfileNode($this->extensionName, Profile::TEMPLATE, $node->getTemplateName(), $varName), $node->getNode('display_start')]));
47
+ $node->setNode('display_end', new Node([new LeaveProfileNode($varName), $node->getNode('display_end')]));
48
+ } elseif ($node instanceof BlockNode) {
49
  $varName = $this->getVarName();
50
+ $node->setNode('body', new BodyNode([
51
+ new EnterProfileNode($this->extensionName, Profile::BLOCK, $node->getAttribute('name'), $varName),
52
  $node->getNode('body'),
53
+ new LeaveProfileNode($varName),
54
  ]));
55
+ } elseif ($node instanceof MacroNode) {
56
  $varName = $this->getVarName();
57
+ $node->setNode('body', new BodyNode([
58
+ new EnterProfileNode($this->extensionName, Profile::MACRO, $node->getAttribute('name'), $varName),
59
  $node->getNode('body'),
60
+ new LeaveProfileNode($varName),
61
  ]));
62
  }
63
 
vendor/twig/twig/lib/Twig/Profiler/Profile.php CHANGED
@@ -14,7 +14,7 @@
14
  *
15
  * @final
16
  */
17
- class Twig_Profiler_Profile implements IteratorAggregate, Serializable
18
  {
19
  const ROOT = 'ROOT';
20
  const BLOCK = 'block';
@@ -153,7 +153,7 @@ class Twig_Profiler_Profile implements IteratorAggregate, Serializable
153
 
154
  public function getIterator()
155
  {
156
- return new ArrayIterator($this->profiles);
157
  }
158
 
159
  public function serialize()
14
  *
15
  * @final
16
  */
17
+ class Twig_Profiler_Profile implements \IteratorAggregate, Serializable
18
  {
19
  const ROOT = 'ROOT';
20
  const BLOCK = 'block';
153
 
154
  public function getIterator()
155
  {
156
+ return new \ArrayIterator($this->profiles);
157
  }
158
 
159
  public function serialize()
vendor/twig/twig/lib/Twig/Sandbox/SecurityError.php CHANGED
@@ -9,12 +9,14 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
12
  /**
13
  * Exception thrown when a security error occurs at runtime.
14
  *
15
  * @author Fabien Potencier <fabien@symfony.com>
16
  */
17
- class Twig_Sandbox_SecurityError extends Twig_Error
18
  {
19
  }
20
 
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Error\Error;
13
+
14
  /**
15
  * Exception thrown when a security error occurs at runtime.
16
  *
17
  * @author Fabien Potencier <fabien@symfony.com>
18
  */
19
+ class Twig_Sandbox_SecurityError extends Error
20
  {
21
  }
22
 
vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFilterError.php CHANGED
@@ -9,16 +9,18 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
12
  /**
13
  * Exception thrown when a not allowed filter is used in a template.
14
  *
15
  * @author Martin Hasoň <martin.hason@gmail.com>
16
  */
17
- class Twig_Sandbox_SecurityNotAllowedFilterError extends Twig_Sandbox_SecurityError
18
  {
19
  private $filterName;
20
 
21
- public function __construct($message, $functionName, $lineno = -1, $filename = null, Exception $previous = null)
22
  {
23
  parent::__construct($message, $lineno, $filename, $previous);
24
  $this->filterName = $functionName;
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Sandbox\SecurityError;
13
+
14
  /**
15
  * Exception thrown when a not allowed filter is used in a template.
16
  *
17
  * @author Martin Hasoň <martin.hason@gmail.com>
18
  */
19
+ class Twig_Sandbox_SecurityNotAllowedFilterError extends SecurityError
20
  {
21
  private $filterName;
22
 
23
+ public function __construct($message, $functionName, $lineno = -1, $filename = null, \Exception $previous = null)
24
  {
25
  parent::__construct($message, $lineno, $filename, $previous);
26
  $this->filterName = $functionName;
vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFunctionError.php CHANGED
@@ -9,16 +9,18 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
12
  /**
13
  * Exception thrown when a not allowed function is used in a template.
14
  *
15
  * @author Martin Hasoň <martin.hason@gmail.com>
16
  */
17
- class Twig_Sandbox_SecurityNotAllowedFunctionError extends Twig_Sandbox_SecurityError
18
  {
19
  private $functionName;
20
 
21
- public function __construct($message, $functionName, $lineno = -1, $filename = null, Exception $previous = null)
22
  {
23
  parent::__construct($message, $lineno, $filename, $previous);
24
  $this->functionName = $functionName;
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Sandbox\SecurityError;
13
+
14
  /**
15
  * Exception thrown when a not allowed function is used in a template.
16
  *
17
  * @author Martin Hasoň <martin.hason@gmail.com>
18
  */
19
+ class Twig_Sandbox_SecurityNotAllowedFunctionError extends SecurityError
20
  {
21
  private $functionName;
22
 
23
+ public function __construct($message, $functionName, $lineno = -1, $filename = null, \Exception $previous = null)
24
  {
25
  parent::__construct($message, $lineno, $filename, $previous);
26
  $this->functionName = $functionName;
vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedMethodError.php CHANGED
@@ -9,17 +9,19 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
12
  /**
13
  * Exception thrown when a not allowed class method is used in a template.
14
  *
15
  * @author Kit Burton-Senior <mail@kitbs.com>
16
  */
17
- class Twig_Sandbox_SecurityNotAllowedMethodError extends Twig_Sandbox_SecurityError
18
  {
19
  private $className;
20
  private $methodName;
21
 
22
- public function __construct($message, $className, $methodName, $lineno = -1, $filename = null, Exception $previous = null)
23
  {
24
  parent::__construct($message, $lineno, $filename, $previous);
25
  $this->className = $className;
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Sandbox\SecurityError;
13
+
14
  /**
15
  * Exception thrown when a not allowed class method is used in a template.
16
  *
17
  * @author Kit Burton-Senior <mail@kitbs.com>
18
  */
19
+ class Twig_Sandbox_SecurityNotAllowedMethodError extends SecurityError
20
  {
21
  private $className;
22
  private $methodName;
23
 
24
+ public function __construct($message, $className, $methodName, $lineno = -1, $filename = null, \Exception $previous = null)
25
  {
26
  parent::__construct($message, $lineno, $filename, $previous);
27
  $this->className = $className;
vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedPropertyError.php CHANGED
@@ -9,17 +9,19 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
12
  /**
13
  * Exception thrown when a not allowed class property is used in a template.
14
  *
15
  * @author Kit Burton-Senior <mail@kitbs.com>
16
  */
17
- class Twig_Sandbox_SecurityNotAllowedPropertyError extends Twig_Sandbox_SecurityError
18
  {
19
  private $className;
20
  private $propertyName;
21
 
22
- public function __construct($message, $className, $propertyName, $lineno = -1, $filename = null, Exception $previous = null)
23
  {
24
  parent::__construct($message, $lineno, $filename, $previous);
25
  $this->className = $className;
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Sandbox\SecurityError;
13
+
14
  /**
15
  * Exception thrown when a not allowed class property is used in a template.
16
  *
17
  * @author Kit Burton-Senior <mail@kitbs.com>
18
  */
19
+ class Twig_Sandbox_SecurityNotAllowedPropertyError extends SecurityError
20
  {
21
  private $className;
22
  private $propertyName;
23
 
24
+ public function __construct($message, $className, $propertyName, $lineno = -1, $filename = null, \Exception $previous = null)
25
  {
26
  parent::__construct($message, $lineno, $filename, $previous);
27
  $this->className = $className;
vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedTagError.php CHANGED
@@ -9,16 +9,18 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
12
  /**
13
  * Exception thrown when a not allowed tag is used in a template.
14
  *
15
  * @author Martin Hasoň <martin.hason@gmail.com>
16
  */
17
- class Twig_Sandbox_SecurityNotAllowedTagError extends Twig_Sandbox_SecurityError
18
  {
19
  private $tagName;
20
 
21
- public function __construct($message, $tagName, $lineno = -1, $filename = null, Exception $previous = null)
22
  {
23
  parent::__construct($message, $lineno, $filename, $previous);
24
  $this->tagName = $tagName;
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Sandbox\SecurityError;
13
+
14
  /**
15
  * Exception thrown when a not allowed tag is used in a template.
16
  *
17
  * @author Martin Hasoň <martin.hason@gmail.com>
18
  */
19
+ class Twig_Sandbox_SecurityNotAllowedTagError extends SecurityError
20
  {
21
  private $tagName;
22
 
23
+ public function __construct($message, $tagName, $lineno = -1, $filename = null, \Exception $previous = null)
24
  {
25
  parent::__construct($message, $lineno, $filename, $previous);
26
  $this->tagName = $tagName;
vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicy.php CHANGED
@@ -9,6 +9,14 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
 
 
 
 
12
  /**
13
  * Represents a security policy which need to be enforced when sandbox mode is enabled.
14
  *
@@ -16,7 +24,7 @@
16
  *
17
  * @author Fabien Potencier <fabien@symfony.com>
18
  */
19
- class Twig_Sandbox_SecurityPolicy implements Twig_Sandbox_SecurityPolicyInterface
20
  {
21
  protected $allowedTags;
22
  protected $allowedFilters;
@@ -47,7 +55,7 @@ class Twig_Sandbox_SecurityPolicy implements Twig_Sandbox_SecurityPolicyInterfac
47
  {
48
  $this->allowedMethods = [];
49
  foreach ($methods as $class => $m) {
50
- $this->allowedMethods[$class] = array_map('strtolower', is_array($m) ? $m : [$m]);
51
  }
52
  }
53
 
@@ -64,27 +72,27 @@ class Twig_Sandbox_SecurityPolicy implements Twig_Sandbox_SecurityPolicyInterfac
64
  public function checkSecurity($tags, $filters, $functions)
65
  {
66
  foreach ($tags as $tag) {
67
- if (!in_array($tag, $this->allowedTags)) {
68
- throw new Twig_Sandbox_SecurityNotAllowedTagError(sprintf('Tag "%s" is not allowed.', $tag), $tag);
69
  }
70
  }
71
 
72
  foreach ($filters as $filter) {
73
- if (!in_array($filter, $this->allowedFilters)) {
74
- throw new Twig_Sandbox_SecurityNotAllowedFilterError(sprintf('Filter "%s" is not allowed.', $filter), $filter);
75
  }
76
  }
77
 
78
  foreach ($functions as $function) {
79
- if (!in_array($function, $this->allowedFunctions)) {
80
- throw new Twig_Sandbox_SecurityNotAllowedFunctionError(sprintf('Function "%s" is not allowed.', $function), $function);
81
  }
82
  }
83
  }
84
 
85
  public function checkMethodAllowed($obj, $method)
86
  {
87
- if ($obj instanceof Twig_TemplateInterface || $obj instanceof Twig_Markup) {
88
  return true;
89
  }
90
 
@@ -92,15 +100,15 @@ class Twig_Sandbox_SecurityPolicy implements Twig_Sandbox_SecurityPolicyInterfac
92
  $method = strtolower($method);
93
  foreach ($this->allowedMethods as $class => $methods) {
94
  if ($obj instanceof $class) {
95
- $allowed = in_array($method, $methods);
96
 
97
  break;
98
  }
99
  }
100
 
101
  if (!$allowed) {
102
- $class = get_class($obj);
103
- throw new Twig_Sandbox_SecurityNotAllowedMethodError(sprintf('Calling "%s" method on a "%s" object is not allowed.', $method, $class), $class, $method);
104
  }
105
  }
106
 
@@ -109,15 +117,15 @@ class Twig_Sandbox_SecurityPolicy implements Twig_Sandbox_SecurityPolicyInterfac
109
  $allowed = false;
110
  foreach ($this->allowedProperties as $class => $properties) {
111
  if ($obj instanceof $class) {
112
- $allowed = in_array($property, is_array($properties) ? $properties : [$properties]);
113
 
114
  break;
115
  }
116
  }
117
 
118
  if (!$allowed) {
119
- $class = get_class($obj);
120
- throw new Twig_Sandbox_SecurityNotAllowedPropertyError(sprintf('Calling "%s" property on a "%s" object is not allowed.', $property, $class), $class, $property);
121
  }
122
  }
123
  }
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Markup;
13
+ use Twig\Sandbox\SecurityNotAllowedFilterError;
14
+ use Twig\Sandbox\SecurityNotAllowedFunctionError;
15
+ use Twig\Sandbox\SecurityNotAllowedMethodError;
16
+ use Twig\Sandbox\SecurityNotAllowedPropertyError;
17
+ use Twig\Sandbox\SecurityNotAllowedTagError;
18
+ use Twig\Sandbox\SecurityPolicyInterface;
19
+
20
  /**
21
  * Represents a security policy which need to be enforced when sandbox mode is enabled.
22
  *
24
  *
25
  * @author Fabien Potencier <fabien@symfony.com>
26
  */
27
+ class Twig_Sandbox_SecurityPolicy implements SecurityPolicyInterface
28
  {
29
  protected $allowedTags;
30
  protected $allowedFilters;
55
  {
56
  $this->allowedMethods = [];
57
  foreach ($methods as $class => $m) {
58
+ $this->allowedMethods[$class] = array_map('strtolower', \is_array($m) ? $m : [$m]);
59
  }
60
  }
61
 
72
  public function checkSecurity($tags, $filters, $functions)
73
  {
74
  foreach ($tags as $tag) {
75
+ if (!\in_array($tag, $this->allowedTags)) {
76
+ throw new SecurityNotAllowedTagError(sprintf('Tag "%s" is not allowed.', $tag), $tag);
77
  }
78
  }
79
 
80
  foreach ($filters as $filter) {
81
+ if (!\in_array($filter, $this->allowedFilters)) {
82
+ throw new SecurityNotAllowedFilterError(sprintf('Filter "%s" is not allowed.', $filter), $filter);
83
  }
84
  }
85
 
86
  foreach ($functions as $function) {
87
+ if (!\in_array($function, $this->allowedFunctions)) {
88
+ throw new SecurityNotAllowedFunctionError(sprintf('Function "%s" is not allowed.', $function), $function);
89
  }
90
  }
91
  }
92
 
93
  public function checkMethodAllowed($obj, $method)
94
  {
95
+ if ($obj instanceof Twig_TemplateInterface || $obj instanceof Markup) {
96
  return true;
97
  }
98
 
100
  $method = strtolower($method);
101
  foreach ($this->allowedMethods as $class => $methods) {
102
  if ($obj instanceof $class) {
103
+ $allowed = \in_array($method, $methods);
104
 
105
  break;
106
  }
107
  }
108
 
109
  if (!$allowed) {
110
+ $class = \get_class($obj);
111
+ throw new SecurityNotAllowedMethodError(sprintf('Calling "%s" method on a "%s" object is not allowed.', $method, $class), $class, $method);
112
  }
113
  }
114
 
117
  $allowed = false;
118
  foreach ($this->allowedProperties as $class => $properties) {
119
  if ($obj instanceof $class) {
120
+ $allowed = \in_array($property, \is_array($properties) ? $properties : [$properties]);
121
 
122
  break;
123
  }
124
  }
125
 
126
  if (!$allowed) {
127
+ $class = \get_class($obj);
128
+ throw new SecurityNotAllowedPropertyError(sprintf('Calling "%s" property on a "%s" object is not allowed.', $property, $class), $class, $property);
129
  }
130
  }
131
  }
vendor/twig/twig/lib/Twig/SimpleFilter.php CHANGED
@@ -9,6 +9,8 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
12
  /**
13
  * Represents a template filter.
14
  *
@@ -35,7 +37,7 @@ class Twig_SimpleFilter
35
  'is_safe_callback' => null,
36
  'pre_escape' => null,
37
  'preserves_safety' => null,
38
- 'node_class' => 'Twig_Node_Expression_Filter',
39
  'deprecated' => false,
40
  'alternative' => null,
41
  ], $options);
@@ -76,14 +78,14 @@ class Twig_SimpleFilter
76
  return $this->options['needs_context'];
77
  }
78
 
79
- public function getSafe(Twig_Node $filterArgs)
80
  {
81
  if (null !== $this->options['is_safe']) {
82
  return $this->options['is_safe'];
83
  }
84
 
85
  if (null !== $this->options['is_safe_callback']) {
86
- return call_user_func($this->options['is_safe_callback'], $filterArgs);
87
  }
88
  }
89
 
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Node\Node;
13
+
14
  /**
15
  * Represents a template filter.
16
  *
37
  'is_safe_callback' => null,
38
  'pre_escape' => null,
39
  'preserves_safety' => null,
40
+ 'node_class' => '\Twig\Node\Expression\FilterExpression',
41
  'deprecated' => false,
42
  'alternative' => null,
43
  ], $options);
78
  return $this->options['needs_context'];
79
  }
80
 
81
+ public function getSafe(Node $filterArgs)
82
  {
83
  if (null !== $this->options['is_safe']) {
84
  return $this->options['is_safe'];
85
  }
86
 
87
  if (null !== $this->options['is_safe_callback']) {
88
+ return \call_user_func($this->options['is_safe_callback'], $filterArgs);
89
  }
90
  }
91
 
vendor/twig/twig/lib/Twig/SimpleFunction.php CHANGED
@@ -9,6 +9,8 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
12
  /**
13
  * Represents a template function.
14
  *
@@ -33,7 +35,7 @@ class Twig_SimpleFunction
33
  'is_variadic' => false,
34
  'is_safe' => null,
35
  'is_safe_callback' => null,
36
- 'node_class' => 'Twig_Node_Expression_Function',
37
  'deprecated' => false,
38
  'alternative' => null,
39
  ], $options);
@@ -74,14 +76,14 @@ class Twig_SimpleFunction
74
  return $this->options['needs_context'];
75
  }
76
 
77
- public function getSafe(Twig_Node $functionArgs)
78
  {
79
  if (null !== $this->options['is_safe']) {
80
  return $this->options['is_safe'];
81
  }
82
 
83
  if (null !== $this->options['is_safe_callback']) {
84
- return call_user_func($this->options['is_safe_callback'], $functionArgs);
85
  }
86
 
87
  return [];
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Node\Node;
13
+
14
  /**
15
  * Represents a template function.
16
  *
35
  'is_variadic' => false,
36
  'is_safe' => null,
37
  'is_safe_callback' => null,
38
+ 'node_class' => '\Twig\Node\Expression\FunctionExpression',
39
  'deprecated' => false,
40
  'alternative' => null,
41
  ], $options);
76
  return $this->options['needs_context'];
77
  }
78
 
79
+ public function getSafe(Node $functionArgs)
80
  {
81
  if (null !== $this->options['is_safe']) {
82
  return $this->options['is_safe'];
83
  }
84
 
85
  if (null !== $this->options['is_safe_callback']) {
86
+ return \call_user_func($this->options['is_safe_callback'], $functionArgs);
87
  }
88
 
89
  return [];
vendor/twig/twig/lib/Twig/SimpleTest.php CHANGED
@@ -30,7 +30,7 @@ class Twig_SimpleTest
30
  $this->callable = $callable;
31
  $this->options = array_merge([
32
  'is_variadic' => false,
33
- 'node_class' => 'Twig_Node_Expression_Test',
34
  'deprecated' => false,
35
  'alternative' => null,
36
  ], $options);
30
  $this->callable = $callable;
31
  $this->options = array_merge([
32
  'is_variadic' => false,
33
+ 'node_class' => '\Twig\Node\Expression\TestExpression',
34
  'deprecated' => false,
35
  'alternative' => null,
36
  ], $options);
vendor/twig/twig/lib/Twig/SourceContextLoaderInterface.php CHANGED
@@ -9,6 +9,9 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
12
  /**
13
  * Adds a getSourceContext() method for loaders.
14
  *
@@ -23,9 +26,9 @@ interface Twig_SourceContextLoaderInterface
23
  *
24
  * @param string $name The template logical name
25
  *
26
- * @return Twig_Source
27
  *
28
- * @throws Twig_Error_Loader When $name is not found
29
  */
30
  public function getSourceContext($name);
31
  }
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Error\LoaderError;
13
+ use Twig\Source;
14
+
15
  /**
16
  * Adds a getSourceContext() method for loaders.
17
  *
26
  *
27
  * @param string $name The template logical name
28
  *
29
+ * @return Source
30
  *
31
+ * @throws LoaderError When $name is not found
32
  */
33
  public function getSourceContext($name);
34
  }
vendor/twig/twig/lib/Twig/Template.php CHANGED
@@ -10,6 +10,14 @@
10
  * file that was distributed with this source code.
11
  */
12
 
 
 
 
 
 
 
 
 
13
  /**
14
  * Default base class for compiled templates.
15
  *
@@ -34,7 +42,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
34
  protected $blocks = [];
35
  protected $traits = [];
36
 
37
- public function __construct(Twig_Environment $env)
38
  {
39
  $this->env = $env;
40
  }
@@ -83,11 +91,11 @@ abstract class Twig_Template implements Twig_TemplateInterface
83
  /**
84
  * Returns information about the original template source code.
85
  *
86
- * @return Twig_Source
87
  */
88
  public function getSourceContext()
89
  {
90
- return new Twig_Source('', $this->getTemplateName());
91
  }
92
 
93
  /**
@@ -108,7 +116,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
108
  *
109
  * @param array $context
110
  *
111
- * @return Twig_TemplateInterface|Twig_TemplateWrapper|false The parent template or false if there is no parent
112
  *
113
  * @internal
114
  */
@@ -125,14 +133,14 @@ abstract class Twig_Template implements Twig_TemplateInterface
125
  return false;
126
  }
127
 
128
- if ($parent instanceof self || $parent instanceof Twig_TemplateWrapper) {
129
  return $this->parents[$parent->getSourceContext()->getName()] = $parent;
130
  }
131
 
132
  if (!isset($this->parents[$parent])) {
133
  $this->parents[$parent] = $this->loadTemplate($parent);
134
  }
135
- } catch (Twig_Error_Loader $e) {
136
  $e->setSourceContext(null);
137
  $e->guess();
138
 
@@ -173,7 +181,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
173
  } elseif (false !== $parent = $this->getParent($context)) {
174
  $parent->displayBlock($name, $context, $blocks, false);
175
  } else {
176
- throw new Twig_Error_Runtime(sprintf('The template has no parent and no traits defining the "%s" block.', $name), -1, $this->getSourceContext());
177
  }
178
  }
179
 
@@ -207,13 +215,13 @@ abstract class Twig_Template implements Twig_TemplateInterface
207
 
208
  // avoid RCEs when sandbox is enabled
209
  if (null !== $template && !$template instanceof self) {
210
- throw new LogicException('A block must be a method on a Twig_Template instance.');
211
  }
212
 
213
  if (null !== $template) {
214
  try {
215
  $template->$block($context, $blocks);
216
- } catch (Twig_Error $e) {
217
  if (!$e->getSourceContext()) {
218
  $e->setSourceContext($template->getSourceContext());
219
  }
@@ -226,8 +234,8 @@ abstract class Twig_Template implements Twig_TemplateInterface
226
  }
227
 
228
  throw $e;
229
- } catch (Exception $e) {
230
- throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $template->getSourceContext(), $e);
231
  }
232
  } elseif (false !== $parent = $this->getParent($context)) {
233
  $parent->displayBlock($name, $context, array_merge($this->blocks, $blocks), false);
@@ -351,18 +359,18 @@ abstract class Twig_Template implements Twig_TemplateInterface
351
  protected function loadTemplate($template, $templateName = null, $line = null, $index = null)
352
  {
353
  try {
354
- if (is_array($template)) {
355
  return $this->env->resolveTemplate($template);
356
  }
357
 
358
- if ($template instanceof self || $template instanceof Twig_TemplateWrapper) {
359
  return $template;
360
  }
361
 
362
  return $this->env->loadTemplate($template, $index);
363
- } catch (Twig_Error $e) {
364
  if (!$e->getSourceContext()) {
365
- $e->setSourceContext($templateName ? new Twig_Source('', $templateName) : $this->getSourceContext());
366
  }
367
 
368
  if ($e->getTemplateLine()) {
@@ -405,13 +413,13 @@ abstract class Twig_Template implements Twig_TemplateInterface
405
  ob_start();
406
  try {
407
  $this->display($context);
408
- } catch (Exception $e) {
409
  while (ob_get_level() > $level) {
410
  ob_end_clean();
411
  }
412
 
413
  throw $e;
414
- } catch (Throwable $e) {
415
  while (ob_get_level() > $level) {
416
  ob_end_clean();
417
  }
@@ -426,7 +434,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
426
  {
427
  try {
428
  $this->doDisplay($context, $blocks);
429
- } catch (Twig_Error $e) {
430
  if (!$e->getSourceContext()) {
431
  $e->setSourceContext($this->getSourceContext());
432
  }
@@ -439,8 +447,8 @@ abstract class Twig_Template implements Twig_TemplateInterface
439
  }
440
 
441
  throw $e;
442
- } catch (Exception $e) {
443
- throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $this->getSourceContext(), $e);
444
  }
445
  }
446
 
@@ -469,18 +477,18 @@ abstract class Twig_Template implements Twig_TemplateInterface
469
  *
470
  * @return mixed The content of the context variable
471
  *
472
- * @throws Twig_Error_Runtime if the variable does not exist and Twig is running in strict mode
473
  *
474
  * @internal
475
  */
476
  final protected function getContext($context, $item, $ignoreStrictCheck = false)
477
  {
478
- if (!array_key_exists($item, $context)) {
479
  if ($ignoreStrictCheck || !$this->env->isStrictVariables()) {
480
  return;
481
  }
482
 
483
- throw new Twig_Error_Runtime(sprintf('Variable "%s" does not exist.', $item), -1, $this->getSourceContext());
484
  }
485
 
486
  return $context[$item];
@@ -498,7 +506,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
498
  *
499
  * @return mixed The attribute value, or a Boolean when $isDefinedTest is true, or null when the attribute is not set and $ignoreStrictCheck is true
500
  *
501
- * @throws Twig_Error_Runtime if the attribute does not exist and Twig is running in strict mode and $isDefinedTest is false
502
  *
503
  * @internal
504
  */
@@ -506,9 +514,9 @@ abstract class Twig_Template implements Twig_TemplateInterface
506
  {
507
  // array
508
  if (self::METHOD_CALL !== $type) {
509
- $arrayItem = is_bool($item) || is_float($item) ? (int) $item : $item;
510
 
511
- if (((is_array($object) || $object instanceof ArrayObject) && (isset($object[$arrayItem]) || array_key_exists($arrayItem, $object)))
512
  || ($object instanceof ArrayAccess && isset($object[$arrayItem]))
513
  ) {
514
  if ($isDefinedTest) {
@@ -518,7 +526,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
518
  return $object[$arrayItem];
519
  }
520
 
521
- if (self::ARRAY_CALL === $type || !is_object($object)) {
522
  if ($isDefinedTest) {
523
  return false;
524
  }
@@ -528,10 +536,10 @@ abstract class Twig_Template implements Twig_TemplateInterface
528
  }
529
 
530
  if ($object instanceof ArrayAccess) {
531
- $message = sprintf('Key "%s" in object with ArrayAccess of class "%s" does not exist.', $arrayItem, get_class($object));
532
- } elseif (is_object($object)) {
533
- $message = sprintf('Impossible to access a key "%s" on an object of class "%s" that does not implement ArrayAccess interface.', $item, get_class($object));
534
- } elseif (is_array($object)) {
535
  if (empty($object)) {
536
  $message = sprintf('Key "%s" does not exist as the array is empty.', $arrayItem);
537
  } else {
@@ -541,19 +549,19 @@ abstract class Twig_Template implements Twig_TemplateInterface
541
  if (null === $object) {
542
  $message = sprintf('Impossible to access a key ("%s") on a null variable.', $item);
543
  } else {
544
- $message = sprintf('Impossible to access a key ("%s") on a %s variable ("%s").', $item, gettype($object), $object);
545
  }
546
  } elseif (null === $object) {
547
  $message = sprintf('Impossible to access an attribute ("%s") on a null variable.', $item);
548
  } else {
549
- $message = sprintf('Impossible to access an attribute ("%s") on a %s variable ("%s").', $item, gettype($object), $object);
550
  }
551
 
552
- throw new Twig_Error_Runtime($message, -1, $this->getSourceContext());
553
  }
554
  }
555
 
556
- if (!is_object($object)) {
557
  if ($isDefinedTest) {
558
  return false;
559
  }
@@ -564,40 +572,40 @@ abstract class Twig_Template implements Twig_TemplateInterface
564
 
565
  if (null === $object) {
566
  $message = sprintf('Impossible to invoke a method ("%s") on a null variable.', $item);
567
- } elseif (is_array($object)) {
568
  $message = sprintf('Impossible to invoke a method ("%s") on an array.', $item);
569
  } else {
570
- $message = sprintf('Impossible to invoke a method ("%s") on a %s variable ("%s").', $item, gettype($object), $object);
571
  }
572
 
573
- throw new Twig_Error_Runtime($message, -1, $this->getSourceContext());
574
  }
575
 
576
  // object property
577
  if (self::METHOD_CALL !== $type && !$object instanceof self) { // Twig_Template does not have public properties, and we don't want to allow access to internal ones
578
- if (isset($object->$item) || array_key_exists((string) $item, $object)) {
579
  if ($isDefinedTest) {
580
  return true;
581
  }
582
 
583
- if ($this->env->hasExtension('Twig_Extension_Sandbox')) {
584
- $this->env->getExtension('Twig_Extension_Sandbox')->checkPropertyAllowed($object, $item);
585
  }
586
 
587
  return $object->$item;
588
  }
589
  }
590
 
591
- $class = get_class($object);
592
 
593
  // object method
594
  if (!isset(self::$cache[$class])) {
595
  // get_class_methods returns all methods accessible in the scope, but we only want public ones to be accessible in templates
596
  if ($object instanceof self) {
597
- $ref = new ReflectionClass($class);
598
  $methods = [];
599
 
600
- foreach ($ref->getMethods(ReflectionMethod::IS_PUBLIC) as $refMethod) {
601
  // Accessing the environment from templates is forbidden to prevent untrusted changes to the environment
602
  if ('getenvironment' !== strtolower($refMethod->name)) {
603
  $methods[] = $refMethod->name;
@@ -655,15 +663,15 @@ abstract class Twig_Template implements Twig_TemplateInterface
655
  return;
656
  }
657
 
658
- throw new Twig_Error_Runtime(sprintf('Neither the property "%1$s" nor one of the methods "%1$s()", "get%1$s()"/"is%1$s()" or "__call()" exist and have public access in class "%2$s".', $item, $class), -1, $this->getSourceContext());
659
  }
660
 
661
  if ($isDefinedTest) {
662
  return true;
663
  }
664
 
665
- if ($this->env->hasExtension('Twig_Extension_Sandbox')) {
666
- $this->env->getExtension('Twig_Extension_Sandbox')->checkMethodAllowed($object, $method);
667
  }
668
 
669
  // Some objects throw exceptions when they have __call, and the method we try
@@ -672,9 +680,9 @@ abstract class Twig_Template implements Twig_TemplateInterface
672
  if (!$arguments) {
673
  $ret = $object->$method();
674
  } else {
675
- $ret = call_user_func_array([$object, $method], $arguments);
676
  }
677
- } catch (BadMethodCallException $e) {
678
  if ($call && ($ignoreStrictCheck || !$this->env->isStrictVariables())) {
679
  return;
680
  }
@@ -694,7 +702,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
694
  }
695
  @trigger_error($message, E_USER_DEPRECATED);
696
 
697
- return '' === $ret ? '' : new Twig_Markup($ret, $this->env->getCharset());
698
  }
699
 
700
  return $ret;
10
  * file that was distributed with this source code.
11
  */
12
 
13
+ use Twig\Environment;
14
+ use Twig\Error\Error;
15
+ use Twig\Error\LoaderError;
16
+ use Twig\Error\RuntimeError;
17
+ use Twig\Markup;
18
+ use Twig\Source;
19
+ use Twig\TemplateWrapper;
20
+
21
  /**
22
  * Default base class for compiled templates.
23
  *
42
  protected $blocks = [];
43
  protected $traits = [];
44
 
45
+ public function __construct(Environment $env)
46
  {
47
  $this->env = $env;
48
  }
91
  /**
92
  * Returns information about the original template source code.
93
  *
94
+ * @return Source
95
  */
96
  public function getSourceContext()
97
  {
98
+ return new Source('', $this->getTemplateName());
99
  }
100
 
101
  /**
116
  *
117
  * @param array $context
118
  *
119
+ * @return Twig_TemplateInterface|TemplateWrapper|false The parent template or false if there is no parent
120
  *
121
  * @internal
122
  */
133
  return false;
134
  }
135
 
136
+ if ($parent instanceof self || $parent instanceof TemplateWrapper) {
137
  return $this->parents[$parent->getSourceContext()->getName()] = $parent;
138
  }
139
 
140
  if (!isset($this->parents[$parent])) {
141
  $this->parents[$parent] = $this->loadTemplate($parent);
142
  }
143
+ } catch (LoaderError $e) {
144
  $e->setSourceContext(null);
145
  $e->guess();
146
 
181
  } elseif (false !== $parent = $this->getParent($context)) {
182
  $parent->displayBlock($name, $context, $blocks, false);
183
  } else {
184
+ throw new RuntimeError(sprintf('The template has no parent and no traits defining the "%s" block.', $name), -1, $this->getSourceContext());
185
  }
186
  }
187
 
215
 
216
  // avoid RCEs when sandbox is enabled
217
  if (null !== $template && !$template instanceof self) {
218
+ throw new \LogicException('A block must be a method on a Twig_Template instance.');
219
  }
220
 
221
  if (null !== $template) {
222
  try {
223
  $template->$block($context, $blocks);
224
+ } catch (Error $e) {
225
  if (!$e->getSourceContext()) {
226
  $e->setSourceContext($template->getSourceContext());
227
  }
234
  }
235
 
236
  throw $e;
237
+ } catch (\Exception $e) {
238
+ throw new RuntimeError(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $template->getSourceContext(), $e);
239
  }
240
  } elseif (false !== $parent = $this->getParent($context)) {
241
  $parent->displayBlock($name, $context, array_merge($this->blocks, $blocks), false);
359
  protected function loadTemplate($template, $templateName = null, $line = null, $index = null)
360
  {
361
  try {
362
+ if (\is_array($template)) {
363
  return $this->env->resolveTemplate($template);
364
  }
365
 
366
+ if ($template instanceof self || $template instanceof TemplateWrapper) {
367
  return $template;
368
  }
369
 
370
  return $this->env->loadTemplate($template, $index);
371
+ } catch (Error $e) {
372
  if (!$e->getSourceContext()) {
373
+ $e->setSourceContext($templateName ? new Source('', $templateName) : $this->getSourceContext());
374
  }
375
 
376
  if ($e->getTemplateLine()) {
413
  ob_start();
414
  try {
415
  $this->display($context);
416
+ } catch (\Exception $e) {
417
  while (ob_get_level() > $level) {
418
  ob_end_clean();
419
  }
420
 
421
  throw $e;
422
+ } catch (\Throwable $e) {
423
  while (ob_get_level() > $level) {
424
  ob_end_clean();
425
  }
434
  {
435
  try {
436
  $this->doDisplay($context, $blocks);
437
+ } catch (Error $e) {
438
  if (!$e->getSourceContext()) {
439
  $e->setSourceContext($this->getSourceContext());
440
  }
447
  }
448
 
449
  throw $e;
450
+ } catch (\Exception $e) {
451
+ throw new RuntimeError(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $this->getSourceContext(), $e);
452
  }
453
  }
454
 
477
  *
478
  * @return mixed The content of the context variable
479
  *
480
+ * @throws RuntimeError if the variable does not exist and Twig is running in strict mode
481
  *
482
  * @internal
483
  */
484
  final protected function getContext($context, $item, $ignoreStrictCheck = false)
485
  {
486
+ if (!\array_key_exists($item, $context)) {
487
  if ($ignoreStrictCheck || !$this->env->isStrictVariables()) {
488
  return;
489
  }
490
 
491
+ throw new RuntimeError(sprintf('Variable "%s" does not exist.', $item), -1, $this->getSourceContext());
492
  }
493
 
494
  return $context[$item];
506
  *
507
  * @return mixed The attribute value, or a Boolean when $isDefinedTest is true, or null when the attribute is not set and $ignoreStrictCheck is true
508
  *
509
+ * @throws RuntimeError if the attribute does not exist and Twig is running in strict mode and $isDefinedTest is false
510
  *
511
  * @internal
512
  */
514
  {
515
  // array
516
  if (self::METHOD_CALL !== $type) {
517
+ $arrayItem = \is_bool($item) || \is_float($item) ? (int) $item : $item;
518
 
519
+ if (((\is_array($object) || $object instanceof \ArrayObject) && (isset($object[$arrayItem]) || \array_key_exists($arrayItem, $object)))
520
  || ($object instanceof ArrayAccess && isset($object[$arrayItem]))
521
  ) {
522
  if ($isDefinedTest) {
526
  return $object[$arrayItem];
527
  }
528
 
529
+ if (self::ARRAY_CALL === $type || !\is_object($object)) {
530
  if ($isDefinedTest) {
531
  return false;
532
  }
536
  }
537
 
538
  if ($object instanceof ArrayAccess) {
539
+ $message = sprintf('Key "%s" in object with ArrayAccess of class "%s" does not exist.', $arrayItem, \get_class($object));
540
+ } elseif (\is_object($object)) {
541
+ $message = sprintf('Impossible to access a key "%s" on an object of class "%s" that does not implement ArrayAccess interface.', $item, \get_class($object));
542
+ } elseif (\is_array($object)) {
543
  if (empty($object)) {
544
  $message = sprintf('Key "%s" does not exist as the array is empty.', $arrayItem);
545
  } else {
549
  if (null === $object) {
550
  $message = sprintf('Impossible to access a key ("%s") on a null variable.', $item);
551
  } else {
552
+ $message = sprintf('Impossible to access a key ("%s") on a %s variable ("%s").', $item, \gettype($object), $object);
553
  }
554
  } elseif (null === $object) {
555
  $message = sprintf('Impossible to access an attribute ("%s") on a null variable.', $item);
556
  } else {
557
+ $message = sprintf('Impossible to access an attribute ("%s") on a %s variable ("%s").', $item, \gettype($object), $object);
558
  }
559
 
560
+ throw new RuntimeError($message, -1, $this->getSourceContext());
561
  }
562
  }
563
 
564
+ if (!\is_object($object)) {
565
  if ($isDefinedTest) {
566
  return false;
567
  }
572
 
573
  if (null === $object) {
574
  $message = sprintf('Impossible to invoke a method ("%s") on a null variable.', $item);
575
+ } elseif (\is_array($object)) {
576
  $message = sprintf('Impossible to invoke a method ("%s") on an array.', $item);
577
  } else {
578
+ $message = sprintf('Impossible to invoke a method ("%s") on a %s variable ("%s").', $item, \gettype($object), $object);
579
  }
580
 
581
+ throw new RuntimeError($message, -1, $this->getSourceContext());
582
  }
583
 
584
  // object property
585
  if (self::METHOD_CALL !== $type && !$object instanceof self) { // Twig_Template does not have public properties, and we don't want to allow access to internal ones
586
+ if (isset($object->$item) || \array_key_exists((string) $item, $object)) {
587
  if ($isDefinedTest) {
588
  return true;
589
  }
590
 
591
+ if ($this->env->hasExtension('\Twig\Extension\SandboxExtension')) {
592
+ $this->env->getExtension('\Twig\Extension\SandboxExtension')->checkPropertyAllowed($object, $item);
593
  }
594
 
595
  return $object->$item;
596
  }
597
  }
598
 
599
+ $class = \get_class($object);
600
 
601
  // object method
602
  if (!isset(self::$cache[$class])) {
603
  // get_class_methods returns all methods accessible in the scope, but we only want public ones to be accessible in templates
604
  if ($object instanceof self) {
605
+ $ref = new \ReflectionClass($class);
606
  $methods = [];
607
 
608
+ foreach ($ref->getMethods(\ReflectionMethod::IS_PUBLIC) as $refMethod) {
609
  // Accessing the environment from templates is forbidden to prevent untrusted changes to the environment
610
  if ('getenvironment' !== strtolower($refMethod->name)) {
611
  $methods[] = $refMethod->name;
663
  return;
664
  }
665
 
666
+ throw new RuntimeError(sprintf('Neither the property "%1$s" nor one of the methods "%1$s()", "get%1$s()"/"is%1$s()" or "__call()" exist and have public access in class "%2$s".', $item, $class), -1, $this->getSourceContext());
667
  }
668
 
669
  if ($isDefinedTest) {
670
  return true;
671
  }
672
 
673
+ if ($this->env->hasExtension('\Twig\Extension\SandboxExtension')) {
674
+ $this->env->getExtension('\Twig\Extension\SandboxExtension')->checkMethodAllowed($object, $method);
675
  }
676
 
677
  // Some objects throw exceptions when they have __call, and the method we try
680
  if (!$arguments) {
681
  $ret = $object->$method();
682
  } else {
683
+ $ret = \call_user_func_array([$object, $method], $arguments);
684
  }
685
+ } catch (\BadMethodCallException $e) {
686
  if ($call && ($ignoreStrictCheck || !$this->env->isStrictVariables())) {
687
  return;
688
  }
702
  }
703
  @trigger_error($message, E_USER_DEPRECATED);
704
 
705
+ return '' === $ret ? '' : new Markup($ret, $this->env->getCharset());
706
  }
707
 
708
  return $ret;
vendor/twig/twig/lib/Twig/TemplateInterface.php CHANGED
@@ -9,6 +9,8 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
12
  /**
13
  * Interface implemented by all compiled templates.
14
  *
@@ -42,7 +44,7 @@ interface Twig_TemplateInterface
42
  /**
43
  * Returns the bound environment for this template.
44
  *
45
- * @return Twig_Environment
46
  */
47
  public function getEnvironment();
48
  }
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Environment;
13
+
14
  /**
15
  * Interface implemented by all compiled templates.
16
  *
44
  /**
45
  * Returns the bound environment for this template.
46
  *
47
+ * @return Environment
48
  */
49
  public function getEnvironment();
50
  }
vendor/twig/twig/lib/Twig/TemplateWrapper.php CHANGED
@@ -9,6 +9,10 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
12
  /**
13
  * Exposes a template to userland.
14
  *
@@ -21,11 +25,11 @@ final class Twig_TemplateWrapper
21
 
22
  /**
23
  * This method is for internal use only and should never be called
24
- * directly (use Twig_Environment::load() instead).
25
  *
26
  * @internal
27
  */
28
- public function __construct(Twig_Environment $env, Twig_Template $template)
29
  {
30
  $this->env = $env;
31
  $this->template = $template;
@@ -42,7 +46,7 @@ final class Twig_TemplateWrapper
42
  {
43
  // using func_get_args() allows to not expose the blocks argument
44
  // as it should only be used by internal code
45
- return $this->template->render($context, func_num_args() > 1 ? func_get_arg(1) : []);
46
  }
47
 
48
  /**
@@ -54,7 +58,7 @@ final class Twig_TemplateWrapper
54
  {
55
  // using func_get_args() allows to not expose the blocks argument
56
  // as it should only be used by internal code
57
- $this->template->display($context, func_num_args() >= 1 ? func_get_arg(1) : []);
58
  }
59
 
60
  /**
@@ -97,13 +101,13 @@ final class Twig_TemplateWrapper
97
  ob_start();
98
  try {
99
  $this->template->displayBlock($name, $context);
100
- } catch (Exception $e) {
101
  while (ob_get_level() > $level) {
102
  ob_end_clean();
103
  }
104
 
105
  throw $e;
106
- } catch (Throwable $e) {
107
  while (ob_get_level() > $level) {
108
  ob_end_clean();
109
  }
@@ -126,7 +130,7 @@ final class Twig_TemplateWrapper
126
  }
127
 
128
  /**
129
- * @return Twig_Source
130
  */
131
  public function getSourceContext()
132
  {
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Environment;
13
+ use Twig\Source;
14
+ use Twig\Template;
15
+
16
  /**
17
  * Exposes a template to userland.
18
  *
25
 
26
  /**
27
  * This method is for internal use only and should never be called
28
+ * directly (use Twig\Environment::load() instead).
29
  *
30
  * @internal
31
  */
32
+ public function __construct(Environment $env, Template $template)
33
  {
34
  $this->env = $env;
35
  $this->template = $template;
46
  {
47
  // using func_get_args() allows to not expose the blocks argument
48
  // as it should only be used by internal code
49
+ return $this->template->render($context, \func_num_args() > 1 ? func_get_arg(1) : []);
50
  }
51
 
52
  /**
58
  {
59
  // using func_get_args() allows to not expose the blocks argument
60
  // as it should only be used by internal code
61
+ $this->template->display($context, \func_num_args() >= 1 ? func_get_arg(1) : []);
62
  }
63
 
64
  /**
101
  ob_start();
102
  try {
103
  $this->template->displayBlock($name, $context);
104
+ } catch (\Exception $e) {
105
  while (ob_get_level() > $level) {
106
  ob_end_clean();
107
  }
108
 
109
  throw $e;
110
+ } catch (\Throwable $e) {
111
  while (ob_get_level() > $level) {
112
  ob_end_clean();
113
  }
130
  }
131
 
132
  /**
133
+ * @return Source
134
  */
135
  public function getSourceContext()
136
  {
vendor/twig/twig/lib/Twig/Test/IntegrationTestCase.php CHANGED
@@ -10,6 +10,16 @@
10
  */
11
 
12
  use PHPUnit\Framework\TestCase;
 
 
 
 
 
 
 
 
 
 
13
 
14
  /**
15
  * Integration test helper.
@@ -25,7 +35,7 @@ abstract class Twig_Test_IntegrationTestCase extends TestCase
25
  abstract protected function getFixturesDir();
26
 
27
  /**
28
- * @return Twig_RuntimeLoaderInterface[]
29
  */
30
  protected function getRuntimeLoaders()
31
  {
@@ -33,7 +43,7 @@ abstract class Twig_Test_IntegrationTestCase extends TestCase
33
  }
34
 
35
  /**
36
- * @return Twig_ExtensionInterface[]
37
  */
38
  protected function getExtensions()
39
  {
@@ -41,7 +51,7 @@ abstract class Twig_Test_IntegrationTestCase extends TestCase
41
  }
42
 
43
  /**
44
- * @return Twig_SimpleFilter[]
45
  */
46
  protected function getTwigFilters()
47
  {
@@ -49,7 +59,7 @@ abstract class Twig_Test_IntegrationTestCase extends TestCase
49
  }
50
 
51
  /**
52
- * @return Twig_SimpleFunction[]
53
  */
54
  protected function getTwigFunctions()
55
  {
@@ -57,7 +67,7 @@ abstract class Twig_Test_IntegrationTestCase extends TestCase
57
  }
58
 
59
  /**
60
- * @return Twig_SimpleTest[]
61
  */
62
  protected function getTwigTests()
63
  {
@@ -86,7 +96,7 @@ abstract class Twig_Test_IntegrationTestCase extends TestCase
86
  $fixturesDir = realpath($this->getFixturesDir());
87
  $tests = [];
88
 
89
- foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($fixturesDir), RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
90
  if (!preg_match('/\.test$/', $file)) {
91
  continue;
92
  }
@@ -110,7 +120,7 @@ abstract class Twig_Test_IntegrationTestCase extends TestCase
110
  $exception = false;
111
  preg_match_all('/--DATA--(.*?)(?:--CONFIG--(.*?))?--EXPECT--(.*?)(?=\-\-DATA\-\-|$)/s', $test, $outputs, PREG_SET_ORDER);
112
  } else {
113
- throw new InvalidArgumentException(sprintf('Test "%s" is not valid.', str_replace($fixturesDir.'/', '', $file)));
114
  }
115
 
116
  $tests[] = [str_replace($fixturesDir.'/', '', $file), $message, $condition, $templates, $exception, $outputs];
@@ -142,14 +152,14 @@ abstract class Twig_Test_IntegrationTestCase extends TestCase
142
  }
143
  }
144
 
145
- $loader = new Twig_Loader_Array($templates);
146
 
147
  foreach ($outputs as $i => $match) {
148
  $config = array_merge([
149
  'cache' => false,
150
  'strict_variables' => true,
151
  ], $match[2] ? eval($match[2].';') : []);
152
- $twig = new Twig_Environment($loader, $config);
153
  $twig->addGlobal('global', 'global');
154
  foreach ($this->getRuntimeLoaders() as $runtimeLoader) {
155
  $twig->addRuntimeLoader($runtimeLoader);
@@ -171,37 +181,37 @@ abstract class Twig_Test_IntegrationTestCase extends TestCase
171
  $twig->addFunction($function);
172
  }
173
 
174
- $p = new ReflectionProperty($twig, 'templateClassPrefix');
175
  $p->setAccessible(true);
176
  $p->setValue($twig, '__TwigTemplate_'.hash('sha256', uniqid(mt_rand(), true), false).'_');
177
 
178
  try {
179
  $template = $twig->loadTemplate('index.twig');
180
- } catch (Exception $e) {
181
  if (false !== $exception) {
182
  $message = $e->getMessage();
183
- $this->assertSame(trim($exception), trim(sprintf('%s: %s', get_class($e), $message)));
184
- $last = substr($message, strlen($message) - 1);
185
  $this->assertTrue('.' === $last || '?' === $last, $message, 'Exception message must end with a dot or a question mark.');
186
 
187
  return;
188
  }
189
 
190
- throw new Twig_Error(sprintf('%s: %s', get_class($e), $e->getMessage()), -1, $file, $e);
191
  }
192
 
193
  try {
194
  $output = trim($template->render(eval($match[1].';')), "\n ");
195
- } catch (Exception $e) {
196
  if (false !== $exception) {
197
- $this->assertSame(trim($exception), trim(sprintf('%s: %s', get_class($e), $e->getMessage())));
198
 
199
  return;
200
  }
201
 
202
- $e = new Twig_Error(sprintf('%s: %s', get_class($e), $e->getMessage()), -1, $file, $e);
203
 
204
- $output = trim(sprintf('%s: %s', get_class($e), $e->getMessage()));
205
  }
206
 
207
  if (false !== $exception) {
@@ -218,8 +228,8 @@ abstract class Twig_Test_IntegrationTestCase extends TestCase
218
  foreach (array_keys($templates) as $name) {
219
  echo "Template: $name\n";
220
  $loader = $twig->getLoader();
221
- if (!$loader instanceof Twig_SourceContextLoaderInterface) {
222
- $source = new Twig_Source($loader->getSource($name), $name);
223
  } else {
224
  $source = $loader->getSourceContext($name);
225
  }
10
  */
11
 
12
  use PHPUnit\Framework\TestCase;
13
+ use Twig\Environment;
14
+ use Twig\Error\Error;
15
+ use Twig\Extension\ExtensionInterface;
16
+ use Twig\Loader\ArrayLoader;
17
+ use Twig\Loader\SourceContextLoaderInterface;
18
+ use Twig\RuntimeLoader\RuntimeLoaderInterface;
19
+ use Twig\Source;
20
+ use Twig\TwigFilter;
21
+ use Twig\TwigFunction;
22
+ use Twig\TwigTest;
23
 
24
  /**
25
  * Integration test helper.
35
  abstract protected function getFixturesDir();
36
 
37
  /**
38
+ * @return RuntimeLoaderInterface[]
39
  */
40
  protected function getRuntimeLoaders()
41
  {
43
  }
44
 
45
  /**
46
+ * @return ExtensionInterface[]
47
  */
48
  protected function getExtensions()
49
  {
51
  }
52
 
53
  /**
54
+ * @return TwigFilter[]
55
  */
56
  protected function getTwigFilters()
57
  {
59
  }
60
 
61
  /**
62
+ * @return TwigFunction[]
63
  */
64
  protected function getTwigFunctions()
65
  {
67
  }
68
 
69
  /**
70
+ * @return TwigTest[]
71
  */
72
  protected function getTwigTests()
73
  {
96
  $fixturesDir = realpath($this->getFixturesDir());
97
  $tests = [];
98
 
99
+ foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($fixturesDir), \RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
100
  if (!preg_match('/\.test$/', $file)) {
101
  continue;
102
  }
120
  $exception = false;
121
  preg_match_all('/--DATA--(.*?)(?:--CONFIG--(.*?))?--EXPECT--(.*?)(?=\-\-DATA\-\-|$)/s', $test, $outputs, PREG_SET_ORDER);
122
  } else {
123
+ throw new \InvalidArgumentException(sprintf('Test "%s" is not valid.', str_replace($fixturesDir.'/', '', $file)));
124
  }
125
 
126
  $tests[] = [str_replace($fixturesDir.'/', '', $file), $message, $condition, $templates, $exception, $outputs];
152
  }
153
  }
154
 
155
+ $loader = new ArrayLoader($templates);
156
 
157
  foreach ($outputs as $i => $match) {
158
  $config = array_merge([
159
  'cache' => false,
160
  'strict_variables' => true,
161
  ], $match[2] ? eval($match[2].';') : []);
162
+ $twig = new Environment($loader, $config);
163
  $twig->addGlobal('global', 'global');
164
  foreach ($this->getRuntimeLoaders() as $runtimeLoader) {
165
  $twig->addRuntimeLoader($runtimeLoader);
181
  $twig->addFunction($function);
182
  }
183
 
184
+ $p = new \ReflectionProperty($twig, 'templateClassPrefix');
185
  $p->setAccessible(true);
186
  $p->setValue($twig, '__TwigTemplate_'.hash('sha256', uniqid(mt_rand(), true), false).'_');
187
 
188
  try {
189
  $template = $twig->loadTemplate('index.twig');
190
+ } catch (\Exception $e) {
191
  if (false !== $exception) {
192
  $message = $e->getMessage();
193
+ $this->assertSame(trim($exception), trim(sprintf('%s: %s', \get_class($e), $message)));
194
+ $last = substr($message, \strlen($message) - 1);
195
  $this->assertTrue('.' === $last || '?' === $last, $message, 'Exception message must end with a dot or a question mark.');
196
 
197
  return;
198
  }
199
 
200
+ throw new Error(sprintf('%s: %s', \get_class($e), $e->getMessage()), -1, $file, $e);
201
  }
202
 
203
  try {
204
  $output = trim($template->render(eval($match[1].';')), "\n ");
205
+ } catch (\Exception $e) {
206
  if (false !== $exception) {
207
+ $this->assertSame(trim($exception), trim(sprintf('%s: %s', \get_class($e), $e->getMessage())));
208
 
209
  return;
210
  }
211
 
212
+ $e = new Error(sprintf('%s: %s', \get_class($e), $e->getMessage()), -1, $file, $e);
213
 
214
+ $output = trim(sprintf('%s: %s', \get_class($e), $e->getMessage()));
215
  }
216
 
217
  if (false !== $exception) {
228
  foreach (array_keys($templates) as $name) {
229
  echo "Template: $name\n";
230
  $loader = $twig->getLoader();
231
+ if (!$loader instanceof SourceContextLoaderInterface) {
232
+ $source = new Source($loader->getSource($name), $name);
233
  } else {
234
  $source = $loader->getSourceContext($name);
235
  }
vendor/twig/twig/lib/Twig/Test/Method.php CHANGED
@@ -9,6 +9,8 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
12
  @trigger_error('The Twig_Test_Method class is deprecated since version 1.12 and will be removed in 2.0. Use Twig_SimpleTest instead.', E_USER_DEPRECATED);
13
 
14
  /**
@@ -23,7 +25,7 @@ class Twig_Test_Method extends Twig_Test
23
  protected $extension;
24
  protected $method;
25
 
26
- public function __construct(Twig_ExtensionInterface $extension, $method, array $options = [])
27
  {
28
  $options['callable'] = [$extension, $method];
29
 
@@ -35,6 +37,6 @@ class Twig_Test_Method extends Twig_Test
35
 
36
  public function compile()
37
  {
38
- return sprintf('$this->env->getExtension(\'%s\')->%s', get_class($this->extension), $this->method);
39
  }
40
  }
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Extension\ExtensionInterface;
13
+
14
  @trigger_error('The Twig_Test_Method class is deprecated since version 1.12 and will be removed in 2.0. Use Twig_SimpleTest instead.', E_USER_DEPRECATED);
15
 
16
  /**
25
  protected $extension;
26
  protected $method;
27
 
28
+ public function __construct(ExtensionInterface $extension, $method, array $options = [])
29
  {
30
  $options['callable'] = [$extension, $method];
31
 
37
 
38
  public function compile()
39
  {
40
+ return sprintf('$this->env->getExtension(\'%s\')->%s', \get_class($this->extension), $this->method);
41
  }
42
  }
vendor/twig/twig/lib/Twig/Test/NodeTestCase.php CHANGED
@@ -10,6 +10,10 @@
10
  */
11
 
12
  use PHPUnit\Framework\TestCase;
 
 
 
 
13
 
14
  abstract class Twig_Test_NodeTestCase extends TestCase
15
  {
@@ -23,7 +27,7 @@ abstract class Twig_Test_NodeTestCase extends TestCase
23
  $this->assertNodeCompilation($source, $node, $environment, $isPattern);
24
  }
25
 
26
- public function assertNodeCompilation($source, Twig_Node $node, Twig_Environment $environment = null, $isPattern = false)
27
  {
28
  $compiler = $this->getCompiler($environment);
29
  $compiler->compile($node);
@@ -35,14 +39,14 @@ abstract class Twig_Test_NodeTestCase extends TestCase
35
  }
36
  }
37
 
38
- protected function getCompiler(Twig_Environment $environment = null)
39
  {
40
- return new Twig_Compiler(null === $environment ? $this->getEnvironment() : $environment);
41
  }
42
 
43
  protected function getEnvironment()
44
  {
45
- return new Twig_Environment(new Twig_Loader_Array([]));
46
  }
47
 
48
  protected function getVariableGetter($name, $line = false)
@@ -62,7 +66,7 @@ abstract class Twig_Test_NodeTestCase extends TestCase
62
 
63
  protected function getAttributeGetter()
64
  {
65
- if (function_exists('twig_template_get_attributes')) {
66
  return 'twig_template_get_attributes($this, ';
67
  }
68
 
10
  */
11
 
12
  use PHPUnit\Framework\TestCase;
13
+ use Twig\Compiler;
14
+ use Twig\Environment;
15
+ use Twig\Loader\ArrayLoader;
16
+ use Twig\Node\Node;
17
 
18
  abstract class Twig_Test_NodeTestCase extends TestCase
19
  {
27
  $this->assertNodeCompilation($source, $node, $environment, $isPattern);
28
  }
29
 
30
+ public function assertNodeCompilation($source, Node $node, Environment $environment = null, $isPattern = false)
31
  {
32
  $compiler = $this->getCompiler($environment);
33
  $compiler->compile($node);
39
  }
40
  }
41
 
42
+ protected function getCompiler(Environment $environment = null)
43
  {
44
+ return new Compiler(null === $environment ? $this->getEnvironment() : $environment);
45
  }
46
 
47
  protected function getEnvironment()
48
  {
49
+ return new Environment(new ArrayLoader([]));
50
  }
51
 
52
  protected function getVariableGetter($name, $line = false)
66
 
67
  protected function getAttributeGetter()
68
  {
69
+ if (\function_exists('twig_template_get_attributes')) {
70
  return 'twig_template_get_attributes($this, ';
71
  }
72
 
vendor/twig/twig/lib/Twig/Token.php CHANGED
@@ -69,14 +69,14 @@ class Twig_Token
69
  */
70
  public function test($type, $values = null)
71
  {
72
- if (null === $values && !is_int($type)) {
73
  $values = $type;
74
  $type = self::NAME_TYPE;
75
  }
76
 
77
  return ($this->type === $type) && (
78
  null === $values ||
79
- (is_array($values) && in_array($this->value, $values)) ||
80
  $this->value == $values
81
  );
82
  }
@@ -156,10 +156,10 @@ class Twig_Token
156
  $name = 'INTERPOLATION_END_TYPE';
157
  break;
158
  default:
159
- throw new LogicException(sprintf('Token of type "%s" does not exist.', $type));
160
  }
161
 
162
- return $short ? $name : 'Twig_Token::'.$name;
163
  }
164
 
165
  /**
@@ -199,7 +199,7 @@ class Twig_Token
199
  case self::INTERPOLATION_END_TYPE:
200
  return 'end of string interpolation';
201
  default:
202
- throw new LogicException(sprintf('Token of type "%s" does not exist.', $type));
203
  }
204
  }
205
  }
69
  */
70
  public function test($type, $values = null)
71
  {
72
+ if (null === $values && !\is_int($type)) {
73
  $values = $type;
74
  $type = self::NAME_TYPE;
75
  }
76
 
77
  return ($this->type === $type) && (
78
  null === $values ||
79
+ (\is_array($values) && \in_array($this->value, $values)) ||
80
  $this->value == $values
81
  );
82
  }
156
  $name = 'INTERPOLATION_END_TYPE';
157
  break;
158
  default:
159
+ throw new \LogicException(sprintf('Token of type "%s" does not exist.', $type));
160
  }
161
 
162
+ return $short ? $name : 'Twig\Token::'.$name;
163
  }
164
 
165
  /**
199
  case self::INTERPOLATION_END_TYPE:
200
  return 'end of string interpolation';
201
  default:
202
+ throw new \LogicException(sprintf('Token of type "%s" does not exist.', $type));
203
  }
204
  }
205
  }
vendor/twig/twig/lib/Twig/TokenParser.php CHANGED
@@ -9,12 +9,15 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
12
  /**
13
  * Base class for all token parsers.
14
  *
15
  * @author Fabien Potencier <fabien@symfony.com>
16
  */
17
- abstract class Twig_TokenParser implements Twig_TokenParserInterface
18
  {
19
  /**
20
  * @var Twig_Parser
@@ -24,7 +27,7 @@ abstract class Twig_TokenParser implements Twig_TokenParserInterface
24
  /**
25
  * Sets the parser associated with this token parser.
26
  */
27
- public function setParser(Twig_Parser $parser)
28
  {
29
  $this->parser = $parser;
30
  }
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Parser;
13
+ use Twig\TokenParser\TokenParserInterface;
14
+
15
  /**
16
  * Base class for all token parsers.
17
  *
18
  * @author Fabien Potencier <fabien@symfony.com>
19
  */
20
+ abstract class Twig_TokenParser implements TokenParserInterface
21
  {
22
  /**
23
  * @var Twig_Parser
27
  /**
28
  * Sets the parser associated with this token parser.
29
  */
30
+ public function setParser(Parser $parser)
31
  {
32
  $this->parser = $parser;
33
  }
vendor/twig/twig/lib/Twig/TokenParser/AutoEscape.php CHANGED
@@ -9,39 +9,43 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
 
 
12
  /**
13
  * Marks a section of a template to be escaped or not.
14
  *
15
- * <pre>
16
- * {% autoescape true %}
17
- * Everything will be automatically escaped in this block
18
- * {% endautoescape %}
19
  *
20
- * {% autoescape false %}
21
- * Everything will be outputed as is in this block
22
- * {% endautoescape %}
23
  *
24
- * {% autoescape true js %}
25
- * Everything will be automatically escaped in this block
26
- * using the js escaping strategy
27
- * {% endautoescape %}
28
- * </pre>
29
  *
30
  * @final
31
  */
32
- class Twig_TokenParser_AutoEscape extends Twig_TokenParser
33
  {
34
- public function parse(Twig_Token $token)
35
  {
36
  $lineno = $token->getLine();
37
  $stream = $this->parser->getStream();
38
 
39
- if ($stream->test(Twig_Token::BLOCK_END_TYPE)) {
40
  $value = 'html';
41
  } else {
42
  $expr = $this->parser->getExpressionParser()->parseExpression();
43
- if (!$expr instanceof Twig_Node_Expression_Constant) {
44
- throw new Twig_Error_Syntax('An escaping strategy must be a string or a bool.', $stream->getCurrent()->getLine(), $stream->getSourceContext());
45
  }
46
  $value = $expr->getAttribute('value');
47
 
@@ -51,25 +55,25 @@ class Twig_TokenParser_AutoEscape extends Twig_TokenParser
51
  $value = 'html';
52
  }
53
 
54
- if ($compat && $stream->test(Twig_Token::NAME_TYPE)) {
55
  @trigger_error('Using the autoescape tag with "true" or "false" before the strategy name is deprecated since version 1.21.', E_USER_DEPRECATED);
56
 
57
  if (false === $value) {
58
- throw new Twig_Error_Syntax('Unexpected escaping strategy as you set autoescaping to false.', $stream->getCurrent()->getLine(), $stream->getSourceContext());
59
  }
60
 
61
  $value = $stream->next()->getValue();
62
  }
63
  }
64
 
65
- $stream->expect(Twig_Token::BLOCK_END_TYPE);
66
  $body = $this->parser->subparse([$this, 'decideBlockEnd'], true);
67
- $stream->expect(Twig_Token::BLOCK_END_TYPE);
68
 
69
- return new Twig_Node_AutoEscape($value, $body, $lineno, $this->getTag());
70
  }
71
 
72
- public function decideBlockEnd(Twig_Token $token)
73
  {
74
  return $token->test('endautoescape');
75
  }
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Error\SyntaxError;
13
+ use Twig\Node\AutoEscapeNode;
14
+ use Twig\Node\Expression\ConstantExpression;
15
+ use Twig\Token;
16
+ use Twig\TokenParser\AbstractTokenParser;
17
+
18
  /**
19
  * Marks a section of a template to be escaped or not.
20
  *
21
+ * {% autoescape true %}
22
+ * Everything will be automatically escaped in this block
23
+ * {% endautoescape %}
 
24
  *
25
+ * {% autoescape false %}
26
+ * Everything will be outputed as is in this block
27
+ * {% endautoescape %}
28
  *
29
+ * {% autoescape true js %}
30
+ * Everything will be automatically escaped in this block
31
+ * using the js escaping strategy
32
+ * {% endautoescape %}
 
33
  *
34
  * @final
35
  */
36
+ class Twig_TokenParser_AutoEscape extends AbstractTokenParser
37
  {
38
+ public function parse(Token $token)
39
  {
40
  $lineno = $token->getLine();
41
  $stream = $this->parser->getStream();
42
 
43
+ if ($stream->test(Token::BLOCK_END_TYPE)) {
44
  $value = 'html';
45
  } else {
46
  $expr = $this->parser->getExpressionParser()->parseExpression();
47
+ if (!$expr instanceof ConstantExpression) {
48
+ throw new SyntaxError('An escaping strategy must be a string or a bool.', $stream->getCurrent()->getLine(), $stream->getSourceContext());
49
  }
50
  $value = $expr->getAttribute('value');
51
 
55
  $value = 'html';
56
  }
57
 
58
+ if ($compat && $stream->test(Token::NAME_TYPE)) {
59
  @trigger_error('Using the autoescape tag with "true" or "false" before the strategy name is deprecated since version 1.21.', E_USER_DEPRECATED);
60
 
61
  if (false === $value) {
62
+ throw new SyntaxError('Unexpected escaping strategy as you set autoescaping to false.', $stream->getCurrent()->getLine(), $stream->getSourceContext());
63
  }
64
 
65
  $value = $stream->next()->getValue();
66
  }
67
  }
68
 
69
+ $stream->expect(Token::BLOCK_END_TYPE);
70
  $body = $this->parser->subparse([$this, 'decideBlockEnd'], true);
71
+ $stream->expect(Token::BLOCK_END_TYPE);
72
 
73
+ return new AutoEscapeNode($value, $body, $lineno, $this->getTag());
74
  }
75
 
76
+ public function decideBlockEnd(Token $token)
77
  {
78
  return $token->test('endautoescape');
79
  }
vendor/twig/twig/lib/Twig/TokenParser/Block.php CHANGED
@@ -10,56 +10,62 @@
10
  * file that was distributed with this source code.
11
  */
12
 
 
 
 
 
 
 
 
 
13
  /**
14
  * Marks a section of a template as being reusable.
15
  *
16
- * <pre>
17
  * {% block head %}
18
  * <link rel="stylesheet" href="style.css" />
19
  * <title>{% block title %}{% endblock %} - My Webpage</title>
20
  * {% endblock %}
21
- * </pre>
22
  *
23
  * @final
24
  */
25
- class Twig_TokenParser_Block extends Twig_TokenParser
26
  {
27
- public function parse(Twig_Token $token)
28
  {
29
  $lineno = $token->getLine();
30
  $stream = $this->parser->getStream();
31
- $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
32
  if ($this->parser->hasBlock($name)) {
33
- throw new Twig_Error_Syntax(sprintf("The block '%s' has already been defined line %d.", $name, $this->parser->getBlock($name)->getTemplateLine()), $stream->getCurrent()->getLine(), $stream->getSourceContext());
34
  }
35
- $this->parser->setBlock($name, $block = new Twig_Node_Block($name, new Twig_Node([]), $lineno));
36
  $this->parser->pushLocalScope();
37
  $this->parser->pushBlockStack($name);
38
 
39
- if ($stream->nextIf(Twig_Token::BLOCK_END_TYPE)) {
40
  $body = $this->parser->subparse([$this, 'decideBlockEnd'], true);
41
- if ($token = $stream->nextIf(Twig_Token::NAME_TYPE)) {
42
  $value = $token->getValue();
43
 
44
  if ($value != $name) {
45
- throw new Twig_Error_Syntax(sprintf('Expected endblock for block "%s" (but "%s" given).', $name, $value), $stream->getCurrent()->getLine(), $stream->getSourceContext());
46
  }
47
  }
48
  } else {
49
- $body = new Twig_Node([
50
- new Twig_Node_Print($this->parser->getExpressionParser()->parseExpression(), $lineno),
51
  ]);
52
  }
53
- $stream->expect(Twig_Token::BLOCK_END_TYPE);
54
 
55
  $block->setNode('body', $body);
56
  $this->parser->popBlockStack();
57
  $this->parser->popLocalScope();
58
 
59
- return new Twig_Node_BlockReference($name, $lineno, $this->getTag());
60
  }
61
 
62
- public function decideBlockEnd(Twig_Token $token)
63
  {
64
  return $token->test('endblock');
65
  }
10
  * file that was distributed with this source code.
11
  */
12
 
13
+ use Twig\Error\SyntaxError;
14
+ use Twig\Node\BlockNode;
15
+ use Twig\Node\BlockReferenceNode;
16
+ use Twig\Node\Node;
17
+ use Twig\Node\PrintNode;
18
+ use Twig\Token;
19
+ use Twig\TokenParser\AbstractTokenParser;
20
+
21
  /**
22
  * Marks a section of a template as being reusable.
23
  *
 
24
  * {% block head %}
25
  * <link rel="stylesheet" href="style.css" />
26
  * <title>{% block title %}{% endblock %} - My Webpage</title>
27
  * {% endblock %}
 
28
  *
29
  * @final
30
  */
31
+ class Twig_TokenParser_Block extends AbstractTokenParser
32
  {
33
+ public function parse(Token $token)
34
  {
35
  $lineno = $token->getLine();
36
  $stream = $this->parser->getStream();
37
+ $name = $stream->expect(Token::NAME_TYPE)->getValue();
38
  if ($this->parser->hasBlock($name)) {
39
+ throw new SyntaxError(sprintf("The block '%s' has already been defined line %d.", $name, $this->parser->getBlock($name)->getTemplateLine()), $stream->getCurrent()->getLine(), $stream->getSourceContext());
40
  }
41
+ $this->parser->setBlock($name, $block = new BlockNode($name, new Node([]), $lineno));
42
  $this->parser->pushLocalScope();
43
  $this->parser->pushBlockStack($name);
44
 
45
+ if ($stream->nextIf(Token::BLOCK_END_TYPE)) {
46
  $body = $this->parser->subparse([$this, 'decideBlockEnd'], true);
47
+ if ($token = $stream->nextIf(Token::NAME_TYPE)) {
48
  $value = $token->getValue();
49
 
50
  if ($value != $name) {
51
+ throw new SyntaxError(sprintf('Expected endblock for block "%s" (but "%s" given).', $name, $value), $stream->getCurrent()->getLine(), $stream->getSourceContext());
52
  }
53
  }
54
  } else {
55
+ $body = new Node([
56
+ new PrintNode($this->parser->getExpressionParser()->parseExpression(), $lineno),
57
  ]);
58
  }
59
+ $stream->expect(Token::BLOCK_END_TYPE);
60
 
61
  $block->setNode('body', $body);
62
  $this->parser->popBlockStack();
63
  $this->parser->popLocalScope();
64
 
65
+ return new BlockReferenceNode($name, $lineno, $this->getTag());
66
  }
67
 
68
+ public function decideBlockEnd(Token $token)
69
  {
70
  return $token->test('endblock');
71
  }
vendor/twig/twig/lib/Twig/TokenParser/Deprecated.php CHANGED
@@ -9,28 +9,29 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
12
  /**
13
  * Deprecates a section of a template.
14
  *
15
- * <pre>
16
- * {% deprecated 'The "base.twig" template is deprecated, use "layout.twig" instead.' %}
17
- *
18
- * {% extends 'layout.html.twig' %}
19
- * </pre>
20
  *
21
  * @author Yonel Ceruto <yonelceruto@gmail.com>
22
  *
23
  * @final
24
  */
25
- class Twig_TokenParser_Deprecated extends Twig_TokenParser
26
  {
27
- public function parse(Twig_Token $token)
28
  {
29
  $expr = $this->parser->getExpressionParser()->parseExpression();
30
 
31
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
32
 
33
- return new Twig_Node_Deprecated($expr, $token->getLine(), $this->getTag());
34
  }
35
 
36
  public function getTag()
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Node\DeprecatedNode;
13
+ use Twig\Token;
14
+ use Twig\TokenParser\AbstractTokenParser;
15
+
16
  /**
17
  * Deprecates a section of a template.
18
  *
19
+ * {% deprecated 'The "base.twig" template is deprecated, use "layout.twig" instead.' %}
20
+ * {% extends 'layout.html.twig' %}
 
 
 
21
  *
22
  * @author Yonel Ceruto <yonelceruto@gmail.com>
23
  *
24
  * @final
25
  */
26
+ class Twig_TokenParser_Deprecated extends AbstractTokenParser
27
  {
28
+ public function parse(Token $token)
29
  {
30
  $expr = $this->parser->getExpressionParser()->parseExpression();
31
 
32
+ $this->parser->getStream()->expect(Token::BLOCK_END_TYPE);
33
 
34
+ return new DeprecatedNode($expr, $token->getLine(), $this->getTag());
35
  }
36
 
37
  public function getTag()
vendor/twig/twig/lib/Twig/TokenParser/Do.php CHANGED
@@ -9,20 +9,24 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
12
  /**
13
  * Evaluates an expression, discarding the returned value.
14
  *
15
  * @final
16
  */
17
- class Twig_TokenParser_Do extends Twig_TokenParser
18
  {
19
- public function parse(Twig_Token $token)
20
  {
21
  $expr = $this->parser->getExpressionParser()->parseExpression();
22
 
23
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
24
 
25
- return new Twig_Node_Do($expr, $token->getLine(), $this->getTag());
26
  }
27
 
28
  public function getTag()
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Node\DoNode;
13
+ use Twig\Token;
14
+ use Twig\TokenParser\AbstractTokenParser;
15
+
16
  /**
17
  * Evaluates an expression, discarding the returned value.
18
  *
19
  * @final
20
  */
21
+ class Twig_TokenParser_Do extends AbstractTokenParser
22
  {
23
+ public function parse(Token $token)
24
  {
25
  $expr = $this->parser->getExpressionParser()->parseExpression();
26
 
27
+ $this->parser->getStream()->expect(Token::BLOCK_END_TYPE);
28
 
29
+ return new DoNode($expr, $token->getLine(), $this->getTag());
30
  }
31
 
32
  public function getTag()
vendor/twig/twig/lib/Twig/TokenParser/Embed.php CHANGED
@@ -9,14 +9,20 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
 
 
12
  /**
13
  * Embeds a template.
14
  *
15
  * @final
16
  */
17
- class Twig_TokenParser_Embed extends Twig_TokenParser_Include
18
  {
19
- public function parse(Twig_Token $token)
20
  {
21
  $stream = $this->parser->getStream();
22
 
@@ -24,19 +30,19 @@ class Twig_TokenParser_Embed extends Twig_TokenParser_Include
24
 
25
  list($variables, $only, $ignoreMissing) = $this->parseArguments();
26
 
27
- $parentToken = $fakeParentToken = new Twig_Token(Twig_Token::STRING_TYPE, '__parent__', $token->getLine());
28
- if ($parent instanceof Twig_Node_Expression_Constant) {
29
- $parentToken = new Twig_Token(Twig_Token::STRING_TYPE, $parent->getAttribute('value'), $token->getLine());
30
- } elseif ($parent instanceof Twig_Node_Expression_Name) {
31
- $parentToken = new Twig_Token(Twig_Token::NAME_TYPE, $parent->getAttribute('name'), $token->getLine());
32
  }
33
 
34
  // inject a fake parent to make the parent() function work
35
  $stream->injectTokens([
36
- new Twig_Token(Twig_Token::BLOCK_START_TYPE, '', $token->getLine()),
37
- new Twig_Token(Twig_Token::NAME_TYPE, 'extends', $token->getLine()),
38
  $parentToken,
39
- new Twig_Token(Twig_Token::BLOCK_END_TYPE, '', $token->getLine()),
40
  ]);
41
 
42
  $module = $this->parser->parse($stream, [$this, 'decideBlockEnd'], true);
@@ -48,12 +54,12 @@ class Twig_TokenParser_Embed extends Twig_TokenParser_Include
48
 
49
  $this->parser->embedTemplate($module);
50
 
51
- $stream->expect(Twig_Token::BLOCK_END_TYPE);
52
 
53
- return new Twig_Node_Embed($module->getTemplateName(), $module->getAttribute('index'), $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag());
54
  }
55
 
56
- public function decideBlockEnd(Twig_Token $token)
57
  {
58
  return $token->test('endembed');
59
  }
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Node\EmbedNode;
13
+ use Twig\Node\Expression\ConstantExpression;
14
+ use Twig\Node\Expression\NameExpression;
15
+ use Twig\Token;
16
+ use Twig\TokenParser\IncludeTokenParser;
17
+
18
  /**
19
  * Embeds a template.
20
  *
21
  * @final
22
  */
23
+ class Twig_TokenParser_Embed extends IncludeTokenParser
24
  {
25
+ public function parse(Token $token)
26
  {
27
  $stream = $this->parser->getStream();
28
 
30
 
31
  list($variables, $only, $ignoreMissing) = $this->parseArguments();
32
 
33
+ $parentToken = $fakeParentToken = new Token(Token::STRING_TYPE, '__parent__', $token->getLine());
34
+ if ($parent instanceof ConstantExpression) {
35
+ $parentToken = new Token(Token::STRING_TYPE, $parent->getAttribute('value'), $token->getLine());
36
+ } elseif ($parent instanceof NameExpression) {
37
+ $parentToken = new Token(Token::NAME_TYPE, $parent->getAttribute('name'), $token->getLine());
38
  }
39
 
40
  // inject a fake parent to make the parent() function work
41
  $stream->injectTokens([
42
+ new Token(Token::BLOCK_START_TYPE, '', $token->getLine()),
43
+ new Token(Token::NAME_TYPE, 'extends', $token->getLine()),
44
  $parentToken,
45
+ new Token(Token::BLOCK_END_TYPE, '', $token->getLine()),
46
  ]);
47
 
48
  $module = $this->parser->parse($stream, [$this, 'decideBlockEnd'], true);
54
 
55
  $this->parser->embedTemplate($module);
56
 
57
+ $stream->expect(Token::BLOCK_END_TYPE);
58
 
59
+ return new EmbedNode($module->getTemplateName(), $module->getAttribute('index'), $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag());
60
  }
61
 
62
+ public function decideBlockEnd(Token $token)
63
  {
64
  return $token->test('endembed');
65
  }
vendor/twig/twig/lib/Twig/TokenParser/Extends.php CHANGED
@@ -10,31 +10,33 @@
10
  * file that was distributed with this source code.
11
  */
12
 
 
 
 
 
13
  /**
14
  * Extends a template by another one.
15
  *
16
- * <pre>
17
  * {% extends "base.html" %}
18
- * </pre>
19
  *
20
  * @final
21
  */
22
- class Twig_TokenParser_Extends extends Twig_TokenParser
23
  {
24
- public function parse(Twig_Token $token)
25
  {
26
  $stream = $this->parser->getStream();
27
 
28
  if (!$this->parser->isMainScope()) {
29
- throw new Twig_Error_Syntax('Cannot extend from a block.', $token->getLine(), $stream->getSourceContext());
30
  }
31
 
32
  if (null !== $this->parser->getParent()) {
33
- throw new Twig_Error_Syntax('Multiple extends tags are forbidden.', $token->getLine(), $stream->getSourceContext());
34
  }
35
  $this->parser->setParent($this->parser->getExpressionParser()->parseExpression());
36
 
37
- $stream->expect(Twig_Token::BLOCK_END_TYPE);
38
  }
39
 
40
  public function getTag()
10
  * file that was distributed with this source code.
11
  */
12
 
13
+ use Twig\Error\SyntaxError;
14
+ use Twig\Token;
15
+ use Twig\TokenParser\AbstractTokenParser;
16
+
17
  /**
18
  * Extends a template by another one.
19
  *
 
20
  * {% extends "base.html" %}
 
21
  *
22
  * @final
23
  */
24
+ class Twig_TokenParser_Extends extends AbstractTokenParser
25
  {
26
+ public function parse(Token $token)
27
  {
28
  $stream = $this->parser->getStream();
29
 
30
  if (!$this->parser->isMainScope()) {
31
+ throw new SyntaxError('Cannot extend from a block.', $token->getLine(), $stream->getSourceContext());
32
  }
33
 
34
  if (null !== $this->parser->getParent()) {
35
+ throw new SyntaxError('Multiple extends tags are forbidden.', $token->getLine(), $stream->getSourceContext());
36
  }
37
  $this->parser->setParent($this->parser->getExpressionParser()->parseExpression());
38
 
39
+ $stream->expect(Token::BLOCK_END_TYPE);
40
  }
41
 
42
  public function getTag()
vendor/twig/twig/lib/Twig/TokenParser/Filter.php CHANGED
@@ -9,37 +9,42 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
 
 
 
12
  /**
13
  * Filters a section of a template by applying filters.
14
  *
15
- * <pre>
16
- * {% filter upper %}
17
- * This text becomes uppercase
18
- * {% endfilter %}
19
- * </pre>
20
  *
21
  * @final
22
  */
23
- class Twig_TokenParser_Filter extends Twig_TokenParser
24
  {
25
- public function parse(Twig_Token $token)
26
  {
27
  $name = $this->parser->getVarName();
28
- $ref = new Twig_Node_Expression_BlockReference(new Twig_Node_Expression_Constant($name, $token->getLine()), null, $token->getLine(), $this->getTag());
29
 
30
  $filter = $this->parser->getExpressionParser()->parseFilterExpressionRaw($ref, $this->getTag());
31
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
32
 
33
  $body = $this->parser->subparse([$this, 'decideBlockEnd'], true);
34
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
35
 
36
- $block = new Twig_Node_Block($name, $body, $token->getLine());
37
  $this->parser->setBlock($name, $block);
38
 
39
- return new Twig_Node_Print($filter, $token->getLine(), $this->getTag());
40
  }
41
 
42
- public function decideBlockEnd(Twig_Token $token)
43
  {
44
  return $token->test('endfilter');
45
  }
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Node\BlockNode;
13
+ use Twig\Node\Expression\BlockReferenceExpression;
14
+ use Twig\Node\Expression\ConstantExpression;
15
+ use Twig\Node\PrintNode;
16
+ use Twig\Token;
17
+ use Twig\TokenParser\AbstractTokenParser;
18
+
19
  /**
20
  * Filters a section of a template by applying filters.
21
  *
22
+ * {% filter upper %}
23
+ * This text becomes uppercase
24
+ * {% endfilter %}
 
 
25
  *
26
  * @final
27
  */
28
+ class Twig_TokenParser_Filter extends AbstractTokenParser
29
  {
30
+ public function parse(Token $token)
31
  {
32
  $name = $this->parser->getVarName();
33
+ $ref = new BlockReferenceExpression(new ConstantExpression($name, $token->getLine()), null, $token->getLine(), $this->getTag());
34
 
35
  $filter = $this->parser->getExpressionParser()->parseFilterExpressionRaw($ref, $this->getTag());
36
+ $this->parser->getStream()->expect(Token::BLOCK_END_TYPE);
37
 
38
  $body = $this->parser->subparse([$this, 'decideBlockEnd'], true);
39
+ $this->parser->getStream()->expect(Token::BLOCK_END_TYPE);
40
 
41
+ $block = new BlockNode($name, $body, $token->getLine());
42
  $this->parser->setBlock($name, $block);
43
 
44
+ return new PrintNode($filter, $token->getLine(), $this->getTag());
45
  }
46
 
47
+ public function decideBlockEnd(Token $token)
48
  {
49
  return $token->test('endfilter');
50
  }
vendor/twig/twig/lib/Twig/TokenParser/Flush.php CHANGED
@@ -9,6 +9,10 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
12
  /**
13
  * Flushes the output to the client.
14
  *
@@ -16,13 +20,13 @@
16
  *
17
  * @final
18
  */
19
- class Twig_TokenParser_Flush extends Twig_TokenParser
20
  {
21
- public function parse(Twig_Token $token)
22
  {
23
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
24
 
25
- return new Twig_Node_Flush($token->getLine(), $this->getTag());
26
  }
27
 
28
  public function getTag()
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Node\FlushNode;
13
+ use Twig\Token;
14
+ use Twig\TokenParser\AbstractTokenParser;
15
+
16
  /**
17
  * Flushes the output to the client.
18
  *
20
  *
21
  * @final
22
  */
23
+ class Twig_TokenParser_Flush extends AbstractTokenParser
24
  {
25
+ public function parse(Token $token)
26
  {
27
+ $this->parser->getStream()->expect(Token::BLOCK_END_TYPE);
28
 
29
+ return new FlushNode($token->getLine(), $this->getTag());
30
  }
31
 
32
  public function getTag()
vendor/twig/twig/lib/Twig/TokenParser/For.php CHANGED
@@ -10,53 +10,61 @@
10
  * file that was distributed with this source code.
11
  */
12
 
 
 
 
 
 
 
 
 
 
 
13
  /**
14
  * Loops over each item of a sequence.
15
  *
16
- * <pre>
17
- * <ul>
18
- * {% for user in users %}
19
- * <li>{{ user.username|e }}</li>
20
- * {% endfor %}
21
- * </ul>
22
- * </pre>
23
  *
24
  * @final
25
  */
26
- class Twig_TokenParser_For extends Twig_TokenParser
27
  {
28
- public function parse(Twig_Token $token)
29
  {
30
  $lineno = $token->getLine();
31
  $stream = $this->parser->getStream();
32
  $targets = $this->parser->getExpressionParser()->parseAssignmentExpression();
33
- $stream->expect(Twig_Token::OPERATOR_TYPE, 'in');
34
  $seq = $this->parser->getExpressionParser()->parseExpression();
35
 
36
  $ifexpr = null;
37
- if ($stream->nextIf(Twig_Token::NAME_TYPE, 'if')) {
38
  $ifexpr = $this->parser->getExpressionParser()->parseExpression();
39
  }
40
 
41
- $stream->expect(Twig_Token::BLOCK_END_TYPE);
42
  $body = $this->parser->subparse([$this, 'decideForFork']);
43
  if ('else' == $stream->next()->getValue()) {
44
- $stream->expect(Twig_Token::BLOCK_END_TYPE);
45
  $else = $this->parser->subparse([$this, 'decideForEnd'], true);
46
  } else {
47
  $else = null;
48
  }
49
- $stream->expect(Twig_Token::BLOCK_END_TYPE);
50
 
51
- if (count($targets) > 1) {
52
  $keyTarget = $targets->getNode(0);
53
- $keyTarget = new Twig_Node_Expression_AssignName($keyTarget->getAttribute('name'), $keyTarget->getTemplateLine());
54
  $valueTarget = $targets->getNode(1);
55
- $valueTarget = new Twig_Node_Expression_AssignName($valueTarget->getAttribute('name'), $valueTarget->getTemplateLine());
56
  } else {
57
- $keyTarget = new Twig_Node_Expression_AssignName('_key', $lineno);
58
  $valueTarget = $targets->getNode(0);
59
- $valueTarget = new Twig_Node_Expression_AssignName($valueTarget->getAttribute('name'), $valueTarget->getTemplateLine());
60
  }
61
 
62
  if ($ifexpr) {
@@ -64,24 +72,24 @@ class Twig_TokenParser_For extends Twig_TokenParser
64
  $this->checkLoopUsageBody($stream, $body);
65
  }
66
 
67
- return new Twig_Node_For($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, $lineno, $this->getTag());
68
  }
69
 
70
- public function decideForFork(Twig_Token $token)
71
  {
72
  return $token->test(['else', 'endfor']);
73
  }
74
 
75
- public function decideForEnd(Twig_Token $token)
76
  {
77
  return $token->test('endfor');
78
  }
79
 
80
  // the loop variable cannot be used in the condition
81
- protected function checkLoopUsageCondition(Twig_TokenStream $stream, Twig_NodeInterface $node)
82
  {
83
- if ($node instanceof Twig_Node_Expression_GetAttr && $node->getNode('node') instanceof Twig_Node_Expression_Name && 'loop' == $node->getNode('node')->getAttribute('name')) {
84
- throw new Twig_Error_Syntax('The "loop" variable cannot be used in a looping condition.', $node->getTemplateLine(), $stream->getSourceContext());
85
  }
86
 
87
  foreach ($node as $n) {
@@ -95,17 +103,17 @@ class Twig_TokenParser_For extends Twig_TokenParser
95
 
96
  // check usage of non-defined loop-items
97
  // it does not catch all problems (for instance when a for is included into another or when the variable is used in an include)
98
- protected function checkLoopUsageBody(Twig_TokenStream $stream, Twig_NodeInterface $node)
99
  {
100
- if ($node instanceof Twig_Node_Expression_GetAttr && $node->getNode('node') instanceof Twig_Node_Expression_Name && 'loop' == $node->getNode('node')->getAttribute('name')) {
101
  $attribute = $node->getNode('attribute');
102
- if ($attribute instanceof Twig_Node_Expression_Constant && in_array($attribute->getAttribute('value'), ['length', 'revindex0', 'revindex', 'last'])) {
103
- throw new Twig_Error_Syntax(sprintf('The "loop.%s" variable is not defined when looping with a condition.', $attribute->getAttribute('value')), $node->getTemplateLine(), $stream->getSourceContext());
104
  }
105
  }
106
 
107
  // should check for parent.loop.XXX usage
108
- if ($node instanceof Twig_Node_For) {
109
  return;
110
  }
111
 
10
  * file that was distributed with this source code.
11
  */
12
 
13
+ use Twig\Error\SyntaxError;
14
+ use Twig\Node\Expression\AssignNameExpression;
15
+ use Twig\Node\Expression\ConstantExpression;
16
+ use Twig\Node\Expression\GetAttrExpression;
17
+ use Twig\Node\Expression\NameExpression;
18
+ use Twig\Node\ForNode;
19
+ use Twig\Token;
20
+ use Twig\TokenParser\AbstractTokenParser;
21
+ use Twig\TokenStream;
22
+
23
  /**
24
  * Loops over each item of a sequence.
25
  *
26
+ * <ul>
27
+ * {% for user in users %}
28
+ * <li>{{ user.username|e }}</li>
29
+ * {% endfor %}
30
+ * </ul>
 
 
31
  *
32
  * @final
33
  */
34
+ class Twig_TokenParser_For extends AbstractTokenParser
35
  {
36
+ public function parse(Token $token)
37
  {
38
  $lineno = $token->getLine();
39
  $stream = $this->parser->getStream();
40
  $targets = $this->parser->getExpressionParser()->parseAssignmentExpression();
41
+ $stream->expect(Token::OPERATOR_TYPE, 'in');
42
  $seq = $this->parser->getExpressionParser()->parseExpression();
43
 
44
  $ifexpr = null;
45
+ if ($stream->nextIf(Token::NAME_TYPE, 'if')) {
46
  $ifexpr = $this->parser->getExpressionParser()->parseExpression();
47
  }
48
 
49
+ $stream->expect(Token::BLOCK_END_TYPE);
50
  $body = $this->parser->subparse([$this, 'decideForFork']);
51
  if ('else' == $stream->next()->getValue()) {
52
+ $stream->expect(Token::BLOCK_END_TYPE);
53
  $else = $this->parser->subparse([$this, 'decideForEnd'], true);
54
  } else {
55
  $else = null;
56
  }
57
+ $stream->expect(Token::BLOCK_END_TYPE);
58
 
59
+ if (\count($targets) > 1) {
60
  $keyTarget = $targets->getNode(0);
61
+ $keyTarget = new AssignNameExpression($keyTarget->getAttribute('name'), $keyTarget->getTemplateLine());
62
  $valueTarget = $targets->getNode(1);
63
+ $valueTarget = new AssignNameExpression($valueTarget->getAttribute('name'), $valueTarget->getTemplateLine());
64
  } else {
65
+ $keyTarget = new AssignNameExpression('_key', $lineno);
66
  $valueTarget = $targets->getNode(0);
67
+ $valueTarget = new AssignNameExpression($valueTarget->getAttribute('name'), $valueTarget->getTemplateLine());
68
  }
69
 
70
  if ($ifexpr) {
72
  $this->checkLoopUsageBody($stream, $body);
73
  }
74
 
75
+ return new ForNode($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, $lineno, $this->getTag());
76
  }
77
 
78
+ public function decideForFork(Token $token)
79
  {
80
  return $token->test(['else', 'endfor']);
81
  }
82
 
83
+ public function decideForEnd(Token $token)
84
  {
85
  return $token->test('endfor');
86
  }
87
 
88
  // the loop variable cannot be used in the condition
89
+ protected function checkLoopUsageCondition(TokenStream $stream, Twig_NodeInterface $node)
90
  {
91
+ if ($node instanceof GetAttrExpression && $node->getNode('node') instanceof NameExpression && 'loop' == $node->getNode('node')->getAttribute('name')) {
92
+ throw new SyntaxError('The "loop" variable cannot be used in a looping condition.', $node->getTemplateLine(), $stream->getSourceContext());
93
  }
94
 
95
  foreach ($node as $n) {
103
 
104
  // check usage of non-defined loop-items
105
  // it does not catch all problems (for instance when a for is included into another or when the variable is used in an include)
106
+ protected function checkLoopUsageBody(TokenStream $stream, Twig_NodeInterface $node)
107
  {
108
+ if ($node instanceof GetAttrExpression && $node->getNode('node') instanceof NameExpression && 'loop' == $node->getNode('node')->getAttribute('name')) {
109
  $attribute = $node->getNode('attribute');
110
+ if ($attribute instanceof ConstantExpression && \in_array($attribute->getAttribute('value'), ['length', 'revindex0', 'revindex', 'last'])) {
111
+ throw new SyntaxError(sprintf('The "loop.%s" variable is not defined when looping with a condition.', $attribute->getAttribute('value')), $node->getTemplateLine(), $stream->getSourceContext());
112
  }
113
  }
114
 
115
  // should check for parent.loop.XXX usage
116
+ if ($node instanceof ForNode) {
117
  return;
118
  }
119
 
vendor/twig/twig/lib/Twig/TokenParser/From.php CHANGED
@@ -9,18 +9,22 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
 
 
12
  /**
13
  * Imports macros.
14
  *
15
- * <pre>
16
  * {% from 'forms.html' import forms %}
17
- * </pre>
18
  *
19
  * @final
20
  */
21
- class Twig_TokenParser_From extends Twig_TokenParser
22
  {
23
- public function parse(Twig_Token $token)
24
  {
25
  $macro = $this->parser->getExpressionParser()->parseExpression();
26
  $stream = $this->parser->getStream();
@@ -28,27 +32,27 @@ class Twig_TokenParser_From extends Twig_TokenParser
28
 
29
  $targets = [];
30
  do {
31
- $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
32
 
33
  $alias = $name;
34
  if ($stream->nextIf('as')) {
35
- $alias = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
36
  }
37
 
38
  $targets[$name] = $alias;
39
 
40
- if (!$stream->nextIf(Twig_Token::PUNCTUATION_TYPE, ',')) {
41
  break;
42
  }
43
  } while (true);
44
 
45
- $stream->expect(Twig_Token::BLOCK_END_TYPE);
46
 
47
- $node = new Twig_Node_Import($macro, new Twig_Node_Expression_AssignName($this->parser->getVarName(), $token->getLine()), $token->getLine(), $this->getTag());
48
 
49
  foreach ($targets as $name => $alias) {
50
  if ($this->parser->isReservedMacroName($name)) {
51
- throw new Twig_Error_Syntax(sprintf('"%s" cannot be an imported macro as it is a reserved keyword.', $name), $token->getLine(), $stream->getSourceContext());
52
  }
53
 
54
  $this->parser->addImportedSymbol('function', $alias, 'get'.$name, $node->getNode('var'));
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Error\SyntaxError;
13
+ use Twig\Node\Expression\AssignNameExpression;
14
+ use Twig\Node\ImportNode;
15
+ use Twig\Token;
16
+ use Twig\TokenParser\AbstractTokenParser;
17
+
18
  /**
19
  * Imports macros.
20
  *
 
21
  * {% from 'forms.html' import forms %}
 
22
  *
23
  * @final
24
  */
25
+ class Twig_TokenParser_From extends AbstractTokenParser
26
  {
27
+ public function parse(Token $token)
28
  {
29
  $macro = $this->parser->getExpressionParser()->parseExpression();
30
  $stream = $this->parser->getStream();
32
 
33
  $targets = [];
34
  do {
35
+ $name = $stream->expect(Token::NAME_TYPE)->getValue();
36
 
37
  $alias = $name;
38
  if ($stream->nextIf('as')) {
39
+ $alias = $stream->expect(Token::NAME_TYPE)->getValue();
40
  }
41
 
42
  $targets[$name] = $alias;
43
 
44
+ if (!$stream->nextIf(Token::PUNCTUATION_TYPE, ',')) {
45
  break;
46
  }
47
  } while (true);
48
 
49
+ $stream->expect(Token::BLOCK_END_TYPE);
50
 
51
+ $node = new ImportNode($macro, new AssignNameExpression($this->parser->getVarName(), $token->getLine()), $token->getLine(), $this->getTag());
52
 
53
  foreach ($targets as $name => $alias) {
54
  if ($this->parser->isReservedMacroName($name)) {
55
+ throw new SyntaxError(sprintf('"%s" cannot be an imported macro as it is a reserved keyword.', $name), $token->getLine(), $stream->getSourceContext());
56
  }
57
 
58
  $this->parser->addImportedSymbol('function', $alias, 'get'.$name, $node->getNode('var'));
vendor/twig/twig/lib/Twig/TokenParser/If.php CHANGED
@@ -10,29 +10,33 @@
10
  * file that was distributed with this source code.
11
  */
12
 
 
 
 
 
 
 
13
  /**
14
  * Tests a condition.
15
  *
16
- * <pre>
17
- * {% if users %}
18
- * <ul>
19
- * {% for user in users %}
20
- * <li>{{ user.username|e }}</li>
21
- * {% endfor %}
22
- * </ul>
23
- * {% endif %}
24
- * </pre>
25
  *
26
  * @final
27
  */
28
- class Twig_TokenParser_If extends Twig_TokenParser
29
  {
30
- public function parse(Twig_Token $token)
31
  {
32
  $lineno = $token->getLine();
33
  $expr = $this->parser->getExpressionParser()->parseExpression();
34
  $stream = $this->parser->getStream();
35
- $stream->expect(Twig_Token::BLOCK_END_TYPE);
36
  $body = $this->parser->subparse([$this, 'decideIfFork']);
37
  $tests = [$expr, $body];
38
  $else = null;
@@ -41,13 +45,13 @@ class Twig_TokenParser_If extends Twig_TokenParser
41
  while (!$end) {
42
  switch ($stream->next()->getValue()) {
43
  case 'else':
44
- $stream->expect(Twig_Token::BLOCK_END_TYPE);
45
  $else = $this->parser->subparse([$this, 'decideIfEnd']);
46
  break;
47
 
48
  case 'elseif':
49
  $expr = $this->parser->getExpressionParser()->parseExpression();
50
- $stream->expect(Twig_Token::BLOCK_END_TYPE);
51
  $body = $this->parser->subparse([$this, 'decideIfFork']);
52
  $tests[] = $expr;
53
  $tests[] = $body;
@@ -58,21 +62,21 @@ class Twig_TokenParser_If extends Twig_TokenParser
58
  break;
59
 
60
  default:
61
- throw new Twig_Error_Syntax(sprintf('Unexpected end of template. Twig was looking for the following tags "else", "elseif", or "endif" to close the "if" block started at line %d).', $lineno), $stream->getCurrent()->getLine(), $stream->getSourceContext());
62
  }
63
  }
64
 
65
- $stream->expect(Twig_Token::BLOCK_END_TYPE);
66
 
67
- return new Twig_Node_If(new Twig_Node($tests), $else, $lineno, $this->getTag());
68
  }
69
 
70
- public function decideIfFork(Twig_Token $token)
71
  {
72
  return $token->test(['elseif', 'else', 'endif']);
73
  }
74
 
75
- public function decideIfEnd(Twig_Token $token)
76
  {
77
  return $token->test(['endif']);
78
  }
10
  * file that was distributed with this source code.
11
  */
12
 
13
+ use Twig\Error\SyntaxError;
14
+ use Twig\Node\IfNode;
15
+ use Twig\Node\Node;
16
+ use Twig\Token;
17
+ use Twig\TokenParser\AbstractTokenParser;
18
+
19
  /**
20
  * Tests a condition.
21
  *
22
+ * {% if users %}
23
+ * <ul>
24
+ * {% for user in users %}
25
+ * <li>{{ user.username|e }}</li>
26
+ * {% endfor %}
27
+ * </ul>
28
+ * {% endif %}
 
 
29
  *
30
  * @final
31
  */
32
+ class Twig_TokenParser_If extends AbstractTokenParser
33
  {
34
+ public function parse(Token $token)
35
  {
36
  $lineno = $token->getLine();
37
  $expr = $this->parser->getExpressionParser()->parseExpression();
38
  $stream = $this->parser->getStream();
39
+ $stream->expect(Token::BLOCK_END_TYPE);
40
  $body = $this->parser->subparse([$this, 'decideIfFork']);
41
  $tests = [$expr, $body];
42
  $else = null;
45
  while (!$end) {
46
  switch ($stream->next()->getValue()) {
47
  case 'else':
48
+ $stream->expect(Token::BLOCK_END_TYPE);
49
  $else = $this->parser->subparse([$this, 'decideIfEnd']);
50
  break;
51
 
52
  case 'elseif':
53
  $expr = $this->parser->getExpressionParser()->parseExpression();
54
+ $stream->expect(Token::BLOCK_END_TYPE);
55
  $body = $this->parser->subparse([$this, 'decideIfFork']);
56
  $tests[] = $expr;
57
  $tests[] = $body;
62
  break;
63
 
64
  default:
65
+ throw new SyntaxError(sprintf('Unexpected end of template. Twig was looking for the following tags "else", "elseif", or "endif" to close the "if" block started at line %d).', $lineno), $stream->getCurrent()->getLine(), $stream->getSourceContext());
66
  }
67
  }
68
 
69
+ $stream->expect(Token::BLOCK_END_TYPE);
70
 
71
+ return new IfNode(new Node($tests), $else, $lineno, $this->getTag());
72
  }
73
 
74
+ public function decideIfFork(Token $token)
75
  {
76
  return $token->test(['elseif', 'else', 'endif']);
77
  }
78
 
79
+ public function decideIfEnd(Token $token)
80
  {
81
  return $token->test(['endif']);
82
  }
vendor/twig/twig/lib/Twig/TokenParser/Import.php CHANGED
@@ -9,27 +9,30 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
 
12
  /**
13
  * Imports macros.
14
  *
15
- * <pre>
16
  * {% import 'forms.html' as forms %}
17
- * </pre>
18
  *
19
  * @final
20
  */
21
- class Twig_TokenParser_Import extends Twig_TokenParser
22
  {
23
- public function parse(Twig_Token $token)
24
  {
25
  $macro = $this->parser->getExpressionParser()->parseExpression();
26
  $this->parser->getStream()->expect('as');
27
- $var = new Twig_Node_Expression_AssignName($this->parser->getStream()->expect(Twig_Token::NAME_TYPE)->getValue(), $token->getLine());
28
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
29
 
30
  $this->parser->addImportedSymbol('template', $var->getAttribute('name'));
31
 
32
- return new Twig_Node_Import($macro, $var, $token->getLine(), $this->getTag());
33
  }
34
 
35
  public function getTag()
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Node\Expression\AssignNameExpression;
13
+ use Twig\Node\ImportNode;
14
+ use Twig\Token;
15
+ use Twig\TokenParser\AbstractTokenParser;
16
+
17
  /**
18
  * Imports macros.
19
  *
 
20
  * {% import 'forms.html' as forms %}
 
21
  *
22
  * @final
23
  */
24
+ class Twig_TokenParser_Import extends AbstractTokenParser
25
  {
26
+ public function parse(Token $token)
27
  {
28
  $macro = $this->parser->getExpressionParser()->parseExpression();
29
  $this->parser->getStream()->expect('as');
30
+ $var = new AssignNameExpression($this->parser->getStream()->expect(Token::NAME_TYPE)->getValue(), $token->getLine());
31
+ $this->parser->getStream()->expect(Token::BLOCK_END_TYPE);
32
 
33
  $this->parser->addImportedSymbol('template', $var->getAttribute('name'));
34
 
35
+ return new ImportNode($macro, $var, $token->getLine(), $this->getTag());
36
  }
37
 
38
  public function getTag()
vendor/twig/twig/lib/Twig/TokenParser/Include.php CHANGED
@@ -10,24 +10,26 @@
10
  * file that was distributed with this source code.
11
  */
12
 
 
 
 
 
13
  /**
14
  * Includes a template.
15
  *
16
- * <pre>
17
  * {% include 'header.html' %}
18
  * Body
19
  * {% include 'footer.html' %}
20
- * </pre>
21
  */
22
- class Twig_TokenParser_Include extends Twig_TokenParser
23
  {
24
- public function parse(Twig_Token $token)
25
  {
26
  $expr = $this->parser->getExpressionParser()->parseExpression();
27
 
28
  list($variables, $only, $ignoreMissing) = $this->parseArguments();
29
 
30
- return new Twig_Node_Include($expr, $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag());
31
  }
32
 
33
  protected function parseArguments()
@@ -35,23 +37,23 @@ class Twig_TokenParser_Include extends Twig_TokenParser
35
  $stream = $this->parser->getStream();
36
 
37
  $ignoreMissing = false;
38
- if ($stream->nextIf(Twig_Token::NAME_TYPE, 'ignore')) {
39
- $stream->expect(Twig_Token::NAME_TYPE, 'missing');
40
 
41
  $ignoreMissing = true;
42
  }
43
 
44
  $variables = null;
45
- if ($stream->nextIf(Twig_Token::NAME_TYPE, 'with')) {
46
  $variables = $this->parser->getExpressionParser()->parseExpression();
47
  }
48
 
49
  $only = false;
50
- if ($stream->nextIf(Twig_Token::NAME_TYPE, 'only')) {
51
  $only = true;
52
  }
53
 
54
- $stream->expect(Twig_Token::BLOCK_END_TYPE);
55
 
56
  return [$variables, $only, $ignoreMissing];
57
  }
10
  * file that was distributed with this source code.
11
  */
12
 
13
+ use Twig\Node\IncludeNode;
14
+ use Twig\Token;
15
+ use Twig\TokenParser\AbstractTokenParser;
16
+
17
  /**
18
  * Includes a template.
19
  *
 
20
  * {% include 'header.html' %}
21
  * Body
22
  * {% include 'footer.html' %}
 
23
  */
24
+ class Twig_TokenParser_Include extends AbstractTokenParser
25
  {
26
+ public function parse(Token $token)
27
  {
28
  $expr = $this->parser->getExpressionParser()->parseExpression();
29
 
30
  list($variables, $only, $ignoreMissing) = $this->parseArguments();
31
 
32
+ return new IncludeNode($expr, $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag());
33
  }
34
 
35
  protected function parseArguments()
37
  $stream = $this->parser->getStream();
38
 
39
  $ignoreMissing = false;
40
+ if ($stream->nextIf(Token::NAME_TYPE, 'ignore')) {
41
+ $stream->expect(Token::NAME_TYPE, 'missing');
42
 
43
  $ignoreMissing = true;
44
  }
45
 
46
  $variables = null;
47
+ if ($stream->nextIf(Token::NAME_TYPE, 'with')) {
48
  $variables = $this->parser->getExpressionParser()->parseExpression();
49
  }
50
 
51
  $only = false;
52
+ if ($stream->nextIf(Token::NAME_TYPE, 'only')) {
53
  $only = true;
54
  }
55
 
56
+ $stream->expect(Token::BLOCK_END_TYPE);
57
 
58
  return [$variables, $only, $ignoreMissing];
59
  }
vendor/twig/twig/lib/Twig/TokenParser/Macro.php CHANGED
@@ -9,44 +9,48 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
 
 
12
  /**
13
  * Defines a macro.
14
  *
15
- * <pre>
16
- * {% macro input(name, value, type, size) %}
17
- * <input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" size="{{ size|default(20) }}" />
18
- * {% endmacro %}
19
- * </pre>
20
  *
21
  * @final
22
  */
23
- class Twig_TokenParser_Macro extends Twig_TokenParser
24
  {
25
- public function parse(Twig_Token $token)
26
  {
27
  $lineno = $token->getLine();
28
  $stream = $this->parser->getStream();
29
- $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
30
 
31
  $arguments = $this->parser->getExpressionParser()->parseArguments(true, true);
32
 
33
- $stream->expect(Twig_Token::BLOCK_END_TYPE);
34
  $this->parser->pushLocalScope();
35
  $body = $this->parser->subparse([$this, 'decideBlockEnd'], true);
36
- if ($token = $stream->nextIf(Twig_Token::NAME_TYPE)) {
37
  $value = $token->getValue();
38
 
39
  if ($value != $name) {
40
- throw new Twig_Error_Syntax(sprintf('Expected endmacro for macro "%s" (but "%s" given).', $name, $value), $stream->getCurrent()->getLine(), $stream->getSourceContext());
41
  }
42
  }
43
  $this->parser->popLocalScope();
44
- $stream->expect(Twig_Token::BLOCK_END_TYPE);
45
 
46
- $this->parser->setMacro($name, new Twig_Node_Macro($name, new Twig_Node_Body([$body]), $arguments, $lineno, $this->getTag()));
47
  }
48
 
49
- public function decideBlockEnd(Twig_Token $token)
50
  {
51
  return $token->test('endmacro');
52
  }
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Error\SyntaxError;
13
+ use Twig\Node\BodyNode;
14
+ use Twig\Node\MacroNode;
15
+ use Twig\Token;
16
+ use Twig\TokenParser\AbstractTokenParser;
17
+
18
  /**
19
  * Defines a macro.
20
  *
21
+ * {% macro input(name, value, type, size) %}
22
+ * <input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" size="{{ size|default(20) }}" />
23
+ * {% endmacro %}
 
 
24
  *
25
  * @final
26
  */
27
+ class Twig_TokenParser_Macro extends AbstractTokenParser
28
  {
29
+ public function parse(Token $token)
30
  {
31
  $lineno = $token->getLine();
32
  $stream = $this->parser->getStream();
33
+ $name = $stream->expect(Token::NAME_TYPE)->getValue();
34
 
35
  $arguments = $this->parser->getExpressionParser()->parseArguments(true, true);
36
 
37
+ $stream->expect(Token::BLOCK_END_TYPE);
38
  $this->parser->pushLocalScope();
39
  $body = $this->parser->subparse([$this, 'decideBlockEnd'], true);
40
+ if ($token = $stream->nextIf(Token::NAME_TYPE)) {
41
  $value = $token->getValue();
42
 
43
  if ($value != $name) {
44
+ throw new SyntaxError(sprintf('Expected endmacro for macro "%s" (but "%s" given).', $name, $value), $stream->getCurrent()->getLine(), $stream->getSourceContext());
45
  }
46
  }
47
  $this->parser->popLocalScope();
48
+ $stream->expect(Token::BLOCK_END_TYPE);
49
 
50
+ $this->parser->setMacro($name, new MacroNode($name, new BodyNode([$body]), $arguments, $lineno, $this->getTag()));
51
  }
52
 
53
+ public function decideBlockEnd(Token $token)
54
  {
55
  return $token->test('endmacro');
56
  }
vendor/twig/twig/lib/Twig/TokenParser/Sandbox.php CHANGED
@@ -9,45 +9,50 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
 
 
 
12
  /**
13
  * Marks a section of a template as untrusted code that must be evaluated in the sandbox mode.
14
  *
15
- * <pre>
16
- * {% sandbox %}
17
- * {% include 'user.html' %}
18
- * {% endsandbox %}
19
- * </pre>
20
  *
21
  * @see https://twig.symfony.com/doc/api.html#sandbox-extension for details
22
  *
23
  * @final
24
  */
25
- class Twig_TokenParser_Sandbox extends Twig_TokenParser
26
  {
27
- public function parse(Twig_Token $token)
28
  {
29
  $stream = $this->parser->getStream();
30
- $stream->expect(Twig_Token::BLOCK_END_TYPE);
31
  $body = $this->parser->subparse([$this, 'decideBlockEnd'], true);
32
- $stream->expect(Twig_Token::BLOCK_END_TYPE);
33
 
34
  // in a sandbox tag, only include tags are allowed
35
- if (!$body instanceof Twig_Node_Include) {
36
  foreach ($body as $node) {
37
- if ($node instanceof Twig_Node_Text && ctype_space($node->getAttribute('data'))) {
38
  continue;
39
  }
40
 
41
- if (!$node instanceof Twig_Node_Include) {
42
- throw new Twig_Error_Syntax('Only "include" tags are allowed within a "sandbox" section.', $node->getTemplateLine(), $stream->getSourceContext());
43
  }
44
  }
45
  }
46
 
47
- return new Twig_Node_Sandbox($body, $token->getLine(), $this->getTag());
48
  }
49
 
50
- public function decideBlockEnd(Twig_Token $token)
51
  {
52
  return $token->test('endsandbox');
53
  }
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Error\SyntaxError;
13
+ use Twig\Node\IncludeNode;
14
+ use Twig\Node\SandboxNode;
15
+ use Twig\Node\TextNode;
16
+ use Twig\Token;
17
+ use Twig\TokenParser\AbstractTokenParser;
18
+
19
  /**
20
  * Marks a section of a template as untrusted code that must be evaluated in the sandbox mode.
21
  *
22
+ * {% sandbox %}
23
+ * {% include 'user.html' %}
24
+ * {% endsandbox %}
 
 
25
  *
26
  * @see https://twig.symfony.com/doc/api.html#sandbox-extension for details
27
  *
28
  * @final
29
  */
30
+ class Twig_TokenParser_Sandbox extends AbstractTokenParser
31
  {
32
+ public function parse(Token $token)
33
  {
34
  $stream = $this->parser->getStream();
35
+ $stream->expect(Token::BLOCK_END_TYPE);
36
  $body = $this->parser->subparse([$this, 'decideBlockEnd'], true);
37
+ $stream->expect(Token::BLOCK_END_TYPE);
38
 
39
  // in a sandbox tag, only include tags are allowed
40
+ if (!$body instanceof IncludeNode) {
41
  foreach ($body as $node) {
42
+ if ($node instanceof TextNode && ctype_space($node->getAttribute('data'))) {
43
  continue;
44
  }
45
 
46
+ if (!$node instanceof IncludeNode) {
47
+ throw new SyntaxError('Only "include" tags are allowed within a "sandbox" section.', $node->getTemplateLine(), $stream->getSourceContext());
48
  }
49
  }
50
  }
51
 
52
+ return new SandboxNode($body, $token->getLine(), $this->getTag());
53
  }
54
 
55
+ public function decideBlockEnd(Token $token)
56
  {
57
  return $token->test('endsandbox');
58
  }
vendor/twig/twig/lib/Twig/TokenParser/Set.php CHANGED
@@ -9,59 +9,57 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
 
12
  /**
13
  * Defines a variable.
14
  *
15
- * <pre>
16
  * {% set foo = 'foo' %}
17
- *
18
  * {% set foo = [1, 2] %}
19
- *
20
  * {% set foo = {'foo': 'bar'} %}
21
- *
22
  * {% set foo = 'foo' ~ 'bar' %}
23
- *
24
  * {% set foo, bar = 'foo', 'bar' %}
25
- *
26
  * {% set foo %}Some content{% endset %}
27
- * </pre>
28
  *
29
  * @final
30
  */
31
- class Twig_TokenParser_Set extends Twig_TokenParser
32
  {
33
- public function parse(Twig_Token $token)
34
  {
35
  $lineno = $token->getLine();
36
  $stream = $this->parser->getStream();
37
  $names = $this->parser->getExpressionParser()->parseAssignmentExpression();
38
 
39
  $capture = false;
40
- if ($stream->nextIf(Twig_Token::OPERATOR_TYPE, '=')) {
41
  $values = $this->parser->getExpressionParser()->parseMultitargetExpression();
42
 
43
- $stream->expect(Twig_Token::BLOCK_END_TYPE);
44
 
45
- if (count($names) !== count($values)) {
46
- throw new Twig_Error_Syntax('When using set, you must have the same number of variables and assignments.', $stream->getCurrent()->getLine(), $stream->getSourceContext());
47
  }
48
  } else {
49
  $capture = true;
50
 
51
- if (count($names) > 1) {
52
- throw new Twig_Error_Syntax('When using set with a block, you cannot have a multi-target.', $stream->getCurrent()->getLine(), $stream->getSourceContext());
53
  }
54
 
55
- $stream->expect(Twig_Token::BLOCK_END_TYPE);
56
 
57
  $values = $this->parser->subparse([$this, 'decideBlockEnd'], true);
58
- $stream->expect(Twig_Token::BLOCK_END_TYPE);
59
  }
60
 
61
- return new Twig_Node_Set($capture, $names, $values, $lineno, $this->getTag());
62
  }
63
 
64
- public function decideBlockEnd(Twig_Token $token)
65
  {
66
  return $token->test('endset');
67
  }
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Error\SyntaxError;
13
+ use Twig\Node\SetNode;
14
+ use Twig\Token;
15
+ use Twig\TokenParser\AbstractTokenParser;
16
+
17
  /**
18
  * Defines a variable.
19
  *
 
20
  * {% set foo = 'foo' %}
 
21
  * {% set foo = [1, 2] %}
 
22
  * {% set foo = {'foo': 'bar'} %}
 
23
  * {% set foo = 'foo' ~ 'bar' %}
 
24
  * {% set foo, bar = 'foo', 'bar' %}
 
25
  * {% set foo %}Some content{% endset %}
 
26
  *
27
  * @final
28
  */
29
+ class Twig_TokenParser_Set extends AbstractTokenParser
30
  {
31
+ public function parse(Token $token)
32
  {
33
  $lineno = $token->getLine();
34
  $stream = $this->parser->getStream();
35
  $names = $this->parser->getExpressionParser()->parseAssignmentExpression();
36
 
37
  $capture = false;
38
+ if ($stream->nextIf(Token::OPERATOR_TYPE, '=')) {
39
  $values = $this->parser->getExpressionParser()->parseMultitargetExpression();
40
 
41
+ $stream->expect(Token::BLOCK_END_TYPE);
42
 
43
+ if (\count($names) !== \count($values)) {
44
+ throw new SyntaxError('When using set, you must have the same number of variables and assignments.', $stream->getCurrent()->getLine(), $stream->getSourceContext());
45
  }
46
  } else {
47
  $capture = true;
48
 
49
+ if (\count($names) > 1) {
50
+ throw new SyntaxError('When using set with a block, you cannot have a multi-target.', $stream->getCurrent()->getLine(), $stream->getSourceContext());
51
  }
52
 
53
+ $stream->expect(Token::BLOCK_END_TYPE);
54
 
55
  $values = $this->parser->subparse([$this, 'decideBlockEnd'], true);
56
+ $stream->expect(Token::BLOCK_END_TYPE);
57
  }
58
 
59
+ return new SetNode($capture, $names, $values, $lineno, $this->getTag());
60
  }
61
 
62
+ public function decideBlockEnd(Token $token)
63
  {
64
  return $token->test('endset');
65
  }
vendor/twig/twig/lib/Twig/TokenParser/Spaceless.php CHANGED
@@ -9,35 +9,36 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
12
  /**
13
  * Remove whitespaces between HTML tags.
14
  *
15
- * <pre>
16
- * {% spaceless %}
17
  * <div>
18
  * <strong>foo</strong>
19
  * </div>
20
- * {% endspaceless %}
21
- *
22
- * {# output will be <div><strong>foo</strong></div> #}
23
- * </pre>
24
  *
25
  * @final
26
  */
27
- class Twig_TokenParser_Spaceless extends Twig_TokenParser
28
  {
29
- public function parse(Twig_Token $token)
30
  {
31
  $lineno = $token->getLine();
32
 
33
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
34
  $body = $this->parser->subparse([$this, 'decideSpacelessEnd'], true);
35
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
36
 
37
- return new Twig_Node_Spaceless($body, $lineno, $this->getTag());
38
  }
39
 
40
- public function decideSpacelessEnd(Twig_Token $token)
41
  {
42
  return $token->test('endspaceless');
43
  }
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Node\SpacelessNode;
13
+ use Twig\Token;
14
+ use Twig\TokenParser\AbstractTokenParser;
15
+
16
  /**
17
  * Remove whitespaces between HTML tags.
18
  *
19
+ * {% spaceless %}
 
20
  * <div>
21
  * <strong>foo</strong>
22
  * </div>
23
+ * {% endspaceless %}
24
+ * {# output will be <div><strong>foo</strong></div> #}
 
 
25
  *
26
  * @final
27
  */
28
+ class Twig_TokenParser_Spaceless extends AbstractTokenParser
29
  {
30
+ public function parse(Token $token)
31
  {
32
  $lineno = $token->getLine();
33
 
34
+ $this->parser->getStream()->expect(Token::BLOCK_END_TYPE);
35
  $body = $this->parser->subparse([$this, 'decideSpacelessEnd'], true);
36
+ $this->parser->getStream()->expect(Token::BLOCK_END_TYPE);
37
 
38
+ return new SpacelessNode($body, $lineno, $this->getTag());
39
  }
40
 
41
+ public function decideSpacelessEnd(Token $token)
42
  {
43
  return $token->test('endspaceless');
44
  }
vendor/twig/twig/lib/Twig/TokenParser/Use.php CHANGED
@@ -9,56 +9,60 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
 
 
12
  /**
13
  * Imports blocks defined in another template into the current template.
14
  *
15
- * <pre>
16
- * {% extends "base.html" %}
17
  *
18
- * {% use "blocks.html" %}
19
  *
20
- * {% block title %}{% endblock %}
21
- * {% block content %}{% endblock %}
22
- * </pre>
23
  *
24
  * @see https://twig.symfony.com/doc/templates.html#horizontal-reuse for details.
25
  *
26
  * @final
27
  */
28
- class Twig_TokenParser_Use extends Twig_TokenParser
29
  {
30
- public function parse(Twig_Token $token)
31
  {
32
  $template = $this->parser->getExpressionParser()->parseExpression();
33
  $stream = $this->parser->getStream();
34
 
35
- if (!$template instanceof Twig_Node_Expression_Constant) {
36
- throw new Twig_Error_Syntax('The template references in a "use" statement must be a string.', $stream->getCurrent()->getLine(), $stream->getSourceContext());
37
  }
38
 
39
  $targets = [];
40
  if ($stream->nextIf('with')) {
41
  do {
42
- $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
43
 
44
  $alias = $name;
45
  if ($stream->nextIf('as')) {
46
- $alias = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
47
  }
48
 
49
- $targets[$name] = new Twig_Node_Expression_Constant($alias, -1);
50
 
51
- if (!$stream->nextIf(Twig_Token::PUNCTUATION_TYPE, ',')) {
52
  break;
53
  }
54
  } while (true);
55
  }
56
 
57
- $stream->expect(Twig_Token::BLOCK_END_TYPE);
58
 
59
- $this->parser->addTrait(new Twig_Node(['template' => $template, 'targets' => new Twig_Node($targets)]));
60
 
61
- return new Twig_Node();
62
  }
63
 
64
  public function getTag()
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Error\SyntaxError;
13
+ use Twig\Node\Expression\ConstantExpression;
14
+ use Twig\Node\Node;
15
+ use Twig\Token;
16
+ use Twig\TokenParser\AbstractTokenParser;
17
+
18
  /**
19
  * Imports blocks defined in another template into the current template.
20
  *
21
+ * {% extends "base.html" %}
 
22
  *
23
+ * {% use "blocks.html" %}
24
  *
25
+ * {% block title %}{% endblock %}
26
+ * {% block content %}{% endblock %}
 
27
  *
28
  * @see https://twig.symfony.com/doc/templates.html#horizontal-reuse for details.
29
  *
30
  * @final
31
  */
32
+ class Twig_TokenParser_Use extends AbstractTokenParser
33
  {
34
+ public function parse(Token $token)
35
  {
36
  $template = $this->parser->getExpressionParser()->parseExpression();
37
  $stream = $this->parser->getStream();
38
 
39
+ if (!$template instanceof ConstantExpression) {
40
+ throw new SyntaxError('The template references in a "use" statement must be a string.', $stream->getCurrent()->getLine(), $stream->getSourceContext());
41
  }
42
 
43
  $targets = [];
44
  if ($stream->nextIf('with')) {
45
  do {
46
+ $name = $stream->expect(Token::NAME_TYPE)->getValue();
47
 
48
  $alias = $name;
49
  if ($stream->nextIf('as')) {
50
+ $alias = $stream->expect(Token::NAME_TYPE)->getValue();
51
  }
52
 
53
+ $targets[$name] = new ConstantExpression($alias, -1);
54
 
55
+ if (!$stream->nextIf(Token::PUNCTUATION_TYPE, ',')) {
56
  break;
57
  }
58
  } while (true);
59
  }
60
 
61
+ $stream->expect(Token::BLOCK_END_TYPE);
62
 
63
+ $this->parser->addTrait(new Node(['template' => $template, 'targets' => new Node($targets)]));
64
 
65
+ return new Node();
66
  }
67
 
68
  public function getTag()
vendor/twig/twig/lib/Twig/TokenParser/With.php CHANGED
@@ -9,6 +9,10 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
12
  /**
13
  * Creates a nested scope.
14
  *
@@ -16,29 +20,29 @@
16
  *
17
  * @final
18
  */
19
- class Twig_TokenParser_With extends Twig_TokenParser
20
  {
21
- public function parse(Twig_Token $token)
22
  {
23
  $stream = $this->parser->getStream();
24
 
25
  $variables = null;
26
  $only = false;
27
- if (!$stream->test(Twig_Token::BLOCK_END_TYPE)) {
28
  $variables = $this->parser->getExpressionParser()->parseExpression();
29
- $only = $stream->nextIf(Twig_Token::NAME_TYPE, 'only');
30
  }
31
 
32
- $stream->expect(Twig_Token::BLOCK_END_TYPE);
33
 
34
  $body = $this->parser->subparse([$this, 'decideWithEnd'], true);
35
 
36
- $stream->expect(Twig_Token::BLOCK_END_TYPE);
37
 
38
- return new Twig_Node_With($body, $variables, $only, $token->getLine(), $this->getTag());
39
  }
40
 
41
- public function decideWithEnd(Twig_Token $token)
42
  {
43
  return $token->test('endwith');
44
  }
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Node\WithNode;
13
+ use Twig\Token;
14
+ use Twig\TokenParser\AbstractTokenParser;
15
+
16
  /**
17
  * Creates a nested scope.
18
  *
20
  *
21
  * @final
22
  */
23
+ class Twig_TokenParser_With extends AbstractTokenParser
24
  {
25
+ public function parse(Token $token)
26
  {
27
  $stream = $this->parser->getStream();
28
 
29
  $variables = null;
30
  $only = false;
31
+ if (!$stream->test(Token::BLOCK_END_TYPE)) {
32
  $variables = $this->parser->getExpressionParser()->parseExpression();
33
+ $only = $stream->nextIf(Token::NAME_TYPE, 'only');
34
  }
35
 
36
+ $stream->expect(Token::BLOCK_END_TYPE);
37
 
38
  $body = $this->parser->subparse([$this, 'decideWithEnd'], true);
39
 
40
+ $stream->expect(Token::BLOCK_END_TYPE);
41
 
42
+ return new WithNode($body, $variables, $only, $token->getLine(), $this->getTag());
43
  }
44
 
45
+ public function decideWithEnd(Token $token)
46
  {
47
  return $token->test('endwith');
48
  }
vendor/twig/twig/lib/Twig/TokenParserBroker.php CHANGED
@@ -10,6 +10,8 @@
10
  * file that was distributed with this source code.
11
  */
12
 
 
 
13
  /**
14
  * Default implementation of a token parser broker.
15
  *
@@ -24,9 +26,9 @@ class Twig_TokenParserBroker implements Twig_TokenParserBrokerInterface
24
  protected $brokers = [];
25
 
26
  /**
27
- * @param array|Traversable $parsers A Traversable of Twig_TokenParserInterface instances
28
- * @param array|Traversable $brokers A Traversable of Twig_TokenParserBrokerInterface instances
29
- * @param bool $triggerDeprecationError
30
  */
31
  public function __construct($parsers = [], $brokers = [], $triggerDeprecationError = true)
32
  {
@@ -35,25 +37,25 @@ class Twig_TokenParserBroker implements Twig_TokenParserBrokerInterface
35
  }
36
 
37
  foreach ($parsers as $parser) {
38
- if (!$parser instanceof Twig_TokenParserInterface) {
39
- throw new LogicException('$parsers must a an array of Twig_TokenParserInterface.');
40
  }
41
  $this->parsers[$parser->getTag()] = $parser;
42
  }
43
  foreach ($brokers as $broker) {
44
  if (!$broker instanceof Twig_TokenParserBrokerInterface) {
45
- throw new LogicException('$brokers must a an array of Twig_TokenParserBrokerInterface.');
46
  }
47
  $this->brokers[] = $broker;
48
  }
49
  }
50
 
51
- public function addTokenParser(Twig_TokenParserInterface $parser)
52
  {
53
  $this->parsers[$parser->getTag()] = $parser;
54
  }
55
 
56
- public function removeTokenParser(Twig_TokenParserInterface $parser)
57
  {
58
  $name = $parser->getTag();
59
  if (isset($this->parsers[$name]) && $parser === $this->parsers[$name]) {
@@ -80,7 +82,7 @@ class Twig_TokenParserBroker implements Twig_TokenParserBrokerInterface
80
  *
81
  * @param string $tag A tag name
82
  *
83
- * @return Twig_TokenParserInterface|null A Twig_TokenParserInterface or null if no suitable TokenParser was found
84
  */
85
  public function getTokenParser($tag)
86
  {
10
  * file that was distributed with this source code.
11
  */
12
 
13
+ use Twig\TokenParser\TokenParserInterface;
14
+
15
  /**
16
  * Default implementation of a token parser broker.
17
  *
26
  protected $brokers = [];
27
 
28
  /**
29
+ * @param array|\Traversable $parsers A \Traversable of Twig_TokenParserInterface instances
30
+ * @param array|\Traversable $brokers A \Traversable of Twig_TokenParserBrokerInterface instances
31
+ * @param bool $triggerDeprecationError
32
  */
33
  public function __construct($parsers = [], $brokers = [], $triggerDeprecationError = true)
34
  {
37
  }
38
 
39
  foreach ($parsers as $parser) {
40
+ if (!$parser instanceof TokenParserInterface) {
41
+ throw new \LogicException('$parsers must a an array of Twig_TokenParserInterface.');
42
  }
43
  $this->parsers[$parser->getTag()] = $parser;
44
  }
45
  foreach ($brokers as $broker) {
46
  if (!$broker instanceof Twig_TokenParserBrokerInterface) {
47
+ throw new \LogicException('$brokers must a an array of Twig_TokenParserBrokerInterface.');
48
  }
49
  $this->brokers[] = $broker;
50
  }
51
  }
52
 
53
+ public function addTokenParser(TokenParserInterface $parser)
54
  {
55
  $this->parsers[$parser->getTag()] = $parser;
56
  }
57
 
58
+ public function removeTokenParser(TokenParserInterface $parser)
59
  {
60
  $name = $parser->getTag();
61
  if (isset($this->parsers[$name]) && $parser === $this->parsers[$name]) {
82
  *
83
  * @param string $tag A tag name
84
  *
85
+ * @return TokenParserInterface|null A Twig_TokenParserInterface or null if no suitable TokenParser was found
86
  */
87
  public function getTokenParser($tag)
88
  {
vendor/twig/twig/lib/Twig/TokenParserBrokerInterface.php CHANGED
@@ -10,6 +10,8 @@
10
  * file that was distributed with this source code.
11
  */
12
 
 
 
13
  /**
14
  * Interface implemented by token parser brokers.
15
  *
@@ -26,12 +28,12 @@ interface Twig_TokenParserBrokerInterface
26
  *
27
  * @param string $tag A tag name
28
  *
29
- * @return Twig_TokenParserInterface|null A Twig_TokenParserInterface or null if no suitable TokenParser was found
30
  */
31
  public function getTokenParser($tag);
32
 
33
  /**
34
- * Calls Twig_TokenParserInterface::setParser on all parsers the implementation knows of.
35
  */
36
  public function setParser(Twig_ParserInterface $parser);
37
 
10
  * file that was distributed with this source code.
11
  */
12
 
13
+ use Twig\TokenParser\TokenParserInterface;
14
+
15
  /**
16
  * Interface implemented by token parser brokers.
17
  *
28
  *
29
  * @param string $tag A tag name
30
  *
31
+ * @return TokenParserInterface|null A Twig_TokenParserInterface or null if no suitable TokenParser was found
32
  */
33
  public function getTokenParser($tag);
34
 
35
  /**
36
+ * Calls Twig\TokenParser\TokenParserInterface::setParser on all parsers the implementation knows of.
37
  */
38
  public function setParser(Twig_ParserInterface $parser);
39
 
vendor/twig/twig/lib/Twig/TokenParserInterface.php CHANGED
@@ -9,6 +9,10 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
12
  /**
13
  * Interface implemented by token parsers.
14
  *
@@ -19,16 +23,16 @@ interface Twig_TokenParserInterface
19
  /**
20
  * Sets the parser associated with this token parser.
21
  */
22
- public function setParser(Twig_Parser $parser);
23
 
24
  /**
25
  * Parses a token and returns a node.
26
  *
27
  * @return Twig_NodeInterface
28
  *
29
- * @throws Twig_Error_Syntax
30
  */
31
- public function parse(Twig_Token $token);
32
 
33
  /**
34
  * Gets the tag name associated with this token parser.
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Error\SyntaxError;
13
+ use Twig\Parser;
14
+ use Twig\Token;
15
+
16
  /**
17
  * Interface implemented by token parsers.
18
  *
23
  /**
24
  * Sets the parser associated with this token parser.
25
  */
26
+ public function setParser(Parser $parser);
27
 
28
  /**
29
  * Parses a token and returns a node.
30
  *
31
  * @return Twig_NodeInterface
32
  *
33
+ * @throws SyntaxError
34
  */
35
+ public function parse(Token $token);
36
 
37
  /**
38
  * Gets the tag name associated with this token parser.
vendor/twig/twig/lib/Twig/TokenStream.php CHANGED
@@ -10,6 +10,10 @@
10
  * file that was distributed with this source code.
11
  */
12
 
 
 
 
 
13
  /**
14
  * Represents a token stream.
15
  *
@@ -32,11 +36,11 @@ class Twig_TokenStream
32
  */
33
  public function __construct(array $tokens, $name = null, $source = null)
34
  {
35
- if (!$name instanceof Twig_Source) {
36
  if (null !== $name || null !== $source) {
37
  @trigger_error(sprintf('Passing a string as the $name argument of %s() is deprecated since version 1.27. Pass a Twig_Source instance instead.', __METHOD__), E_USER_DEPRECATED);
38
  }
39
- $this->source = new Twig_Source($source, $name);
40
  } else {
41
  $this->source = $name;
42
  }
@@ -54,18 +58,18 @@ class Twig_TokenStream
54
 
55
  public function injectTokens(array $tokens)
56
  {
57
- $this->tokens = array_merge(array_slice($this->tokens, 0, $this->current), $tokens, array_slice($this->tokens, $this->current));
58
  }
59
 
60
  /**
61
  * Sets the pointer to the next token and returns the old one.
62
  *
63
- * @return Twig_Token
64
  */
65
  public function next()
66
  {
67
  if (!isset($this->tokens[++$this->current])) {
68
- throw new Twig_Error_Syntax('Unexpected end of template.', $this->tokens[$this->current - 1]->getLine(), $this->source);
69
  }
70
 
71
  return $this->tokens[$this->current - 1];
@@ -74,7 +78,7 @@ class Twig_TokenStream
74
  /**
75
  * Tests a token, sets the pointer to the next one and returns it or throws a syntax error.
76
  *
77
- * @return Twig_Token|null The next token if the condition is true, null otherwise
78
  */
79
  public function nextIf($primary, $secondary = null)
80
  {
@@ -86,17 +90,17 @@ class Twig_TokenStream
86
  /**
87
  * Tests a token and returns it or throws a syntax error.
88
  *
89
- * @return Twig_Token
90
  */
91
  public function expect($type, $value = null, $message = null)
92
  {
93
  $token = $this->tokens[$this->current];
94
  if (!$token->test($type, $value)) {
95
  $line = $token->getLine();
96
- throw new Twig_Error_Syntax(sprintf('%sUnexpected token "%s" of value "%s" ("%s" expected%s).',
97
  $message ? $message.'. ' : '',
98
- Twig_Token::typeToEnglish($token->getType()), $token->getValue(),
99
- Twig_Token::typeToEnglish($type), $value ? sprintf(' with value "%s"', $value) : ''),
100
  $line,
101
  $this->source
102
  );
@@ -111,12 +115,12 @@ class Twig_TokenStream
111
  *
112
  * @param int $number
113
  *
114
- * @return Twig_Token
115
  */
116
  public function look($number = 1)
117
  {
118
  if (!isset($this->tokens[$this->current + $number])) {
119
- throw new Twig_Error_Syntax('Unexpected end of template.', $this->tokens[$this->current + $number - 1]->getLine(), $this->source);
120
  }
121
 
122
  return $this->tokens[$this->current + $number];
@@ -139,11 +143,11 @@ class Twig_TokenStream
139
  */
140
  public function isEOF()
141
  {
142
- return Twig_Token::EOF_TYPE === $this->tokens[$this->current]->getType();
143
  }
144
 
145
  /**
146
- * @return Twig_Token
147
  */
148
  public function getCurrent()
149
  {
@@ -183,7 +187,7 @@ class Twig_TokenStream
183
  /**
184
  * Gets the source associated with this stream.
185
  *
186
- * @return Twig_Source
187
  *
188
  * @internal
189
  */
10
  * file that was distributed with this source code.
11
  */
12
 
13
+ use Twig\Error\SyntaxError;
14
+ use Twig\Source;
15
+ use Twig\Token;
16
+
17
  /**
18
  * Represents a token stream.
19
  *
36
  */
37
  public function __construct(array $tokens, $name = null, $source = null)
38
  {
39
+ if (!$name instanceof Source) {
40
  if (null !== $name || null !== $source) {
41
  @trigger_error(sprintf('Passing a string as the $name argument of %s() is deprecated since version 1.27. Pass a Twig_Source instance instead.', __METHOD__), E_USER_DEPRECATED);
42
  }
43
+ $this->source = new Source($source, $name);
44
  } else {
45
  $this->source = $name;
46
  }
58
 
59
  public function injectTokens(array $tokens)
60
  {
61
+ $this->tokens = array_merge(\array_slice($this->tokens, 0, $this->current), $tokens, \array_slice($this->tokens, $this->current));
62
  }
63
 
64
  /**
65
  * Sets the pointer to the next token and returns the old one.
66
  *
67
+ * @return Token
68
  */
69
  public function next()
70
  {
71
  if (!isset($this->tokens[++$this->current])) {
72
+ throw new SyntaxError('Unexpected end of template.', $this->tokens[$this->current - 1]->getLine(), $this->source);
73
  }
74
 
75
  return $this->tokens[$this->current - 1];
78
  /**
79
  * Tests a token, sets the pointer to the next one and returns it or throws a syntax error.
80
  *
81
+ * @return Token|null The next token if the condition is true, null otherwise
82
  */
83
  public function nextIf($primary, $secondary = null)
84
  {
90
  /**
91
  * Tests a token and returns it or throws a syntax error.
92
  *
93
+ * @return Token
94
  */
95
  public function expect($type, $value = null, $message = null)
96
  {
97
  $token = $this->tokens[$this->current];
98
  if (!$token->test($type, $value)) {
99
  $line = $token->getLine();
100
+ throw new SyntaxError(sprintf('%sUnexpected token "%s" of value "%s" ("%s" expected%s).',
101
  $message ? $message.'. ' : '',
102
+ Token::typeToEnglish($token->getType()), $token->getValue(),
103
+ Token::typeToEnglish($type), $value ? sprintf(' with value "%s"', $value) : ''),
104
  $line,
105
  $this->source
106
  );
115
  *
116
  * @param int $number
117
  *
118
+ * @return Token
119
  */
120
  public function look($number = 1)
121
  {
122
  if (!isset($this->tokens[$this->current + $number])) {
123
+ throw new SyntaxError('Unexpected end of template.', $this->tokens[$this->current + $number - 1]->getLine(), $this->source);
124
  }
125
 
126
  return $this->tokens[$this->current + $number];
143
  */
144
  public function isEOF()
145
  {
146
+ return Token::EOF_TYPE === $this->tokens[$this->current]->getType();
147
  }
148
 
149
  /**
150
+ * @return Token
151
  */
152
  public function getCurrent()
153
  {
187
  /**
188
  * Gets the source associated with this stream.
189
  *
190
+ * @return Source
191
  *
192
  * @internal
193
  */
vendor/twig/twig/lib/Twig/Util/DeprecationCollector.php CHANGED
@@ -9,6 +9,11 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
 
12
  /**
13
  * @author Fabien Potencier <fabien@symfony.com>
14
  *
@@ -19,7 +24,7 @@ class Twig_Util_DeprecationCollector
19
  private $twig;
20
  private $deprecations;
21
 
22
- public function __construct(Twig_Environment $twig)
23
  {
24
  $this->twig = $twig;
25
  }
@@ -34,23 +39,23 @@ class Twig_Util_DeprecationCollector
34
  */
35
  public function collectDir($dir, $ext = '.twig')
36
  {
37
- $iterator = new RegexIterator(
38
- new RecursiveIteratorIterator(
39
- new RecursiveDirectoryIterator($dir), RecursiveIteratorIterator::LEAVES_ONLY
40
  ), '{'.preg_quote($ext).'$}'
41
  );
42
 
43
- return $this->collect(new Twig_Util_TemplateDirIterator($iterator));
44
  }
45
 
46
  /**
47
  * Returns deprecations for passed templates.
48
  *
49
- * @param Traversable $iterator An iterator of templates (where keys are template names and values the contents of the template)
50
  *
51
  * @return array An array of deprecations
52
  */
53
- public function collect(Traversable $iterator)
54
  {
55
  $this->deprecations = [];
56
 
@@ -58,8 +63,8 @@ class Twig_Util_DeprecationCollector
58
 
59
  foreach ($iterator as $name => $contents) {
60
  try {
61
- $this->twig->parse($this->twig->tokenize(new Twig_Source($contents, $name)));
62
- } catch (Twig_Error_Syntax $e) {
63
  // ignore templates containing syntax errors
64
  }
65
  }
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Environment;
13
+ use Twig\Error\SyntaxError;
14
+ use Twig\Source;
15
+ use Twig\Util\TemplateDirIterator;
16
+
17
  /**
18
  * @author Fabien Potencier <fabien@symfony.com>
19
  *
24
  private $twig;
25
  private $deprecations;
26
 
27
+ public function __construct(Environment $twig)
28
  {
29
  $this->twig = $twig;
30
  }
39
  */
40
  public function collectDir($dir, $ext = '.twig')
41
  {
42
+ $iterator = new \RegexIterator(
43
+ new \RecursiveIteratorIterator(
44
+ new \RecursiveDirectoryIterator($dir), \RecursiveIteratorIterator::LEAVES_ONLY
45
  ), '{'.preg_quote($ext).'$}'
46
  );
47
 
48
+ return $this->collect(new TemplateDirIterator($iterator));
49
  }
50
 
51
  /**
52
  * Returns deprecations for passed templates.
53
  *
54
+ * @param \Traversable $iterator An iterator of templates (where keys are template names and values the contents of the template)
55
  *
56
  * @return array An array of deprecations
57
  */
58
+ public function collect(\Traversable $iterator)
59
  {
60
  $this->deprecations = [];
61
 
63
 
64
  foreach ($iterator as $name => $contents) {
65
  try {
66
+ $this->twig->parse($this->twig->tokenize(new Source($contents, $name)));
67
+ } catch (SyntaxError $e) {
68
  // ignore templates containing syntax errors
69
  }
70
  }
vendor/twig/twig/test/Twig/Tests/Cache/FilesystemTest.php CHANGED
@@ -9,7 +9,9 @@
9
  * file that was distributed with this source code.
10
  */
11
 
12
- require_once dirname(dirname(__FILE__)).'/FilesystemHelper.php';
 
 
13
 
14
  class Twig_Tests_Cache_FilesystemTest extends \PHPUnit\Framework\TestCase
15
  {
@@ -22,7 +24,7 @@ class Twig_Tests_Cache_FilesystemTest extends \PHPUnit\Framework\TestCase
22
  $nonce = hash('sha256', uniqid(mt_rand(), true));
23
  $this->classname = '__Twig_Tests_Cache_FilesystemTest_Template_'.$nonce;
24
  $this->directory = sys_get_temp_dir().'/twig-test';
25
- $this->cache = new Twig_Cache_Filesystem($this->directory);
26
  }
27
 
28
  protected function tearDown()
@@ -36,7 +38,7 @@ class Twig_Tests_Cache_FilesystemTest extends \PHPUnit\Framework\TestCase
36
  {
37
  $key = $this->directory.'/cache/cachefile.php';
38
 
39
- $dir = dirname($key);
40
  @mkdir($dir, 0777, true);
41
  $this->assertTrue(is_dir($dir));
42
  $this->assertFalse(class_exists($this->classname, false));
@@ -76,12 +78,12 @@ class Twig_Tests_Cache_FilesystemTest extends \PHPUnit\Framework\TestCase
76
  }
77
 
78
  /**
79
- * @expectedException RuntimeException
80
  * @expectedExceptionMessage Unable to create the cache directory
81
  */
82
  public function testWriteFailMkdir()
83
  {
84
- if (defined('PHP_WINDOWS_VERSION_BUILD')) {
85
  $this->markTestSkipped('Read-only directories not possible on Windows.');
86
  }
87
 
@@ -98,12 +100,12 @@ class Twig_Tests_Cache_FilesystemTest extends \PHPUnit\Framework\TestCase
98
  }
99
 
100
  /**
101
- * @expectedException RuntimeException
102
  * @expectedExceptionMessage Unable to write in the cache directory
103
  */
104
  public function testWriteFailDirWritable()
105
  {
106
- if (defined('PHP_WINDOWS_VERSION_BUILD')) {
107
  $this->markTestSkipped('Read-only directories not possible on Windows.');
108
  }
109
 
@@ -122,7 +124,7 @@ class Twig_Tests_Cache_FilesystemTest extends \PHPUnit\Framework\TestCase
122
  }
123
 
124
  /**
125
- * @expectedException RuntimeException
126
  * @expectedExceptionMessage Failed to write cache file
127
  */
128
  public function testWriteFailWriteFile()
@@ -143,7 +145,7 @@ class Twig_Tests_Cache_FilesystemTest extends \PHPUnit\Framework\TestCase
143
  {
144
  $key = $this->directory.'/cache/cachefile.php';
145
 
146
- $dir = dirname($key);
147
  @mkdir($dir, 0777, true);
148
  $this->assertTrue(is_dir($dir));
149
 
@@ -166,8 +168,8 @@ class Twig_Tests_Cache_FilesystemTest extends \PHPUnit\Framework\TestCase
166
  */
167
  public function testGenerateKey($expected, $input)
168
  {
169
- $cache = new Twig_Cache_Filesystem($input);
170
- $this->assertRegExp($expected, $cache->generateKey('_test_', get_class($this)));
171
  }
172
 
173
  public function provideDirectories()
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Cache\FilesystemCache;
13
+
14
+ require_once \dirname(__DIR__).'/FilesystemHelper.php';
15
 
16
  class Twig_Tests_Cache_FilesystemTest extends \PHPUnit\Framework\TestCase
17
  {
24
  $nonce = hash('sha256', uniqid(mt_rand(), true));
25
  $this->classname = '__Twig_Tests_Cache_FilesystemTest_Template_'.$nonce;
26
  $this->directory = sys_get_temp_dir().'/twig-test';
27
+ $this->cache = new FilesystemCache($this->directory);
28
  }
29
 
30
  protected function tearDown()
38
  {
39
  $key = $this->directory.'/cache/cachefile.php';
40
 
41
+ $dir = \dirname($key);
42
  @mkdir($dir, 0777, true);
43
  $this->assertTrue(is_dir($dir));
44
  $this->assertFalse(class_exists($this->classname, false));
78
  }
79
 
80
  /**
81
+ * @expectedException \RuntimeException
82
  * @expectedExceptionMessage Unable to create the cache directory
83
  */
84
  public function testWriteFailMkdir()
85
  {
86
+ if (\defined('PHP_WINDOWS_VERSION_BUILD')) {
87
  $this->markTestSkipped('Read-only directories not possible on Windows.');
88
  }
89
 
100
  }
101
 
102
  /**
103
+ * @expectedException \RuntimeException
104
  * @expectedExceptionMessage Unable to write in the cache directory
105
  */
106
  public function testWriteFailDirWritable()
107
  {
108
+ if (\defined('PHP_WINDOWS_VERSION_BUILD')) {
109
  $this->markTestSkipped('Read-only directories not possible on Windows.');
110
  }
111
 
124
  }
125
 
126
  /**
127
+ * @expectedException \RuntimeException
128
  * @expectedExceptionMessage Failed to write cache file
129
  */
130
  public function testWriteFailWriteFile()
145
  {
146
  $key = $this->directory.'/cache/cachefile.php';
147
 
148
+ $dir = \dirname($key);
149
  @mkdir($dir, 0777, true);
150
  $this->assertTrue(is_dir($dir));
151
 
168
  */
169
  public function testGenerateKey($expected, $input)
170
  {
171
+ $cache = new FilesystemCache($input);
172
+ $this->assertRegExp($expected, $cache->generateKey('_test_', \get_class($this)));
173
  }
174
 
175
  public function provideDirectories()
vendor/twig/twig/test/Twig/Tests/CompilerTest.php CHANGED
@@ -9,11 +9,14 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
12
  class Twig_Tests_CompilerTest extends \PHPUnit\Framework\TestCase
13
  {
14
  public function testReprNumericValueWithLocale()
15
  {
16
- $compiler = new Twig_Compiler(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
17
 
18
  $locale = setlocale(LC_NUMERIC, 0);
19
  if (false === $locale) {
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Compiler;
13
+ use Twig\Environment;
14
+
15
  class Twig_Tests_CompilerTest extends \PHPUnit\Framework\TestCase
16
  {
17
  public function testReprNumericValueWithLocale()
18
  {
19
+ $compiler = new Compiler(new Environment($this->getMockBuilder('\Twig\Loader\LoaderInterface')->getMock()));
20
 
21
  $locale = setlocale(LC_NUMERIC, 0);
22
  if (false === $locale) {
vendor/twig/twig/test/Twig/Tests/ContainerRuntimeLoaderTest.php CHANGED
@@ -9,6 +9,8 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
12
  class Twig_Tests_ContainerRuntimeLoaderTest extends \PHPUnit\Framework\TestCase
13
  {
14
  /**
@@ -18,9 +20,9 @@ class Twig_Tests_ContainerRuntimeLoaderTest extends \PHPUnit\Framework\TestCase
18
  {
19
  $container = $this->getMockBuilder('Psr\Container\ContainerInterface')->getMock();
20
  $container->expects($this->once())->method('has')->with('stdClass')->willReturn(true);
21
- $container->expects($this->once())->method('get')->with('stdClass')->willReturn(new stdClass());
22
 
23
- $loader = new Twig_ContainerRuntimeLoader($container);
24
 
25
  $this->assertInstanceOf('stdClass', $loader->load('stdClass'));
26
  }
@@ -34,7 +36,7 @@ class Twig_Tests_ContainerRuntimeLoaderTest extends \PHPUnit\Framework\TestCase
34
  $container->expects($this->once())->method('has')->with('Foo');
35
  $container->expects($this->never())->method('get');
36
 
37
- $loader = new Twig_ContainerRuntimeLoader($container);
38
  $this->assertNull($loader->load('Foo'));
39
  }
40
  }
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\RuntimeLoader\ContainerRuntimeLoader;
13
+
14
  class Twig_Tests_ContainerRuntimeLoaderTest extends \PHPUnit\Framework\TestCase
15
  {
16
  /**
20
  {
21
  $container = $this->getMockBuilder('Psr\Container\ContainerInterface')->getMock();
22
  $container->expects($this->once())->method('has')->with('stdClass')->willReturn(true);
23
+ $container->expects($this->once())->method('get')->with('stdClass')->willReturn(new \stdClass());
24
 
25
+ $loader = new ContainerRuntimeLoader($container);
26
 
27
  $this->assertInstanceOf('stdClass', $loader->load('stdClass'));
28
  }
36
  $container->expects($this->once())->method('has')->with('Foo');
37
  $container->expects($this->never())->method('get');
38
 
39
+ $loader = new ContainerRuntimeLoader($container);
40
  $this->assertNull($loader->load('Foo'));
41
  }
42
  }
vendor/twig/twig/test/Twig/Tests/CustomExtensionTest.php CHANGED
@@ -9,13 +9,16 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
12
  class CustomExtensionTest extends \PHPUnit\Framework\TestCase
13
  {
14
  /**
15
  * @requires PHP 5.3
16
  * @dataProvider provideInvalidExtensions
17
  */
18
- public function testGetInvalidOperators(Twig_ExtensionInterface $extension, $expectedExceptionMessage)
19
  {
20
  if (method_exists($this, 'expectException')) {
21
  $this->expectException('InvalidArgumentException');
@@ -24,7 +27,7 @@ class CustomExtensionTest extends \PHPUnit\Framework\TestCase
24
  $this->setExpectedException('InvalidArgumentException', $expectedExceptionMessage);
25
  }
26
 
27
- $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
28
  $env->addExtension($extension);
29
  $env->getUnaryOperators();
30
  }
@@ -32,13 +35,13 @@ class CustomExtensionTest extends \PHPUnit\Framework\TestCase
32
  public function provideInvalidExtensions()
33
  {
34
  return [
35
- [new InvalidOperatorExtension(new stdClass()), '"InvalidOperatorExtension::getOperators()" must return an array with operators, got "stdClass".'],
36
  [new InvalidOperatorExtension([1, 2, 3]), '"InvalidOperatorExtension::getOperators()" must return an array of 2 elements, got 3.'],
37
  ];
38
  }
39
  }
40
 
41
- class InvalidOperatorExtension implements Twig_ExtensionInterface
42
  {
43
  private $operators;
44
 
@@ -47,7 +50,7 @@ class InvalidOperatorExtension implements Twig_ExtensionInterface
47
  $this->operators = $operators;
48
  }
49
 
50
- public function initRuntime(Twig_Environment $environment)
51
  {
52
  }
53
 
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Environment;
13
+ use Twig\Extension\ExtensionInterface;
14
+
15
  class CustomExtensionTest extends \PHPUnit\Framework\TestCase
16
  {
17
  /**
18
  * @requires PHP 5.3
19
  * @dataProvider provideInvalidExtensions
20
  */
21
+ public function testGetInvalidOperators(ExtensionInterface $extension, $expectedExceptionMessage)
22
  {
23
  if (method_exists($this, 'expectException')) {
24
  $this->expectException('InvalidArgumentException');
27
  $this->setExpectedException('InvalidArgumentException', $expectedExceptionMessage);
28
  }
29
 
30
+ $env = new Environment($this->getMockBuilder('\Twig\Loader\LoaderInterface')->getMock());
31
  $env->addExtension($extension);
32
  $env->getUnaryOperators();
33
  }
35
  public function provideInvalidExtensions()
36
  {
37
  return [
38
+ [new InvalidOperatorExtension(new \stdClass()), '"InvalidOperatorExtension::getOperators()" must return an array with operators, got "stdClass".'],
39
  [new InvalidOperatorExtension([1, 2, 3]), '"InvalidOperatorExtension::getOperators()" must return an array of 2 elements, got 3.'],
40
  ];
41
  }
42
  }
43
 
44
+ class InvalidOperatorExtension implements ExtensionInterface
45
  {
46
  private $operators;
47
 
50
  $this->operators = $operators;
51
  }
52
 
53
+ public function initRuntime(Environment $environment)
54
  {
55
  }
56
 
vendor/twig/twig/test/Twig/Tests/EnvironmentTest.php CHANGED
@@ -9,7 +9,22 @@
9
  * file that was distributed with this source code.
10
  */
11
 
12
- require_once dirname(__FILE__).'/FilesystemHelper.php';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
  class Twig_Tests_EnvironmentTest extends \PHPUnit\Framework\TestCase
15
  {
@@ -20,7 +35,7 @@ class Twig_Tests_EnvironmentTest extends \PHPUnit\Framework\TestCase
20
  */
21
  public function testLegacyTokenizeSignature()
22
  {
23
- $env = new Twig_Environment();
24
  $stream = $env->tokenize('{{ foo }}', 'foo');
25
  $this->assertEquals('{{ foo }}', $stream->getSource());
26
  $this->assertEquals('foo', $stream->getFilename());
@@ -31,30 +46,30 @@ class Twig_Tests_EnvironmentTest extends \PHPUnit\Framework\TestCase
31
  */
32
  public function testLegacyCompileSourceSignature()
33
  {
34
- $loader = new Twig_Loader_Array(['foo' => '{{ foo }}']);
35
- $env = new Twig_Environment($loader);
36
  $this->assertContains('getTemplateName', $env->compileSource('{{ foo }}', 'foo'));
37
  }
38
 
39
  /**
40
- * @expectedException LogicException
41
  * @expectedExceptionMessage You must set a loader first.
42
  * @group legacy
43
  */
44
  public function testRenderNoLoader()
45
  {
46
- $env = new Twig_Environment();
47
  $env->render('test');
48
  }
49
 
50
  public function testAutoescapeOption()
51
  {
52
- $loader = new Twig_Loader_Array([
53
  'html' => '{{ foo }} {{ foo }}',
54
  'js' => '{{ bar }} {{ bar }}',
55
  ]);
56
 
57
- $twig = new Twig_Environment($loader, [
58
  'debug' => true,
59
  'cache' => false,
60
  'autoescape' => [$this, 'escapingStrategyCallback'],
@@ -73,12 +88,12 @@ class Twig_Tests_EnvironmentTest extends \PHPUnit\Framework\TestCase
73
  {
74
  // to be removed in 2.0
75
  $loader = $this->getMockBuilder('Twig_EnvironmentTestLoaderInterface')->getMock();
76
- //$loader = $this->getMockBuilder(['Twig_LoaderInterface', 'Twig_SourceContextLoaderInterface'])->getMock();
77
- $loader->expects($this->any())->method('getSourceContext')->will($this->returnValue(new Twig_Source('', '')));
78
 
79
  // globals can be added after calling getGlobals
80
 
81
- $twig = new Twig_Environment($loader);
82
  $twig->addGlobal('foo', 'foo');
83
  $twig->getGlobals();
84
  $twig->addGlobal('foo', 'bar');
@@ -86,7 +101,7 @@ class Twig_Tests_EnvironmentTest extends \PHPUnit\Framework\TestCase
86
  $this->assertEquals('bar', $globals['foo']);
87
 
88
  // globals can be modified after a template has been loaded
89
- $twig = new Twig_Environment($loader);
90
  $twig->addGlobal('foo', 'foo');
91
  $twig->getGlobals();
92
  $twig->loadTemplate('index');
@@ -95,7 +110,7 @@ class Twig_Tests_EnvironmentTest extends \PHPUnit\Framework\TestCase
95
  $this->assertEquals('bar', $globals['foo']);
96
 
97
  // globals can be modified after extensions init
98
- $twig = new Twig_Environment($loader);
99
  $twig->addGlobal('foo', 'foo');
100
  $twig->getGlobals();
101
  $twig->getFunctions();
@@ -104,8 +119,8 @@ class Twig_Tests_EnvironmentTest extends \PHPUnit\Framework\TestCase
104
  $this->assertEquals('bar', $globals['foo']);
105
 
106
  // globals can be modified after extensions and a template has been loaded
107
- $arrayLoader = new Twig_Loader_Array(['index' => '{{foo}}']);
108
- $twig = new Twig_Environment($arrayLoader);
109
  $twig->addGlobal('foo', 'foo');
110
  $twig->getGlobals();
111
  $twig->getFunctions();
@@ -114,7 +129,7 @@ class Twig_Tests_EnvironmentTest extends \PHPUnit\Framework\TestCase
114
  $globals = $twig->getGlobals();
115
  $this->assertEquals('bar', $globals['foo']);
116
 
117
- $twig = new Twig_Environment($arrayLoader);
118
  $twig->getGlobals();
119
  $twig->addGlobal('foo', 'bar');
120
  $template = $twig->loadTemplate('index');
@@ -122,31 +137,31 @@ class Twig_Tests_EnvironmentTest extends \PHPUnit\Framework\TestCase
122
 
123
  /* to be uncomment in Twig 2.0
124
  // globals cannot be added after a template has been loaded
125
- $twig = new Twig_Environment($loader);
126
  $twig->addGlobal('foo', 'foo');
127
  $twig->getGlobals();
128
  $twig->loadTemplate('index');
129
  try {
130
  $twig->addGlobal('bar', 'bar');
131
  $this->fail();
132
- } catch (LogicException $e) {
133
  $this->assertFalse(array_key_exists('bar', $twig->getGlobals()));
134
  }
135
 
136
  // globals cannot be added after extensions init
137
- $twig = new Twig_Environment($loader);
138
  $twig->addGlobal('foo', 'foo');
139
  $twig->getGlobals();
140
  $twig->getFunctions();
141
  try {
142
  $twig->addGlobal('bar', 'bar');
143
  $this->fail();
144
- } catch (LogicException $e) {
145
  $this->assertFalse(array_key_exists('bar', $twig->getGlobals()));
146
  }
147
 
148
  // globals cannot be added after extensions and a template has been loaded
149
- $twig = new Twig_Environment($loader);
150
  $twig->addGlobal('foo', 'foo');
151
  $twig->getGlobals();
152
  $twig->getFunctions();
@@ -154,17 +169,17 @@ class Twig_Tests_EnvironmentTest extends \PHPUnit\Framework\TestCase
154
  try {
155
  $twig->addGlobal('bar', 'bar');
156
  $this->fail();
157
- } catch (LogicException $e) {
158
  $this->assertFalse(array_key_exists('bar', $twig->getGlobals()));
159
  }
160
 
161
  // test adding globals after a template has been loaded without call to getGlobals
162
- $twig = new Twig_Environment($loader);
163
  $twig->loadTemplate('index');
164
  try {
165
  $twig->addGlobal('bar', 'bar');
166
  $this->fail();
167
- } catch (LogicException $e) {
168
  $this->assertFalse(array_key_exists('bar', $twig->getGlobals()));
169
  }
170
  */
@@ -172,18 +187,18 @@ class Twig_Tests_EnvironmentTest extends \PHPUnit\Framework\TestCase
172
 
173
  public function testExtensionsAreNotInitializedWhenRenderingACompiledTemplate()
174
  {
175
- $cache = new Twig_Cache_Filesystem($dir = sys_get_temp_dir().'/twig');
176
  $options = ['cache' => $cache, 'auto_reload' => false, 'debug' => false];
177
 
178
  // force compilation
179
- $twig = new Twig_Environment($loader = new Twig_Loader_Array(['index' => '{{ foo }}']), $options);
180
 
181
  $key = $cache->generateKey('index', $twig->getTemplateClass('index'));
182
- $cache->write($key, $twig->compileSource(new Twig_Source('{{ foo }}', 'index')));
183
 
184
  // check that extensions won't be initialized when rendering a template that is already in the cache
185
  $twig = $this
186
- ->getMockBuilder('Twig_Environment')
187
  ->setConstructorArgs([$loader, $options])
188
  ->setMethods(['initExtensions'])
189
  ->getMock()
@@ -203,9 +218,9 @@ class Twig_Tests_EnvironmentTest extends \PHPUnit\Framework\TestCase
203
  $templateName = __FUNCTION__;
204
  $templateContent = __FUNCTION__;
205
 
206
- $cache = $this->getMockBuilder('Twig_CacheInterface')->getMock();
207
  $loader = $this->getMockLoader($templateName, $templateContent);
208
- $twig = new Twig_Environment($loader, ['cache' => $cache, 'auto_reload' => true, 'debug' => false]);
209
 
210
  // Cache miss: getTimestamp returns 0 and as a result the load() is
211
  // skipped.
@@ -230,9 +245,9 @@ class Twig_Tests_EnvironmentTest extends \PHPUnit\Framework\TestCase
230
  $templateName = __FUNCTION__;
231
  $templateContent = __FUNCTION__;
232
 
233
- $cache = $this->getMockBuilder('Twig_CacheInterface')->getMock();
234
  $loader = $this->getMockLoader($templateName, $templateContent);
235
- $twig = new Twig_Environment($loader, ['cache' => $cache, 'auto_reload' => true, 'debug' => false]);
236
 
237
  $now = time();
238
 
@@ -258,9 +273,9 @@ class Twig_Tests_EnvironmentTest extends \PHPUnit\Framework\TestCase
258
  $templateName = __FUNCTION__;
259
  $templateContent = __FUNCTION__;
260
 
261
- $cache = $this->getMockBuilder('Twig_CacheInterface')->getMock();
262
  $loader = $this->getMockLoader($templateName, $templateContent);
263
- $twig = new Twig_Environment($loader, ['cache' => $cache, 'auto_reload' => true, 'debug' => false]);
264
 
265
  $now = time();
266
 
@@ -286,7 +301,7 @@ class Twig_Tests_EnvironmentTest extends \PHPUnit\Framework\TestCase
286
  */
287
  public function testHasGetExtensionWithDynamicName()
288
  {
289
- $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
290
 
291
  $ext1 = new Twig_Tests_EnvironmentTest_Extension_DynamicWithDeprecatedName('ext1');
292
  $ext2 = new Twig_Tests_EnvironmentTest_Extension_DynamicWithDeprecatedName('ext2');
@@ -304,7 +319,7 @@ class Twig_Tests_EnvironmentTest extends \PHPUnit\Framework\TestCase
304
 
305
  public function testHasGetExtensionByClassName()
306
  {
307
- $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
308
  $twig->addExtension($ext = new Twig_Tests_EnvironmentTest_Extension());
309
  $this->assertTrue($twig->hasExtension('Twig_Tests_EnvironmentTest_Extension'));
310
  $this->assertTrue($twig->hasExtension('\Twig_Tests_EnvironmentTest_Extension'));
@@ -318,7 +333,7 @@ class Twig_Tests_EnvironmentTest extends \PHPUnit\Framework\TestCase
318
 
319
  public function testAddExtension()
320
  {
321
- $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
322
  $twig->addExtension(new Twig_Tests_EnvironmentTest_Extension());
323
 
324
  $this->assertArrayHasKey('test', $twig->getTags());
@@ -343,7 +358,7 @@ class Twig_Tests_EnvironmentTest extends \PHPUnit\Framework\TestCase
343
  */
344
  public function testAddExtensionWithDeprecatedGetGlobals()
345
  {
346
- $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
347
  $twig->addExtension(new Twig_Tests_EnvironmentTest_Extension_WithGlobals());
348
 
349
  $this->deprecations = [];
@@ -362,7 +377,7 @@ class Twig_Tests_EnvironmentTest extends \PHPUnit\Framework\TestCase
362
  */
363
  public function testRemoveExtension()
364
  {
365
- $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
366
  $twig->addExtension(new Twig_Tests_EnvironmentTest_Extension_WithDeprecatedName());
367
  $twig->removeExtension('environment_test');
368
 
@@ -379,27 +394,29 @@ class Twig_Tests_EnvironmentTest extends \PHPUnit\Framework\TestCase
379
  public function testAddMockExtension()
380
  {
381
  // should be replaced by the following in 2.0 (this current code is just to avoid a dep notice)
382
- // $extension = $this->getMockBuilder('Twig_Extension')->getMock();
383
  $extension = eval(<<<EOF
384
- class Twig_Tests_EnvironmentTest_ExtensionInEval extends Twig_Extension
 
 
385
  {
386
  }
387
  EOF
388
  );
389
  $extension = new Twig_Tests_EnvironmentTest_ExtensionInEval();
390
 
391
- $loader = new Twig_Loader_Array(['page' => 'hey']);
392
 
393
- $twig = new Twig_Environment($loader);
394
  $twig->addExtension($extension);
395
 
396
- $this->assertInstanceOf('Twig_ExtensionInterface', $twig->getExtension(get_class($extension)));
397
  $this->assertTrue($twig->isTemplateFresh('page', time()));
398
  }
399
 
400
  public function testInitRuntimeWithAnExtensionUsingInitRuntimeNoDeprecation()
401
  {
402
- $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
403
  $twig->addExtension(new Twig_Tests_EnvironmentTest_ExtensionWithoutDeprecationInitRuntime());
404
  $twig->initRuntime();
405
 
@@ -413,7 +430,7 @@ EOF
413
  */
414
  public function testInitRuntimeWithAnExtensionUsingInitRuntimeDeprecation()
415
  {
416
- $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
417
  $twig->addExtension(new Twig_Tests_EnvironmentTest_ExtensionWithDeprecationInitRuntime());
418
 
419
  $this->deprecations = [];
@@ -439,7 +456,7 @@ EOF
439
  */
440
  public function testOverrideExtension()
441
  {
442
- $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
443
  $twig->addExtension(new Twig_Tests_EnvironmentTest_ExtensionWithDeprecationInitRuntime());
444
 
445
  $this->deprecations = [];
@@ -456,10 +473,10 @@ EOF
456
 
457
  public function testAddRuntimeLoader()
458
  {
459
- $runtimeLoader = $this->getMockBuilder('Twig_RuntimeLoaderInterface')->getMock();
460
  $runtimeLoader->expects($this->any())->method('load')->will($this->returnValue(new Twig_Tests_EnvironmentTest_Runtime()));
461
 
462
- $loader = new Twig_Loader_Array([
463
  'func_array' => '{{ from_runtime_array("foo") }}',
464
  'func_array_default' => '{{ from_runtime_array() }}',
465
  'func_array_named_args' => '{{ from_runtime_array(name="foo") }}',
@@ -468,7 +485,7 @@ EOF
468
  'func_string_named_args' => '{{ from_runtime_string(name="foo") }}',
469
  ]);
470
 
471
- $twig = new Twig_Environment($loader);
472
  $twig->addExtension(new Twig_Tests_EnvironmentTest_ExtensionWithoutRuntime());
473
  $twig->addRuntimeLoader($runtimeLoader);
474
 
@@ -481,12 +498,12 @@ EOF
481
  }
482
 
483
  /**
484
- * @expectedException Twig_Error_Runtime
485
  * @expectedExceptionMessage Circular reference detected for Twig template "base.html.twig", path: base.html.twig -> base.html.twig in "base.html.twig" at line 1
486
  */
487
  public function testFailLoadTemplateOnCircularReference()
488
  {
489
- $twig = new Twig_Environment(new Twig_Loader_Array([
490
  'base.html.twig' => '{% extends "base.html.twig" %}',
491
  ]));
492
 
@@ -494,12 +511,12 @@ EOF
494
  }
495
 
496
  /**
497
- * @expectedException Twig_Error_Runtime
498
  * @expectedExceptionMessage Circular reference detected for Twig template "base1.html.twig", path: base1.html.twig -> base2.html.twig -> base1.html.twig in "base1.html.twig" at line 1
499
  */
500
  public function testFailLoadTemplateOnComplexCircularReference()
501
  {
502
- $twig = new Twig_Environment(new Twig_Loader_Array([
503
  'base1.html.twig' => '{% extends "base2.html.twig" %}',
504
  'base2.html.twig' => '{% extends "base1.html.twig" %}',
505
  ]));
@@ -511,11 +528,11 @@ EOF
511
  {
512
  // to be removed in 2.0
513
  $loader = $this->getMockBuilder('Twig_EnvironmentTestLoaderInterface')->getMock();
514
- //$loader = $this->getMockBuilder(['Twig_LoaderInterface', 'Twig_SourceContextLoaderInterface'])->getMock();
515
  $loader->expects($this->any())
516
  ->method('getSourceContext')
517
  ->with($templateName)
518
- ->will($this->returnValue(new Twig_Source($templateContent, $templateName)));
519
  $loader->expects($this->any())
520
  ->method('getCacheKey')
521
  ->with($templateName)
@@ -525,7 +542,7 @@ EOF
525
  }
526
  }
527
 
528
- class Twig_Tests_EnvironmentTest_Extension_WithGlobals extends Twig_Extension
529
  {
530
  public function getGlobals()
531
  {
@@ -535,7 +552,7 @@ class Twig_Tests_EnvironmentTest_Extension_WithGlobals extends Twig_Extension
535
  }
536
  }
537
 
538
- class Twig_Tests_EnvironmentTest_Extension extends Twig_Extension implements Twig_Extension_GlobalsInterface
539
  {
540
  public function getTokenParsers()
541
  {
@@ -554,21 +571,21 @@ class Twig_Tests_EnvironmentTest_Extension extends Twig_Extension implements Twi
554
  public function getFilters()
555
  {
556
  return [
557
- new Twig_SimpleFilter('foo_filter', 'foo_filter'),
558
  ];
559
  }
560
 
561
  public function getTests()
562
  {
563
  return [
564
- new Twig_SimpleTest('foo_test', 'foo_test'),
565
  ];
566
  }
567
 
568
  public function getFunctions()
569
  {
570
  return [
571
- new Twig_SimpleFunction('foo_function', 'foo_function'),
572
  ];
573
  }
574
 
@@ -589,7 +606,7 @@ class Twig_Tests_EnvironmentTest_Extension extends Twig_Extension implements Twi
589
  }
590
  class_alias('Twig_Tests_EnvironmentTest_Extension', 'Twig\Tests\EnvironmentTest\Extension', false);
591
 
592
- class Twig_Tests_EnvironmentTest_Extension_WithDeprecatedName extends Twig_Extension
593
  {
594
  public function getName()
595
  {
@@ -597,7 +614,7 @@ class Twig_Tests_EnvironmentTest_Extension_WithDeprecatedName extends Twig_Exten
597
  }
598
  }
599
 
600
- class Twig_Tests_EnvironmentTest_Extension_DynamicWithDeprecatedName extends Twig_Extension
601
  {
602
  private $name;
603
 
@@ -612,9 +629,9 @@ class Twig_Tests_EnvironmentTest_Extension_DynamicWithDeprecatedName extends Twi
612
  }
613
  }
614
 
615
- class Twig_Tests_EnvironmentTest_TokenParser extends Twig_TokenParser
616
  {
617
- public function parse(Twig_Token $token)
618
  {
619
  }
620
 
@@ -624,14 +641,14 @@ class Twig_Tests_EnvironmentTest_TokenParser extends Twig_TokenParser
624
  }
625
  }
626
 
627
- class Twig_Tests_EnvironmentTest_NodeVisitor implements Twig_NodeVisitorInterface
628
  {
629
- public function enterNode(Twig_NodeInterface $node, Twig_Environment $env)
630
  {
631
  return $node;
632
  }
633
 
634
- public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env)
635
  {
636
  return $node;
637
  }
@@ -642,27 +659,27 @@ class Twig_Tests_EnvironmentTest_NodeVisitor implements Twig_NodeVisitorInterfac
642
  }
643
  }
644
 
645
- class Twig_Tests_EnvironmentTest_ExtensionWithDeprecationInitRuntime extends Twig_Extension
646
  {
647
- public function initRuntime(Twig_Environment $env)
648
  {
649
  }
650
  }
651
 
652
- class Twig_Tests_EnvironmentTest_ExtensionWithoutDeprecationInitRuntime extends Twig_Extension implements Twig_Extension_InitRuntimeInterface
653
  {
654
- public function initRuntime(Twig_Environment $env)
655
  {
656
  }
657
  }
658
 
659
- class Twig_Tests_EnvironmentTest_ExtensionWithoutRuntime extends Twig_Extension
660
  {
661
  public function getFunctions()
662
  {
663
  return [
664
- new Twig_SimpleFunction('from_runtime_array', ['Twig_Tests_EnvironmentTest_Runtime', 'fromRuntime']),
665
- new Twig_SimpleFunction('from_runtime_string', 'Twig_Tests_EnvironmentTest_Runtime::fromRuntime'),
666
  ];
667
  }
668
 
@@ -681,6 +698,6 @@ class Twig_Tests_EnvironmentTest_Runtime
681
  }
682
 
683
  // to be removed in 2.0
684
- interface Twig_EnvironmentTestLoaderInterface extends Twig_LoaderInterface, Twig_SourceContextLoaderInterface
685
  {
686
  }
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Cache\FilesystemCache;
13
+ use Twig\Environment;
14
+ use Twig\Extension\AbstractExtension;
15
+ use Twig\Extension\GlobalsInterface;
16
+ use Twig\Extension\InitRuntimeInterface;
17
+ use Twig\Loader\ArrayLoader;
18
+ use Twig\Loader\LoaderInterface;
19
+ use Twig\NodeVisitor\NodeVisitorInterface;
20
+ use Twig\Source;
21
+ use Twig\Token;
22
+ use Twig\TokenParser\AbstractTokenParser;
23
+ use Twig\TwigFilter;
24
+ use Twig\TwigFunction;
25
+ use Twig\TwigTest;
26
+
27
+ require_once __DIR__.'/FilesystemHelper.php';
28
 
29
  class Twig_Tests_EnvironmentTest extends \PHPUnit\Framework\TestCase
30
  {
35
  */
36
  public function testLegacyTokenizeSignature()
37
  {
38
+ $env = new Environment();
39
  $stream = $env->tokenize('{{ foo }}', 'foo');
40
  $this->assertEquals('{{ foo }}', $stream->getSource());
41
  $this->assertEquals('foo', $stream->getFilename());
46
  */
47
  public function testLegacyCompileSourceSignature()
48
  {
49
+ $loader = new ArrayLoader(['foo' => '{{ foo }}']);
50
+ $env = new Environment($loader);
51
  $this->assertContains('getTemplateName', $env->compileSource('{{ foo }}', 'foo'));
52
  }
53
 
54
  /**
55
+ * @expectedException \LogicException
56
  * @expectedExceptionMessage You must set a loader first.
57
  * @group legacy
58
  */
59
  public function testRenderNoLoader()
60
  {
61
+ $env = new Environment();
62
  $env->render('test');
63
  }
64
 
65
  public function testAutoescapeOption()
66
  {
67
+ $loader = new ArrayLoader([
68
  'html' => '{{ foo }} {{ foo }}',
69
  'js' => '{{ bar }} {{ bar }}',
70
  ]);
71
 
72
+ $twig = new Environment($loader, [
73
  'debug' => true,
74
  'cache' => false,
75
  'autoescape' => [$this, 'escapingStrategyCallback'],
88
  {
89
  // to be removed in 2.0
90
  $loader = $this->getMockBuilder('Twig_EnvironmentTestLoaderInterface')->getMock();
91
+ //$loader = $this->getMockBuilder(['\Twig\Loader\LoaderInterface', '\Twig\Loader\SourceContextLoaderInterface'])->getMock();
92
+ $loader->expects($this->any())->method('getSourceContext')->will($this->returnValue(new Source('', '')));
93
 
94
  // globals can be added after calling getGlobals
95
 
96
+ $twig = new Environment($loader);
97
  $twig->addGlobal('foo', 'foo');
98
  $twig->getGlobals();
99
  $twig->addGlobal('foo', 'bar');
101
  $this->assertEquals('bar', $globals['foo']);
102
 
103
  // globals can be modified after a template has been loaded
104
+ $twig = new Environment($loader);
105
  $twig->addGlobal('foo', 'foo');
106
  $twig->getGlobals();
107
  $twig->loadTemplate('index');
110
  $this->assertEquals('bar', $globals['foo']);
111
 
112
  // globals can be modified after extensions init
113
+ $twig = new Environment($loader);
114
  $twig->addGlobal('foo', 'foo');
115
  $twig->getGlobals();
116
  $twig->getFunctions();
119
  $this->assertEquals('bar', $globals['foo']);
120
 
121
  // globals can be modified after extensions and a template has been loaded
122
+ $arrayLoader = new ArrayLoader(['index' => '{{foo}}']);
123
+ $twig = new Environment($arrayLoader);
124
  $twig->addGlobal('foo', 'foo');
125
  $twig->getGlobals();
126
  $twig->getFunctions();
129
  $globals = $twig->getGlobals();
130
  $this->assertEquals('bar', $globals['foo']);
131
 
132
+ $twig = new Environment($arrayLoader);
133
  $twig->getGlobals();
134
  $twig->addGlobal('foo', 'bar');
135
  $template = $twig->loadTemplate('index');
137
 
138
  /* to be uncomment in Twig 2.0
139
  // globals cannot be added after a template has been loaded
140
+ $twig = new Environment($loader);
141
  $twig->addGlobal('foo', 'foo');
142
  $twig->getGlobals();
143
  $twig->loadTemplate('index');
144
  try {
145
  $twig->addGlobal('bar', 'bar');
146
  $this->fail();
147
+ } catch (\LogicException $e) {
148
  $this->assertFalse(array_key_exists('bar', $twig->getGlobals()));
149
  }
150
 
151
  // globals cannot be added after extensions init
152
+ $twig = new Environment($loader);
153
  $twig->addGlobal('foo', 'foo');
154
  $twig->getGlobals();
155
  $twig->getFunctions();
156
  try {
157
  $twig->addGlobal('bar', 'bar');
158
  $this->fail();
159
+ } catch (\LogicException $e) {
160
  $this->assertFalse(array_key_exists('bar', $twig->getGlobals()));
161
  }
162
 
163
  // globals cannot be added after extensions and a template has been loaded
164
+ $twig = new Environment($loader);
165
  $twig->addGlobal('foo', 'foo');
166
  $twig->getGlobals();
167
  $twig->getFunctions();
169
  try {
170
  $twig->addGlobal('bar', 'bar');
171
  $this->fail();
172
+ } catch (\LogicException $e) {
173
  $this->assertFalse(array_key_exists('bar', $twig->getGlobals()));
174
  }
175
 
176
  // test adding globals after a template has been loaded without call to getGlobals
177
+ $twig = new Environment($loader);
178
  $twig->loadTemplate('index');
179
  try {
180
  $twig->addGlobal('bar', 'bar');
181
  $this->fail();
182
+ } catch (\LogicException $e) {
183
  $this->assertFalse(array_key_exists('bar', $twig->getGlobals()));
184
  }
185
  */
187
 
188
  public function testExtensionsAreNotInitializedWhenRenderingACompiledTemplate()
189
  {
190
+ $cache = new FilesystemCache($dir = sys_get_temp_dir().'/twig');
191
  $options = ['cache' => $cache, 'auto_reload' => false, 'debug' => false];
192
 
193
  // force compilation
194
+ $twig = new Environment($loader = new ArrayLoader(['index' => '{{ foo }}']), $options);
195
 
196
  $key = $cache->generateKey('index', $twig->getTemplateClass('index'));
197
+ $cache->write($key, $twig->compileSource(new Source('{{ foo }}', 'index')));
198
 
199
  // check that extensions won't be initialized when rendering a template that is already in the cache
200
  $twig = $this
201
+ ->getMockBuilder('\Twig\Environment')
202
  ->setConstructorArgs([$loader, $options])
203
  ->setMethods(['initExtensions'])
204
  ->getMock()
218
  $templateName = __FUNCTION__;
219
  $templateContent = __FUNCTION__;
220
 
221
+ $cache = $this->getMockBuilder('\Twig\Cache\CacheInterface')->getMock();
222
  $loader = $this->getMockLoader($templateName, $templateContent);
223
+ $twig = new Environment($loader, ['cache' => $cache, 'auto_reload' => true, 'debug' => false]);
224
 
225
  // Cache miss: getTimestamp returns 0 and as a result the load() is
226
  // skipped.
245
  $templateName = __FUNCTION__;
246
  $templateContent = __FUNCTION__;
247
 
248
+ $cache = $this->getMockBuilder('\Twig\Cache\CacheInterface')->getMock();
249
  $loader = $this->getMockLoader($templateName, $templateContent);
250
+ $twig = new Environment($loader, ['cache' => $cache, 'auto_reload' => true, 'debug' => false]);
251
 
252
  $now = time();
253
 
273
  $templateName = __FUNCTION__;
274
  $templateContent = __FUNCTION__;
275
 
276
+ $cache = $this->getMockBuilder('\Twig\Cache\CacheInterface')->getMock();
277
  $loader = $this->getMockLoader($templateName, $templateContent);
278
+ $twig = new Environment($loader, ['cache' => $cache, 'auto_reload' => true, 'debug' => false]);
279
 
280
  $now = time();
281
 
301
  */
302
  public function testHasGetExtensionWithDynamicName()
303
  {
304
+ $twig = new Environment($this->getMockBuilder('\Twig\Loader\LoaderInterface')->getMock());
305
 
306
  $ext1 = new Twig_Tests_EnvironmentTest_Extension_DynamicWithDeprecatedName('ext1');
307
  $ext2 = new Twig_Tests_EnvironmentTest_Extension_DynamicWithDeprecatedName('ext2');
319
 
320
  public function testHasGetExtensionByClassName()
321
  {
322
+ $twig = new Environment($this->getMockBuilder('\Twig\Loader\LoaderInterface')->getMock());
323
  $twig->addExtension($ext = new Twig_Tests_EnvironmentTest_Extension());
324
  $this->assertTrue($twig->hasExtension('Twig_Tests_EnvironmentTest_Extension'));
325
  $this->assertTrue($twig->hasExtension('\Twig_Tests_EnvironmentTest_Extension'));
333
 
334
  public function testAddExtension()
335
  {
336
+ $twig = new Environment($this->getMockBuilder('\Twig\Loader\LoaderInterface')->getMock());
337
  $twig->addExtension(new Twig_Tests_EnvironmentTest_Extension());
338
 
339
  $this->assertArrayHasKey('test', $twig->getTags());
358
  */
359
  public function testAddExtensionWithDeprecatedGetGlobals()
360
  {
361
+ $twig = new Environment($this->getMockBuilder('\Twig\Loader\LoaderInterface')->getMock());
362
  $twig->addExtension(new Twig_Tests_EnvironmentTest_Extension_WithGlobals());
363
 
364
  $this->deprecations = [];
377
  */
378
  public function testRemoveExtension()
379
  {
380
+ $twig = new Environment($this->getMockBuilder('\Twig\Loader\LoaderInterface')->getMock());
381
  $twig->addExtension(new Twig_Tests_EnvironmentTest_Extension_WithDeprecatedName());
382
  $twig->removeExtension('environment_test');
383
 
394
  public function testAddMockExtension()
395
  {
396
  // should be replaced by the following in 2.0 (this current code is just to avoid a dep notice)
397
+ // $extension = $this->getMockBuilder('\Twig\Extension\AbstractExtension')->getMock();
398
  $extension = eval(<<<EOF
399
+ use Twig\Extension\AbstractExtension;
400
+
401
+ class Twig_Tests_EnvironmentTest_ExtensionInEval extends AbstractExtension
402
  {
403
  }
404
  EOF
405
  );
406
  $extension = new Twig_Tests_EnvironmentTest_ExtensionInEval();
407
 
408
+ $loader = new ArrayLoader(['page' => 'hey']);
409
 
410
+ $twig = new Environment($loader);
411
  $twig->addExtension($extension);
412
 
413
+ $this->assertInstanceOf('\Twig\Extension\ExtensionInterface', $twig->getExtension(\get_class($extension)));
414
  $this->assertTrue($twig->isTemplateFresh('page', time()));
415
  }
416
 
417
  public function testInitRuntimeWithAnExtensionUsingInitRuntimeNoDeprecation()
418
  {
419
+ $twig = new Environment($this->getMockBuilder('\Twig\Loader\LoaderInterface')->getMock());
420
  $twig->addExtension(new Twig_Tests_EnvironmentTest_ExtensionWithoutDeprecationInitRuntime());
421
  $twig->initRuntime();
422
 
430
  */
431
  public function testInitRuntimeWithAnExtensionUsingInitRuntimeDeprecation()
432
  {
433
+ $twig = new Environment($this->getMockBuilder('\Twig\Loader\LoaderInterface')->getMock());
434
  $twig->addExtension(new Twig_Tests_EnvironmentTest_ExtensionWithDeprecationInitRuntime());
435
 
436
  $this->deprecations = [];
456
  */
457
  public function testOverrideExtension()
458
  {
459
+ $twig = new Environment($this->getMockBuilder('\Twig\Loader\LoaderInterface')->getMock());
460
  $twig->addExtension(new Twig_Tests_EnvironmentTest_ExtensionWithDeprecationInitRuntime());
461
 
462
  $this->deprecations = [];
473
 
474
  public function testAddRuntimeLoader()
475
  {
476
+ $runtimeLoader = $this->getMockBuilder('\Twig\RuntimeLoader\RuntimeLoaderInterface')->getMock();
477
  $runtimeLoader->expects($this->any())->method('load')->will($this->returnValue(new Twig_Tests_EnvironmentTest_Runtime()));
478
 
479
+ $loader = new ArrayLoader([
480
  'func_array' => '{{ from_runtime_array("foo") }}',
481
  'func_array_default' => '{{ from_runtime_array() }}',
482
  'func_array_named_args' => '{{ from_runtime_array(name="foo") }}',
485
  'func_string_named_args' => '{{ from_runtime_string(name="foo") }}',
486
  ]);
487
 
488
+ $twig = new Environment($loader);
489
  $twig->addExtension(new Twig_Tests_EnvironmentTest_ExtensionWithoutRuntime());
490
  $twig->addRuntimeLoader($runtimeLoader);
491
 
498
  }
499
 
500
  /**
501
+ * @expectedException \Twig\Error\RuntimeError
502
  * @expectedExceptionMessage Circular reference detected for Twig template "base.html.twig", path: base.html.twig -> base.html.twig in "base.html.twig" at line 1
503
  */
504
  public function testFailLoadTemplateOnCircularReference()
505
  {
506
+ $twig = new Environment(new ArrayLoader([
507
  'base.html.twig' => '{% extends "base.html.twig" %}',
508
  ]));
509
 
511
  }
512
 
513
  /**
514
+ * @expectedException \Twig\Error\RuntimeError
515
  * @expectedExceptionMessage Circular reference detected for Twig template "base1.html.twig", path: base1.html.twig -> base2.html.twig -> base1.html.twig in "base1.html.twig" at line 1
516
  */
517
  public function testFailLoadTemplateOnComplexCircularReference()
518
  {
519
+ $twig = new Environment(new ArrayLoader([
520
  'base1.html.twig' => '{% extends "base2.html.twig" %}',
521
  'base2.html.twig' => '{% extends "base1.html.twig" %}',
522
  ]));
528
  {
529
  // to be removed in 2.0
530
  $loader = $this->getMockBuilder('Twig_EnvironmentTestLoaderInterface')->getMock();
531
+ //$loader = $this->getMockBuilder(['\Twig\Loader\LoaderInterface', '\Twig\Loader\SourceContextLoaderInterface'])->getMock();
532
  $loader->expects($this->any())
533
  ->method('getSourceContext')
534
  ->with($templateName)
535
+ ->will($this->returnValue(new Source($templateContent, $templateName)));
536
  $loader->expects($this->any())
537
  ->method('getCacheKey')
538
  ->with($templateName)
542
  }
543
  }
544
 
545
+ class Twig_Tests_EnvironmentTest_Extension_WithGlobals extends AbstractExtension
546
  {
547
  public function getGlobals()
548
  {
552
  }
553
  }
554
 
555
+ class Twig_Tests_EnvironmentTest_Extension extends AbstractExtension implements GlobalsInterface
556
  {
557
  public function getTokenParsers()
558
  {
571
  public function getFilters()
572
  {
573
  return [
574
+ new TwigFilter('foo_filter', 'foo_filter'),
575
  ];
576
  }
577
 
578
  public function getTests()
579
  {
580
  return [
581
+ new TwigTest('foo_test', 'foo_test'),
582
  ];
583
  }
584
 
585
  public function getFunctions()
586
  {
587
  return [
588
+ new TwigFunction('foo_function', 'foo_function'),
589
  ];
590
  }
591
 
606
  }
607
  class_alias('Twig_Tests_EnvironmentTest_Extension', 'Twig\Tests\EnvironmentTest\Extension', false);
608
 
609
+ class Twig_Tests_EnvironmentTest_Extension_WithDeprecatedName extends AbstractExtension
610
  {
611
  public function getName()
612
  {
614
  }
615
  }
616
 
617
+ class Twig_Tests_EnvironmentTest_Extension_DynamicWithDeprecatedName extends AbstractExtension
618
  {
619
  private $name;
620
 
629
  }
630
  }
631
 
632
+ class Twig_Tests_EnvironmentTest_TokenParser extends AbstractTokenParser
633
  {
634
+ public function parse(Token $token)
635
  {
636
  }
637
 
641
  }
642
  }
643
 
644
+ class Twig_Tests_EnvironmentTest_NodeVisitor implements NodeVisitorInterface
645
  {
646
+ public function enterNode(Twig_NodeInterface $node, Environment $env)
647
  {
648
  return $node;
649
  }
650
 
651
+ public function leaveNode(Twig_NodeInterface $node, Environment $env)
652
  {
653
  return $node;
654
  }
659
  }
660
  }
661
 
662
+ class Twig_Tests_EnvironmentTest_ExtensionWithDeprecationInitRuntime extends AbstractExtension
663
  {
664
+ public function initRuntime(Environment $env)
665
  {
666
  }
667
  }
668
 
669
+ class Twig_Tests_EnvironmentTest_ExtensionWithoutDeprecationInitRuntime extends AbstractExtension implements InitRuntimeInterface
670
  {
671
+ public function initRuntime(Environment $env)
672
  {
673
  }
674
  }
675
 
676
+ class Twig_Tests_EnvironmentTest_ExtensionWithoutRuntime extends AbstractExtension
677
  {
678
  public function getFunctions()
679
  {
680
  return [
681
+ new TwigFunction('from_runtime_array', ['Twig_Tests_EnvironmentTest_Runtime', 'fromRuntime']),
682
+ new TwigFunction('from_runtime_string', 'Twig_Tests_EnvironmentTest_Runtime::fromRuntime'),
683
  ];
684
  }
685
 
698
  }
699
 
700
  // to be removed in 2.0
701
+ interface Twig_EnvironmentTestLoaderInterface extends LoaderInterface, Twig_SourceContextLoaderInterface
702
  {
703
  }
vendor/twig/twig/test/Twig/Tests/ErrorTest.php CHANGED
@@ -9,27 +9,34 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
 
 
 
 
12
  class Twig_Tests_ErrorTest extends \PHPUnit\Framework\TestCase
13
  {
14
  public function testErrorWithObjectFilename()
15
  {
16
- $error = new Twig_Error('foo');
17
- $error->setSourceContext(new Twig_Source('', new SplFileInfo(__FILE__)));
18
 
19
  $this->assertContains('test'.DIRECTORY_SEPARATOR.'Twig'.DIRECTORY_SEPARATOR.'Tests'.DIRECTORY_SEPARATOR.'ErrorTest.php', $error->getMessage());
20
  }
21
 
22
  public function testErrorWithArrayFilename()
23
  {
24
- $error = new Twig_Error('foo');
25
- $error->setSourceContext(new Twig_Source('', ['foo' => 'bar']));
26
 
27
  $this->assertEquals('foo in {"foo":"bar"}', $error->getMessage());
28
  }
29
 
30
  public function testTwigExceptionGuessWithMissingVarAndArrayLoader()
31
  {
32
- $loader = new Twig_Loader_Array([
33
  'base.html' => '{% block content %}{% endblock %}',
34
  'index.html' => <<<EOHTML
35
  {% extends 'base.html' %}
@@ -41,14 +48,14 @@ class Twig_Tests_ErrorTest extends \PHPUnit\Framework\TestCase
41
  {% endblock %}
42
  EOHTML
43
  ]);
44
- $twig = new Twig_Environment($loader, ['strict_variables' => true, 'debug' => true, 'cache' => false]);
45
 
46
  $template = $twig->loadTemplate('index.html');
47
  try {
48
  $template->render([]);
49
 
50
  $this->fail();
51
- } catch (Twig_Error_Runtime $e) {
52
  $this->assertEquals('Variable "foo" does not exist in "index
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use Twig\Environment;
13
+ use Twig\Error\Error;
14
+ use Twig\Error\RuntimeError;
15
+ use Twig\Loader\ArrayLoader;
16
+ use Twig\Loader\FilesystemLoader;
17
+ use Twig\Source;
18
+
19
  class Twig_Tests_ErrorTest extends \PHPUnit\Framework\TestCase
20
  {
21
  public function testErrorWithObjectFilename()
22
  {
23
+ $error = new Error('foo');
24
+ $error->setSourceContext(new Source('', new \SplFileInfo(__FILE__)));
25
 
26
  $this->assertContains('test'.DIRECTORY_SEPARATOR.'Twig'.DIRECTORY_SEPARATOR.'Tests'.DIRECTORY_SEPARATOR.'ErrorTest.php', $error->getMessage());
27
  }
28
 
29
  public function testErrorWithArrayFilename()
30
  {
31
+ $error = new Error('foo');
32
+ $error->setSourceContext(new Source('', ['foo' => 'bar']));
33
 
34
  $this->assertEquals('foo in {"foo":"bar"}', $error->getMessage());
35
  }
36
 
37
  public function testTwigExceptionGuessWithMissingVarAndArrayLoader()
38
  {
39
+ $loader = new ArrayLoader([
40
  'base.html' => '{% block content %}{% endblock %}',
41
  'index.html' => <<<EOHTML
42
  {% extends 'base.html' %}
48
  {% endblock %}
49
  EOHTML
50
  ]);
51
+ $twig = new Environment($loader, ['strict_variables' => true, 'debug' => true, 'cache' => false]);
52
 
53
  $template = $twig->loadTemplate('index.html');
54
  try {
55
  $template->render([]);
56
 
57
  $this->fail();
58
+ } catch (RuntimeError $e) {
59
  $this->assertEquals('Variable "foo" does not exist in "index